Merge "Implementation of connectivity abstraction feature Release v0.5" into connecti...
authorsudarshan prasad <sudarshan.prasad@intel.com>
Thu, 11 Dec 2014 23:33:53 +0000 (15:33 -0800)
committerGerrit Code Review <gerrit@oicreview.vlan14.01.org>
Thu, 11 Dec 2014 23:33:53 +0000 (15:33 -0800)
360 files changed:
resource/csdk/connectivity/RELEASE v0.5 [new file with mode: 0644]
resource/csdk/connectivity/api/cacommon.h
resource/csdk/connectivity/api/cainterface.h
resource/csdk/connectivity/build/android/Makefile [new file with mode: 0644]
resource/csdk/connectivity/build/android/jni/Android.mk [new file with mode: 0644]
resource/csdk/connectivity/build/android/jni/Application.mk [new file with mode: 0644]
resource/csdk/connectivity/build/arduino/Makefile
resource/csdk/connectivity/build/linux/Makefile
resource/csdk/connectivity/build/tizen/README.txt [new file with mode: 0644]
resource/csdk/connectivity/build/tizen/gbsbuild.sh
resource/csdk/connectivity/common/inc/logger.h
resource/csdk/connectivity/common/inc/umutex.h
resource/csdk/connectivity/common/src/umutex.c
resource/csdk/connectivity/common/src/uthreadpool.c
resource/csdk/connectivity/doc/release/RELEASE v0.4 [moved from resource/csdk/connectivity/RELEASE v0.4 with 100% similarity]
resource/csdk/connectivity/inc/caadapterutils.h
resource/csdk/connectivity/inc/caedradapter.h
resource/csdk/connectivity/inc/caedradapter_singlethread.h
resource/csdk/connectivity/inc/caethernetadapter.h
resource/csdk/connectivity/inc/caethernetcore.h [deleted file]
resource/csdk/connectivity/inc/caethernetinterface.h [new file with mode: 0644]
resource/csdk/connectivity/inc/cainterfacecontroller.h
resource/csdk/connectivity/inc/caleadapter.h
resource/csdk/connectivity/inc/calecore.h
resource/csdk/connectivity/inc/camessagehandler.h
resource/csdk/connectivity/inc/camsgparser.h
resource/csdk/connectivity/inc/canetworkconfigurator.h
resource/csdk/connectivity/inc/caprotocolmessage.h
resource/csdk/connectivity/inc/caqueueingthread.h
resource/csdk/connectivity/inc/caremotehandler.h
resource/csdk/connectivity/inc/cawifiadapter.h
resource/csdk/connectivity/inc/cawificore.h [deleted file]
resource/csdk/connectivity/inc/cawifiinterface.h [new file with mode: 0644]
resource/csdk/connectivity/inc/com_iotivity_jar_CALeInterface.h [new file with mode: 0644]
resource/csdk/connectivity/inc/com_iotivity_jar_CAWiFiInterface.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/Android.mk [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/android-internal/config.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/android/glibconfig.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/Android.mk [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/Makefile.am [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/abicheck.sh [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/galloca.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/garray.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/garray.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gasyncqueue.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gasyncqueue.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gatomic-gcc.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gatomic.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gatomic.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gbacktrace.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gbacktrace.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gbase64.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gbase64.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gbitlock.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gbitlock.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gbookmarkfile.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gbookmarkfile.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gbsearcharray.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gbuffer.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gbuffer.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gcache.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gcache.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gchecksum.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gchecksum.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gcompletion.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gcompletion.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gconvert.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gconvert.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gdataset.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gdataset.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gdatasetprivate.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gdate.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gdate.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gdatetime.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gdatetime.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gdebug.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gdir.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gdir.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gen-script-table.pl [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gen-unicode-tables.pl [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gerror.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gerror.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gfileutils.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gfileutils.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/ghash.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/ghash.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/ghook.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/ghook.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/ghostutils.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/ghostutils.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gi18n-lib.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gi18n.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/giochannel.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/giochannel.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/giounix.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/giowin32.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gkeyfile.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gkeyfile.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glib-mirroring-tab/Makefile [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glib-mirroring-tab/gen-mirroring-tab.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glib-mirroring-tab/packtab.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glib-mirroring-tab/packtab.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glib-object.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glib.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glib.py [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glib.rc.in [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glib.stp.in [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glib.symbols [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glib_probes.d [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glib_trace.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glibconfig.h.win32.in [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glibintl.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glist.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/glist.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gmacros.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gmain.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gmain.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gmappedfile.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gmappedfile.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gmarkup.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gmarkup.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gmem.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gmem.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gmessages.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gmessages.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gmirroringtable.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnode.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnode.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/Makefile.am [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/README [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/asnprintf.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/g-gnulib.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/makefile.msc [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf-args.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf-args.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf-parse.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf-parse.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/vasnprintf.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/vasnprintf.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/goption.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/goption.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gpattern.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gpattern.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gpoll.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gpoll.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gprimes.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gprimes.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gprintf.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gprintf.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gprintfint.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gqsort.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gqsort.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gquark.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gqueue.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gqueue.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/grand.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/grand.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gregex.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gregex.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/grel.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/grel.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gscanner.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gscanner.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gscripttable.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gsequence.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gsequence.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gshell.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gshell.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gslice.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gslice.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gslist.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gslist.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gspawn-win32-helper.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gspawn-win32.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gspawn.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gspawn.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gstdio.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gstdio.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gstrfuncs.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gstrfuncs.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gstring.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gstring.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gtester-report [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gtester.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gtestutils.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gtestutils.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gthread.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gthread.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gthreadpool.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gthreadpool.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gthreadprivate.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gtimer.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gtimer.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gtimezone.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gtimezone.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gtimezoneprivate.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gtree.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gtree.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gtypes.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gunibreak.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gunibreak.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gunichartables.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gunicode.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gunicodeprivate.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gunicollate.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gunicomp.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gunidecomp.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gunidecomp.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/guniprop.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gurifuncs.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gurifuncs.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gutf8.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gutils.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gutils.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-core.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-core.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-internal.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-parser.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-serialiser.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-serialiser.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gvariant.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gvariant.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gvarianttype.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gvarianttype.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gvarianttypeinfo.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gvarianttypeinfo.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gwin32.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/gwin32.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/.gitignore [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/Makefile.am [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/README [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/codeset.m4 [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/config.charset [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/glibc21.m4 [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/libcharset-glib.patch [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/libcharset.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/localcharset.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/localcharset.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/make-patch.sh [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/ref-add.sin [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/ref-del.sin [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/update.sh [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/libglib-gdb.py.in [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/makefile.msc.in [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/Android.mk [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/COPYING [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/Makefile.am [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/makefile.msc [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_chartables.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_compile.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_config.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_dfa_exec.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_exec.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_fullinfo.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_get.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_globals.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_internal.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_newline.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_ord2utf8.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_study.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_tables.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_try_flipped.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_ucp_searchfuncs.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_xclass.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/pcre/ucp.h [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/glib/win_iconv.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/.gitignore [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/Android.mk [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/ChangeLog [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/Makefile.am [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/gthread-impl.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/gthread-none.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/gthread-posix.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/gthread-win32.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/gthread.def [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/gthread.rc.in [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/makefile.msc.in [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/tests/.gitignore [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/tests/1bit-mutex.c [new file with mode: 0644]
resource/csdk/connectivity/lib/android/glib-master/gthread/tests/Makefile.am [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_app/Makefile [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_app/jni/Android.mk [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_app/jni/Application.mk [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_app/sample_main.c [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/AndroidManifest.xml [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/Makefile [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/jni/Android.mk [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/jni/Application.mk [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/jni/ResourceModel.c [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/jni/com_iotivity_service_RMInterface.h [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/proguard-project.txt [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/res/layout/activity_main.xml [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/res/menu/main.xml [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/res/values-v11/styles.xml [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/res/values-v14/styles.xml [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/res/values-w820dp/dimens.xml [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/res/values/dimens.xml [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/res/values/strings.xml [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/res/values/styles.xml [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/src/com/iotivity/jar/CALeInterface.java [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/src/com/iotivity/jar/CAWiFiInterface.java [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/src/com/iotivity/service/MainActivity.java [new file with mode: 0644]
resource/csdk/connectivity/samples/android/sample_service/src/com/iotivity/service/RMInterface.java [new file with mode: 0644]
resource/csdk/connectivity/samples/arduino/casample.cpp
resource/csdk/connectivity/samples/arduino/sample_main.cpp
resource/csdk/connectivity/samples/linux/sample_main.c
resource/csdk/connectivity/samples/tizen/casample.c
resource/csdk/connectivity/src/adapter_util/camsgparser.c
resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtclient.c
resource/csdk/connectivity/src/bt_edr_adapter/tizen/cabtmanager.c
resource/csdk/connectivity/src/bt_le_adapter/android/caleadapter.c [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.c [new file with mode: 0644]
resource/csdk/connectivity/src/bt_le_adapter/linux/README.txt [deleted file]
resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclient.h
resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.c
resource/csdk/connectivity/src/bt_le_adapter/tizen/cableclientutil.h
resource/csdk/connectivity/src/bt_le_adapter/tizen/cableserver.c
resource/csdk/connectivity/src/caconnectivitymanager.c
resource/csdk/connectivity/src/caconnectivitymanager_singlethread.c
resource/csdk/connectivity/src/cainterfacecontroller.c
resource/csdk/connectivity/src/cainterfacecontroller_singlethread.c
resource/csdk/connectivity/src/camessagehandler.c
resource/csdk/connectivity/src/camessagehandler_singlethread.c
resource/csdk/connectivity/src/canetworkconfigurator.c
resource/csdk/connectivity/src/canetworkconfigurator_singlethread.c
resource/csdk/connectivity/src/caprotocolmessage.c
resource/csdk/connectivity/src/caqueueingthread.c
resource/csdk/connectivity/src/caremotehandler.c
resource/csdk/connectivity/src/ethernet_adapter/arduino/README.txt [deleted file]
resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter.c [new file with mode: 0644]
resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetadapter.c [deleted file]
resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetclient.c [new file with mode: 0644]
resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetcore.c [deleted file]
resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetnwmonitor.c [new file with mode: 0644]
resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetserver.c [new file with mode: 0644]
resource/csdk/connectivity/src/wifi_adapter/android/cawificlient.c [new file with mode: 0644]
resource/csdk/connectivity/src/wifi_adapter/android/cawifinwmonitor.c [new file with mode: 0644]
resource/csdk/connectivity/src/wifi_adapter/android/cawifiserver.c [new file with mode: 0644]
resource/csdk/connectivity/src/wifi_adapter/cawifiadapter.c [new file with mode: 0644]
resource/csdk/connectivity/src/wifi_adapter/linux/cawifiadapter.c [deleted file]
resource/csdk/connectivity/src/wifi_adapter/linux/cawificlient.c [new file with mode: 0644]
resource/csdk/connectivity/src/wifi_adapter/linux/cawificore.c [deleted file]
resource/csdk/connectivity/src/wifi_adapter/linux/cawifinwmonitor.c [new file with mode: 0644]
resource/csdk/connectivity/src/wifi_adapter/linux/cawifiserver.c [new file with mode: 0644]
resource/csdk/connectivity/src/wifi_adapter/tizen/caethernetadapter.c [deleted file]
resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiadapter.c [deleted file]
resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.c
resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.h [deleted file]
resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.c [deleted file]
resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.h [deleted file]
resource/csdk/connectivity/src/wifi_adapter/tizen/cawifinwmonitor.c [new file with mode: 0644]
resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.c
resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.h [deleted file]
resource/csdk/connectivity/unittests/linux/sample1_unittest.cc

diff --git a/resource/csdk/connectivity/RELEASE v0.5 b/resource/csdk/connectivity/RELEASE v0.5
new file mode 100644 (file)
index 0000000..131e7dc
--- /dev/null
@@ -0,0 +1,89 @@
+Project Name: IoTivity
+Release Version No: CA_v0.5
+API Version: CA_v0.5
+
+Release Description:
+Connectivity Abstraction provides a unified approach to send different OIC messages across multiple transports.
+
+Supported Platform OS: 
+1) Ubuntu 12.0.4 and above:
+       Connectivity : WIFI, ETHERNET
+2) Tizen 2.3
+       Connectivity : WIFI, EDR, BLE(1:1).
+3) Arduino Mega
+       Connectivity : WIFI, ETH,BLE
+4) Android 5.0
+       Connectivity : WIFI, BLE
+
+Preconditions:
+1)gcc 4.6.3 and above.
+2)glib library (sudo apt-get install libglib2.0-dev)
+3)libcoap.a library ( do make @lib/libcoap-4.1.1)
+
+
+Scope of Release:
+1. Supported APIs ( please check below APIs)
+2. Samples to test for Supported APIs.
+3. OIC Coding guidelines followed based on the current CSDK source.
+4. Multi-Threaded, Single threaded Connectivity abstraction.
+5. Executed Open Source Verification and Prevent analysis.
+Type of Release: Source
+The following Connectivity Abstraction API features are supported in this release:
+
+Supported APIs
+CAInitialize()
+CATerminate()
+CAStartListeningServer()
+CAStartDiscoveryServer()
+CARegisterHandler()
+CAhandleRequestResponse()
+FindResource()
+SendRequest()
+SendResponse()
+SelectNetwork()
+UnselectNetwork()
+SendNotification()
+AdvertizeResource()
+CAGenerateToken()
+CADestryToken()
+CAGetNetworkInfo()
+
+
+Known and Open Issues:
+1) OIC Log, OIC Malloc will be removed once name changes applied to OIC Bases code.
+2) Tizen platform BLE stack is not stable. So we may see random crashes.
+
+How to Build for Linux:
+Follow below steps to execute CA Client / server in different systems
+Step 1: Build Libcoap library
+Make File Location @connectivity\lib\libcoap-4.1.1
+Step 2: Build CA library
+Make File Location @connectivity\build\linux
+Step 3: Samples
+Make File Location @connectivity\samples\linux
+
+Execution:
+linux$ export LD_LIBRARY_PATH=../../build/out/
+linux$ ./out/sample_main
+
+
+Follow below sequence to test
+
+Client Option:   c
+Server Option:  s
+
+Client Option:  f (provide a/light)
+Server Option: h (will pick from queue and send response)
+Client Option:  h (to pick server response)
+
+Client Option:  r (provide “ServerIP:5383/a/request”)
+Server Option: h (will pick from queue and send response)
+Client Option:  h (to pick server response)
+
+Server Option: a
+Client Option: h (to pick server response)
+
+Server Option: b (provide ServerIP:5383/a/notify)
+Client Option: h (to pick server response)
+
+Client: Server side: n for network selection (WIFI enabled by default)
index fd683b8..a1dd635 100644 (file)
@@ -151,15 +151,15 @@ typedef union
 } CAAddress_t;
 
 /**
- @brief Quality of service for Base source code
+ @brief Message Type for Base source code
  */
 typedef enum
 {
-    CA_LOW_QOS = 0,
-    CA_MEDIUM_QOS,
-    CA_HIGH_QOS,
-    CA_NA_QOS // No Quality is defined, let the stack decide
-} CAQualityOfService_t;
+    CA_MSG_CONFIRM = 0,  /* confirmable message (requires ACK/RST) */
+    CA_MSG_NONCONFIRM,   /* non-confirmable message (one-shot message) */
+    CA_MSG_ACKNOWLEDGE,  /* used to acknowledge confirmable messages */
+    CA_MSG_RESET         /* indicates error in received messages */
+} CAMessageType_t;
 
 /**
  @brief Allowed method to be used by resource model
@@ -185,6 +185,18 @@ typedef struct
     CAConnectivityType_t connectivityType;
 } CARemoteEndpoint_t;
 
+
+/**
+ @brief Group endpoint information for connectivities
+ */
+typedef struct
+{
+    /** Resource URI information **/
+    CAURI_t resourceUri;
+    /** Connectivity of the endpoint**/
+    CAConnectivityType_t connectivityType;
+} CAGroupEndpoint_t;
+
 /**
  @brief Local Connectivity information
  */
@@ -225,10 +237,9 @@ typedef enum
 typedef enum
 {
     /* Success status code - START HERE */
+    CA_SUCCESS = 200,
     CA_CREATED = 201,
     CA_DELETED = 202,
-    CA_VALID = 203,
-    CA_CONTENT = 205,
     CA_BAD_REQ = 400,
     CA_BAD_OPT = 402,
     CA_NOT_FOUND = 404
@@ -269,7 +280,7 @@ typedef struct
 typedef struct
 {
     /**Qos for the request **/
-    CAQualityOfService_t qos;
+    CAMessageType_t type;
     /** Token for CA**/
     CAToken_t token;
     /** Header Options for the request **/
index 6a2f6a2..e86a76c 100644 (file)
@@ -146,7 +146,17 @@ CAResult_t CAFindResource(const CAURI_t resourceUri, const CAToken_t token);
 CAResult_t CASendRequest(const CARemoteEndpoint_t *object, CARequestInfo_t *requestInfo);
 
 /**
- * @brief   Sendi the response
+ * @brief   Send control Request on a resource to multicast group
+ * @param   object      [IN]    Group Endpoint where the payload need to be sent.
+ *                              This Remote endpoint is delivered with Request or response callback.
+ * @param   requestInfo [IN ]   information for the request.
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CASendRequestToAll(const CAGroupEndpoint_t* object, 
+    const CARequestInfo_t* requestInfo);
+
+/**
+ * @brief   Send the response
  * @param   object          [IN]    Remote Endpoint where the payload need to be sent.
  *                                  This Remote endpoint is delivered with Request or response callback
  * @param   responseInfo    [IN ]   information for the response
@@ -170,8 +180,8 @@ CAResult_t CASendNotification(const CARemoteEndpoint_t *object, CAResponseInfo_t
  * @param   numOptions  [IN]    number of options
  * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
-CAResult_t CAAdvertiseResource(const CAURI_t resourceUri, CAToken_t token, CAHeaderOption_t* options,
-                               uint8_t numOptions);
+CAResult_t CAAdvertiseResource(const CAURI_t resourceUri, CAToken_t token, 
+                    CAHeaderOption_t* options,uint8_t numOptions);
 
 /**
  * @brief   Select network to use
diff --git a/resource/csdk/connectivity/build/android/Makefile b/resource/csdk/connectivity/build/android/Makefile
new file mode 100644 (file)
index 0000000..9710ed2
--- /dev/null
@@ -0,0 +1,18 @@
+#Assumes ndk directory is at ~/
+#set ndk directory PATH in .bashrc and use the ndk-build directly
+NDK_PATH = ~/ndk
+NDK_BUILD = $(NDK_PATH)/ndk-build
+
+BUILD_DIR = $(CURDIR)
+APPLICATION_BUILD = $(BUILD_DIR)
+ROOT_DIR = $(BUILD_DIR)
+
+#Clean files
+LIBS_DIR = $(ROOT_DIR)/libs
+OBJ_DIR = $(ROOT_DIR)/obj
+
+all:
+       $(NDK_BUILD) NDK_PROJECT_PATH=$(APPLICATION_BUILD)
+
+clean :
+       @$(RM) -rf $(LIBS_DIR) $(OBJ_DIR)
\ No newline at end of file
diff --git a/resource/csdk/connectivity/build/android/jni/Android.mk b/resource/csdk/connectivity/build/android/jni/Android.mk
new file mode 100644 (file)
index 0000000..432bee8
--- /dev/null
@@ -0,0 +1,119 @@
+#define build type
+BUILD = debug
+
+PROJECT_ROOT_PATH                      ?= ../..
+PROJECT_API_PATH                       = $(PROJECT_ROOT_PATH)/api
+PROJECT_INC_PATH                       = $(PROJECT_ROOT_PATH)/inc
+PROJECT_SRC_PATH                       = $(PROJECT_ROOT_PATH)/src
+PROJECT_COMMON_PATH                    = $(PROJECT_ROOT_PATH)/common
+PROJECT_COMMON_INC_PATH                = $(PROJECT_COMMON_PATH)/inc
+PROJECT_COMMON_SRC_PATH                = $(PROJECT_COMMON_PATH)/src
+PROJECT_LIB_PATH                       = $(PROJECT_ROOT_PATH)/lib
+
+#Modify below values to enable/disable the Adapter
+#Suffix "NO_" to disable given adapter  
+EDR                    = EDR_ADAPTER
+WIFI           = WIFI_ADAPTER
+LE                     = LE_ADAPTER
+ETHERNET       = NO_ETHERNET_ADAPTER
+
+#Add Pre processor definitions
+DEFINE_FLAG =  -DWITH_POSIX -D__ANDROID__
+DEFINE_FLAG += -D$(EDR) -D$(LE) -D$(WIFI) -D$(ETHERNET) 
+
+#Add Debug flags here
+DEBUG_FLAG     = -DTB_LOG
+#DEBUG_FLAG    += -DADB_SHELL
+
+BUILD_FLAG.debug       = $(DEFINE_FLAG) $(DEBUG_FLAG) 
+BUILD_FLAG.release     =       $(DEFINE_FLAG)
+BUILD_FLAG = $(BUILD_FLAG.$(BUILD))
+
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#Build glib
+include $(CLEAR_VARS)
+
+include $(PROJECT_LIB_PATH)/android/glib-master/Android.mk
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#Build CACommon
+include $(CLEAR_VARS)
+
+#Build Common Libraries
+LOCAL_PATH = $(PROJECT_COMMON_SRC_PATH)
+LOCAL_MODULE = CACommon
+LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
+
+LOCAL_SHARED_LIBRARIES = glib-2.0 gthread-2.0
+
+LOCAL_CFLAGS = -D__ANDROID__ $(DEBUG_FLAG)
+
+LOCAL_C_INCLUDES = $(PROJECT_COMMON_INC_PATH)
+LOCAL_C_INCLUDES += $(PROJECT_API_PATH)
+LOCAL_C_INCLUDES += $(PROJECT_LIB_PATH)/android/glib-master \
+                                       $(PROJECT_LIB_PATH)/android/glib-master/android
+
+LOCAL_SRC_FILES        =       oic_logger.c \
+                                       oic_console_logger.c logger.c oic_malloc.c \
+                                       uarraylist.c uqueue.c oic_string.c \
+                                       uthreadpool.c umutex.c
+
+include $(BUILD_STATIC_LIBRARY)
+
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#Build CACoap
+
+include $(CLEAR_VARS)
+
+LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
+LOCAL_PATH = $(PROJECT_LIB_PATH)/libcoap-4.1.1
+LOCAL_MODULE = CACoap
+LOCAL_EXPORT_C_INCLUDES = $(PROJECT_LIB_PATH)/libcoap-4.1.1
+LOCAL_CFLAGS = -DWITH_POSIX
+LOCAL_SRC_FILES        = pdu.c net.c debug.c encode.c uri.c coap_list.c resource.c hashkey.c \
+                                       str.c option.c async.c subscribe.c block.c
+
+include $(BUILD_STATIC_LIBRARY)
+
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#Build CA
+
+#Relative path to LOCAL_PATH (PROJECT_SRC_PATH)
+LOCAL_PLATFORM                                 = android
+
+ENET_ADAPTER_PATH                      = ethernet_adapter/$(LOCAL_PLATFORM)
+EDR_ADAPTER_PATH                       = bt_edr_adapter/$(LOCAL_PLATFORM)
+LE_ADAPTER_PATH                                = bt_le_adapter/$(LOCAL_PLATFORM)
+WIFI_ADAPTER_PATH                      = wifi_adapter/$(LOCAL_PLATFORM)
+ADAPTER_UTILS                          = adapter_util
+
+include $(CLEAR_VARS)
+
+LOCAL_LDLIBS += -L$(SYSROOT)/usr/lib -llog
+LOCAL_PATH = $(PROJECT_SRC_PATH)
+LOCAL_MODULE = CA
+
+LOCAL_STATIC_LIBRARIES = CACommon CACoap
+
+LOCAL_C_INCLUDES = $(PROJECT_API_PATH)
+LOCAL_C_INCLUDES += $(PROJECT_COMMON_INC_PATH)
+LOCAL_C_INCLUDES += $(PROJECT_INC_PATH)
+LOCAL_C_INCLUDES += $(PROJECT_LIB_PATH)/libcoap-4.1.1
+
+LOCAL_C_INCLUDES += $(PROJECT_LIB_PATH)/android/glib-master \
+                                       $(PROJECT_LIB_PATH)/android/glib-master/android
+
+LOCAL_CFLAGS += $(BUILD_FLAG)
+
+LOCAL_SRC_FILES        = \
+                                       caconnectivitymanager.c caremotehandler.c cainterfacecontroller.c camessagehandler.c \
+                                       canetworkconfigurator.c caprotocolmessage.c \
+                                       caqueueingthread.c \
+                                       $(ADAPTER_UTILS)/caadapterutils.c $(ADAPTER_UTILS)/camessagequeue.c \
+                                       $(ADAPTER_UTILS)/camsgparser.c \
+                                       $(EDR_ADAPTER_PATH)/caedradapter.c \
+                                       $(LE_ADAPTER_PATH)/caleadapter.c $(LE_ADAPTER_PATH)/caleclient.c $(LE_ADAPTER_PATH)/caleserver.c \
+                                       wifi_adapter/cawifiadapter.c $(WIFI_ADAPTER_PATH)/cawifiserver.c \
+                                       $(WIFI_ADAPTER_PATH)/cawificlient.c $(WIFI_ADAPTER_PATH)/cawifinwmonitor.c 
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/resource/csdk/connectivity/build/android/jni/Application.mk b/resource/csdk/connectivity/build/android/jni/Application.mk
new file mode 100644 (file)
index 0000000..cb79d88
--- /dev/null
@@ -0,0 +1,9 @@
+#Specify Android.mk path w.r.t APPLICATION_BUILD in the Makefile
+APP_PROJECT_PATH = ./
+
+APP_STL = gnustl_shared
+
+APP_PLATFORM = android-19
+APP_CPPFLAGS += -fexceptions
+APP_CPPFLAGS += -frtti += -Wno-error=format-security
+APP_CFLAGS = -Wno-error=format-security
\ No newline at end of file
index b8d0e4b..01b5ddd 100644 (file)
@@ -9,7 +9,7 @@ BUILD    := release
 PLATFORM := arduinomega
 TRANSPORT := BLE
 OBJ_DIR := ./bin
-APP_NAME := casample
+APP_NAME := sample_main
 ARDUINO_PORT := ttyACM0
 
 include ./local.properties
index 7f62225..c23f62c 100644 (file)
@@ -34,7 +34,7 @@ COMMON_MAKE = common.mk
 include $(COMMON_MAKE)
 
 #Modify below values to enable/disable the Adapter
-#Suffix "NO_" to disable given adapter  
+#Suffix "NO_" to disable given adapter
 EDR = NO_EDR_ADAPTER
 WIFI = WIFI_ADAPTER
 LE = NO_LE_ADAPTER
@@ -50,28 +50,31 @@ DEBUG_FLAG += -DTB_LOG
 ##
 ##     definitions
 ##
-LIB_PREFIX                             = CA
-ETHERNET_ADAPTER               = ethernet_adapter
-WIFI_ADAPTER                   = wifi_adapter
-BT_ADAPTER                             = bt_edr_adapter
-BLE_ADAPTER                            = bt_le_adapter
-ETHERNET_ADAPTER_PATH  = $(PROJECT_SRC_PATH)/$(ETHERNET_ADAPTER)/$(PLATFORM)
-WIFI_ADAPTER_PATH              = $(PROJECT_SRC_PATH)/$(WIFI_ADAPTER)/$(PLATFORM)
-BT_ADAPTER_PATH                        = $(PROJECT_SRC_PATH)/$(BT_ADAPTER)/$(PLATFORM)
-BLE_ADAPTER_PATH               = $(PROJECT_SRC_PATH)/$(BLE_ADAPTER)/$(PLATFORM)
-TARGET                                 = lib$(PROJECT_NAME).so.$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)
-TARGET_ALIAS                   = lib$(PROJECT_NAME).so
+LIB_PREFIX = CA
+ETHERNET_ADAPTER = ethernet_adapter
+WIFI_ADAPTER = wifi_adapter
+BT_ADAPTER = bt_edr_adapter
+BLE_ADAPTER = bt_le_adapter
+ETHERNET_ADAPTER_PATH = $(PROJECT_SRC_PATH)/$(ETHERNET_ADAPTER)/$(PLATFORM)
+ETHERNET_ADAPTER_COMMON_PATH = $(PROJECT_SRC_PATH)/$(ETHERNET_ADAPTER)
+WIFI_ADAPTER_PATH = $(PROJECT_SRC_PATH)/$(WIFI_ADAPTER)/$(PLATFORM)
+WIFI_ADAPTER_COMMON_PATH = $(PROJECT_SRC_PATH)/$(WIFI_ADAPTER)
+BT_ADAPTER_PATH        = $(PROJECT_SRC_PATH)/$(BT_ADAPTER)/$(PLATFORM)
+BLE_ADAPTER_PATH = $(PROJECT_SRC_PATH)/$(BLE_ADAPTER)/$(PLATFORM)
+ADAPTER_UTILS_PATH = $(PROJECT_SRC_PATH)/adapter_util
+TARGET = lib$(PROJECT_NAME).so.$(VERSION_MAJOR).$(VERSION_MINOR).$(VERSION_PATCH)
+TARGET_ALIAS = lib$(PROJECT_NAME).so
 
 ##
 ##     libcoap
 ##
 libcoap_build_dir = $(PROJECT_LIB_PATH)/libcoap-4.1.1
 
-LDFLAGS:=-L$(libcoap_build_dir)
-LDLIBS:=-lcoap
+LDFLAGS := -L$(libcoap_build_dir)
+LDLIBS := -lcoap
 
-BUILD_FLAG.debug       = $(DEFINE_FLAG) $(DEBUG_FLAG) 
-BUILD_FLAG.release     =       $(DEFINE_FLAG)
+BUILD_FLAG.debug = $(DEFINE_FLAG) $(DEBUG_FLAG)
+BUILD_FLAG.release =   $(DEFINE_FLAG)
 BUILD_FLAG = $(BUILD_FLAG.$(BUILD))
 
 DEBUG_DIR = ./debug
@@ -80,42 +83,39 @@ RELEASE_DIR = ./release
 ##
 ##     file declaration
 ##
-COMPONENT_SRCS                 =  \
-logger.c oic_malloc.c oic_logger.c oic_console_logger.c \
-caconnectivitymanager.c caremotehandler.c cainterfacecontroller.c camessagehandler.c   \
-canetworkconfigurator.c caedradapter.c caleadapter.c   \
-caethernetadapter.c cawifiadapter.c \
-caprotocolmessage.c cawificore.c caethernetcore.c\
-caqueueingthread.c \
-uqueue.c uarraylist.c umutex.c uthreadpool.c \
-
-COMPONENT_OBJS                 = $(COMPONENT_SRCS:%.c=$(OBJ_DIR)/%.o)
+COMPONENT_SRCS := logger.c oic_logger.c oic_console_logger.c oic_malloc.c oic_string.c uqueue.c uarraylist.c umutex.c uthreadpool.c
+COMPONENT_SRCS += caconnectivitymanager.c caremotehandler.c cainterfacecontroller.c camessagehandler.c caqueueingthread.c canetworkconfigurator.c caprotocolmessage.c
+COMPONENT_SRCS += caadapterutils.c camessagequeue.c
+COMPONENT_SRCS += caethernetadapter.c cawifiadapter.c caedradapter.c caleadapter.c
+COMPONENT_SRCS += cawifiserver.c cawificlient.c cawifinwmonitor.c
+COMPONENT_SRCS += caethernetserver.c caethernetclient.c caethernetnwmonitor.c
+COMPONENT_OBJS = $(COMPONENT_SRCS:%.c=$(OBJ_DIR)/%.o)
 
 ##
 ##     compiler flags
 ##
-CFLAGS                         =       -g -c -Wall -fPIC `pkg-config --cflags glib-2.0`
-
-LFLAGS                         =       -ldl -lpthread `pkg-config --libs glib-2.0`
-
-IFLAGS                         =       -I$(PROJECT_COMMON_INC_PATH)    \
-                                               -I$(PROJECT_API_PATH)   \
-                                               -I$(PROJECT_INC_PATH)   \
-                                               -I$(ETHERNET_ADAPTER_PATH)      \
-                                               -I$(WIFI_ADAPTER_PATH)  \
-                                               -I$(BT_ADAPTER_PATH)    \
-                                               -I$(BLE_ADAPTER_PATH)   \
-                        -I$(libcoap_build_dir)
-
-DFLAGS                         = -D__LINUX__           \
-                      -DWITH_POSIX             \
-                      $(BUILD_FLAG)\
+CFLAGS = -g -c -Wall -fPIC `pkg-config --cflags glib-2.0`
+LFLAGS = -ldl -lpthread `pkg-config --libs glib-2.0`
+IFLAGS = -I$(PROJECT_COMMON_INC_PATH)  \
+       -I$(PROJECT_API_PATH)   \
+       -I$(PROJECT_INC_PATH)   \
+       -I$(ETHERNET_ADAPTER_PATH)      \
+       -I$(WIFI_ADAPTER_PATH)  \
+       -I$(BT_ADAPTER_PATH)    \
+       -I$(BLE_ADAPTER_PATH)   \
+        -I$(libcoap_build_dir)
+
+DFLAGS = -D__LINUX__ -DWITH_POSIX $(BUILD_FLAG)
+
 ##
 ##     compile and link rules
 ##
 vpath %.c $(PROJECT_COMMON_SRC_PATH)
+vpath %.c $(ADAPTER_UTILS_PATH)
 vpath %.c $(ETHERNET_ADAPTER_PATH)
+vpath %.c $(ETHERNET_ADAPTER_COMMON_PATH)
 vpath %.c $(WIFI_ADAPTER_PATH)
+vpath %.c $(WIFI_ADAPTER_COMMON_PATH)
 vpath %.c $(BT_ADAPTER_PATH)
 vpath %.c $(BLE_ADAPTER_PATH)
 vpath %.c $(PROJECT_SRC_PATH)
@@ -133,11 +133,11 @@ all : $(TARGET)
 $(TARGET) : $(COMPONENT_OBJS)
        cd $(libcoap_build_dir); $(MAKE)
        @$(MAKE_PROJECT_OUT_PATH)
-       @$(CC) -shared -Wl,-soname,$(TARGET) -o $@ $(COMPONENT_OBJS) $(LFLAGS) $(LDFLAGS) $(LDLIBS) 
+       @$(CC) -shared -Wl,-soname,$(TARGET) -o $@ $(COMPONENT_OBJS) $(LFLAGS) $(LDFLAGS) $(LDLIBS)
        @$(MV) $(TARGET) $(PROJECT_OUT_PATH)/.
        @$(CD) $(PROJECT_OUT_PATH); $(MAKE_TARGET_ALIAS)
-clean :        
+
+clean :
        cd $(libcoap_build_dir) && make clean
        @$(RM) $(DEBUG_DIR) $(RELEASE_DIR)\
                        $(PROJECT_OUT_PATH)
diff --git a/resource/csdk/connectivity/build/tizen/README.txt b/resource/csdk/connectivity/build/tizen/README.txt
new file mode 100644 (file)
index 0000000..00ba7ec
--- /dev/null
@@ -0,0 +1,15 @@
+Compiling Interface APIs FOR TIZEN:
+===================================
+1) Get the latest interface APIs code from repo and build it in Tizen GBS[connectivity/build]
+        To Build in Tizen GBS Platform, Use this command "sudo make PLATFORM=tizen" from the above directory.
+
+       By Default, "ALL" the TRANSPORTS are built. To build a specific TRANSPORT [BT,BLE,WIFI], use the following command :
+       sudo make PLATFORM=tizen TRANSPORT=BLE
+    
+       [Note: Combination of Transports can be build by giving the option as TRANSPORT=BLE,BT. Transport names are case insensitive]
+
+2) For Verification, Build Sample Console App and execute in Tizen Device.
+
+Note:
+====
+For Tizen BLE, please copy headers present in "external\headers\include" folder to your GBS configuration(GBS has old BLE headers).
\ No newline at end of file
index bc77706..1705555 100644 (file)
@@ -34,6 +34,7 @@ if echo $1 | grep -q -i "ALL"
 then
 echo "Building All the Transports"
 cp ../../src/wifi_adapter/tizen/* $sourcedir/tizen/tmp/
+cp ../../src/wifi_adapter/*.c $sourcedir/tizen/tmp/
 cp ../../src/bt_edr_adapter/* $sourcedir/tizen/tmp/
 cp ../../src/bt_edr_adapter/tizen/* $sourcedir/tizen/tmp/
 cp ../../src/bt_le_adapter/* $sourcedir/tizen/tmp/
@@ -43,6 +44,7 @@ else
 if echo $1 | grep -q -i "WIFI"
 then
 echo "Copying WIFI Adapter Source Codes"
+cp ../../src/wifi_adapter/*.c $sourcedir/tizen/tmp/
 cp ../../src/wifi_adapter/tizen/* $sourcedir/tizen/tmp/
 adapterMacro="$adapterMacro -DWIFI_ADAPTER"
 fi
index 39fb62a..9be024d 100644 (file)
@@ -178,13 +178,24 @@ void OICLogv(LogLevel level, const char *tag, const int16_t lineNum, const char
 #endif //__TIZEN__
 #else //TB_LOG
 
+#ifdef __ANDROID__
+#define OIC_LOG_CONFIG(ctx)
+#define OIC_LOG_SHUTDOWN()
+#define OIC_LOG_BUFFER(level, tag, buffer, bufferSize)
+#define OIC_LOG_INIT()
+#define OIC_LOG(level,tag,mes) __android_log_print(ANDROID_LOG_INFO, tag, mes)
+#define OIC_LOG_V(level,tag,fmt,args...) __android_log_print(ANDROID_LOG_INFO, tag, fmt,##args)
+
+#else
 #define OIC_LOG_CONFIG(ctx)
 #define OIC_LOG_SHUTDOWN()
 #define OIC_LOG(level, tag, logStr)
 #define OIC_LOG_V(level, tag, ...)
 #define OIC_LOG_BUFFER(level, tag, buffer, bufferSize)
 #define OIC_LOG_INIT()
-#endif
+#endif //__ANDROID__
+#endif // TB_LOG
+
 
 #ifdef __cplusplus
 }
index 6c222a9..6566404 100644 (file)
@@ -24,6 +24,8 @@
 #ifndef __UMUTEX_H_
 #define __UMUTEX_H_
 
+#include <stdint.h>
+
 #include "cacommon.h"
 
 #ifdef __cplusplus
@@ -128,6 +130,20 @@ void u_cond_broadcast(u_cond cond);
 void u_cond_wait(u_cond cond, u_mutex mutex);
 
 /**
+ * @fn  u_cond_wait
+ * @brief  Waits untill this thread woken up on @cond,
+ *      but not longer than until the time specified by milliseconds.
+ *      The mutex is unlocked before falling asleep and locked again before resuming.
+ *      If milliseconds is 0 or under, u_cond_timed_wait() acts like u_cond_wait().
+ *
+ * @param  cond  The condtion to be wait for to signal
+ * @param  mutex  The mutex which is currently locked from calling thread
+ * @param  microseconds  relative time for waiting, microseconds
+ *
+ */
+void u_cond_timed_wait(u_cond cond, u_mutex mutex, int32_t microseconds);
+
+/**
  * @fn  u_cond_free
  * @brief  Free the condition
  *
index 93cfef0..1640d3f 100644 (file)
@@ -23,7 +23,7 @@
 
 #include "umutex.h"
 #include <glib.h>
-
+#include <string.h>
 #include "logger.h"
 
 /**
@@ -160,6 +160,38 @@ void u_cond_wait(u_cond cond, u_mutex mutex)
     g_cond_wait(condition, mutexLock);
 }
 
+void u_cond_timed_wait(u_cond cond, u_mutex mutex, int32_t microseconds)
+{
+    if (NULL == mutex)
+    {
+        OIC_LOG_V(ERROR, TAG,"u_cond_wait, Invalid mutex !");
+        return;
+    }
+
+    if (NULL == cond)
+    {
+        OIC_LOG_V(ERROR, TAG,"u_cond_wait, Invalid condition !");
+        return;
+    }
+
+    GMutex *mutexLock = (GMutex *) mutex;
+    GCond *condition = (GCond *) cond;
+
+    if (microseconds <= 0)
+    {
+        g_cond_wait(condition, mutexLock);
+        return;
+    }
+
+    GTimeVal abs_time;
+    memset(&abs_time, 0, sizeof(GTimeVal));
+
+    g_get_current_time(&abs_time);
+    g_time_val_add(&abs_time, microseconds);
+
+    g_cond_timed_wait(condition, mutexLock, &abs_time);
+}
+
 void u_cond_free(u_cond cond)
 {
     if (NULL == cond)
index a65302b..4331fe8 100644 (file)
@@ -44,6 +44,11 @@ CAResult_t u_thread_pool_init(uint32_t num_of_threads, u_thread_pool_t *thread_p
 
     GError *error = NULL;
 
+#ifdef __ANDROID__
+    //If not intialized, gthreadpool intialize check fails
+    g_thread_init(NULL);
+#endif //__ANDROID__
+
     gThreadpool = g_thread_pool_new(run, NULL, num_of_threads, TRUE, &error);
     if (NULL == gThreadpool)
     {
index 9d1ea0b..a8b25f5 100644 (file)
@@ -70,8 +70,8 @@ extern "C"
  * @fn CAAdapterCreateLocalEndpoint
  * @brief Create CALocalConnectivity_t instance.
  */
-CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CAConnectivityType_t type, const char *address,
-        const char *interfaceName);
+CALocalConnectivity_t *CAAdapterCreateLocalEndpoint(CAConnectivityType_t type, 
+            const char *address,const char *interfaceName);
 
 /**
  * @fn CAAdapterCopyLocalEndpoint
@@ -89,8 +89,8 @@ void CAAdapterFreeLocalEndpoint(CALocalConnectivity_t *localEndPoint);
  * @fn CAAdapterCreateRemoteEndpoint
  * @brief Allocate CARemoteEndpoint_t instance.
  */
-CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CAConnectivityType_t type, const char *address,
-        const char *resourceUri);
+CARemoteEndpoint_t *CAAdapterCreateRemoteEndpoint(CAConnectivityType_t type, 
+            const char *address,const char *resourceUri);
 
 /**
  * @fn CAAdapterCopyRemoteEndpoint
index f454611..293761b 100644 (file)
@@ -42,7 +42,7 @@ extern "C"
  *
  * @param[in]  registerCallback  To register EDR interfaces to Connectivity Abstraction Layer
  * @param[in]  reqRespCallback  Callback to be notified on receival of request/responses from
- *                                          peer bluetooth devices.
+ * peer bluetooth devices.
  * @param[in]  netCallback  Callback to be notified when network adapter state changes.
  * @param[in]  threadPool  Thread pool for handling asynchronous tasks.
  *
@@ -50,7 +50,7 @@ extern "C"
  * @retval  #CA_STATUS_OK  Successful
  * @retval  #CA_STATUS_INVALID_PARAM  Invalid input parameters
  * @retval  #CA_ADAPTER_NOT_ENABLED Initialization is successful, but bluetooth adapter is
- *                                                      not enabled
+ * not enabled
  * @retval  #CA_STATUS_FAILED Operation failed
  */
 CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
@@ -61,7 +61,7 @@ CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
 /**
  * @fn  CAStartEDR
  * @brief  Starting EDR connectivity adapters. As its peer to peer it doesnot require to start
- *           any servers.
+ * any servers.
  *
  * @return  #CA_STATUS_OK on success otherwise proper error code.
  * @retval  #CA_STATUS_OK  Successful
@@ -74,7 +74,7 @@ CAResult_t CAStartEDR();
 /**
  * @fn  CAStartEDRListeningServer
  * @brief  Starting listening server for receiving multicast search requests.
- *            Starts RFCOMM Server with prefixed UUID as per OIC specification.
+ * Starts RFCOMM Server with prefixed UUID as per OIC specification.
  *
  * @return  #CA_STATUS_OK on success otherwise proper error code.
  * @retval  #CA_STATUS_OK  Successful
@@ -88,12 +88,12 @@ CAResult_t CAStartEDRListeningServer();
 /**
  * @fn  CAStartEDRDiscoveryServer
  * @brief  Starting discovery server for receiving multicast advertisements.
- *            Starts RFCOMM Server with prefixed UUID as per OIC specification.
+ * Starts RFCOMM Server with prefixed UUID as per OIC specification.
  *
  * @return  #CA_STATUS_OK on success otherwise proper error code.
  * @retval  #CA_STATUS_OK  Successful
  * @retval  #CA_SERVER_STARTED_ALREADY  Server is already started and running for the predefined
- *                                                            service UUID
+ * service UUID
  * @retval  #CA_STATUS_FAILED Operation failed
  *
  */
@@ -110,12 +110,13 @@ CAResult_t CAStartEDRDiscoveryServer();
  * @return  Number of bytes sent on the network. 0 indicates failed to send data.
  *
  */
-uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data, uint32_t dataLength);
+uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data, 
+                            uint32_t dataLength);
 
 /**
  * @fn  CASendEDRMulticastData
  * @brief  Sends multicast data to all discovered bluetooth OIC devices using the adapter
- *           connectivity.
+ * connectivity.
  *
  * @param[in]  data  Data which needs to be send to all discovered bluetooth OIC device.
  * @param[in]  dataLength  Length of data in bytes.
@@ -126,16 +127,6 @@ uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *da
 uint32_t CASendEDRMulticastData(void *data, uint32_t dataLength);
 
 /**
- *            Starts RFCOMM Server with prefixed UUID as per OIC specification.
- *
- * @return  #CA_STATUS_OK on success otherwise proper error code.
- * @retval  #CA_STATUS_OK  Successful
- * @retval  #CA_SERVER_STARTED_ALREADY  Server is already started and running for the predefined
- *                                                            service UUID
- * @retval  #CA_STATUS_FAILED Operation failed
- *
- * @return  Number of bytes sent on the network. 0 indicates failed to send data.
- *
  * @fn  CAGetEDRInterfaceInformation
  * @brief  Get EDR Connectivity network information.
  *
@@ -165,7 +156,7 @@ CAResult_t CAReadEDRData();
 /**
  * @fn  CAStopEDR
  * @brief  Stopping the adapters and close socket connections
- *           EDR Stops all RFCOMM servers and close sockets.
+ * EDR Stops all RFCOMM servers and close sockets.
  *
  * @return  #CA_STATUS_OK on success
  *
@@ -175,7 +166,7 @@ CAResult_t CAStopEDR();
 /**
  * @fn  CATerminateEDR
  * @brief  Terminate the EDR connectivity adapter.
- *           Configuration information will be deleted from further use.
+ * Configuration information will be deleted from further use.
  *
  */
 void CATerminateEDR();
index 71a13cb..2bb9a9a 100644 (file)
@@ -49,7 +49,8 @@ extern "C"
  * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
 CAResult_t CAInitializeEDR(CARegisterConnectivityCallback registerCallback,
-                           CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback);
+                           CANetworkPacketReceivedCallback reqRespCallback, 
+                           CANetworkChangeCallback netCallback);
 /**
  * @brief Starting EDR connectivity adapters .As its peer to peer it doesnot require to start any servers
  * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
@@ -81,7 +82,8 @@ CAResult_t CAStartEDRDiscoveryServer();
  * @param   dataLen     [IN]    Size of data to be sent.
  * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
  */
-uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen);
+uint32_t CASendEDRUnicastData(const CARemoteEndpoint_t *endpoint, void *data, 
+                                    uint32_t dataLen);
 
 /**
  * @brief Sends Multicast data to the endpoint using the EDR connectivity.
@@ -107,7 +109,8 @@ CAResult_t CAStartEDRNotifyServer();
  * @param   dataLen     [IN]    Size of data to be sent.
  * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
  */
-uint32_t CASendEDRNotification(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen);
+uint32_t CASendEDRNotification(const CARemoteEndpoint_t *endpoint, void *data, 
+                        uint32_t dataLen);
 
 /**
  * @brief Get EDR Connectivity network information
index 118fee1..650d012 100644 (file)
@@ -36,15 +36,15 @@ extern "C"
 
 /**
  * @brief API to initialize Ethernet Interface.
- * @param registerCallback [IN] To register Ethernet interfaces to Connectivity Abstraction Layer
- * @param reqRespCallback [IN] sending responses and discovery messages from unicast,
- * multicast servers
+ * @param registerCallback [IN] To register ETHERNET interfaces to Connectivity Abstraction Layer
+ * @param networkPacketCallback [IN] sending responses and discovery messages
+ * from unicast , multicast servers
  * @param netCallback [IN] Intimate the network additions to Connectivity Abstraction Layer.
  * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
 CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
-                                CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback,
-                                u_thread_pool_t handle);
+                            CANetworkPacketReceivedCallback networkPacketCallback,
+                            CANetworkChangeCallback netCallback, u_thread_pool_t handle);
 
 /**
  * @brief Start Ethernet Interface adapter.
@@ -64,8 +64,8 @@ CAResult_t CAStartEthernetListeningServer();
 /**
  * @brief for starting discovery servers for receiving multicast advertisements
  * Transport Specific Behavior:
- * Ethernet Starts Start multicast server on all available IPs and prefixed port number as per
- * OIC Specification
+ * Ethernet Starts Start multicast server on all available IPs and prefixed port
+ * number as per OIC Specification
  * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
 CAResult_t CAStartEthernetDiscoveryServer();
@@ -73,14 +73,14 @@ CAResult_t CAStartEthernetDiscoveryServer();
 /**
  * @brief Sends data to the endpoint using the adapter connectivity.
  * Note: length must be > 0.
- * @param   endpoint    [IN]    Remote Endpoint information (like ipaddress , port, reference
- * uri and connectivity type) to which the unicast data has to be sent.
+ * @param   endpoint    [IN]    Remote Endpoint information (like ipaddress , port,
+ * reference uri and connectivity type) to which the unicast data has to be sent.
  * @param   data        [IN]    Data which required to be sent.
  * @param   dataLen     [IN]    Size of data to be sent.
  * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
  */
 uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t *endpoint, void *data,
-                                   uint32_t dataLen);
+                                        uint32_t dataLen);
 
 /**
  * @brief Sends Multicast data to the endpoint using the Ethernet connectivity.
@@ -92,23 +92,6 @@ uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t *endpoint, void *dat
 uint32_t CASendEthernetMulticastData(void *data, uint32_t dataLen);
 
 /**
- * @brief Starts notification server on Ethernet adapters.
- * @return CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
- */
-CAResult_t CAStartEthernetNotifyRecvServers();
-
-/**
- * @brief Send notification information.
- * Note: length must be > 0.
- * @param   endpoint    [IN]    Remote Endpoint information (like ipaddress , port,
- * reference uri and connectivity type) to which the unicast data has to be sent.
- * @param   data        [IN]    Data which required to be sent.
- * @param   dataLen     [IN]    Size of data to be sent.
- * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
- */
-uint32_t CASendEthernetNotification(const CARemoteEndpoint_t *endpoint, void *data,
-                                    uint32_t dataLen);
-/**
  * @brief Get Ethernet Connectivity network information
  * @param   info        [OUT]   Local connectivity information structures
  * @param   size        [OUT]   Number of local connectivity structures.
@@ -139,4 +122,4 @@ void CATerminateEthernet();
 } /* extern "C" */
 #endif
 
-#endif//#ifndef __CA_ETHERNET_ADAPTER_H__
+#endif  // #ifndef __CA_ETHERNET_ADAPTER_H__
diff --git a/resource/csdk/connectivity/inc/caethernetcore.h b/resource/csdk/connectivity/inc/caethernetcore.h
deleted file mode 100644 (file)
index c212319..0000000
+++ /dev/null
@@ -1,70 +0,0 @@
-/******************************************************************
- *
- * Copyright 2014 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
-
-/**
- * @file caethernetcore.h
- * @brief This file contains the APIs for Ethernet communications.
- */
-#ifndef __CA_ETHERNETCORE_H_
-#define __CA_ETHERNETCORE_H_
-
-#include "cacommon.h"
-#include "config.h"
-#include "coap.h"
-#include "uthreadpool.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-typedef void (*CAPacketReceiveCallback)(char* address, const char* data, uint32_t length);
-
-void CAEthernetInitialize(u_thread_pool_t handle);
-
-void CAEthernetTerminate();
-
-int32_t CAEthernetSendUnicastMessage(const char* address, char* data, uint32_t length);
-
-int32_t CAEthernetSendMulticastMessage(const char* m_address, char* data, uint32_t length);
-
-int32_t CAEthernetStartUnicastServer();
-
-int32_t CAEthernetStartMulticastServer();
-
-int32_t CAEthernetStopUnicastServer();
-
-int32_t CAEthernetStopMulticastServer();
-
-void CAEthernetSetCallback(CAPacketReceiveCallback callback);
-
-void CAEthernetGetLocalAddress(char *addressBuffer);
-
-int32_t CAEthernetSendUnicastMessageImpl(const char *address, const char *data, uint32_t length);
-
-int32_t CAEthernetSendMulticastMessageImpl(const char *msg, uint32_t length);
-
-CAResult_t CAGetEthernetInterfaceInfo(CALocalConnectivity_t **info, uint32_t* size);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif
diff --git a/resource/csdk/connectivity/inc/caethernetinterface.h b/resource/csdk/connectivity/inc/caethernetinterface.h
new file mode 100644 (file)
index 0000000..2ff7044
--- /dev/null
@@ -0,0 +1,337 @@
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+
+/**
+ * @file caethernetinterface.h
+ * @brief This file provides APIs ethernet client/server/network monitor modules
+ */
+
+#ifndef _CA_ETHERNET_INTERFACE_
+#define _CA_ETHERNET_INTERFACE_
+
+#include <stdbool.h>
+
+#include "cacommon.h"
+#include "uthreadpool.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @enum CAAdapterServerType_t
+ * @brief Enum for defining different server types.
+ */
+typedef enum
+{
+    CA_UNICAST_SERVER = 0,
+    CA_MULTICAST_SERVER,
+    CA_SECURED_UNICAST_SERVER
+} CAAdapterServerType_t;
+
+/**
+ * @fn  CAEthernetPacketReceivedCallback
+ * @brief  Callback to be notified on receival of any data from remote OIC devices.
+ *
+ * @param[in]  ipAddress  IP address of remote OIC device.
+ * @param[in]  port  Port number on which data is received.
+ * @param[in]  data  Data received from remote OIC device.
+ * @param[in]  dataLength  Length of data in bytes.
+ *
+ * @pre  Callback must be registered using CAEthernetSetPacketReceiveCallback()
+ */
+typedef void (*CAEthernetPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
+        const void *data, const uint32_t dataLength);
+
+/**
+ * @fn  CAEthernetExceptionCallback
+ * @brief  Callback to be notified when exception occures on multicast/unicast server.
+ *
+ * @param[in]  type  Type of server either #CA_UNICAST_SERVER or $CA_MULTICAST_SERVER
+ *
+ * @pre  Callback must be registered using CAEthernetSetExceptionCallback()
+ */
+typedef void (*CAEthernetExceptionCallback)(CAAdapterServerType_t type);
+
+/**
+ * @fn  CAEthernetInitializeServer
+ * @brief  API to initialize Ethernet server
+ *
+ * @param[in]  threadPool  Thread pool for managing Unicast/Multicast server threads.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAEthernetInitializeServer(const u_thread_pool_t threadPool);
+
+#ifdef ARDUINO
+/**
+ * @fn  CAEthernetInitializeServer
+ * @brief  API to initialize Ethernet server
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAEthernetInitializeServer(void);
+#endif //ARDUINO
+
+/**
+ * @fn  CAEthernetTerminateServer
+ * @brief  API to terminate Ethernet server
+ */
+void CAEthernetTerminateServer(void);
+
+/**
+ * @fn  CAEthernetStartMulticastServer
+ * @brief  API to start multicast server for specified multicast address and port
+ *
+ * @param[in]  localAddress  Local adapter address to which server to be binded.
+ * @param[in]  multicastAddress  Multicast group address.
+ * @param[in]  multicastPort  Port number on which server to be running.
+ * @param[out]  serverFD  Multicast server socket FD.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_SERVER_STARTED_ALREADY Multicast server is already started and running.
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char *multicastAddress,
+                                      const int16_t multicastPort, int32_t *serverFD);
+
+/**
+ * @fn  CAEthernetStartUnicastServer
+ * @brief  API to start unicast server for specified local address and port
+ *
+ * @param[in]  localAddress  Local adapter address to which server to be binded.
+ * @param[in][out]  port  Port number on which server to be running.
+ * Port number on which server actually started will be returned.
+ * @param[in]  forceStart  Indicate whether to start server forcesfully on specified port or not.
+ * @param[out]  serverFD  Unicast server socket FD.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_SERVER_STARTED_ALREADY Unicast server is already started and running.
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
+                                    const bool forceStart, int32_t *serverFD);
+
+/**
+ * @fn  CAEthernetStopMulticastServer
+ * @brief  API to stop multicast server.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStopMulticastServer(void);
+
+/**
+ * @fn  CAEthernetStopUnicastServer
+ * @brief  API to stop unicast server.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStopUnicastServer();
+
+/**
+ * @fn  CAEthernetGetUnicastServerInfo
+ * @brief  API to get running unicast server information.
+ * @remarks  @ipAddress must be freed using free().
+ *
+ * @param[in]  ipAddress  IP address on which server is binded and running.
+ * @param[out]  port  Port number on which server is running
+ * @param[out]  serverFD  Server socket fd.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD);
+
+/**
+ * @fn  CAEthernetSetPacketReceiveCallback
+ * @brief  API to set callback for receiving data packets from peer devices.
+ *
+ * @param[in]  callback Callback to be notified on receival of unicast/multicast data packets.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+void CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCallback callback);
+
+#ifdef ARDUINO
+/**
+ * @fn  CAEthernetReadData
+ * @brief  API to pull data
+ */
+void CAEthernetPullData();
+#endif // ARDUINO
+
+/**
+ * @fn  CAEthernetSetExceptionCallback
+ * @brief  API to set callback for receiving exception notifications.
+ *
+ * @param[in]  callback  Callback to be notified on occurance of exception running servers.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+void CAEthernetSetExceptionCallback(CAEthernetExceptionCallback callback);
+
+/**
+ * @fn  CAEthernetSetUnicastSocket
+ * @brief  API to set socket description for sending unicast UDP data
+ *
+ * @param[in]  socketFD  Socket descriptor used for sending UDP data.
+ *
+ */
+void CAEthernetSetUnicastSocket(const int32_t socketFD);
+
+/**
+ * @fn  CAEthernetSendUnicastData
+ * @brief  API to send unicast UDP data
+ *
+ * @param[in]  remoteAddress  IP address to which data needs to be send.
+ * @param[in]  port  Port to which data needs to be send.
+ * @param[in]  data  Data to be send.
+ * @param[in]  dataLength  Length of data in bytes
+ * @param[in]  isMulticast  whether data needs to be sent to multicast ip
+ * @param[out]  sentLength  Number of bytes actually sent
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+uint32_t CAEthernetSendData(const char *remoteAddress, const uint32_t port,
+                        const void *data, const uint32_t dataLength, bool isMulticast);
+
+/**
+ * @fn  CAEthernetConnectionStateChangeCallback
+ * @brief  Callback to be notified when ethernet adapter connection state changes.
+ *
+ * @param[in]  ipAddress  IP address of remote OIC device.
+ * @param[in]  status  Connection status either #CA_INTERFACE_UP or #CA_INTERFACE_DOWN.
+ *
+ * @pre  Callback must be registered using CAEthernetSetConnectionStateChangeCallback()
+ */
+typedef void (*CAEthernetConnectionStateChangeCallback)(const char *ipAddress,
+        const CANetworkStatus_t status);
+
+/**
+ * @fn  CAEthernetInitializeNetworkMonitor
+ * @brief  API to initialize Ethernet network monitor
+ *
+ * @param[in]  threadPool  Thread pool for managing network monitor thread.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAEthernetInitializeNetworkMonitor(const u_thread_pool_t threadPool);
+
+#ifdef ARDUINO
+/**
+ * @fn  CAEthernetInitializeServer
+ * @brief  API to initialize Ethernet server
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAEthernetInitializeNetworkMonitor(void);
+#endif //ARDUINO
+
+/**
+ * @fn  CAEthernetTerminateNetworkMonitor
+ * @brief  API to terminate Ethernet network monitor
+ */
+void CAEthernetTerminateNetworkMonitor(void);
+
+/**
+ * @fn  CAEthernetStartNetworkMonitor
+ * @brief  API to start network monitoring process.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStartNetworkMonitor(void);
+
+/**
+ * @fn  CAEthernetStopNetworkMonitor
+ * @brief  API to stop network monitoring process.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetStopNetworkMonitor(void);
+
+/**
+ * @fn  CAEthernetGetInterfaceInfo
+ * @brief  API to get local adapter network information.
+ * @remarks  @interfaceName and @ipAddress must be freed using free().
+ *
+ * @param[out]  interfaceName  Local adapter interface name
+ * @param[out]  ipAddress  IP address
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAEthernetGetInterfaceInfo(char **interfaceName, char **ipAddress);
+
+/**
+ * @fn  CAEthernetIsConnected
+ * @brief  API to get ethernet adapter connection state.
+ *
+ * @return  true if ethernet adapter is connected, otherwise false
+ */
+bool CAEthernetIsConnected(void);
+
+/**
+ * @fn  CAEthernetSetConnectionStateChangeCallback
+ * @brief  API to set callback for receiving local ethernet adapter connection status.
+ *
+ * @param[in]  callback  Callback to be notified when local ethernet adapter connection state changes.
+ *
+ */
+void CAEthernetSetConnectionStateChangeCallback(CAEthernetConnectionStateChangeCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CA_ETHERNET_INTERFACE_
index 09be6fd..bca90c0 100644 (file)
  * limitations under the License.
  *
  ******************************************************************/
+
+/**
+ * @file caadapterutils.h
+ * @brief This file contains common utility function for CA transport adaptors.
+ */
+
 #ifndef __CA_INTERFACE_CONTROLLER_H_
 #define __CA_INTERFACE_CONTROLLER_H_
 
@@ -28,26 +34,83 @@ extern "C"
 {
 #endif
 
+/**
+ * @brief   Initializes different adapters based on the compilation flags.
+ * @param   handle       [IN]    thread pool handle created by message handler for different adapters.
+ * @return  none
+ */
 void CAInitializeAdapters(u_thread_pool_t handle);
 
+/**
+ * @brief   Set the received packets callback for message handler
+ * @param   callback       [IN]    message handler callback to receive packets from different adapters.
+ * @return  none
+ */
 void CASetPacketReceivedCallback(CANetworkPacketReceivedCallback callback);
 
+/**
+ * @brief   Set the network status changed callback for message handler
+ * @param   callback       [IN]    message handler network status callback to receive network changes.
+ * @return  none
+ */
 void CASetNetworkChangeCallback(CANetworkChangeCallback callback);
 
+/**
+ * @brief   Starting different connectivity adapters based on the network selection.
+ * @param   connectivity       [IN]    interested network for starting
+ * @return  none
+ */
 void CAStartAdapter(CAConnectivityType_t connectivity);
 
+/**
+ * @brief   Stopping different connectivity adapters based on the network un-selection.
+ * @param   callback       [IN]    un selected network for stopping the packets transfer
+ * @return  none
+ */
 void CAStopAdapter(CAConnectivityType_t connectivity);
 
+/**
+ * @brief   Get network information such as ipaddress and mac information
+ * @param   info       [OUT]    connectivity information such as ipaddress and mac information
+ * @param   size       [OUT]    number of connectivity information structures
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
 CAResult_t CAGetNetworkInfo(CALocalConnectivity_t **info, uint32_t *size);
 
-CAResult_t CASendUnicastData(CARemoteEndpoint_t* endpoint, void* data, uint32_t length);
+/**
+ * @brief   Sends unicast data to the remote endpoint
+ * @param   endpoint       [IN]    endpoint information where the data has to be sent
+ * @param   data              [IN]    data that needs to be sent
+ * @param   length              [IN]    length of the data that needs to be sent
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CASendUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t length);
+
+/**
+ * @brief   Sends multicast data to all endpoints in the network.
+ * @param   data              [IN]    data that needs to be sent
+ * @param   length              [IN]    length of the data that needs to be sent
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
 
 CAResult_t CASendMulticastData(void *data, uint32_t length);
 
+/**
+ * @brief   Start listening servers to receive search requests from clients
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
 CAResult_t CAStartListeningServerAdapters();
 
+/**
+ * @brief   Start discovery servers to receive advertisements from server
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
 CAResult_t CAStartDiscoveryServerAdapters();
 
+/**
+ * @brief   Terminates  the adapters which are initialized during the initialization
+ * @return  none
+ */
 void CATerminateAdapters();
 
 #ifdef __cplusplus
index 08e45aa..7773fad 100644 (file)
@@ -82,7 +82,8 @@ CAResult_t CAStartLEDiscoveryServer();
  * @param   dataLen   [IN]  Size of data to be sent.
  * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
  */
-uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen);
+uint32_t CASendLEUnicastData(const CARemoteEndpoint_t *endpoint, void *data, 
+                                uint32_t dataLen);
 
 /**
  * @brief Sends Multicast data to the endpoint using the LE connectivity.
@@ -108,7 +109,8 @@ CAResult_t CAStartLENotifyServer();
  * @param   dataLen   [IN]    Size of data to be sent.
  * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
  */
-uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen);
+uint32_t CASendLENotification(const CARemoteEndpoint_t *endpoint, void *data, 
+                                    uint32_t dataLen);
 
 /**
  * @brief Get LE Connectivity network information
index 23e14f3..f720c33 100644 (file)
  ******************************************************************/
 
 /**
- * @file cawificore.h
- * @brief This file contains the APIs for Wi-Fi communications.
+ * @file calecore.h
+ * @brief This file contains the APIs for BT LE communications.
  */
 #ifndef __CA_LECORE_H_
 #define __CA_LECORE_H_
 
 #include "cacommon.h"
 #include "uthreadpool.h"
+#include "jni.h"
 
 #ifdef __cplusplus
 extern "C"
@@ -39,52 +40,111 @@ void CALEInitialize(u_thread_pool_t handle);
 
 void CALETerminate();
 
-int32_t CALESendUnicastMessage(const char* address, const char* data, int32_t length);
+int32_t CALESendUnicastMessage(const char* address, const char* data, uint32_t dataLen);
 
-int32_t CALESendMulticastMessage(const char* m_address, const char* data);
+int32_t CALESendMulticastMessage(const char* data, uint32_t dataLen);
 
-int32_t CALEStartUnicastServer(const char* address, int32_t port);
+int32_t CALEStartUnicastServer(const char* address);
 
-int32_t CALEStartMulticastServer(const char* m_address, int32_t port);
+int32_t CALEStartMulticastServer();
 
-int32_t CALEStopUnicastServer(int32_t server_id);
+int32_t CALEStopUnicastServer(int32_t serverID);
 
-int32_t CALEStopMulticastServer(int32_t server_id);
+int32_t CALEStopMulticastServer(int32_t serverID);
 
 void CALESetCallback(CAPacketReceiveCallback callback);
 
-void CAGetLocalAddress(char* addressBuffer);
+void CALEGetInterfaceInfo(CALocalConnectivity_t **info, uint32_t* size);
 
-int32_t CASendUnicastMessageImpl(const char* address, const char* data);
+void CAGetLocalAddress(char* address);
 
-int32_t CASendMulticastMessageImpl(const char* msg);
+int32_t CALESendUnicastMessageImpl(const char* address, const char* data, uint32_t dataLen);
+
+int32_t CALESendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen);
 
 /**
  * BT Common Method : JNI
  */
-jstring CANativeGetLocalDeviceAddress(JNIEnvenv);
+jstring CANativeGetLocalDeviceAddress(JNIEnv *env);
 
 jobjectArray CANativeGetBondedDevices(JNIEnv *env);
 
 jint CANativeGetBTStateOnInfo(JNIEnv *env);
 
+jboolean CANativeIsEnableBTAdapter(JNIEnv *env);
+
+jstring CANativeGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice);
+
+jstring CANativeGetAddressFromGattObj(JNIEnv *env, jobject gatt);
+
 jstring CANativeGetRemoteAddress(JNIEnv *env, jobject bluetoothSocketObj);
 
+/**
+ * BLE Method : JNI
+ */
 void CANativeGattClose(JNIEnv *env, jobject bluetoothGatt);
 
-void CANativeLEStartScan(JNIEnv *env, jobject callback);
+void CANativeLEStartScan();
+
+void CANativeLEStartScanImpl(JNIEnv *env, jobject callback);
+
+void CANativeLEStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback);
 
-void CANativeLEScanService(JNIEnv *env, jobjectArray uuids, jobject callback);
+jobject CANativeGetUUIDObject(JNIEnv *env, const char* uuid);
 
-void CANativeLEStopScan(JNIEnv *env, jobject callback);
+void CANativeLEStopScan();
 
-void CANativeLEConnect(JNIEnv *env, jstring address, jobject context, jboolean autoConnect, jobject callback);
+void CANativeLEStopScanImpl(JNIEnv *env, jobject callback);
+
+void CANativeLEConnect(JNIEnv *env, jobject bluetoothDevice, jobject context, jboolean autoconnect,
+    jobject callback);
 
 void CANativeLEDisconnect(JNIEnv *env, jobject bluetoothGatt);
 
 void CANativeLEDiscoverServices(JNIEnv *env, jobject bluetoothGatt);
 
 void CANativeLESendData(JNIEnv *env, jobject bluetoothGatt, jobject gattCharacteristic);
+
+jboolean CANativeSetCharacteristicNoti(JNIEnv *env, jobject bluetoothGatt);
+
+jobject CANativeCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jstring data);
+
+jobject CANativeGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID);
+
+jbyteArray CANativeGetValueFromCharacteristic(JNIEnv *env, jobject characteristic);
+
+/**
+ * BluetoothDevice List
+ */
+void CANativeCreateScanDeviceList(JNIEnv *env);
+
+void CANativeAddScanDeviceToList(JNIEnv *env, jobject device);
+
+jboolean CANativeIsDeviceInList(JNIEnv *env, const char* remoteAddress);
+
+void CANativeRemoveAllDevices(JNIEnv *env);
+
+void CANativeRemoveDevice(JNIEnv *env, jstring remoteAddress);
+
+void CAReorderingDeviceList(uint32_t index);
+
+/**
+ * BluetoothGatt List
+ */
+void CANativeCreateGattObjList(JNIEnv *env);
+
+void CANativeAddGattobjToList(JNIEnv *env, jobject gatt);
+
+jboolean CANativeIsGattObjInList(JNIEnv *env, const char* remoteAddress);
+
+void CANativeRemoveAllGattObjsList(JNIEnv *env);
+
+void CANativeLEDisconnectAll(JNIEnv *env);
+
+void CANativeRemoveGattObj(JNIEnv *env, jstring address);
+
+void CAReorderingGattList(uint32_t index);
+
 #ifdef __cplusplus
 } /* extern "C" */
 #endif
index df17e6c..44c6e4b 100644 (file)
  * limitations under the License.
  *
  ******************************************************************/
+/**
+ * @file camessagehandler.h
+ * @brief This file contains message functionality.
+ */
+
 #ifndef __CA_MESSAGE_HANDLER_H_
 #define __CA_MESSAGE_HANDLER_H_
 
@@ -28,20 +33,68 @@ extern "C"
 {
 #endif
 
-CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequestInfo_t *request);
+/**
+ * @brief   Detaches control from the caller for sending unicast request
+ * @param   endpoint       [IN]    endpoint information where the data has to be sent
+ * @param   request              [IN]    request that needs to be sent
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *endpoint,
+        const CARequestInfo_t *request);
+
+/**
+ * @brief   Detaches control from the caller for sending multicast request
+ * @param   endpoint       [IN]    endpoint information where the data has to be sent
+ * @param   request              [IN]    request that needs to be sent
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t* object, 
+            const CARequestInfo_t* request);
 
-CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object,
-                                   const CAResponseInfo_t *response);
+/**
+ * @brief   Detaches control from the caller for sending response
+ * @param   endpoint       [IN]    endpoint information where the data has to be sent
+ * @param   response              [IN]    request that needs to be sent
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *endpoint,
+        const CAResponseInfo_t *response);
 
-CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token, const CAHeaderOption_t* options,
-                                      uint8_t numOptions);
+/**
+ * @brief   Detaches control from the caller for sending request
+ * @param   resourceUri       [IN]   resource uri that needs to  be sent in the request
+ * @param   token              [IN]    token information of the request
+ * @param   options       [IN]    header options that need to be append in the request
+ * @param   numOptions              [IN]    number of options be appended
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t token,
+        const CAHeaderOption_t* options, uint8_t numOptions);
 
-void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler);
+/**
+ * @brief   Setting the request and response callbacks for network packets
+ * @param   ReqHandler       [IN]    callback for receiving the requests
+ * @param   RespHandler  [IN]    callback for receiving the response
+ * @return  void
+ */
+void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, 
+                            CAResponseCallback RespHandler);
 
+/**
+ * @brief  Initialize the message handler by starting thread pool and initializing the send and reive queue
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
 CAResult_t CAInitializeMessageHandler();
 
+/**
+ * @brief Terminate the message handler by stopping  the thread pool and destroying the queues
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
 void CATerminateMessageHandler();
 
+/**
+ * @brief Handler for receiving request and response callback in singled thread model
+ */
 void CAHandleRequestResponseCallbacks();
 
 #ifdef __cplusplus
index 3b3f529..77acfcd 100644 (file)
@@ -90,7 +90,8 @@ uint32_t CAParseHeader(const char* header);
 *
 * @return
 */
-uint32_t CAFragmentData(const char* data, char** dataSegment, uint32_t TotalLen, uint32_t offset);
+uint32_t CAFragmentData(const char* data, char** dataSegment, uint32_t TotalLen, 
+                        uint32_t offset);
 
 /**
 * @fn CADeFragmentData
@@ -98,7 +99,8 @@ uint32_t CAFragmentData(const char* data, char** dataSegment, uint32_t TotalLen,
 *
 * @return
 */
-uint32_t CADeFragmentData(const char* datasegment, char** data, uint32_t TotalLen, uint32_t offset);
+uint32_t CADeFragmentData(const char* datasegment, char** data, uint32_t TotalLen, 
+                        uint32_t offset);
 
 #ifdef __cplusplus
 } /* extern "C" */
index 4e93bf6..188de03 100644 (file)
  * limitations under the License.
  *
  ******************************************************************/
+/**
+ * @file canetworkconfigurator.h
+ * @brief This file contains  utility function for network configurations.
+ */
+
 #ifndef _NETWORK_CONFIGURATOR_H_
 #define _NETWORK_CONFIGURATOR_H_
 
@@ -28,13 +33,32 @@ extern "C"
 {
 #endif
 
-
+/**
+ * @brief   Add network type to the selected networks for network packets reception
+ * @param   CAConnectivityType       [IN]    connectivity type that needs to be added
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
 CAResult_t CAAddNetworkType(uint32_t CAConnectivityType);
 
+/**
+ * @brief   Add network type to the un selected for network packets reception
+ * @param   CAConnectivityType       [IN]    connectivity type that needs to be removed
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
 CAResult_t CARemoveNetworkType(uint32_t CAConnectivityType);
 
+/**
+ * @brief   Get selected network information
+ * @return array list having the connectivity types
+ */
 u_arraylist_t *CAGetSelectedNetworkList();
 
+/**
+ * @brief  Getnetwork informations of the selected networks
+ * @param   info    [OUT]   LocalConnectivity objects
+ * @param   size    [OUT]   No Of Array objects
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
 CAResult_t CAGetNetworkInformationInternal(CALocalConnectivity_t **info, uint32_t *size);
 
 #ifdef __cplusplus
index 9861e4c..59f5ec6 100644 (file)
  * limitations under the License.
  *
  ******************************************************************/
+/**
+ * @file caprotocolmessage.h
+ * @brief This file contains common function for handling protocol messages.
+ */
+
 #ifndef __CA_PROTOCOL_MESSAGE_H_
 #define __CA_PROTOCOL_MESSAGE_H_
 
@@ -33,61 +38,153 @@ extern "C"
 typedef uint32_t code_t;
 
 /**
- * function for generating
+ * @brief   generates pdu structure from the given information.
+ * @param   uri              [IN]    uri information of the pdu
+ * @param   code              [IN]    cod of the pdu packet
+ * @param   info              [IN]    pdu information such as request code ,response code and payload
+ * @return  coap_pdu_t     created pdu
  */
 coap_pdu_t *CAGeneratePdu(const char *uri, const uint32_t code, const CAInfo_t info);
 
 /**
  * function for generating
  */
-uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, char *outUri);
 
+/**
+ * @brief   extracts request information from received pdu.
+ * @param   pdu              [IN]    received pdu
+ * @param   outReqInfo     [OUT]    request info structure made from received pdu
+ * @param   outUri           [OUT]    uri received in the received pdu
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, 
+                                        char *outUri);
+
+/**
+ * @brief   extracts response information from received pdu.
+ * @param   pdu              [IN]    received pdu
+ * @param   outResInfo     [OUT]    request info structure made from received pdu
+ * @param   outUri           [OUT]    uri received in the received pdu
+ * @return  0 or 1 ( CAResult_t error codes in cacommon.h)
+ */
 uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo,
         char *outUri);
 
-coap_pdu_t* CACreatePDUforRequest(const code_t code, coap_list_t *options, const CAInfo_t info);
+/**
+ * @brief   creates pdu from the request information
+ * @param   code              [IN]    request or response code
+ * @param   options              [IN]    options for the request and response
+ * @param   outUri           [IN]    information to create pdu
+ * @return  coap_pdu_t
+ */
+coap_pdu_t* CACreatePDUforRequest(const code_t code, coap_list_t *options, 
+                                        const CAInfo_t info);
+
+/**
+ * @brief   creates pdu from the request information and paylod
+ * @param   code              [IN]    request or response code alloted
+ * @param   options              [IN]    options for the request and response backpacked
+ * @param   payload       [IN]    payload for the request or response consumed
+ * @param   outUri           [IN]    information to create pdu
+ * @return  coap_pdu_t
+ */
 
 coap_pdu_t *CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *optlist,
         const char* payload, const CAInfo_t info);
 
 /**
- * funtion for parsing
+ * @brief   parse the URI and creates the options
+ * @param   uriInfo              [IN]   uri information
+ * @param   options              [IN]   options information
+ * @return  None
  */
 void CAParseURI(const char *uriInfo, coap_list_t **options);
 
 /**
- * funtion for parsing
+ * @brief   create option list from header information in the info
+ * @param   code              [IN]   uri information
+ * @param   info              [IN]   options information
+ * @param   optlist              [IN]   options information
+ * @return  None
  */
 void CAParseHeadOption(const uint32_t code, const CAInfo_t info, coap_list_t **optlist);
 
-coap_list_t *CACreateNewOptionNode(const uint16_t key, const uint32_t length, const uint8_t *data);
+/**
+ * @brief   creates option node from key lenght and data
+ * @param   key              [IN]    key for the that needs to be sent
+ * @param   length              [IN]    length of the data that needs to be sent
+ * @param   data              [IN]    data that needs to be sent
+ * @return  created list
+ */
+coap_list_t *CACreateNewOptionNode(const uint16_t key, const uint32_t length, 
+                                            const uint8_t *data);
 
+/**
+ * @brief   order the inserted options
+ * @param   a              [IN]    option 1 for insertion
+ * @param   b              [IN]    option 2 for insertion
+ * @return  0 or 1
+ */
 int CAOrderOpts(void *a, void *b);
 
+/**
+ * @brief   number of options count
+ * @param   opt_iter              [IN]   option iteration for count
+ * @return number of options
+ */
 uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter);
 
+/**
+ * @brief   gets option data
+ * @param   data              [IN]    data that is received
+ * @param   length              [IN]    length of the data
+ * @param   result              [IN]    result of the operation
+ * @param   buflen              [IN]    buffer length of the result
+ * @param   encode_always              [IN]    encoded data
+ * @return  0 or 1
+ */
 uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *result, uint32_t buflen,
         uint32_t encode_always);
 
 /**
- * funtion for get PDU information
+ * @brief   extracts request information from received pdu.
+ * @param   pdu              [IN]  received pdu
+ * @param   outCode    [OUT]    code of the received pdu
+ * @param   outInfo      [OUT]    request info structure made from received pdu
+ * @param   outUri          [OUT]    uri received in the received pdu
+ * @return  None
  */
-void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo, char *outUri);
+void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo, 
+                        char *outUri);
 
 /**
- * funtion for parsing
+ * @brief   create pdu fromn received data
+ * @param   data              [IN]   received data
+ * @param   length              [IN]   length of the data received
+ * @param   outCode       [IN]   code received
+ * @return  None
  */
 coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode);
 
 /**
- * function for token
+ * @brief  generates the token
+ * @param   token              [OUT]   generated token
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
  */
+
 CAResult_t CAGenerateTokenInternal(CAToken_t *token);
 
+/**
+ * @brief  destroys the token
+ * @param   token              [IN]   generated token
+ * @return  none
+ */
 void CADestroyTokenInternal(CAToken_t token);
 
 /**
- * Deinitialize
+ * @brief   destroy the ca info structure
+ * @param   info              [IN]   info structure  created from received  packet
+ * @return  none
  */
 void CADeinitialize(CAInfo_t *info);
 
index 89bf067..f88746d 100644 (file)
@@ -17,9 +17,9 @@
  * limitations under the License.
  *
  ******************************************************************/
-
 /**
  * @file caqueueingthread.h
+ * @brief This file contains common utility function for handling message ques
  */
 #ifndef __CA_THREAD_H_
 #define __CA_THREAD_H_
@@ -35,28 +35,65 @@ extern "C"
 {
 #endif
 
+/**Thread function to be invoked**/
 typedef void (*CAThreadTask)(void* threadData);
 
 typedef struct
 {
+    /** Thread pool of the thread started **/
     u_thread_pool_t threadPool;
+    /** mutex for synchrnoization **/
     u_mutex threadMutex;
+    /** conditional mutex for synchrnoization **/
     u_cond threadCond;
+    /**Thread function to be invoked**/
     CAThreadTask threadTask;
+    /** Variable to inform the thread to stop **/
     CABool_t isStop;
+    /** Que on which the thread is operating. **/
     u_queue_t* dataQueue;
 } CAQueueingThread_t;
 
+/**
+ * @brief   Initializes the queing thread
+ * @param   thread       [IN]    thread data for each thread
+ * @param   handle              [IN]    thread pool handle created
+ * @param   task              [IN]   function to be called for reach data
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
 CAResult_t CAQueueingThreadInitialize(CAQueueingThread_t* thread, u_thread_pool_t handle,
         CAThreadTask task);
 
+/**
+ * @brief   Starting the queueing thread
+ * @param   thread       [IN]    thread data that needs to be started
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
 CAResult_t CAQueueingThreadStart(CAQueueingThread_t* thread);
 
-// shallow copy
+/**
+ * @brief   Add queueing thread data for new thread
+ * @param   thread       [IN]    thread data for new thread control
+ * @param   data              [IN]    data that needs to be given for each thread
+ * @param   size              [IN]    length of the data
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
 CAResult_t CAQueueingThreadAddData(CAQueueingThread_t* thread, void* data, uint32_t size);
 
+/**
+ * @brief   Stopping the queueing thread
+ * @param   thread       [IN]    thread data that needs to be started
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+
 CAResult_t CAQueueingThreadStop(CAQueueingThread_t* thread);
 
+/**
+ * @brief   Terminating  the queing thread
+ * @param   thread       [IN]    thread data for each thread
+ * @return  CA_STATUS_OK or ERROR CODES ( CAResult_t error codes in cacommon.h)
+ */
+
 CAResult_t CAQueueingThreadDestroy(CAQueueingThread_t* thread);
 
 #ifdef __cplusplus
index 4c3a984..1fe2873 100644 (file)
  * limitations under the License.
  *
  ******************************************************************/
+
+/**
+ * @file caremotehandler.h
+ * @brief This file contains common utility function for remote endpoints
+ */
+
 #ifndef __CA_REMOTE_HANDLER_H_
 #define __CA_REMOTE_HANDLER_H_
 
@@ -31,22 +37,64 @@ extern "C"
 {
 #endif
 
-CARemoteEndpoint_t* CACloneRemoteEndpoint(const CARemoteEndpoint_t* rep);
+/**
+ * @brief   Creates a new remote endpoint from the input endpoint
+ * @param   endpoint       [IN]    endpoint information where the data has to be sent
+ * @return  remote endpoint created
+ */
+CARemoteEndpoint_t* CACloneRemoteEndpoint(const CARemoteEndpoint_t* endpoint);
 
+/**
+ * @brief   Creates a new remote endpoint from the input uri
+ * @param   uri       [IN]    absolute uri information to  create remote endpoint
+ * @return  remote endpoint created
+ */
 CARemoteEndpoint_t* CACreateRemoteEndpointUriInternal(const CAURI_t uri);
 
+/**
+ * @brief   Creates a new remote endpoint from the input and other information
+ * @param   resourceUri       [IN]    absolute uri information to  create remote endpoint
+ * @param   addr       [IN]    address of the ednpoint
+ * @param   type       [IN]    connectivity type of the endpoint
+ * @return  remote endpoint created
+ */
 CARemoteEndpoint_t* CACreateRemoteEndpointInternal(const CAURI_t resourceUri,
         const CAAddress_t addr, const CAConnectivityType_t type);
 
+/**
+ * @brief   Destroy remote endpoint
+ * @param   endpoint       [IN]    endpoint information where the data has to be sent
+ * @return  none
+ */
 void CADestroyRemoteEndpointInternal(CARemoteEndpoint_t* rep);
 
-CARequestInfo_t* CACloneRequestInfo(const CARequestInfo_t* rep);
+/**
+ * @brief   Creates a new request information
+ * @param   rep       [IN]    request information that needs to be duplicated
+ * @return  remote endpoint created
+ */
+CARequestInfo_t* CACloneRequestInfo(const CARequestInfo_t* request);
 
-void CADestroyRequestInfoInternal(CARequestInfo_t* rep);
+/**
+ * @brief   Destroy the request information
+ * @param   rep       [IN]    request information that needs to be destroyed
+ * @return none
+ */
+void CADestroyRequestInfoInternal(CARequestInfo_t* request);
 
-CAResponseInfo_t* CACloneResponseInfo(const CAResponseInfo_t* rep);
+/**
+ * @brief   Creates a new response information
+ * @param   rep       [IN]    response information that needs to be duplicated
+ * @return  remote endpoint created
+ */
+CAResponseInfo_t* CACloneResponseInfo(const CAResponseInfo_t* response);
 
-void CADestroyResponseInfoInternal(CAResponseInfo_t* rep);
+/**
+ * @brief   Destroy the response information
+ * @param   rep       [IN]    response information that needs to be destroyed
+ * @return
+ */
+void CADestroyResponseInfoInternal(CAResponseInfo_t* response);
 
 #ifdef __cplusplus
 } /* extern "C" */
index 02b3a14..929dafb 100644 (file)
@@ -79,7 +79,8 @@ CAResult_t CAStartWIFIDiscoveryServer();
  * @param   dataLen     [IN]    Size of data to be sent.
  * @return - The number of bytes sent on the network. Return value equal to zero indicates error.
  */
-uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen);
+uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *endpoint, void *data, 
+                                        uint32_t dataLen);
 
 /**
  * @brief Sends Multicast data to the endpoint using the WIFI connectivity.
diff --git a/resource/csdk/connectivity/inc/cawificore.h b/resource/csdk/connectivity/inc/cawificore.h
deleted file mode 100644 (file)
index f8311e5..0000000
+++ /dev/null
@@ -1,76 +0,0 @@
-/******************************************************************
- *
- * Copyright 2014 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
-
-/**
- * @file cawificore.h
- * @brief This file contains the APIs for Wi-Fi communications.
- */
-#ifndef __CA_WIFICORE_H_
-#define __CA_WIFICORE_H_
-
-#include "cacommon.h"
-#include "config.h"
-#include "coap.h"
-#include "uthreadpool.h"
-
-#ifdef __cplusplus
-extern "C"
-{
-#endif
-
-typedef void (*CAPacketReceiveCallback)(char* address, const int port, const char* data,
-        uint32_t length);
-
-void CAWiFiSetCallback(CAPacketReceiveCallback callback);
-
-void CAWiFiInitMutex();
-
-void CAWiFiInitialize(u_thread_pool_t handle);
-
-int32_t CABindUnicastSocket();
-
-void CAWiFiTerminate();
-
-int32_t CAWiFiSendUnicastMessage(const char* address, const int port, char* data, uint32_t length);
-
-int32_t CAWiFiSendMulticastMessage(const char* m_address, char* data, uint32_t dataLen);
-
-int32_t CAWiFiStartUnicastServer();
-
-int32_t CAWiFiStartMulticastServer();
-
-int32_t CAWiFiStopUnicastServer();
-
-int32_t CAWiFiStopMulticastServer();
-
-void CAGetLocalAddress(char *addressBuffer);
-
-int32_t CASendUnicastMessageImpl(const char *address, const int port, const char *data,
-        uint32_t len);
-
-int32_t CASendMulticastMessageImpl(const char *msg, uint32_t len);
-
-CAResult_t CAGetWIFIInterfaceInfo(CALocalConnectivity_t **info, uint32_t* size);
-
-#ifdef __cplusplus
-} /* extern "C" */
-#endif
-
-#endif
diff --git a/resource/csdk/connectivity/inc/cawifiinterface.h b/resource/csdk/connectivity/inc/cawifiinterface.h
new file mode 100644 (file)
index 0000000..5b290c6
--- /dev/null
@@ -0,0 +1,337 @@
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+
+/**
+ * @file cawifiinterface.h
+ * @brief This file provides APIs wifi client/server/network monitor modules
+ */
+
+#ifndef _CA_WIFI_INTERFACE_
+#define _CA_WIFI_INTERFACE_
+
+#include <stdbool.h>
+
+#include "cacommon.h"
+#include "uthreadpool.h"
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+/**
+ * @enum CAAdapterServerType_t
+ * @brief Enum for defining different server types.
+ */
+typedef enum
+{
+    CA_UNICAST_SERVER = 0,
+    CA_MULTICAST_SERVER,
+    CA_SECURED_UNICAST_SERVER
+} CAAdapterServerType_t;
+
+/**
+ * @fn  CAWiFiPacketReceivedCallback
+ * @brief  Callback to be notified on receival of any data from remote OIC devices.
+ *
+ * @param[in]  ipAddress  IP address of remote OIC device.
+ * @param[in]  port  Port number on which data is received.
+ * @param[in]  data  Data received from remote OIC device.
+ * @param[in]  dataLength  Length of data in bytes.
+ *
+ * @pre  Callback must be registered using CAWiFiSetPacketReceiveCallback()
+ */
+typedef void (*CAWiFiPacketReceivedCallback)(const char *ipAddress, const uint32_t port,
+        const void *data, const uint32_t dataLength);
+
+/**
+ * @fn  CAWiFiExceptionCallback
+ * @brief  Callback to be notified when exception occures on multicast/unicast server.
+ *
+ * @param[in]  type  Type of server either #CA_UNICAST_SERVER or $CA_MULTICAST_SERVER
+ *
+ * @pre  Callback must be registered using CAWiFiSetExceptionCallback()
+ */
+typedef void (*CAWiFiExceptionCallback)(CAAdapterServerType_t type);
+
+/**
+ * @fn  CAWiFiInitializeServer
+ * @brief  API to initialize Wifi server
+ *
+ * @param[in]  threadPool  Thread pool for managing Unicast/Multicast server threads.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAWiFiInitializeServer(const u_thread_pool_t threadPool);
+
+#ifdef ARDUINO
+/**
+ * @fn  CAWiFiInitializeServer
+ * @brief  API to initialize Wifi server
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAWiFiInitializeServer(void);
+#endif //ARDUINO
+
+/**
+ * @fn  CAWiFiTerminateServer
+ * @brief  API to terminate Wifi server
+ */
+void CAWiFiTerminateServer(void);
+
+/**
+ * @fn  CAWiFiStartMulticastServer
+ * @brief  API to start multicast server for specified multicast address and port
+ *
+ * @param[in]  localAddress  Local adapter address to which server to be binded.
+ * @param[in]  multicastAddress  Multicast group address.
+ * @param[in]  multicastPort  Port number on which server to be running.
+ * @param[out]  serverFD  Multicast server socket FD.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_SERVER_STARTED_ALREADY Multicast server is already started and running.
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *multicastAddress,
+                                      const int16_t multicastPort, int32_t *serverFD);
+
+/**
+ * @fn  CAWiFiStartUnicastServer
+ * @brief  API to start unicast server for specified local address and port
+ *
+ * @param[in]  localAddress  Local adapter address to which server to be binded.
+ * @param[in][out]  port  Port number on which server to be running.
+ * Port number on which server actually started will be returned.
+ * @param[in]  forceStart  Indicate whether to start server forcesfully on specified port or not.
+ * @param[out]  serverFD  Unicast server socket FD.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_SERVER_STARTED_ALREADY Unicast server is already started and running.
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
+                                    const bool forceStart, int32_t *serverFD);
+
+/**
+ * @fn  CAWiFiStopMulticastServer
+ * @brief  API to stop multicast server.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStopMulticastServer(void);
+
+/**
+ * @fn  CAWiFiStopUnicastServer
+ * @brief  API to stop unicast server.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStopUnicastServer();
+
+/**
+ * @fn  CAWiFiGetUnicastServerInfo
+ * @brief  API to get running unicast server information.
+ * @remarks  @ipAddress must be freed using free().
+ *
+ * @param[in]  ipAddress  IP address on which server is binded and running.
+ * @param[out]  port  Port number on which server is running
+ * @param[out]  serverFD  Server socket fd.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD);
+
+/**
+ * @fn  CAWiFiSetPacketReceiveCallback
+ * @brief  API to set callback for receiving data packets from peer devices.
+ *
+ * @param[in]  callback Callback to be notified on receival of unicast/multicast data packets.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+void CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCallback callback);
+
+#ifdef ARDUINO
+/**
+ * @fn  CAWiFiReadData
+ * @brief  API to pull data
+ */
+void CAWiFiPullData();
+#endif // ARDUINO
+
+/**
+ * @fn  CAWiFiSetExceptionCallback
+ * @brief  API to set callback for receiving exception notifications.
+ *
+ * @param[in]  callback  Callback to be notified on occurance of exception running servers.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+void CAWiFiSetExceptionCallback(CAWiFiExceptionCallback callback);
+
+/**
+ * @fn  CAWiFiSetUnicastSocket
+ * @brief  API to set socket description for sending unicast UDP data
+ *
+ * @param[in]  socketFD  Socket descriptor used for sending UDP data.
+ *
+ */
+void CAWiFiSetUnicastSocket(const int32_t socketFD);
+
+/**
+ * @fn  CAWiFiSendUnicastData
+ * @brief  API to send unicast UDP data
+ *
+ * @param[in]  remoteAddress  IP address to which data needs to be send.
+ * @param[in]  port  Port to which data needs to be send.
+ * @param[in]  data  Data to be send.
+ * @param[in]  dataLength  Length of data in bytes
+ * @param[in]  isMulticast  whether data needs to be sent to multicast ip
+ * @param[out]  sentLength  Number of bytes actually sent
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
+                        const void *data, const uint32_t dataLength, bool isMulticast);
+
+/**
+ * @fn  CAWiFiConnectionStateChangeCallback
+ * @brief  Callback to be notified when wifi adapter connection state changes.
+ *
+ * @param[in]  ipAddress  IP address of remote OIC device.
+ * @param[in]  status  Connection status either #CA_INTERFACE_UP or #CA_INTERFACE_DOWN.
+ *
+ * @pre  Callback must be registered using CAWiFiSetConnectionStateChangeCallback()
+ */
+typedef void (*CAWiFiConnectionStateChangeCallback)(const char *ipAddress,
+        const CANetworkStatus_t status);
+
+/**
+ * @fn  CAWiFiInitializeNetworkMonitor
+ * @brief  API to initialize Wifi network monitor
+ *
+ * @param[in]  threadPool  Thread pool for managing network monitor thread.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAWiFiInitializeNetworkMonitor(const u_thread_pool_t threadPool);
+
+#ifdef ARDUINO
+/**
+ * @fn  CAWiFiInitializeServer
+ * @brief  API to initialize Wifi server
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Initialization failed
+ */
+CAResult_t CAWiFiInitializeNetworkMonitor(void);
+#endif //ARDUINO
+
+/**
+ * @fn  CAWiFiTerminateNetworkMonitor
+ * @brief  API to terminate Wifi network monitor
+ */
+void CAWiFiTerminateNetworkMonitor(void);
+
+/**
+ * @fn  CAWiFiStartNetworkMonitor
+ * @brief  API to start network monitoring process.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStartNetworkMonitor(void);
+
+/**
+ * @fn  CAWiFiStopNetworkMonitor
+ * @brief  API to stop network monitoring process.
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiStopNetworkMonitor(void);
+
+/**
+ * @fn  CAWiFiGetInterfaceInfo
+ * @brief  API to get local adapter network information.
+ * @remarks  @interfaceName and @ipAddress must be freed using free().
+ *
+ * @param[out]  interfaceName  Local adapter interface name
+ * @param[out]  ipAddress  IP address
+ *
+ * @return  #CA_STATUS_OK on success otherwise proper error code.
+ * @retval  #CA_STATUS_OK  Successful
+ * @retval  #CA_STATUS_INVALID_PARAM Invalid input data
+ * @retval  #CA_STATUS_FAILED Operation failed
+ */
+CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress);
+
+/**
+ * @fn  CAWiFiIsConnected
+ * @brief  API to get wifi adapter connection state.
+ *
+ * @return  true if wifi adapter is connected, otherwise false
+ */
+bool CAWiFiIsConnected(void);
+
+/**
+ * @fn  CAWiFiSetConnectionStateChangeCallback
+ * @brief  API to set callback for receiving local wifi adapter connection status.
+ *
+ * @param[in]  callback  Callback to be notified when local wifi adapter connection state changes.
+ *
+ */
+void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback callback);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif //_CA_WIFI_INTERFACE_
\ No newline at end of file
diff --git a/resource/csdk/connectivity/inc/com_iotivity_jar_CALeInterface.h b/resource/csdk/connectivity/inc/com_iotivity_jar_CALeInterface.h
new file mode 100644 (file)
index 0000000..a10a34a
--- /dev/null
@@ -0,0 +1,109 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_iotivity_jar_CALeInterface */
+
+#ifndef _Included_com_iotivity_jar_CALeInterface
+#define _Included_com_iotivity_jar_CALeInterface
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CARegisterLeScanCallback
+ * Signature: (Landroid/bluetooth/BluetoothAdapter/LeScanCallback;)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterLeScanCallback
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CARegisterLeGattCallback
+ * Signature: (Landroid/bluetooth/BluetoothGattCallback;)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterLeGattCallback
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeScanCallback
+ * Signature: (Landroid/bluetooth/BluetoothDevice;I[B)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeScanCallback
+  (JNIEnv *, jobject, jobject, jint, jbyteArray);
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattConnectionStateChangeCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattConnectionStateChangeCallback
+  (JNIEnv *, jobject, jobject, jint, jint);
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattServicesDiscoveredCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattServicesDiscoveredCallback
+  (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattCharacteristicReadCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristicReadCallback
+  (JNIEnv *, jobject, jobject, jobject, jstring, jint);
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattCharacteristicWritjclasseCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristicWriteCallback
+  (JNIEnv *, jobject, jobject, jobject, jstring, jint);
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattCharacteristicChangedCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristicChangedCallback
+  (JNIEnv *, jobject, jobject, jobject, jstring);
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattDescriptorReadCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattDescriptorReadCallback
+  (JNIEnv *, jobject, jobject, jobject, jint);
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattDescriptorWriteCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattDescriptorWriteCallback
+  (JNIEnv *, jobject, jobject, jobject, jint);
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattReliableWriteCompletedCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattReliableWriteCompletedCallback
+  (JNIEnv *, jobject, jobject, jint);
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattReadRemoteRssiCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattReadRemoteRssiCallback
+  (JNIEnv *, jobject, jobject, jint, jint);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/resource/csdk/connectivity/inc/com_iotivity_jar_CAWiFiInterface.h b/resource/csdk/connectivity/inc/com_iotivity_jar_CAWiFiInterface.h
new file mode 100644 (file)
index 0000000..828c37a
--- /dev/null
@@ -0,0 +1,29 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_iotivity_jar_CAWiFiInterface */
+
+#ifndef _Included_com_iotivity_jar_CAWiFiInterface
+#define _Included_com_iotivity_jar_CAWiFiInterface
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     com_iotivity_jar_CAWiFiInterface
+ * Method:    CAWiFiStateEnabled
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CAWiFiInterface_CAWiFiStateEnabled
+  (JNIEnv *, jclass);
+
+/*
+ * Class:     com_iotivity_jar_CAWiFiInterface
+ * Method:    CAWiFiStateDisabled
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CAWiFiInterface_CAWiFiStateDisabled
+  (JNIEnv *, jclass);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/resource/csdk/connectivity/lib/android/glib-master/Android.mk b/resource/csdk/connectivity/lib/android/glib-master/Android.mk
new file mode 100644 (file)
index 0000000..8d8d6e9
--- /dev/null
@@ -0,0 +1,55 @@
+# This file is the top android makefile for all sub-modules.
+
+LOCAL_PATH := $(call my-dir)
+
+GLIB_TOP := $(LOCAL_PATH)
+
+GLIB_BUILD_STATIC := $(BUILD_STATIC)
+
+GLIB_C_INCLUDES :=                     \
+       $(GLIB_TOP)                     \
+       $(GLIB_TOP)/glib                \
+       $(GLIB_TOP)/android
+
+GTHREAD_C_INCLUDES :=                  \
+       $(GLIB_C_INCLUDES)              \
+       $(GLIB_TOP)/gthread
+
+#GOBJECT_C_INCLUDES :=                 \
+#      $(GLIB_C_INCLUDES)              \
+#      $(GLIB_TOP)/gobject             \
+#      $(GLIB_TOP)/gobject/android
+
+#GMODULE_C_INCLUDES :=                 \
+#      $(GLIB_C_INCLUDES)              \
+#      $(GLIB_TOP)/gmodule
+
+#GIO_C_INCLUDES :=                     \
+#      $(GLIB_C_INCLUDES)              \
+#      $(GLIB_TOP)/gio                 \
+#      $(GLIB_TOP)/gio/android
+
+#GLIB_SHARED_LIBRARIES :=              \
+#      libgmodule-2.0                  \
+#      libgobject-2.0                  \
+#      libgthread-2.0                  \
+#      libglib-2.0
+
+GLIB_SHARED_LIBRARIES :=               \
+       libgthread-2.0                  \
+       libglib-2.0
+
+GLIB_STATIC_LIBRARIES :=               \
+       $(GLIB_SHARED_LIBRARIES)        \
+       libpcre
+
+include $(CLEAR_VARS)
+
+
+include $(GLIB_TOP)/glib/Android.mk
+include $(GLIB_TOP)/gthread/Android.mk
+#include $(GLIB_TOP)/gobject/Android.mk
+#include $(GLIB_TOP)/gmodule/Android.mk
+#include $(GLIB_TOP)/gio/Android.mk
+#include $(GLIB_TOP)/tests/Android.mk
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/android-internal/config.h b/resource/csdk/connectivity/lib/android/glib-master/android-internal/config.h
new file mode 100644 (file)
index 0000000..67e69fe
--- /dev/null
@@ -0,0 +1,742 @@
+/* config.h.  Generated from config.h.in by configure.  */
+/* config.h.in.  Generated from configure.in by autoheader.  */
+
+/* Define if building universal (internal helper macro) */
+/* #undef AC_APPLE_UNIVERSAL_BUILD */
+
+/* define if asm blocks can use numeric local labels */
+/* #undef ASM_NUMERIC_LABELS */
+
+/* poll doesn't work on devices */
+/* #undef BROKEN_POLL */
+
+/* Define to one of `_getb67', `GETB67', `getb67' for Cray-2 and Cray-YMP
+   systems. This function is required for `alloca.c' support on those systems.
+   */
+/* #undef CRAY_STACKSEG_END */
+
+/* Define to 1 if using `alloca.c'. */
+/* #undef C_ALLOCA */
+
+/* Whether to disable memory pools */
+#define DISABLE_MEM_POOLS
+
+/* Whether to enable GC friendliness by default */
+/* #undef ENABLE_GC_FRIENDLY_DEFAULT */
+
+/* always defined to indicate that i18n is enabled */
+/* #define ENABLE_NLS 1 */
+
+/* include GRegex */
+#define ENABLE_REGEX 1
+
+/* Define the gettext package to be used */
+#define GETTEXT_PACKAGE "glib20"
+
+/* Define to the GLIB binary age */
+#define GLIB_BINARY_AGE 2401
+
+/* Byte contents of gmutex */
+#define GLIB_BYTE_CONTENTS_GMUTEX no
+
+/* Define to the GLIB interface age */
+#define GLIB_INTERFACE_AGE 1
+
+/* Define the location where the catalogs will be installed */
+#define GLIB_LOCALE_DIR ""
+
+/* Define to the GLIB major version */
+#define GLIB_MAJOR_VERSION 2
+
+/* Define to the GLIB micro version */
+#define GLIB_MICRO_VERSION 1
+
+/* Define to the GLIB minor version */
+#define GLIB_MINOR_VERSION 24
+
+/* The size of gmutex, as computed by sizeof. */
+#define GLIB_SIZEOF_GMUTEX 24
+
+/* The size of system_thread, as computed by sizeof. */
+#define GLIB_SIZEOF_SYSTEM_THREAD 4
+
+/* alpha atomic implementation */
+/* #undef G_ATOMIC_ALPHA */
+
+/* arm atomic implementation */
+/* #undef G_ATOMIC_ARM */
+
+/* cris atomic implementation */
+/* #undef G_ATOMIC_CRIS */
+
+/* crisv32 atomic implementation */
+/* #undef G_ATOMIC_CRISV32 */
+
+/* i486 atomic implementation */
+/* #undef G_ATOMIC_I486 */
+
+/* ia64 atomic implementation */
+/* #undef G_ATOMIC_IA64 */
+
+/* powerpc atomic implementation */
+/* #undef G_ATOMIC_POWERPC */
+
+/* s390 atomic implementation */
+/* #undef G_ATOMIC_S390 */
+
+/* sparcv9 atomic implementation */
+/* #undef G_ATOMIC_SPARCV9 */
+
+/* x86_64 atomic implementation */
+/* #undef G_ATOMIC_X86_64 */
+
+/* Have inline keyword */
+#define G_HAVE_INLINE 1
+
+/* Have __inline keyword */
+#define G_HAVE___INLINE 1
+
+/* Have __inline__ keyword */
+#define G_HAVE___INLINE__ 1
+
+/* Source file containing theread implementation */
+#define G_THREAD_SOURCE "gthread-posix.c"
+
+/* A 'va_copy' style function */
+#define G_VA_COPY va_copy
+
+/* 'va_lists' cannot be copies as values */
+/* #undef G_VA_COPY_AS_ARRAY */
+
+/* Define to 1 if you have `alloca', as a function or macro. */
+#define HAVE_ALLOCA 1
+
+/* Define to 1 if you have <alloca.h> and it should be used (not on Ultrix).
+   */
+#define HAVE_ALLOCA_H 1
+
+/* Define to 1 if you have the <arpa/nameser_compat.h> header file. */
+/* #define HAVE_ARPA_NAMESER_COMPAT_H 1 */
+
+/* Define to 1 if you have the `atexit' function. */
+#define HAVE_ATEXIT 1
+
+/* Define to 1 if you have the <attr/xattr.h> header file. */
+/* #undef HAVE_ATTR_XATTR_H */
+
+/* Define to 1 if you have the `bind_textdomain_codeset' function. */
+/* #define HAVE_BIND_TEXTDOMAIN_CODESET 1 */
+
+/* Define if you have a version of the snprintf function with semantics as
+   specified by the ISO C99 standard. */
+/* #define HAVE_C99_SNPRINTF 1 */
+
+/* Define if you have a version of the vsnprintf function with semantics as
+   specified by the ISO C99 standard. */
+/* #define HAVE_C99_VSNPRINTF 1 */
+
+/* define to 1 if Carbon is available */
+/* #undef HAVE_CARBON */
+
+/* Define to 1 if you have the `chown' function. */
+#define HAVE_CHOWN 1
+
+/* Define to 1 if you have the `clock_gettime' function. */
+#define HAVE_CLOCK_GETTIME 1
+
+/* Have nl_langinfo (CODESET) */
+/* #define HAVE_CODESET 1 */
+
+/* Define to 1 if you have the <crt_externs.h> header file. */
+/* #undef HAVE_CRT_EXTERNS_H */
+
+/* Define to 1 if you have the `dcgettext' function. */
+#define HAVE_DCGETTEXT 1
+
+/* Define to 1 if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define to 1 if you have the <dlfcn.h> header file. */
+#define HAVE_DLFCN_H 1
+
+/* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
+/* #undef HAVE_DOPRNT */
+
+/* define for working do while(0) macros */
+#define HAVE_DOWHILE_MACROS 1
+
+/* Define to 1 if you have the `endmntent' function. */
+/* #undef HAVE_ENDMNTENT */
+
+/* Define to 1 if you have the `endservent' function. */
+#define HAVE_ENDSERVENT 1
+
+/* Define if we have FAM */
+/* #undef HAVE_FAM */
+
+/* Define to 1 if you have the <fam.h> header file. */
+/* #undef HAVE_FAM_H */
+
+/* Define if we have FAMNoExists in fam */
+/* #undef HAVE_FAM_NO_EXISTS */
+
+/* Define to 1 if you have the `fchmod' function. */
+#define HAVE_FCHMOD 1
+
+/* Define to 1 if you have the `fchown' function. */
+#define HAVE_FCHOWN 1
+
+/* Define to 1 if you have the `fdwalk' function. */
+/* #undef HAVE_FDWALK */
+
+/* Define to 1 if you have the <float.h> header file. */
+#define HAVE_FLOAT_H 1
+
+/* Define to 1 if you have the <fstab.h> header file. */
+#define HAVE_FSTAB_H 1
+
+/* Define to 1 if you have the `fsync' function. */
+#define HAVE_FSYNC 1
+
+/* we have the futex(2) system call */
+/* #define HAVE_FUTEX test "$have_futex" = "yes" */
+
+/* Define to 1 if you have the `getcwd' function. */
+#define HAVE_GETCWD 1
+
+/* Define to 1 if you have the `getc_unlocked' function. */
+#define HAVE_GETC_UNLOCKED 1
+
+/* Define to 1 if you have the `getgrgid' function. */
+#define HAVE_GETGRGID 1
+
+/* Define to 1 if you have the `getmntent_r' function. */
+/* #undef HAVE_GETMNTENT_R */
+
+/* Define to 1 if you have the `getmntinfo' function. */
+/* #undef HAVE_GETMNTINFO */
+
+/* Define to 1 if you have the `getprotobyname_r' function. */
+#define HAVE_GETPROTOBYNAME_R 1
+
+/* Define to 1 if you have the `getpwuid' function. */
+#define HAVE_GETPWUID 1
+
+/* Define if the GNU gettext() function is already present or preinstalled. */
+#define HAVE_GETTEXT 1
+
+/* Define to 1 if you have the `gmtime_r' function. */
+#define HAVE_GMTIME_R 1
+
+/* define to use system printf */
+#define HAVE_GOOD_PRINTF 1
+
+/* Define to 1 if you have the <grp.h> header file. */
+#define HAVE_GRP_H 1
+
+/* Define to 1 if you have the `hasmntopt' function. */
+/* #undef HAVE_HASMNTOPT */
+
+/* Define to 1 if you have the `inotify_init1' function. */
+/* #undef HAVE_INOTIFY_INIT1 */
+
+/* define to support printing 64-bit integers with format I64 */
+/* #undef HAVE_INT64_AND_I64 */
+
+/* Define if you have the 'intmax_t' type in <stdint.h> or <inttypes.h>. */
+#define HAVE_INTMAX_T 1
+
+/* Define to 1 if you have the <inttypes.h> header file. */
+#define HAVE_INTTYPES_H 1
+
+/* Define if <inttypes.h> exists, doesn't clash with <sys/types.h>, and
+   declares uintmax_t. */
+#define HAVE_INTTYPES_H_WITH_UINTMAX 1
+
+/* Define if you have <langinfo.h> and nl_langinfo(CODESET). */
+/* #define HAVE_LANGINFO_CODESET 1 */
+
+/* Define to 1 if you have the `lchmod' function. */
+/* #undef HAVE_LCHMOD */
+
+/* Define to 1 if you have the `lchown' function. */
+#define HAVE_LCHOWN 1
+
+/* Define if your <locale.h> file defines LC_MESSAGES. */
+#define HAVE_LC_MESSAGES 1
+
+/* Define to 1 if you have the <limits.h> header file. */
+#define HAVE_LIMITS_H 1
+
+/* Define to 1 if you have the `link' function. */
+#define HAVE_LINK 1
+
+/* Define to 1 if you have the <locale.h> header file. */
+/* #define HAVE_LOCALE_H 1 */
+
+/* Define to 1 if you have the `localtime_r' function. */
+#define HAVE_LOCALTIME_R 1
+
+/* Define if you have the 'long double' type. */
+#define HAVE_LONG_DOUBLE 1
+
+/* Define if you have the 'long long' type. */
+#define HAVE_LONG_LONG 1
+
+/* define if system printf can print long long */
+/* #define HAVE_LONG_LONG_FORMAT 1 */
+
+/* Define to 1 if you have the `lstat' function. */
+#define HAVE_LSTAT 1
+
+/* Define to 1 if you have the <malloc.h> header file. */
+#define HAVE_MALLOC_H 1
+
+/* Define to 1 if you have the `memalign' function. */
+#define HAVE_MEMALIGN 1
+
+/* Define to 1 if you have the `memmove' function. */
+#define HAVE_MEMMOVE 1
+
+/* Define to 1 if you have the <memory.h> header file. */
+#define HAVE_MEMORY_H 1
+
+/* Define to 1 if you have the `mmap' function. */
+/* #define HAVE_MMAP 1 */
+
+/* Define to 1 if you have the <mntent.h> header file. */
+#define HAVE_MNTENT_H 1
+
+/* Have a monotonic clock */
+/* #define HAVE_MONOTONIC_CLOCK 1 */
+
+/* Define to 1 if you have the `nanosleep' function. */
+#define HAVE_NANOSLEEP 1
+
+/* Define to 1 if you have the <netdb.h> header file. */
+#define HAVE_NETDB_H 1
+
+/* Have non-POSIX function getgrgid_r */
+/* #undef HAVE_NONPOSIX_GETGRGID_R */
+
+/* Have non-POSIX function getpwuid_r */
+/* #undef HAVE_NONPOSIX_GETPWUID_R */
+
+/* Define to 1 if you have the `nsleep' function. */
+/* #undef HAVE_NSLEEP */
+
+/* Define to 1 if you have the `on_exit' function. */
+#define HAVE_ON_EXIT 1
+
+/* Define to 1 if you have the `pipe2' function. */
+/* #define HAVE_PIPE2 1 */
+
+/* Define to 1 if you have the `poll' function. */
+#define HAVE_POLL 1
+
+/* Have POSIX function getgrgid_r */
+/* #undef HAVE_POSIX_GETGRGID_R */
+
+/* Have POSIX function getpwuid_r */
+/* #define HAVE_POSIX_GETPWUID_R 1 */
+
+/* Define to 1 if you have the `posix_memalign' function. */
+/* #define HAVE_POSIX_MEMALIGN 1 */
+
+/* Have function pthread_attr_setstacksize */
+#define HAVE_PTHREAD_ATTR_SETSTACKSIZE 1
+
+/* Define to 1 if the system has the type `ptrdiff_t'. */
+#define HAVE_PTRDIFF_T 1
+
+/* Define to 1 if you have the <pwd.h> header file. */
+#define HAVE_PWD_H 1
+
+/* Define to 1 if `pw_gecos' is a member of `struct passwd'. */
+/* #undef HAVE_STRUCT_PASSWD_PW_GECOS */
+
+/* Define to 1 if you have the `readlink' function. */
+#define HAVE_READLINK 1
+
+/* Define to 1 if you have the <sched.h> header file. */
+#define HAVE_SCHED_H 1
+
+/* Define to 1 if libselinux is available */
+/* #undef HAVE_SELINUX */
+
+/* Define to 1 if you have the <selinux/selinux.h> header file. */
+/* #undef HAVE_SELINUX_SELINUX_H */
+
+/* Define to 1 if you have the `setenv' function. */
+#define HAVE_SETENV 1
+
+/* Define to 1 if you have the `setlocale' function. */
+#define HAVE_SETLOCALE 1
+
+/* Define to 1 if you have the `setmntent' function. */
+/* #undef HAVE_SETMNTENT */
+
+/* Define to 1 if you have the `setresuid' function. */
+#define HAVE_SETRESUID 1
+
+/* Define to 1 if you have the `setreuid' function. */
+#define HAVE_SETREUID 1
+
+/* Define to 1 if you have the `snprintf' function. */
+#define HAVE_SNPRINTF 1
+
+/* Define to 1 if you have the `splice' function. */
+/* #define HAVE_SPLICE 1 */
+
+/* Define to 1 if you have the `statfs' function. */
+#define HAVE_STATFS 1
+
+/* Define to 1 if you have the `statvfs' function. */
+/* #undef HAVE_STATVFS */
+
+/* Define to 1 if you have the <stddef.h> header file. */
+#define HAVE_STDDEF_H 1
+
+/* Define to 1 if you have the <stdint.h> header file. */
+#define HAVE_STDINT_H 1
+
+/* Define if <stdint.h> exists, doesn't clash with <sys/types.h>, and declares
+   uintmax_t. */
+#define HAVE_STDINT_H_WITH_UINTMAX 1
+
+/* Define to 1 if you have the <stdlib.h> header file. */
+#define HAVE_STDLIB_H 1
+
+/* Define to 1 if you have the `stpcpy' function. */
+/* #define HAVE_STPCPY 1 */
+
+/* Define to 1 if you have the `strcasecmp' function. */
+#define HAVE_STRCASECMP 1
+
+/* Define to 1 if you have the `strerror' function. */
+#define HAVE_STRERROR 1
+
+/* Define to 1 if you have the <strings.h> header file. */
+#define HAVE_STRINGS_H 1
+
+/* Define to 1 if you have the <string.h> header file. */
+#define HAVE_STRING_H 1
+
+/* Have functions strlcpy and strlcat */
+/* #undef HAVE_STRLCPY */
+
+/* Define to 1 if you have the `strncasecmp' function. */
+#define HAVE_STRNCASECMP 1
+
+/* Define to 1 if you have the `strndup' function. */
+#define HAVE_STRNDUP 1
+
+/* Define to 1 if you have the `strsignal' function. */
+#define HAVE_STRSIGNAL 1
+
+/* Define to 1 if `f_bavail' is a member of `struct statfs'. */
+#define HAVE_STRUCT_STATFS_F_BAVAIL 1
+
+/* Define to 1 if `f_fstypename' is a member of `struct statfs'. */
+/* #undef HAVE_STRUCT_STATFS_F_FSTYPENAME */
+
+/* Define to 1 if `f_basetype' is a member of `struct statvfs'. */
+/* #undef HAVE_STRUCT_STATVFS_F_BASETYPE */
+
+/* Define to 1 if `st_atimensec' is a member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_ATIMENSEC */
+
+/* Define to 1 if `st_atim.tv_nsec' is a member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_ATIM_TV_NSEC */
+
+/* Define to 1 if `st_blksize' is a member of `struct stat'. */
+#define HAVE_STRUCT_STAT_ST_BLKSIZE 1
+
+/* Define to 1 if `st_blocks' is a member of `struct stat'. */
+#define HAVE_STRUCT_STAT_ST_BLOCKS 1
+
+/* Define to 1 if `st_ctimensec' is a member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_CTIMENSEC */
+
+/* Define to 1 if `st_ctim.tv_nsec' is a member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_CTIM_TV_NSEC */
+
+/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_MTIMENSEC */
+
+/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */
+/* #undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC */
+
+/* Define to 1 if you have the `symlink' function. */
+#define HAVE_SYMLINK 1
+
+/* Define to 1 if you have the <sys/inotify.h> header file. */
+#define HAVE_SYS_INOTIFY_H 1
+
+/* Define to 1 if you have the <sys/mntctl.h> header file. */
+/* #undef HAVE_SYS_MNTCTL_H */
+
+/* Define to 1 if you have the <sys/mnttab.h> header file. */
+/* #undef HAVE_SYS_MNTTAB_H */
+
+/* Define to 1 if you have the <sys/mount.h> header file. */
+#define HAVE_SYS_MOUNT_H 1
+
+/* Define to 1 if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define to 1 if you have the <sys/poll.h> header file. */
+#define HAVE_SYS_POLL_H 1
+
+/* Define to 1 if you have the <sys/prctl.h> header file. */
+#define HAVE_SYS_PRCTL_H 1
+
+/* Define to 1 if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* found fd_set in sys/select.h */
+#define HAVE_SYS_SELECT_H 1
+
+/* Define to 1 if you have the <sys/statfs.h> header file. */
+#define HAVE_SYS_STATFS_H 1
+
+/* Define to 1 if you have the <sys/statvfs.h> header file. */
+/* #undef HAVE_SYS_STATVFS_H */
+
+/* Define to 1 if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define to 1 if you have the <sys/sysctl.h> header file. */
+#define HAVE_SYS_SYSCTL_H 1
+
+/* Define to 1 if you have the <sys/times.h> header file. */
+#define HAVE_SYS_TIMES_H 1
+
+/* Define to 1 if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define to 1 if you have the <sys/types.h> header file. */
+#define HAVE_SYS_TYPES_H 1
+
+/* Define to 1 if you have the <sys/uio.h> header file. */
+#define HAVE_SYS_UIO_H 1
+
+/* Define to 1 if you have the <sys/vfstab.h> header file. */
+/* #undef HAVE_SYS_VFSTAB_H */
+
+/* Define to 1 if you have the <sys/vfs.h> header file. */
+#define HAVE_SYS_VFS_H 1
+
+/* Define to 1 if you have the <sys/vmount.h> header file. */
+/* #undef HAVE_SYS_VMOUNT_H */
+
+/* Define to 1 if you have the <sys/wait.h> header file. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define to 1 if you have the <sys/xattr.h> header file. */
+/* #undef HAVE_SYS_XATTR_H */
+
+/* Define to 1 if you have the `timegm' function. */
+/* #define HAVE_TIMEGM 1 */
+
+/* Define to 1 if you have the ucred structure. */
+#define HAVE_STRUCT_UCRED 1
+
+/* Define to 1 if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if your printf function family supports positional parameters as
+   specified by Unix98. */
+/* #define HAVE_UNIX98_PRINTF 1 */
+
+/* Define to 1 if you have the `unsetenv' function. */
+#define HAVE_UNSETENV 1
+
+/* Define to 1 if you have the `utimes' function. */
+#define HAVE_UTIMES 1
+
+/* Define to 1 if you have the `valloc' function. */
+#define HAVE_VALLOC 1
+
+/* Define to 1 if you have the <values.h> header file. */
+#define HAVE_VALUES_H 1
+
+/* Define to 1 if you have the `vasprintf' function. */
+#define HAVE_VASPRINTF 1
+
+/* Define to 1 if you have the `vprintf' function. */
+#define HAVE_VPRINTF 1
+
+/* Define to 1 if you have the `vsnprintf' function. */
+#define HAVE_VSNPRINTF 1
+
+/* Define if you have the 'wchar_t' type. */
+/* #define HAVE_WCHAR_T 1 */
+
+/* Define to 1 if you have the `wcslen' function. */
+/* #define HAVE_WCSLEN 1 */
+
+/* Define if you have the 'wint_t' type. */
+/* #define HAVE_WINT_T 1 */
+
+/* Have a working bcopy */
+/* #undef HAVE_WORKING_BCOPY */
+
+/* Define to 1 if you have the <wspiapi.h> header file. */
+/* #undef HAVE_WSPIAPI_H */
+
+/* Define to 1 if xattr is available */
+/* #undef HAVE_XATTR */
+
+/* Define to 1 if xattr API uses XATTR_NOFOLLOW */
+/* #undef HAVE_XATTR_NOFOLLOW */
+
+/* Define to 1 if you have the `_NSGetEnviron' function. */
+/* #undef HAVE__NSGETENVIRON */
+
+/* Define to the sub-directory in which libtool stores uninstalled libraries.
+   */
+#define LT_OBJDIR ".libs/"
+
+/* Do we cache iconv descriptors */
+#undef NEED_ICONV_CACHE
+
+/* didn't find fd_set */
+/* #undef NO_FD_SET */
+
+/* Define to 1 if your C compiler doesn't accept -c and -o together. */
+/* #undef NO_MINUS_C_MINUS_O */
+
+/* global 'sys_errlist' not found */
+/* #undef NO_SYS_ERRLIST */
+
+/* global 'sys_siglist' not found */
+/* #undef NO_SYS_SIGLIST */
+
+/* global 'sys_siglist' not declared */
+/* #undef NO_SYS_SIGLIST_DECL */
+
+/* Define to the address where bug reports for this package should be sent. */
+#define PACKAGE_BUGREPORT "http://bugzilla.gnome.org/enter_bug.cgi?product=glib"
+
+/* Define to the full name of this package. */
+#define PACKAGE_NAME "glib"
+
+/* Define to the full name and version of this package. */
+#define PACKAGE_STRING "glib 2.24.1"
+
+/* Define to the one symbol short name of this package. */
+#define PACKAGE_TARNAME "glib"
+
+/* Define to the home page for this package. */
+#define PACKAGE_URL ""
+
+/* Define to the version of this package. */
+#define PACKAGE_VERSION "2.24.1"
+
+/* Maximum POSIX RT priority */
+#define POSIX_MAX_PRIORITY sched_get_priority_max(SCHED_OTHER)
+
+/* define if posix_memalign() can allocate any size */
+#define POSIX_MEMALIGN_WITH_COMPLIANT_ALLOCS 1
+
+/* Minimum POSIX RT priority */
+#define POSIX_MIN_PRIORITY sched_get_priority_min(SCHED_OTHER)
+
+/* The POSIX RT yield function */
+#define POSIX_YIELD_FUNC sched_yield()
+
+/* whether realloc (NULL,) works */
+#define REALLOC_0_WORKS 1
+
+/* Define if you have correct malloc prototypes */
+#define SANE_MALLOC_PROTOS 1
+
+/* The size of `char', as computed by sizeof. */
+#define SIZEOF_CHAR 1
+
+/* The size of `int', as computed by sizeof. */
+#define SIZEOF_INT 4
+
+/* The size of `long', as computed by sizeof. */
+#define SIZEOF_LONG 4
+
+/* The size of `long long', as computed by sizeof. */
+#define SIZEOF_LONG_LONG 8
+
+/* The size of `short', as computed by sizeof. */
+#define SIZEOF_SHORT 2
+
+/* The size of `size_t', as computed by sizeof. */
+#define SIZEOF_SIZE_T 4
+
+/* The size of `void *', as computed by sizeof. */
+#define SIZEOF_VOID_P 4
+
+/* The size of `__int64', as computed by sizeof. */
+#define SIZEOF___INT64 0
+
+/* If using the C implementation of alloca, define if you know the
+   direction of stack growth for your system; otherwise it will be
+   automatically deduced at runtime.
+       STACK_DIRECTION > 0 => grows toward higher addresses
+       STACK_DIRECTION < 0 => grows toward lower addresses
+       STACK_DIRECTION = 0 => direction of growth unknown */
+/* #undef STACK_DIRECTION */
+
+/* Number of arguments to statfs() */
+#define STATFS_ARGS 2
+
+/* Define to 1 if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Using GNU libiconv */
+#undef USE_LIBICONV_GNU
+
+/* Using a native implementation of iconv in a separate library */
+#undef USE_LIBICONV_NATIVE
+
+/* using the system-supplied PCRE library */
+/* #undef USE_SYSTEM_PCRE */
+
+/* Define WORDS_BIGENDIAN to 1 if your processor stores words with the most
+   significant byte first (like Motorola and SPARC, unlike Intel). */
+#if defined AC_APPLE_UNIVERSAL_BUILD
+# if defined __BIG_ENDIAN__
+#  define WORDS_BIGENDIAN 1
+# endif
+#else
+# ifndef WORDS_BIGENDIAN
+/* #  undef WORDS_BIGENDIAN */
+# endif
+#endif
+
+/* Number of bits in a file offset, on hosts where this is settable. */
+#define _FILE_OFFSET_BITS 64
+
+/* Define for large files, on AIX-style hosts. */
+/* #undef _LARGE_FILES */
+
+/* Needed to get declarations for msg_control and msg_controllen on Solaris */
+/* #undef _XOPEN_SOURCE */
+
+/* Needed to get declarations for msg_control and msg_controllen on Solaris */
+/* #undef _XOPEN_SOURCE_EXTENDED */
+
+/* Needed to get declarations for msg_control and msg_controllen on Solaris */
+/* #undef __EXTENSIONS__ */
+
+/* Define to empty if `const' does not conform to ANSI C. */
+/* #undef const */
+
+/* Define to long or long long if <inttypes.h> and <stdint.h> don't define. */
+/* #undef intmax_t */
+
+/* Define to empty if the C compiler doesn't support this keyword. */
+/* #undef signed */
+
+/* Define to `unsigned int' if <sys/types.h> does not define. */
+/* #undef size_t */
+
+/* Android specific build define */
+#define BUILD_WITH_ANDROID 1
diff --git a/resource/csdk/connectivity/lib/android/glib-master/android/glibconfig.h b/resource/csdk/connectivity/lib/android/glib-master/android/glibconfig.h
new file mode 100644 (file)
index 0000000..add65da
--- /dev/null
@@ -0,0 +1,243 @@
+/* glibconfig.h
+ *
+ * This is a generated file.  Please modify 'configure.in'
+ */
+
+#ifndef __G_LIBCONFIG_H__
+#define __G_LIBCONFIG_H__
+
+#include <glib/gmacros.h>
+
+#include <limits.h>
+#include <float.h>
+#define GLIB_HAVE_ALLOCA_H
+#define GLIB_HAVE_SYS_POLL_H
+
+/* Specifies that GLib's g_print*() functions wrap the
+ * system printf functions.  This is useful to know, for example,
+ * when using glibc's register_printf_function().
+ */
+#define GLIB_USING_SYSTEM_PRINTF
+
+G_BEGIN_DECLS
+
+#define G_MINFLOAT     FLT_MIN
+#define G_MAXFLOAT     FLT_MAX
+#define G_MINDOUBLE    DBL_MIN
+#define G_MAXDOUBLE    DBL_MAX
+#define G_MINSHORT     SHRT_MIN
+#define G_MAXSHORT     SHRT_MAX
+#define G_MAXUSHORT    USHRT_MAX
+#define G_MININT       INT_MIN
+#define G_MAXINT       INT_MAX
+#define G_MAXUINT      UINT_MAX
+#define G_MINLONG      LONG_MIN
+#define G_MAXLONG      LONG_MAX
+#define G_MAXULONG     ULONG_MAX
+
+typedef signed char gint8;
+typedef unsigned char guint8;
+typedef signed short gint16;
+typedef unsigned short guint16;
+#define G_GINT16_MODIFIER "h"
+#define G_GINT16_FORMAT "hi"
+#define G_GUINT16_FORMAT "hu"
+typedef signed int gint32;
+typedef unsigned int guint32;
+#define G_GINT32_MODIFIER ""
+#define G_GINT32_FORMAT "i"
+#define G_GUINT32_FORMAT "u"
+#define G_HAVE_GINT64 1          /* deprecated, always true */
+
+G_GNUC_EXTENSION typedef signed long long gint64;
+G_GNUC_EXTENSION typedef unsigned long long guint64;
+
+#define G_GINT64_CONSTANT(val) (G_GNUC_EXTENSION (val##LL))
+#define G_GUINT64_CONSTANT(val)        (G_GNUC_EXTENSION (val##ULL))
+#define G_GINT64_MODIFIER "ll"
+#define G_GINT64_FORMAT "lli"
+#define G_GUINT64_FORMAT "llu"
+
+#define GLIB_SIZEOF_VOID_P 4
+#define GLIB_SIZEOF_LONG   4
+#define GLIB_SIZEOF_SIZE_T 4
+
+typedef signed int gssize;
+typedef unsigned int gsize;
+#define G_GSIZE_MODIFIER ""
+#define G_GSSIZE_FORMAT "i"
+#define G_GSIZE_FORMAT "u"
+
+#define G_MAXSIZE      G_MAXUINT
+#define G_MINSSIZE     G_MININT
+#define G_MAXSSIZE     G_MAXINT
+
+typedef gint64 goffset;
+#define G_MINOFFSET    G_MININT64
+#define G_MAXOFFSET    G_MAXINT64
+
+#define G_GOFFSET_MODIFIER      G_GINT64_MODIFIER
+#define G_GOFFSET_FORMAT        G_GINT64_FORMAT
+#define G_GOFFSET_CONSTANT(val) G_GINT64_CONSTANT(val)
+
+
+#define GPOINTER_TO_INT(p)     ((gint)   (p))
+#define GPOINTER_TO_UINT(p)    ((guint)  (p))
+
+#define GINT_TO_POINTER(i)     ((gpointer)  (i))
+#define GUINT_TO_POINTER(u)    ((gpointer)  (u))
+
+typedef signed int gintptr;
+typedef unsigned int guintptr;
+
+#define G_GINTPTR_MODIFIER      ""
+#define G_GINTPTR_FORMAT        "i"
+#define G_GUINTPTR_FORMAT       "u"
+
+#ifdef NeXT /* @#%@! NeXTStep */
+# define g_ATEXIT(proc)        (!atexit (proc))
+#else
+# define g_ATEXIT(proc)        (atexit (proc))
+#endif
+
+#define g_memmove(dest,src,len) G_STMT_START { memmove ((dest), (src), (len)); } G_STMT_END
+
+#define GLIB_MAJOR_VERSION 2
+#define GLIB_MINOR_VERSION 24
+#define GLIB_MICRO_VERSION 1
+
+#define G_OS_UNIX
+
+
+#define G_VA_COPY      va_copy
+
+#ifdef __cplusplus
+#define        G_HAVE_INLINE   1
+#else  /* !__cplusplus */
+#define G_HAVE_INLINE 1
+#define G_HAVE___INLINE 1
+#define G_HAVE___INLINE__ 1
+#endif /* !__cplusplus */
+
+#ifdef __cplusplus
+#define G_CAN_INLINE   1
+#else  /* !__cplusplus */
+#define G_CAN_INLINE   1
+#endif
+
+#ifndef __cplusplus
+# define G_HAVE_ISO_VARARGS 1
+#endif
+#ifdef __cplusplus
+# define G_HAVE_ISO_VARARGS 1
+#endif
+
+/* gcc-2.95.x supports both gnu style and ISO varargs, but if -ansi
+ * is passed ISO vararg support is turned off, and there is no work
+ * around to turn it on, so we unconditionally turn it off.
+ */
+#if __GNUC__ == 2 && __GNUC_MINOR__ == 95
+#  undef G_HAVE_ISO_VARARGS
+#endif
+
+#define G_HAVE_GNUC_VARARGS 1
+#define G_HAVE_GROWING_STACK 0
+
+#define G_HAVE_GNUC_VISIBILITY 1
+#if defined(__SUNPRO_C) && (__SUNPRO_C >= 0x590)
+#define G_GNUC_INTERNAL __attribute__((visibility("hidden")))
+#elif defined(__SUNPRO_C) && (__SUNPRO_C >= 0x550)
+#define G_GNUC_INTERNAL __hidden
+#elif defined (__GNUC__) && defined (G_HAVE_GNUC_VISIBILITY)
+#define G_GNUC_INTERNAL __attribute__((visibility("hidden")))
+#else
+#define G_GNUC_INTERNAL
+#endif
+
+#define G_THREADS_ENABLED
+#define G_THREADS_IMPL_POSIX
+typedef struct _GStaticMutex GStaticMutex;
+struct _GStaticMutex
+{
+  struct _GMutex *runtime_mutex;
+  union {
+    char   pad[24];
+    double dummy_double;
+    void  *dummy_pointer;
+    long   dummy_long;
+  } static_mutex;
+};
+#define        G_STATIC_MUTEX_INIT     { NULL, { { 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0} } }
+#define        g_static_mutex_get_mutex(mutex) \
+  (g_thread_use_default_impl ? ((GMutex*)(gpointer) ((mutex)->static_mutex.pad)) : \
+   g_static_mutex_get_mutex_impl_shortcut (&((mutex)->runtime_mutex)))
+/* This represents a system thread as used by the implementation. An
+ * alien implementaion, as loaded by g_thread_init can only count on
+ * "sizeof (gpointer)" bytes to store their info. We however need more
+ * for some of our native implementations. */
+typedef union _GSystemThread GSystemThread;
+union _GSystemThread
+{
+  char   data[4];
+  double dummy_double;
+  void  *dummy_pointer;
+  long   dummy_long;
+};
+
+#define G_ATOMIC_OP_MEMORY_BARRIER_NEEDED 1
+
+#define GINT16_TO_LE(val)      ((gint16) (val))
+#define GUINT16_TO_LE(val)     ((guint16) (val))
+#define GINT16_TO_BE(val)      ((gint16) GUINT16_SWAP_LE_BE (val))
+#define GUINT16_TO_BE(val)     (GUINT16_SWAP_LE_BE (val))
+#define GINT32_TO_LE(val)      ((gint32) (val))
+#define GUINT32_TO_LE(val)     ((guint32) (val))
+#define GINT32_TO_BE(val)      ((gint32) GUINT32_SWAP_LE_BE (val))
+#define GUINT32_TO_BE(val)     (GUINT32_SWAP_LE_BE (val))
+#define GINT64_TO_LE(val)      ((gint64) (val))
+#define GUINT64_TO_LE(val)     ((guint64) (val))
+#define GINT64_TO_BE(val)      ((gint64) GUINT64_SWAP_LE_BE (val))
+#define GUINT64_TO_BE(val)     (GUINT64_SWAP_LE_BE (val))
+#define GLONG_TO_LE(val)       ((glong) GINT32_TO_LE (val))
+#define GULONG_TO_LE(val)      ((gulong) GUINT32_TO_LE (val))
+#define GLONG_TO_BE(val)       ((glong) GINT32_TO_BE (val))
+#define GULONG_TO_BE(val)      ((gulong) GUINT32_TO_BE (val))
+#define GINT_TO_LE(val)                ((gint) GINT32_TO_LE (val))
+#define GUINT_TO_LE(val)       ((guint) GUINT32_TO_LE (val))
+#define GINT_TO_BE(val)                ((gint) GINT32_TO_BE (val))
+#define GUINT_TO_BE(val)       ((guint) GUINT32_TO_BE (val))
+#define GSIZE_TO_LE(val)       ((gsize) GUINT32_TO_LE (val))
+#define GSSIZE_TO_LE(val)      ((gssize) GINT32_TO_LE (val))
+#define GSIZE_TO_BE(val)       ((gsize) GUINT32_TO_BE (val))
+#define GSSIZE_TO_BE(val)      ((gssize) GINT32_TO_BE (val))
+#define G_BYTE_ORDER G_LITTLE_ENDIAN
+
+#define GLIB_SYSDEF_POLLIN =1
+#define GLIB_SYSDEF_POLLOUT =4
+#define GLIB_SYSDEF_POLLPRI =2
+#define GLIB_SYSDEF_POLLHUP =16
+#define GLIB_SYSDEF_POLLERR =8
+#define GLIB_SYSDEF_POLLNVAL =32
+
+#define G_MODULE_SUFFIX "so"
+
+/* A GPid is an abstraction for a process "handle". It is *not* an
+ * abstraction for a process identifier in general. GPid is used in
+ * GLib only for descendant processes spawned with the g_spawn*
+ * functions. On POSIX there is no "process handle" concept as such,
+ * but on Windows a GPid is a handle to a process, a kind of pointer,
+ * not a process identifier.
+ */
+typedef int GPid;
+
+#define GLIB_SYSDEF_AF_UNIX 1
+#define GLIB_SYSDEF_AF_INET 2
+#define GLIB_SYSDEF_AF_INET6 10
+
+#define GLIB_SYSDEF_MSG_OOB 1
+#define GLIB_SYSDEF_MSG_PEEK 2
+#define GLIB_SYSDEF_MSG_DONTROUTE 4
+
+G_END_DECLS
+
+#endif /* GLIBCONFIG_H */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib.h b/resource/csdk/connectivity/lib/android/glib-master/glib.h
new file mode 100644 (file)
index 0000000..06d0190
--- /dev/null
@@ -0,0 +1,99 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __G_LIB_H__
+#define __G_LIB_H__
+
+#define __GLIB_H_INSIDE__
+
+#include <glib/galloca.h>
+#include <glib/garray.h>
+#include <glib/gasyncqueue.h>
+#include <glib/gatomic.h>
+#include <glib/gbacktrace.h>
+#include <glib/gbase64.h>
+#include <glib/gbitlock.h>
+#include <glib/gbookmarkfile.h>
+#include <glib/gcache.h>
+#include <glib/gchecksum.h>
+#include <glib/gcompletion.h>
+#include <glib/gconvert.h>
+#include <glib/gdataset.h>
+#include <glib/gdate.h>
+#include <glib/gdatetime.h>
+#include <glib/gdir.h>
+#include <glib/gerror.h>
+#include <glib/gfileutils.h>
+#include <glib/ghash.h>
+#include <glib/ghook.h>
+#include <glib/ghostutils.h>
+#include <glib/giochannel.h>
+#include <glib/gkeyfile.h>
+#include <glib/glist.h>
+#include <glib/gmacros.h>
+#include <glib/gmain.h>
+#include <glib/gmappedfile.h>
+#include <glib/gmarkup.h>
+#include <glib/gmem.h>
+#include <glib/gmessages.h>
+#include <glib/gnode.h>
+#include <glib/goption.h>
+#include <glib/gpattern.h>
+#include <glib/gpoll.h>
+#include <glib/gprimes.h>
+#include <glib/gqsort.h>
+#include <glib/gquark.h>
+#include <glib/gqueue.h>
+#include <glib/grand.h>
+#include <glib/grel.h>
+#include <glib/gregex.h>
+#include <glib/gscanner.h>
+#include <glib/gsequence.h>
+#include <glib/gshell.h>
+#include <glib/gslice.h>
+#include <glib/gslist.h>
+#include <glib/gspawn.h>
+#include <glib/gstrfuncs.h>
+#include <glib/gstring.h>
+#include <glib/gtestutils.h>
+#include <glib/gthread.h>
+#include <glib/gthreadpool.h>
+#include <glib/gtimer.h>
+#include <glib/gtimezone.h>
+#include <glib/gtree.h>
+#include <glib/gtypes.h>
+#include <glib/gunicode.h>
+#include <glib/gurifuncs.h>
+#include <glib/gutils.h>
+#include <glib/gvarianttype.h>
+#include <glib/gvariant.h>
+#ifdef G_PLATFORM_WIN32
+#include <glib/gwin32.h>
+#endif
+
+#undef __GLIB_H_INSIDE__
+
+#endif /* __G_LIB_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/Android.mk b/resource/csdk/connectivity/lib/android/glib-master/glib/Android.mk
new file mode 100644 (file)
index 0000000..1e7daf8
--- /dev/null
@@ -0,0 +1,107 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+    ./libcharset/localcharset.c \
+    garray.c        \
+    gasyncqueue.c   \
+    gatomic.c       \
+    gbacktrace.c    \
+    gbase64.c       \
+    gbitlock.c      \
+    gbookmarkfile.c \
+    gbuffer.c       \
+    gcache.c        \
+    gchecksum.c     \
+    gcompletion.c   \
+    gconvert.c      \
+    gdataset.c      \
+    gdate.c         \
+    gdatetime.c     \
+    gdir.c          \
+    gerror.c        \
+    gfileutils.c    \
+    ghash.c         \
+    ghook.c         \
+    ghostutils.c    \
+    giochannel.c    \
+    gkeyfile.c      \
+    glist.c         \
+    gmain.c         \
+    gmappedfile.c   \
+    gmarkup.c       \
+    gmem.c          \
+    gmessages.c     \
+    gnode.c         \
+    goption.c       \
+    gpattern.c      \
+    gpoll.c         \
+    gprimes.c       \
+    gqsort.c        \
+    gqueue.c        \
+    grel.c          \
+    grand.c         \
+    gregex.c        \
+    gscanner.c      \
+    gsequence.c     \
+    gshell.c        \
+    gslice.c        \
+    gslist.c        \
+    gstdio.c        \
+    gstrfuncs.c     \
+    gstring.c       \
+    gtestutils.c    \
+    gthread.c       \
+    gthreadpool.c   \
+    gtimer.c        \
+    gtimezone.c     \
+    gtree.c         \
+    guniprop.c      \
+    gutf8.c         \
+    gunibreak.c     \
+    gunicollate.c   \
+    gunidecomp.c    \
+    gurifuncs.c     \
+    gutils.c        \
+    gvariant.c      \
+    gvariant-core.c \
+    gvariant-parser.c \
+    gvariant-serialiser.c \
+    gvarianttypeinfo.c \
+    gvarianttype.c  \
+    gprintf.c       \
+    giounix.c       \
+    gspawn.c
+
+LOCAL_MODULE := libglib-2.0
+
+LOCAL_C_INCLUDES :=                    \
+       $(GLIB_TOP)                     \
+       $(GLIB_TOP)/android             \
+       $(GLIB_TOP)/android-internal    \
+       $(LOCAL_PATH)/android-internal  \
+       $(LOCAL_PATH)/libcharset        \
+       $(LOCAL_PATH)/gnulib            \
+       $(LOCAL_PATH)/pcre
+
+# ./glib private macros, copy from Makefile.am
+LOCAL_CFLAGS := \
+       -DLIBDIR=\"$(libdir)\"          \
+       -DHAVE_CONFIG_H                 \
+       -DG_LOG_DOMAIN=\"GLib\"         \
+       -DPCRE_STATIC                   \
+       -DG_DISABLE_DEPRECATED          \
+       -DGLIB_COMPILATION
+
+ifeq ($(GLIB_BUILD_STATIC),true)
+include $(BUILD_STATIC_LIBRARY)
+else
+LOCAL_STATIC_LIBRARIES := libpcre
+LOCAL_LDLIBS :=                                \
+       -llog
+
+include $(BUILD_SHARED_LIBRARY)
+endif
+
+include $(LOCAL_PATH)/pcre/Android.mk
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/Makefile.am b/resource/csdk/connectivity/lib/android/glib-master/glib/Makefile.am
new file mode 100644 (file)
index 0000000..f95ef60
--- /dev/null
@@ -0,0 +1,466 @@
+## Process this file with automake to produce Makefile.in
+include $(top_srcdir)/Makefile.decl
+
+BUILT_SOURCES =
+DISTCLEANFILES =
+CLEANFILES =
+
+#
+# Generate glibconfig.h
+#
+# The timestamp of the stamp file is used to indicate if glibconfig.h is
+# up to date with respect to config.status.  In the usual case, changes
+# to config.status will not result in changes to glibconfig.h so we
+# avoid touching its timestamp (in order not to rebuild the whole tree).
+#
+DISTCLEANFILES += glibconfig-stamp glibconfig.h
+BUILT_SOURCES += glibconfig-stamp
+configexecincludedir = $(libdir)/glib-2.0/include
+nodist_configexecinclude_HEADERS = glibconfig.h
+glibconfig-stamp: ../config.status
+       $(AM_V_GEN) cd $(top_builddir) && \
+         $(SHELL) ./config.status glib/glibconfig.h
+       @touch glibconfig-stamp
+
+
+
+if HAVE_GOOD_PRINTF
+else
+PRINTF_SUBDIR = gnulib
+printf_la = gnulib/libgnulib.la
+endif 
+
+if ENABLE_REGEX
+if USE_SYSTEM_PCRE
+else
+MAYBE_PCRE = pcre 
+endif
+gregex_c = gregex.c
+gregex_h = gregex.h
+else
+gregex_c =
+gregex_h =
+endif
+
+if HAVE_GCC_BUILTINS_FOR_ATOMIC_OPERATIONS
+gatomic_c = gatomic-gcc.c
+else
+gatomic_c = gatomic.c
+endif
+
+SUBDIRS = libcharset $(PRINTF_SUBDIR) $(MAYBE_PCRE) update-pcre . tests
+
+DIST_SUBDIRS = libcharset gnulib pcre update-pcre tests
+
+AM_CPPFLAGS =                          \
+       $(glib_INCLUDES)                \
+       $(pcre_inc)                     \
+       -DG_LOG_DOMAIN=\"GLib\"         \
+       $(GLIB_DEBUG_FLAGS)             \
+       -DG_DISABLE_DEPRECATED          \
+       -DGLIB_COMPILATION              \
+       -DPCRE_STATIC
+
+glib.def: glib.symbols
+       $(AM_V_GEN) (echo -e EXPORTS; $(CPP) -P -DINCLUDE_VARIABLES -DINCLUDE_INTERNAL_SYMBOLS -DG_OS_WIN32 -DALL_FILES - <$(srcdir)/glib.symbols | sed -e '/^$$/d' -e 's/^/    /' -e 's/G_GNUC_[^ ]*//g') > glib.def
+
+if OS_LINUX
+if HAVE_GNUC_VISIBILITY
+TESTS_ENVIRONMENT = GLIB_DEBUG_FLAGS="$(GLIB_DEBUG_FLAGS)"
+TESTS = abicheck.sh
+endif
+endif
+
+MIRRORING_TAB_SOURCE =                                 \
+       glib-mirroring-tab/Makefile             \
+       glib-mirroring-tab/gen-mirroring-tab.c  \
+       glib-mirroring-tab/packtab.h            \
+       glib-mirroring-tab/packtab.c
+
+# The compilation of GRegex can be disabled, but the source files must
+# be distributed.
+EXTRA_DIST +=                  \
+       makefile.msc.in         \
+       glib.rc.in              \
+       gen-unicode-tables.pl   \
+       gen-script-table.pl     \
+       glibconfig.h.win32.in   \
+       abicheck.sh             \
+       glib.symbols            \
+       gregex.c                \
+       gregex.h                \
+       win_iconv.c             \
+       libglib-gdb.py.in       \
+       $(MIRRORING_TAB_SOURCE)
+
+# These may be in the builddir too
+BUILT_EXTRA_DIST =             \
+       makefile.msc            \
+       glibconfig.h.win32      \
+       glib.rc
+
+lib_LTLIBRARIES = libglib-2.0.la
+
+if OS_WIN32_AND_DLL_COMPILATION
+if MS_LIB_AVAILABLE
+noinst_DATA = glib-2.0.lib
+
+install_ms_lib_cmd = $(INSTALL) glib-2.0.lib $(DESTDIR)$(libdir)
+uninstall_ms_lib_cmd = -rm $(DESTDIR)$(libdir)/glib-2.0.lib
+endif
+endif
+
+install-ms-lib:
+       $(install_ms_lib_cmd)
+
+uninstall-ms-lib:
+       $(uninstall_ms_lib_cmd)
+
+libglib_2_0_la_SOURCES =       \
+       glib_probes.d           \
+       garray.c                \
+       gasyncqueue.c           \
+       $(gatomic_c)            \
+       gbacktrace.c            \
+       gbase64.c               \
+       gbitlock.c              \
+       gbookmarkfile.c         \
+       gbsearcharray.h         \
+       gbuffer.c               \
+       gbuffer.h               \
+       gcache.c                \
+       gchecksum.c             \
+       gcompletion.c           \
+       gconvert.c              \
+       gdataset.c              \
+       gdatasetprivate.h       \
+       gdate.c                 \
+       gdatetime.c             \
+       gdir.c                  \
+       gerror.c                \
+       gfileutils.c            \
+       ghash.c                 \
+       ghook.c                 \
+       ghostutils.c            \
+       giochannel.c            \
+       gkeyfile.c              \
+       glibintl.h              \
+       glib_trace.h            \
+       glist.c                 \
+       gmain.c                 \
+       gmappedfile.c           \
+       gmarkup.c               \
+       gmem.c                  \
+       gmessages.c             \
+       gmirroringtable.h       \
+       gnode.c                 \
+       goption.c               \
+       gpattern.c              \
+       gpoll.c                 \
+       gprimes.c               \
+       gqsort.c                \
+       gqueue.c                \
+       grel.c                  \
+       grand.c                 \
+       $(gregex_c)             \
+       gscanner.c              \
+       gscripttable.h          \
+       gsequence.c             \
+       gshell.c                \
+       gslice.c                \
+       gslist.c                \
+       gstdio.c                \
+       gstrfuncs.c             \
+       gstring.c               \
+       gtestutils.c            \
+       gthread.c               \
+       gthreadprivate.h        \
+       gthreadpool.c           \
+       gtimer.c                \
+       gtimezoneprivate.h      \
+       gtimezone.c             \
+       gtree.c                 \
+       guniprop.c              \
+       gutf8.c                 \
+       gunibreak.h             \
+       gunibreak.c             \
+       gunichartables.h        \
+       gunicollate.c           \
+       gunicomp.h              \
+       gunidecomp.h            \
+       gunidecomp.c            \
+       gunicodeprivate.h       \
+       gurifuncs.c             \
+       gutils.c                \
+       gvariant.h              \
+       gvariant.c              \
+       gvariant-core.h         \
+       gvariant-core.c         \
+       gvariant-internal.h     \
+       gvariant-parser.c       \
+       gvariant-serialiser.h   \
+       gvariant-serialiser.c   \
+       gvarianttypeinfo.h      \
+       gvarianttypeinfo.c      \
+       gvarianttype.c          \
+       gdebug.h                \
+       gprintf.c               \
+       gprintfint.h
+
+
+EXTRA_libglib_2_0_la_SOURCES = \
+       giounix.c       \
+       giowin32.c      \
+       gspawn.c        \
+       gspawn-win32.c  \
+       gwin32.c
+
+glibincludedir=$(includedir)/glib-2.0
+glibinclude_HEADERS =   \
+       glib-object.h   \
+       glib.h
+
+glibsubincludedir=$(includedir)/glib-2.0/glib
+glibsubinclude_HEADERS =   \
+       galloca.h       \
+       garray.h        \
+       gasyncqueue.h   \
+       gatomic.h       \
+       gbacktrace.h    \
+       gbase64.h       \
+       gbitlock.h      \
+       gbookmarkfile.h \
+       gcache.h        \
+       gchecksum.h     \
+       gcompletion.h   \
+       gconvert.h      \
+       gdataset.h      \
+       gdate.h         \
+       gdatetime.h     \
+       gdir.h          \
+       gerror.h        \
+       gfileutils.h    \
+       ghash.h         \
+       ghook.h         \
+       ghostutils.h    \
+       gi18n.h         \
+       gi18n-lib.h     \
+       giochannel.h    \
+       gkeyfile.h      \
+       glist.h         \
+       gmacros.h       \
+       gmain.h         \
+       gmappedfile.h   \
+       gmarkup.h       \
+       gmem.h          \
+       gmessages.h     \
+       gnode.h         \
+       goption.h       \
+       gpattern.h      \
+       gpoll.h         \
+       gprimes.h       \
+       gqsort.h        \
+       gquark.h        \
+       gqueue.h        \
+       grand.h         \
+       $(gregex_h)     \
+       grel.h          \
+       gscanner.h      \
+       gsequence.h     \
+       gshell.h        \
+       gslice.h        \
+       gslist.h        \
+       gspawn.h        \
+       gstdio.h        \
+       gstrfuncs.h     \
+       gtestutils.h    \
+       gstring.h       \
+       gthread.h       \
+       gthreadpool.h   \
+       gtimer.h        \
+       gtimezone.h     \
+       gtree.h         \
+       gtypes.h        \
+       gunicode.h      \
+       gurifuncs.h     \
+       gutils.h        \
+       gvarianttype.h  \
+       gvariant.h      \
+       gwin32.h        \
+       gprintf.h
+
+install-data-local: install-ms-lib install-def-file
+       @if test -f $(glibincludedir)/glist.h ; then                                    \
+         echo "*** Old headers found in $(glibincludedir). You should remove the" ;    \
+         echo "*** contents of this directory and type 'make install' again." ;        \
+         false ;                                                                       \
+       fi
+
+uninstall-local: uninstall-ms-lib uninstall-def-file
+
+if PLATFORM_WIN32
+no_undefined = -no-undefined
+endif
+
+if OS_WIN32_AND_DLL_COMPILATION
+export_symbols = -export-symbols glib.def
+
+glib_win32_res = glib-win32-res.o
+glib_win32_res_ldflag = -Wl,$(glib_win32_res)
+
+glib_def = glib.def
+
+install-def-file:
+       $(INSTALL) glib.def $(DESTDIR)$(libdir)/glib-2.0.def
+
+uninstall-def-file:
+       -rm $(DESTDIR)$(libdir)/glib-2.0.def
+else
+install-def-file:
+uninstall-def-file:
+
+export_symbols = $(LIBTOOL_EXPORT_OPTIONS)
+endif
+
+if ENABLE_REGEX
+if USE_SYSTEM_PCRE
+pcre_lib = $(PCRE_LIBS)
+pcre_inc = $(PCRE_CFLAGS)
+else
+pcre_lib = pcre/libpcre.la
+pcre_inc =
+endif
+else
+pcre_lib =
+pcre_inc =
+endif
+
+libglib_2_0_la_LIBADD = libcharset/libcharset.la $(printf_la) @GIO@ @GSPAWN@ @PLATFORMDEP@ @ICONV_LIBS@ @G_LIBS_EXTRA@ $(pcre_lib)
+libglib_2_0_la_DEPENDENCIES = libcharset/libcharset.la $(printf_la) @GIO@ @GSPAWN@ @PLATFORMDEP@ $(glib_win32_res) $(glib_def)
+
+libglib_2_0_la_LDFLAGS = $(GLIB_LINK_FLAGS) \
+        $(glib_win32_res_ldflag) \
+       -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
+       -export-dynamic $(no_undefined) $(export_symbols)
+
+INSTALL_PROGS=
+
+if ENABLE_DTRACE
+glib_probes.h: glib_probes.d Makefile
+       $(DTRACE) -C -h -s $< -o $@.tmp
+       sed -e "s,define STAP_HAS_SEMAPHORES 1,undef STAP_HAS_SEMAPHORES," < $@.tmp > $@ && rm -f $@.tmp
+glib_probes.o: glib_probes.d Makefile
+       $(DTRACE) -G -s $< -o $@
+BUILT_SOURCES += glib_probes.h glib_probes.o
+CLEANFILES += glib_probes.h glib_probes.h.tmp
+libglib_2_0_la_LIBADD += glib_probes.o
+endif
+
+if ENABLE_SYSTEMTAP
+tapset_in_files = glib.stp.in
+tapsetdir   = @ABS_TAPSET_DIR@
+tapset_DATA = $(tapset_in_files:.stp.in=.stp)
+EXTRA_DIST += $(tapset_in_files)
+endif
+
+gspawn-win32-helper-console.c:
+       echo '#define HELPER_CONSOLE' >$@
+       echo '#include "gspawn-win32-helper.c"' >>$@
+
+gspawn-win64-helper.c:
+       echo '#include "gspawn-win32-helper.c"' >$@
+
+gspawn-win64-helper-console.c:
+       echo '#define HELPER_CONSOLE' >$@
+       echo '#include "gspawn-win32-helper.c"' >>$@
+
+
+if OS_WIN32
+if OS_WIN32_X64
+INSTALL_PROGS += gspawn-win64-helper gspawn-win64-helper-console
+gspawn_win64_helper_LDADD = libglib-2.0.la
+gspawn_win64_helper_LDFLAGS = -mwindows
+gspawn_win64_helper_console_LDADD = libglib-2.0.la
+else
+INSTALL_PROGS += gspawn-win32-helper gspawn-win32-helper-console
+gspawn_win32_helper_LDADD = libglib-2.0.la
+gspawn_win32_helper_LDFLAGS = -mwindows
+gspawn_win32_helper_console_LDADD = libglib-2.0.la
+endif
+endif
+
+glib-win32-res.o: glib.rc
+       $(WINDRES) glib.rc $@
+
+bin_PROGRAMS    = ${INSTALL_PROGS}
+
+if OS_UNIX
+
+INSTALL_PROGS  += gtester
+gtester_SOURCES         = gtester.c
+gtester_LDADD   = libglib-2.0.la 
+
+auto_config_binscripts = gtester-report
+bin_SCRIPTS = ${auto_config_binscripts}
+EXTRA_DIST += ${auto_config_binscripts}
+
+CONFIGVARS = \
+       "bindir"        : "${bindir}",          \
+       "glib-version"  : "${GLIB_VERSION}"
+
+install-exec-hook:
+       for sf in ${auto_config_binscripts} ; do \
+         mv -f "$(DESTDIR)$(bindir)/$$sf" "$(DESTDIR)$(bindir)/$$sf".tmp \
+         && sed < "$(DESTDIR)$(bindir)/$$sf".tmp > "$(DESTDIR)$(bindir)/$$sf" \
+           -e '1,24s|^ *#@PKGINSTALL_CONFIGVARS_IN24LINES@|  ${CONFIGVARS}|' \
+           -e '1,1s|#! /usr/bin/env python\([0-9]\+\(\.[0-9]\+\)\?\)\?|#!${PYTHON}|' \
+         || exit $$? ; \
+         chmod a+x $(DESTDIR)$(bindir)/$$sf ; \
+         rm -f "$(DESTDIR)$(bindir)/$$sf".tmp ; \
+       done
+
+endif
+
+glib-2.0.lib: libglib-2.0.la glib.def
+       lib -machine:@LIB_EXE_MACHINE_FLAG@ -name:libglib-2.0-$(LT_CURRENT_MINUS_AGE).dll -def:glib.def -out:$@
+
+dist-hook: $(BUILT_EXTRA_DIST) ../build/win32/vs9/glib.vcproj
+       files='$(BUILT_EXTRA_DIST)'; \
+       for f in $$files; do \
+         if test -f $$f; then d=.; else d=$(srcdir); fi; \
+         cp $$d/$$f $(distdir) || exit 1; done
+
+../build/win32/vs9/glib.vcproj: $(top_srcdir)/build/win32/vs9/glib.vcprojin
+       for F in $(libglib_2_0_la_SOURCES); do \
+               case $$F in \
+               *-gcc.c) \
+                       ;; \
+               *.c)    echo '   <File RelativePath="..\..\..\glib\'$$F'" />' \
+                       ;; \
+               esac; \
+       done >libglib.sourcefiles
+       $(CPP) -P - <$(top_srcdir)/build/win32/vs9/glib.vcprojin >$@
+
+distclean-local:
+       if test $(srcdir) = .; then :; else \
+           rm -f libglib-gdb.py; \
+       fi
+
+# install gdb scripts
+gdbdir = $(datadir)/glib-2.0/gdb
+dist_gdb_SCRIPTS = glib.py
+
+libglib-gdb.py: libglib-gdb.py.in
+       $(AM_V_GEN) $(SED) -e "s|\@datadir\@|$(datadir)|" $(srcdir)/libglib-gdb.py.in > libglib-gdb.py
+
+
+install-data-hook: libglib-gdb.py
+       mkdir -p $(DESTDIR)$(datadir)/gdb/auto-load$(ABS_GLIB_RUNTIME_LIBDIR)
+       $(INSTALL) libglib-gdb.py $(DESTDIR)$(datadir)/gdb/auto-load$(ABS_GLIB_RUNTIME_LIBDIR)/libglib-2.0.so.0.$(LT_CURRENT).$(LT_REVISION)-gdb.py
+if HAVE_GLIB_RUNTIME_LIBDIR
+       mkdir -p $(DESTDIR)$(libdir)/$(GLIB_RUNTIME_LIBDIR)
+       mv $(DESTDIR)$(libdir)/libglib-2.0.so.0 $(DESTDIR)$(libdir)/$(GLIB_RUNTIME_LIBDIR)
+       mv $(DESTDIR)$(libdir)/libglib-2.0.so.0.$(LT_CURRENT).$(LT_REVISION) $(DESTDIR)$(libdir)/$(GLIB_RUNTIME_LIBDIR)
+       rm -f $(DESTDIR)$(libdir)/libglib-2.0.so
+       ln -s $(GLIB_RUNTIME_LIBDIR)/libglib-2.0.so.0.$(LT_CURRENT).$(LT_REVISION) $(DESTDIR)$(libdir)/libglib-2.0.so
+endif
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/abicheck.sh b/resource/csdk/connectivity/lib/android/glib-master/glib/abicheck.sh
new file mode 100644 (file)
index 0000000..d2c9d88
--- /dev/null
@@ -0,0 +1,13 @@
+#! /bin/sh
+
+egrep '^#([^i]|if).*[^\]$' "${builddir:-.}/glibconfig.h" > glibconfig.cpp
+
+INCLUDES="-include ${top_builddir:-..}/config.h"
+INCLUDES="$INCLUDES -include glibconfig.cpp $GLIB_DEBUG_FLAGS"
+
+cpp -P -DINCLUDE_INTERNAL_SYMBOLS -DINCLUDE_VARIABLES -DG_STDIO_NO_WRAP_ON_UNIX -DALL_FILES $INCLUDES "${srcdir:-.}/glib.symbols" | sed -e '/^$/d' -e 's/ G_GNUC.*$//' -e 's/ PRIVATE$//' | sort > expected-abi
+rm -f glibconfig.cpp
+
+nm -D -g --defined-only .libs/libglib-2.0.so | cut -d ' ' -f 3 | egrep -v '^(__bss_start|_edata|_end)' | sort > actual-abi
+
+diff -u expected-abi actual-abi && rm -f expected-abi actual-abi
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/galloca.h b/resource/csdk/connectivity/lib/android/glib-master/glib/galloca.h
new file mode 100644 (file)
index 0000000..f8b2e87
--- /dev/null
@@ -0,0 +1,110 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_ALLOCA_H__
+#define __G_ALLOCA_H__
+
+#include <glib/gtypes.h>
+
+#if defined (GLIB_HAVE_ALLOCA_H)
+/* a native and working alloca.h is there */ 
+# include <alloca.h>
+#elif defined (__GNUC__)
+/* GCC does the right thing */
+# undef alloca
+# define alloca(size)   __builtin_alloca (size)
+#else /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */
+# if defined(_MSC_VER) || defined(__DMC__)
+#  include <malloc.h>
+#  define alloca _alloca
+# else /* !_MSC_VER && !__DMC__ */
+#  ifdef _AIX
+#   pragma alloca
+#  else /* !_AIX */
+#   ifndef alloca /* predefined by HP cc +Olibcalls */
+G_BEGIN_DECLS
+char *alloca ();
+G_END_DECLS
+#   endif /* !alloca */
+#  endif /* !_AIX */
+# endif /* !_MSC_VER && !__DMC__ */
+#endif /* !__GNUC__ && !GLIB_HAVE_ALLOCA_H */
+
+/**
+ * g_alloca:
+ * @size: number of bytes to allocate.
+ * 
+ * Allocates @size bytes on the stack; these bytes will be freed when the current
+ * stack frame is cleaned up. This macro essentially just wraps the alloca()
+ * function present on most UNIX variants.
+ * Thus it provides the same advantages and pitfalls as alloca():
+ * <variablelist>
+ *   <varlistentry><term></term><listitem><para>
+ *     + alloca() is very fast, as on most systems it's implemented by just adjusting
+ *     the stack pointer register.
+ *   </para></listitem></varlistentry>
+ *   <varlistentry><term></term><listitem><para>
+ *     + It doesn't cause any memory fragmentation, within its scope, separate alloca()
+ *     blocks just build up and are released together at function end.
+ *   </para></listitem></varlistentry>
+ *   <varlistentry><term></term><listitem><para>
+ *     - Allocation sizes have to fit into the current stack frame. For instance in a
+ *       threaded environment on Linux, the per-thread stack size is limited to 2 Megabytes,
+ *       so be sparse with alloca() uses.
+ *   </para></listitem></varlistentry>
+ *   <varlistentry><term></term><listitem><para>
+ *     - Allocation failure due to insufficient stack space is not indicated with a %NULL
+ *       return like e.g. with malloc(). Instead, most systems probably handle it the same
+ *       way as out of stack space situations from infinite function recursion, i.e.
+ *       with a segmentation fault.
+ *   </para></listitem></varlistentry>
+ *   <varlistentry><term></term><listitem><para>
+ *     - Special care has to be taken when mixing alloca() with GNU C variable sized arrays.
+ *       Stack space allocated with alloca() in the same scope as a variable sized array
+ *       will be freed together with the variable sized array upon exit of that scope, and
+ *       not upon exit of the enclosing function scope.
+ *   </para></listitem></varlistentry>
+ * </variablelist>
+ * 
+ * Returns: space for @size bytes, allocated on the stack
+ */
+#define g_alloca(size)          alloca (size)
+/**
+ * g_newa:
+ * @struct_type: Type of memory chunks to be allocated
+ * @n_structs: Number of chunks to be allocated
+ * 
+ * Wraps g_alloca() in a more typesafe manner.
+ * 
+ * Returns: Pointer to stack space for @n_structs chunks of type @struct_type
+ */
+#define g_newa(struct_type, n_structs) ((struct_type*) g_alloca (sizeof (struct_type) * (gsize) (n_structs)))
+
+#endif /* __G_ALLOCA_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/garray.c b/resource/csdk/connectivity/lib/android/glib-master/glib/garray.c
new file mode 100644 (file)
index 0000000..ac9a354
--- /dev/null
@@ -0,0 +1,1587 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/* 
+ * MT safe
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+
+#include "garray.h"
+
+#include "gmem.h"
+#include "gthread.h"
+#include "gmessages.h"
+#include "gqsort.h"
+
+
+/**
+ * SECTION: arrays
+ * @title: Arrays
+ * @short_description: arrays of arbitrary elements which grow
+ *                     automatically as elements are added
+ *
+ * Arrays are similar to standard C arrays, except that they grow
+ * automatically as elements are added.
+ *
+ * Array elements can be of any size (though all elements of one array
+ * are the same size), and the array can be automatically cleared to
+ * '0's and zero-terminated.
+ *
+ * To create a new array use g_array_new().
+ *
+ * To add elements to an array, use g_array_append_val(),
+ * g_array_append_vals(), g_array_prepend_val(), and
+ * g_array_prepend_vals().
+ *
+ * To access an element of an array, use g_array_index().
+ *
+ * To set the size of an array, use g_array_set_size().
+ *
+ * To free an array, use g_array_free().
+ *
+ * <example>
+ *  <title>Using a #GArray to store #gint values</title>
+ *  <programlisting>
+ *   GArray *garray;
+ *   gint i;
+ *   /<!-- -->* We create a new array to store gint values.
+ *      We don't want it zero-terminated or cleared to 0's. *<!-- -->/
+ *   garray = g_array_new (FALSE, FALSE, sizeof (gint));
+ *   for (i = 0; i &lt; 10000; i++)
+ *     g_array_append_val (garray, i);
+ *   for (i = 0; i &lt; 10000; i++)
+ *     if (g_array_index (garray, gint, i) != i)
+ *       g_print ("ERROR: got &percnt;d instead of &percnt;d\n",
+ *                g_array_index (garray, gint, i), i);
+ *   g_array_free (garray, TRUE);
+ *  </programlisting>
+ * </example>
+ **/
+
+#define MIN_ARRAY_SIZE  16
+
+typedef struct _GRealArray  GRealArray;
+
+/**
+ * GArray:
+ * @data: a pointer to the element data. The data may be moved as
+ *        elements are added to the #GArray.
+ * @len: the number of elements in the #GArray not including the
+ *       possible terminating zero element.
+ *
+ * Contains the public fields of an <link
+ * linkend="glib-arrays">Array</link>.
+ **/
+struct _GRealArray
+{
+  guint8 *data;
+  guint   len;
+  guint   alloc;
+  guint   elt_size;
+  guint   zero_terminated : 1;
+  guint   clear : 1;
+  volatile gint ref_count;
+};
+
+/**
+ * g_array_index:
+ * @a: a #GArray.
+ * @t: the type of the elements.
+ * @i: the index of the element to return.
+ * @Returns: the element of the #GArray at the index given by @i.
+ *
+ * Returns the element of a #GArray at the given index. The return
+ * value is cast to the given type.
+ *
+ * <example>
+ *  <title>Getting a pointer to an element in a #GArray</title>
+ *  <programlisting>
+ *   EDayViewEvent *event;
+ *   /<!-- -->* This gets a pointer to the 4th element
+ *      in the array of EDayViewEvent structs. *<!-- -->/
+ *   event = &amp;g_array_index (events, EDayViewEvent, 3);
+ *  </programlisting>
+ * </example>
+ **/
+
+#define g_array_elt_len(array,i) ((array)->elt_size * (i))
+#define g_array_elt_pos(array,i) ((array)->data + g_array_elt_len((array),(i)))
+#define g_array_elt_zero(array, pos, len)                              \
+  (memset (g_array_elt_pos ((array), pos), 0,  g_array_elt_len ((array), len)))
+#define g_array_zero_terminate(array) G_STMT_START{                    \
+  if ((array)->zero_terminated)                                                \
+    g_array_elt_zero ((array), (array)->len, 1);                       \
+}G_STMT_END
+
+static guint g_nearest_pow        (gint        num) G_GNUC_CONST;
+static void  g_array_maybe_expand (GRealArray *array,
+                                  gint        len);
+
+/**
+ * g_array_new:
+ * @zero_terminated: %TRUE if the array should have an extra element at
+ *                   the end which is set to 0.
+ * @clear_: %TRUE if #GArray elements should be automatically cleared
+ *          to 0 when they are allocated.
+ * @element_size: the size of each element in bytes.
+ * @Returns: the new #GArray.
+ *
+ * Creates a new #GArray with a reference count of 1.
+ **/
+GArray*
+g_array_new (gboolean zero_terminated,
+            gboolean clear,
+            guint    elt_size)
+{
+  return (GArray*) g_array_sized_new (zero_terminated, clear, elt_size, 0);
+}
+
+/**
+ * g_array_sized_new:
+ * @zero_terminated: %TRUE if the array should have an extra element at
+ *                   the end with all bits cleared.
+ * @clear_: %TRUE if all bits in the array should be cleared to 0 on
+ *          allocation.
+ * @element_size: size of each element in the array.
+ * @reserved_size: number of elements preallocated.
+ * @Returns: the new #GArray.
+ *
+ * Creates a new #GArray with @reserved_size elements preallocated and
+ * a reference count of 1. This avoids frequent reallocation, if you
+ * are going to add many elements to the array. Note however that the
+ * size of the array is still 0.
+ **/
+GArray* g_array_sized_new (gboolean zero_terminated,
+                          gboolean clear,
+                          guint    elt_size,
+                          guint    reserved_size)
+{
+  GRealArray *array = g_slice_new (GRealArray);
+
+  array->data            = NULL;
+  array->len             = 0;
+  array->alloc           = 0;
+  array->zero_terminated = (zero_terminated ? 1 : 0);
+  array->clear           = (clear ? 1 : 0);
+  array->elt_size        = elt_size;
+  array->ref_count       = 1;
+
+  if (array->zero_terminated || reserved_size != 0)
+    {
+      g_array_maybe_expand (array, reserved_size);
+      g_array_zero_terminate(array);
+    }
+
+  return (GArray*) array;
+}
+
+/**
+ * g_array_ref:
+ * @array: A #GArray.
+ *
+ * Atomically increments the reference count of @array by one. This
+ * function is MT-safe and may be called from any thread.
+ *
+ * Returns: The passed in #GArray.
+ *
+ * Since: 2.22
+ **/
+GArray *
+g_array_ref (GArray *array)
+{
+  GRealArray *rarray = (GRealArray*) array;
+  g_return_val_if_fail (array, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&rarray->ref_count) > 0, array);
+  g_atomic_int_inc (&rarray->ref_count);
+  return array;
+}
+
+/**
+ * g_array_unref:
+ * @array: A #GArray.
+ *
+ * Atomically decrements the reference count of @array by one. If the
+ * reference count drops to 0, all memory allocated by the array is
+ * released. This function is MT-safe and may be called from any
+ * thread.
+ *
+ * Since: 2.22
+ **/
+void
+g_array_unref (GArray *array)
+{
+  GRealArray *rarray = (GRealArray*) array;
+  g_return_if_fail (array);
+  g_return_if_fail (g_atomic_int_get (&rarray->ref_count) > 0);
+  if (g_atomic_int_dec_and_test (&rarray->ref_count))
+    g_array_free (array, TRUE);
+}
+
+/**
+ * g_array_get_element_size:
+ * @array: A #GArray.
+ *
+ * Gets the size of the elements in @array.
+ *
+ * Returns: Size of each element, in bytes.
+ *
+ * Since: 2.22
+ **/
+guint
+g_array_get_element_size (GArray *array)
+{
+  GRealArray *rarray = (GRealArray*) array;
+
+  g_return_val_if_fail (array, 0);
+
+  return rarray->elt_size;
+}
+
+/**
+ * g_array_free:
+ * @array: a #GArray.
+ * @free_segment: if %TRUE the actual element data is freed as well.
+ * @Returns: the element data if @free_segment is %FALSE, otherwise
+ *           %NULL.  The element data should be freed using g_free().
+ *
+ * Frees the memory allocated for the #GArray. If @free_segment is
+ * %TRUE it frees the memory block holding the elements as well and
+ * also each element if @array has a @element_free_func set. Pass
+ * %FALSE if you want to free the #GArray wrapper but preserve the
+ * underlying array for use elsewhere. If the reference count of @array
+ * is greater than one, the #GArray wrapper is preserved but the size
+ * of @array will be set to zero.
+ *
+ * <note><para>If array elements contain dynamically-allocated memory,
+ * they should be freed separately.</para></note>
+ **/
+gchar*
+g_array_free (GArray   *farray,
+             gboolean  free_segment)
+{
+  GRealArray *array = (GRealArray*) farray;
+  gchar* segment;
+  gboolean preserve_wrapper;
+
+  g_return_val_if_fail (array, NULL);
+
+  /* if others are holding a reference, preserve the wrapper but do free/return the data */
+  preserve_wrapper = FALSE;
+  if (g_atomic_int_get (&array->ref_count) > 1)
+    preserve_wrapper = TRUE;
+
+  if (free_segment)
+    {
+      g_free (array->data);
+      segment = NULL;
+    }
+  else
+    segment = (gchar*) array->data;
+
+  if (preserve_wrapper)
+    {
+      array->data            = NULL;
+      array->len             = 0;
+      array->alloc           = 0;
+    }
+  else
+    {
+      g_slice_free1 (sizeof (GRealArray), array);
+    }
+
+  return segment;
+}
+
+/**
+ * g_array_append_vals:
+ * @array: a #GArray.
+ * @data: a pointer to the elements to append to the end of the array.
+ * @len: the number of elements to append.
+ * @Returns: the #GArray.
+ *
+ * Adds @len elements onto the end of the array.
+ **/
+/**
+ * g_array_append_val:
+ * @a: a #GArray.
+ * @v: the value to append to the #GArray.
+ * @Returns: the #GArray.
+ *
+ * Adds the value on to the end of the array. The array will grow in
+ * size automatically if necessary.
+ *
+ * <note><para>g_array_append_val() is a macro which uses a reference
+ * to the value parameter @v. This means that you cannot use it with
+ * literal values such as "27". You must use variables.</para></note>
+ **/
+GArray*
+g_array_append_vals (GArray       *farray,
+                    gconstpointer data,
+                    guint         len)
+{
+  GRealArray *array = (GRealArray*) farray;
+
+  g_return_val_if_fail (array, NULL);
+
+  g_array_maybe_expand (array, len);
+
+  memcpy (g_array_elt_pos (array, array->len), data, 
+         g_array_elt_len (array, len));
+
+  array->len += len;
+
+  g_array_zero_terminate (array);
+
+  return farray;
+}
+
+/**
+ * g_array_prepend_vals:
+ * @array: a #GArray.
+ * @data: a pointer to the elements to prepend to the start of the
+ *        array.
+ * @len: the number of elements to prepend.
+ * @Returns: the #GArray.
+ *
+ * Adds @len elements onto the start of the array.
+ *
+ * This operation is slower than g_array_append_vals() since the
+ * existing elements in the array have to be moved to make space for
+ * the new elements.
+ **/
+/**
+ * g_array_prepend_val:
+ * @a: a #GArray.
+ * @v: the value to prepend to the #GArray.
+ * @Returns: the #GArray.
+ *
+ * Adds the value on to the start of the array. The array will grow in
+ * size automatically if necessary.
+ *
+ * This operation is slower than g_array_append_val() since the
+ * existing elements in the array have to be moved to make space for
+ * the new element.
+ *
+ * <note><para>g_array_prepend_val() is a macro which uses a reference
+ * to the value parameter @v. This means that you cannot use it with
+ * literal values such as "27". You must use variables.</para></note>
+ **/
+GArray*
+g_array_prepend_vals (GArray        *farray,
+                     gconstpointer  data,
+                     guint          len)
+{
+  GRealArray *array = (GRealArray*) farray;
+
+  g_return_val_if_fail (array, NULL);
+
+  g_array_maybe_expand (array, len);
+
+  g_memmove (g_array_elt_pos (array, len), g_array_elt_pos (array, 0), 
+            g_array_elt_len (array, array->len));
+
+  memcpy (g_array_elt_pos (array, 0), data, g_array_elt_len (array, len));
+
+  array->len += len;
+
+  g_array_zero_terminate (array);
+
+  return farray;
+}
+
+/**
+ * g_array_insert_vals:
+ * @array: a #GArray.
+ * @index_: the index to place the elements at.
+ * @data: a pointer to the elements to insert.
+ * @len: the number of elements to insert.
+ * @Returns: the #GArray.
+ *
+ * Inserts @len elements into a #GArray at the given index.
+ **/
+/**
+ * g_array_insert_val:
+ * @a: a #GArray.
+ * @i: the index to place the element at.
+ * @v: the value to insert into the array.
+ * @Returns: the #GArray.
+ *
+ * Inserts an element into an array at the given index.
+ *
+ * <note><para>g_array_insert_val() is a macro which uses a reference
+ * to the value parameter @v. This means that you cannot use it with
+ * literal values such as "27". You must use variables.</para></note>
+ **/
+GArray*
+g_array_insert_vals (GArray        *farray,
+                    guint          index_,
+                    gconstpointer  data,
+                    guint          len)
+{
+  GRealArray *array = (GRealArray*) farray;
+
+  g_return_val_if_fail (array, NULL);
+
+  g_array_maybe_expand (array, len);
+
+  g_memmove (g_array_elt_pos (array, len + index_), 
+            g_array_elt_pos (array, index_), 
+            g_array_elt_len (array, array->len - index_));
+
+  memcpy (g_array_elt_pos (array, index_), data, g_array_elt_len (array, len));
+
+  array->len += len;
+
+  g_array_zero_terminate (array);
+
+  return farray;
+}
+
+/**
+ * g_array_set_size:
+ * @array: a #GArray.
+ * @length: the new size of the #GArray.
+ * @Returns: the #GArray.
+ *
+ * Sets the size of the array, expanding it if necessary. If the array
+ * was created with @clear_ set to %TRUE, the new elements are set to 0.
+ **/
+GArray*
+g_array_set_size (GArray *farray,
+                 guint   length)
+{
+  GRealArray *array = (GRealArray*) farray;
+
+  g_return_val_if_fail (array, NULL);
+
+  if (length > array->len)
+    {
+      g_array_maybe_expand (array, length - array->len);
+      
+      if (array->clear)
+       g_array_elt_zero (array, array->len, length - array->len);
+    }
+  else if (G_UNLIKELY (g_mem_gc_friendly) && length < array->len)
+    g_array_elt_zero (array, length, array->len - length);
+  
+  array->len = length;
+  
+  g_array_zero_terminate (array);
+  
+  return farray;
+}
+
+/**
+ * g_array_remove_index:
+ * @array: a #GArray.
+ * @index_: the index of the element to remove.
+ * @Returns: the #GArray.
+ *
+ * Removes the element at the given index from a #GArray. The following
+ * elements are moved down one place.
+ **/
+GArray*
+g_array_remove_index (GArray *farray,
+                     guint   index_)
+{
+  GRealArray* array = (GRealArray*) farray;
+
+  g_return_val_if_fail (array, NULL);
+
+  g_return_val_if_fail (index_ < array->len, NULL);
+
+  if (index_ != array->len - 1)
+    g_memmove (g_array_elt_pos (array, index_),
+              g_array_elt_pos (array, index_ + 1),
+              g_array_elt_len (array, array->len - index_ - 1));
+  
+  array->len -= 1;
+
+  if (G_UNLIKELY (g_mem_gc_friendly))
+    g_array_elt_zero (array, array->len, 1);
+  else
+    g_array_zero_terminate (array);
+
+  return farray;
+}
+
+/**
+ * g_array_remove_index_fast:
+ * @array: a @GArray.
+ * @index_: the index of the element to remove.
+ * @Returns: the #GArray.
+ *
+ * Removes the element at the given index from a #GArray. The last
+ * element in the array is used to fill in the space, so this function
+ * does not preserve the order of the #GArray. But it is faster than
+ * g_array_remove_index().
+ **/
+GArray*
+g_array_remove_index_fast (GArray *farray,
+                          guint   index_)
+{
+  GRealArray* array = (GRealArray*) farray;
+
+  g_return_val_if_fail (array, NULL);
+
+  g_return_val_if_fail (index_ < array->len, NULL);
+
+  if (index_ != array->len - 1)
+    memcpy (g_array_elt_pos (array, index_), 
+           g_array_elt_pos (array, array->len - 1),
+           g_array_elt_len (array, 1));
+  
+  array->len -= 1;
+
+  if (G_UNLIKELY (g_mem_gc_friendly))
+    g_array_elt_zero (array, array->len, 1);
+  else
+    g_array_zero_terminate (array);
+
+  return farray;
+}
+
+/**
+ * g_array_remove_range:
+ * @array: a @GArray.
+ * @index_: the index of the first element to remove.
+ * @length: the number of elements to remove.
+ * @Returns: the #GArray.
+ *
+ * Removes the given number of elements starting at the given index
+ * from a #GArray.  The following elements are moved to close the gap.
+ *
+ * Since: 2.4
+ **/
+GArray*
+g_array_remove_range (GArray *farray,
+                      guint   index_,
+                      guint   length)
+{
+  GRealArray *array = (GRealArray*) farray;
+
+  g_return_val_if_fail (array, NULL);
+  g_return_val_if_fail (index_ < array->len, NULL);
+  g_return_val_if_fail (index_ + length <= array->len, NULL);
+
+  if (index_ + length != array->len)
+    g_memmove (g_array_elt_pos (array, index_), 
+               g_array_elt_pos (array, index_ + length), 
+               (array->len - (index_ + length)) * array->elt_size);
+
+  array->len -= length;
+  if (G_UNLIKELY (g_mem_gc_friendly))
+    g_array_elt_zero (array, array->len, length);
+  else
+    g_array_zero_terminate (array);
+
+  return farray;
+}
+
+/**
+ * g_array_sort:
+ * @array: a #GArray.
+ * @compare_func: comparison function.
+ *
+ * Sorts a #GArray using @compare_func which should be a qsort()-style
+ * comparison function (returns less than zero for first arg is less
+ * than second arg, zero for equal, greater zero if first arg is
+ * greater than second arg).
+ *
+ * If two array elements compare equal, their order in the sorted array
+ * is undefined.
+ **/
+void
+g_array_sort (GArray       *farray,
+             GCompareFunc  compare_func)
+{
+  GRealArray *array = (GRealArray*) farray;
+
+  g_return_if_fail (array != NULL);
+
+  qsort (array->data,
+        array->len,
+        array->elt_size,
+        compare_func);
+}
+
+/**
+ * g_array_sort_with_data:
+ * @array: a #GArray.
+ * @compare_func: comparison function.
+ * @user_data: data to pass to @compare_func.
+ *
+ * Like g_array_sort(), but the comparison function receives an extra
+ * user data argument.
+ **/
+void
+g_array_sort_with_data (GArray           *farray,
+                       GCompareDataFunc  compare_func,
+                       gpointer          user_data)
+{
+  GRealArray *array = (GRealArray*) farray;
+
+  g_return_if_fail (array != NULL);
+
+  g_qsort_with_data (array->data,
+                    array->len,
+                    array->elt_size,
+                    compare_func,
+                    user_data);
+}
+
+/* Returns the smallest power of 2 greater than n, or n if
+ * such power does not fit in a guint
+ */
+static guint
+g_nearest_pow (gint num)
+{
+  guint n = 1;
+
+  while (n < num && n > 0)
+    n <<= 1;
+
+  return n ? n : num;
+}
+
+static void
+g_array_maybe_expand (GRealArray *array,
+                     gint        len)
+{
+  guint want_alloc = g_array_elt_len (array, array->len + len + 
+                                     array->zero_terminated);
+
+  if (want_alloc > array->alloc)
+    {
+      want_alloc = g_nearest_pow (want_alloc);
+      want_alloc = MAX (want_alloc, MIN_ARRAY_SIZE);
+
+      array->data = g_realloc (array->data, want_alloc);
+
+      if (G_UNLIKELY (g_mem_gc_friendly))
+        memset (array->data + array->alloc, 0, want_alloc - array->alloc);
+
+      array->alloc = want_alloc;
+    }
+}
+
+/**
+ * SECTION: arrays_pointer
+ * @title: Pointer Arrays
+ * @short_description: arrays of pointers to any type of data, which
+ *                     grow automatically as new elements are added
+ *
+ * Pointer Arrays are similar to Arrays but are used only for storing
+ * pointers.
+ *
+ * <note><para>If you remove elements from the array, elements at the
+ * end of the array are moved into the space previously occupied by the
+ * removed element. This means that you should not rely on the index of
+ * particular elements remaining the same. You should also be careful
+ * when deleting elements while iterating over the array.</para></note>
+ *
+ * To create a pointer array, use g_ptr_array_new().
+ *
+ * To add elements to a pointer array, use g_ptr_array_add().
+ *
+ * To remove elements from a pointer array, use g_ptr_array_remove(),
+ * g_ptr_array_remove_index() or g_ptr_array_remove_index_fast().
+ *
+ * To access an element of a pointer array, use g_ptr_array_index().
+ *
+ * To set the size of a pointer array, use g_ptr_array_set_size().
+ *
+ * To free a pointer array, use g_ptr_array_free().
+ *
+ * <example>
+ *  <title>Using a #GPtrArray</title>
+ *  <programlisting>
+ *   GPtrArray *gparray;
+ *   gchar *string1 = "one", *string2 = "two", *string3 = "three";
+ *
+ *   gparray = g_ptr_array_new (<!-- -->);
+ *   g_ptr_array_add (gparray, (gpointer) string1);
+ *   g_ptr_array_add (gparray, (gpointer) string2);
+ *   g_ptr_array_add (gparray, (gpointer) string3);
+ *
+ *   if (g_ptr_array_index (gparray, 0) != (gpointer) string1)
+ *     g_print ("ERROR: got &percnt;p instead of &percnt;p\n",
+ *              g_ptr_array_index (gparray, 0), string1);
+ *
+ *   g_ptr_array_free (gparray, TRUE);
+ *  </programlisting>
+ * </example>
+ **/
+
+typedef struct _GRealPtrArray  GRealPtrArray;
+
+/**
+ * GPtrArray:
+ * @pdata: points to the array of pointers, which may be moved when the
+ *         array grows.
+ * @len: number of pointers in the array.
+ *
+ * Contains the public fields of a pointer array.
+ **/
+struct _GRealPtrArray
+{
+  gpointer     *pdata;
+  guint         len;
+  guint         alloc;
+  volatile gint ref_count;
+  GDestroyNotify element_free_func;
+};
+
+/**
+ * g_ptr_array_index:
+ * @array: a #GPtrArray.
+ * @index_: the index of the pointer to return.
+ * @Returns: the pointer at the given index.
+ *
+ * Returns the pointer at the given index of the pointer array.
+ **/
+
+static void g_ptr_array_maybe_expand (GRealPtrArray *array,
+                                     gint           len);
+
+/**
+ * g_ptr_array_new:
+ * @Returns: the new #GPtrArray.
+ *
+ * Creates a new #GPtrArray with a reference count of 1.
+ **/
+GPtrArray*
+g_ptr_array_new (void)
+{
+  return g_ptr_array_sized_new (0);
+}
+
+/**
+ * g_ptr_array_sized_new:
+ * @reserved_size: number of pointers preallocated.
+ * @Returns: the new #GPtrArray.
+ *
+ * Creates a new #GPtrArray with @reserved_size pointers preallocated
+ * and a reference count of 1. This avoids frequent reallocation, if
+ * you are going to add many pointers to the array. Note however that
+ * the size of the array is still 0.
+ **/
+GPtrArray*  
+g_ptr_array_sized_new (guint reserved_size)
+{
+  GRealPtrArray *array = g_slice_new (GRealPtrArray);
+
+  array->pdata = NULL;
+  array->len = 0;
+  array->alloc = 0;
+  array->ref_count = 1;
+  array->element_free_func = NULL;
+
+  if (reserved_size != 0)
+    g_ptr_array_maybe_expand (array, reserved_size);
+
+  return (GPtrArray*) array;  
+}
+
+/**
+ * g_ptr_array_new_with_free_func:
+ * @element_free_func: A function to free elements with destroy @array or %NULL.
+ *
+ * Creates a new #GPtrArray with a reference count of 1 and use @element_free_func
+ * for freeing each element when the array is destroyed either via
+ * g_ptr_array_unref(), when g_ptr_array_free() is called with @free_segment
+ * set to %TRUE or when removing elements.
+ *
+ * Returns: A new #GPtrArray.
+ *
+ * Since: 2.22
+ **/
+GPtrArray *
+g_ptr_array_new_with_free_func (GDestroyNotify element_free_func)
+{
+  GPtrArray *array;
+
+  array = g_ptr_array_new ();
+  g_ptr_array_set_free_func (array, element_free_func);
+  return array;
+}
+
+/**
+ * g_ptr_array_set_free_func:
+ * @array: A #GPtrArray.
+ * @element_free_func: A function to free elements with destroy @array or %NULL.
+ *
+ * Sets a function for freeing each element when @array is destroyed
+ * either via g_ptr_array_unref(), when g_ptr_array_free() is called
+ * with @free_segment set to %TRUE or when removing elements.
+ *
+ * Since: 2.22
+ **/
+void
+g_ptr_array_set_free_func (GPtrArray        *array,
+                           GDestroyNotify    element_free_func)
+{
+  GRealPtrArray* rarray = (GRealPtrArray*) array;
+
+  g_return_if_fail (array);
+
+  rarray->element_free_func = element_free_func;
+}
+
+/**
+ * g_ptr_array_ref:
+ * @array: A #GArray.
+ *
+ * Atomically increments the reference count of @array by one. This
+ * function is MT-safe and may be called from any thread.
+ *
+ * Returns: The passed in #GPtrArray.
+ *
+ * Since: 2.22
+ **/
+GPtrArray *
+g_ptr_array_ref (GPtrArray *array)
+{
+  GRealPtrArray *rarray = (GRealPtrArray*) array;
+
+  g_return_val_if_fail (array, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&rarray->ref_count) > 0, array);
+  g_atomic_int_inc (&rarray->ref_count);
+  return array;
+}
+
+/**
+ * g_ptr_array_unref:
+ * @array: A #GPtrArray.
+ *
+ * Atomically decrements the reference count of @array by one. If the
+ * reference count drops to 0, the effect is the same as calling
+ * g_ptr_array_free() with @free_segment set to %TRUE. This function
+ * is MT-safe and may be called from any thread.
+ *
+ * Since: 2.22
+ **/
+void
+g_ptr_array_unref (GPtrArray *array)
+{
+  GRealPtrArray *rarray = (GRealPtrArray*) array;
+
+  g_return_if_fail (array);
+  g_return_if_fail (g_atomic_int_get (&rarray->ref_count) > 0);
+  if (g_atomic_int_dec_and_test (&rarray->ref_count))
+    g_ptr_array_free (array, TRUE);
+}
+
+/**
+ * g_ptr_array_free:
+ * @array: a #GPtrArray.
+ * @free_seg: if %TRUE the actual pointer array is freed as well.
+ * @Returns: the pointer array if @free_seg is %FALSE, otherwise %NULL.
+ *           The pointer array should be freed using g_free().
+ *
+ * Frees the memory allocated for the #GPtrArray. If @free_seg is %TRUE
+ * it frees the memory block holding the elements as well. Pass %FALSE
+ * if you want to free the #GPtrArray wrapper but preserve the
+ * underlying array for use elsewhere. If the reference count of @array
+ * is greater than one, the #GPtrArray wrapper is preserved but the
+ * size of @array will be set to zero.
+ *
+ * <note><para>If array contents point to dynamically-allocated
+ * memory, they should be freed separately if @free_seg is %TRUE and no
+ * #GDestroyNotify function has been set for @array.</para></note>
+ **/
+gpointer*
+g_ptr_array_free (GPtrArray *farray,
+                 gboolean   free_segment)
+{
+  GRealPtrArray *array = (GRealPtrArray*) farray;
+  gpointer* segment;
+  gboolean preserve_wrapper;
+
+  g_return_val_if_fail (array, NULL);
+
+  /* if others are holding a reference, preserve the wrapper but do free/return the data */
+  preserve_wrapper = FALSE;
+  if (g_atomic_int_get (&array->ref_count) > 1)
+    preserve_wrapper = TRUE;
+
+  if (free_segment)
+    {
+      if (array->element_free_func != NULL)
+        g_ptr_array_foreach (farray, (GFunc) array->element_free_func, NULL);
+      g_free (array->pdata);
+      segment = NULL;
+    }
+  else
+    segment = array->pdata;
+
+  if (preserve_wrapper)
+    {
+      array->pdata = NULL;
+      array->len = 0;
+      array->alloc = 0;
+    }
+  else
+    {
+      g_slice_free1 (sizeof (GRealPtrArray), array);
+    }
+
+  return segment;
+}
+
+static void
+g_ptr_array_maybe_expand (GRealPtrArray *array,
+                         gint           len)
+{
+  if ((array->len + len) > array->alloc)
+    {
+      guint old_alloc = array->alloc;
+      array->alloc = g_nearest_pow (array->len + len);
+      array->alloc = MAX (array->alloc, MIN_ARRAY_SIZE);
+      array->pdata = g_realloc (array->pdata, sizeof (gpointer) * array->alloc);
+      if (G_UNLIKELY (g_mem_gc_friendly))
+        for ( ; old_alloc < array->alloc; old_alloc++)
+          array->pdata [old_alloc] = NULL;
+    }
+}
+
+/**
+ * g_ptr_array_set_size:
+ * @array: a #GPtrArray.
+ * @length: the new length of the pointer array.
+ *
+ * Sets the size of the array. When making the array larger,
+ * newly-added elements will be set to %NULL. When making it smaller,
+ * if @array has a non-%NULL #GDestroyNotify function then it will be
+ * called for the removed elements.
+ **/
+void
+g_ptr_array_set_size  (GPtrArray *farray,
+                      gint       length)
+{
+  GRealPtrArray* array = (GRealPtrArray*) farray;
+
+  g_return_if_fail (array);
+
+  if (length > array->len)
+    {
+      int i;
+      g_ptr_array_maybe_expand (array, (length - array->len));
+      /* This is not 
+       *     memset (array->pdata + array->len, 0,
+       *            sizeof (gpointer) * (length - array->len));
+       * to make it really portable. Remember (void*)NULL needn't be
+       * bitwise zero. It of course is silly not to use memset (..,0,..).
+       */
+      for (i = array->len; i < length; i++)
+       array->pdata[i] = NULL;
+    }
+  else if (length < array->len)
+    g_ptr_array_remove_range (farray, length, array->len - length);
+
+  array->len = length;
+}
+
+/**
+ * g_ptr_array_remove_index:
+ * @array: a #GPtrArray.
+ * @index_: the index of the pointer to remove.
+ * @Returns: the pointer which was removed.
+ *
+ * Removes the pointer at the given index from the pointer array. The
+ * following elements are moved down one place. If @array has a
+ * non-%NULL #GDestroyNotify function it is called for the removed
+ * element.
+ **/
+gpointer
+g_ptr_array_remove_index (GPtrArray *farray,
+                         guint      index_)
+{
+  GRealPtrArray* array = (GRealPtrArray*) farray;
+  gpointer result;
+
+  g_return_val_if_fail (array, NULL);
+
+  g_return_val_if_fail (index_ < array->len, NULL);
+
+  result = array->pdata[index_];
+  
+  if (array->element_free_func != NULL)
+    array->element_free_func (array->pdata[index_]);
+
+  if (index_ != array->len - 1)
+    g_memmove (array->pdata + index_, array->pdata + index_ + 1, 
+               sizeof (gpointer) * (array->len - index_ - 1));
+  
+  array->len -= 1;
+
+  if (G_UNLIKELY (g_mem_gc_friendly))
+    array->pdata[array->len] = NULL;
+
+  return result;
+}
+
+/**
+ * g_ptr_array_remove_index_fast:
+ * @array: a #GPtrArray.
+ * @index_: the index of the pointer to remove.
+ * @Returns: the pointer which was removed.
+ *
+ * Removes the pointer at the given index from the pointer array. The
+ * last element in the array is used to fill in the space, so this
+ * function does not preserve the order of the array. But it is faster
+ * than g_ptr_array_remove_index(). If @array has a non-%NULL
+ * #GDestroyNotify function it is called for the removed element.
+ **/
+gpointer
+g_ptr_array_remove_index_fast (GPtrArray *farray,
+                              guint      index_)
+{
+  GRealPtrArray* array = (GRealPtrArray*) farray;
+  gpointer result;
+
+  g_return_val_if_fail (array, NULL);
+
+  g_return_val_if_fail (index_ < array->len, NULL);
+
+  result = array->pdata[index_];
+
+  if (array->element_free_func != NULL)
+    array->element_free_func (array->pdata[index_]);
+
+  if (index_ != array->len - 1)
+    array->pdata[index_] = array->pdata[array->len - 1];
+
+  array->len -= 1;
+
+  if (G_UNLIKELY (g_mem_gc_friendly))
+    array->pdata[array->len] = NULL;
+
+  return result;
+}
+
+/**
+ * g_ptr_array_remove_range:
+ * @array: a @GPtrArray.
+ * @index_: the index of the first pointer to remove.
+ * @length: the number of pointers to remove.
+ *
+ * Removes the given number of pointers starting at the given index
+ * from a #GPtrArray.  The following elements are moved to close the
+ * gap. If @array has a non-%NULL #GDestroyNotify function it is called
+ * for the removed elements.
+ *
+ * Since: 2.4
+ **/
+void
+g_ptr_array_remove_range (GPtrArray *farray,
+                          guint      index_,
+                          guint      length)
+{
+  GRealPtrArray* array = (GRealPtrArray*) farray;
+  guint n;
+
+  g_return_if_fail (array);
+  g_return_if_fail (index_ < array->len);
+  g_return_if_fail (index_ + length <= array->len);
+
+  if (array->element_free_func != NULL)
+    {
+      for (n = index_; n < index_ + length; n++)
+        array->element_free_func (array->pdata[n]);
+    }
+
+  if (index_ + length != array->len)
+    {
+      g_memmove (&array->pdata[index_],
+                 &array->pdata[index_ + length], 
+                 (array->len - (index_ + length)) * sizeof (gpointer));
+    }
+
+  array->len -= length;
+  if (G_UNLIKELY (g_mem_gc_friendly))
+    {
+      guint i;
+      for (i = 0; i < length; i++)
+        array->pdata[array->len + i] = NULL;
+    }
+}
+
+/**
+ * g_ptr_array_remove:
+ * @array: a #GPtrArray.
+ * @data: the pointer to remove.
+ * @Returns: %TRUE if the pointer is removed. %FALSE if the pointer is
+ *           not found in the array.
+ *
+ * Removes the first occurrence of the given pointer from the pointer
+ * array. The following elements are moved down one place. If @array
+ * has a non-%NULL #GDestroyNotify function it is called for the
+ * removed element.
+ *
+ * It returns %TRUE if the pointer was removed, or %FALSE if the
+ * pointer was not found.
+ **/
+gboolean
+g_ptr_array_remove (GPtrArray *farray,
+                   gpointer   data)
+{
+  GRealPtrArray* array = (GRealPtrArray*) farray;
+  guint i;
+
+  g_return_val_if_fail (array, FALSE);
+
+  for (i = 0; i < array->len; i += 1)
+    {
+      if (array->pdata[i] == data)
+       {
+         g_ptr_array_remove_index (farray, i);
+         return TRUE;
+       }
+    }
+
+  return FALSE;
+}
+
+/**
+ * g_ptr_array_remove_fast:
+ * @array: a #GPtrArray.
+ * @data: the pointer to remove.
+ * @Returns: %TRUE if the pointer was found in the array.
+ *
+ * Removes the first occurrence of the given pointer from the pointer
+ * array. The last element in the array is used to fill in the space,
+ * so this function does not preserve the order of the array. But it is
+ * faster than g_ptr_array_remove(). If @array has a non-%NULL
+ * #GDestroyNotify function it is called for the removed element.
+ *
+ * It returns %TRUE if the pointer was removed, or %FALSE if the
+ * pointer was not found.
+ **/
+gboolean
+g_ptr_array_remove_fast (GPtrArray *farray,
+                        gpointer   data)
+{
+  GRealPtrArray* array = (GRealPtrArray*) farray;
+  guint i;
+
+  g_return_val_if_fail (array, FALSE);
+
+  for (i = 0; i < array->len; i += 1)
+    {
+      if (array->pdata[i] == data)
+       {
+         g_ptr_array_remove_index_fast (farray, i);
+         return TRUE;
+       }
+    }
+
+  return FALSE;
+}
+
+/**
+ * g_ptr_array_add:
+ * @array: a #GPtrArray.
+ * @data: the pointer to add.
+ *
+ * Adds a pointer to the end of the pointer array. The array will grow
+ * in size automatically if necessary.
+ **/
+void
+g_ptr_array_add (GPtrArray *farray,
+                gpointer   data)
+{
+  GRealPtrArray* array = (GRealPtrArray*) farray;
+
+  g_return_if_fail (array);
+
+  g_ptr_array_maybe_expand (array, 1);
+
+  array->pdata[array->len++] = data;
+}
+
+/**
+ * g_ptr_array_sort:
+ * @array: a #GPtrArray.
+ * @compare_func: comparison function.
+ *
+ * Sorts the array, using @compare_func which should be a qsort()-style
+ * comparison function (returns less than zero for first arg is less
+ * than second arg, zero for equal, greater than zero if irst arg is
+ * greater than second arg).
+ *
+ * If two array elements compare equal, their order in the sorted array
+ * is undefined.
+ *
+ * <note><para>The comparison function for g_ptr_array_sort() doesn't
+ * take the pointers from the array as arguments, it takes pointers to
+ * the pointers in the array.</para></note>
+ **/
+void
+g_ptr_array_sort (GPtrArray    *array,
+                 GCompareFunc  compare_func)
+{
+  g_return_if_fail (array != NULL);
+
+  qsort (array->pdata,
+        array->len,
+        sizeof (gpointer),
+        compare_func);
+}
+
+/**
+ * g_ptr_array_sort_with_data:
+ * @array: a #GPtrArray.
+ * @compare_func: comparison function.
+ * @user_data: data to pass to @compare_func.
+ *
+ * Like g_ptr_array_sort(), but the comparison function has an extra
+ * user data argument.
+ *
+ * <note><para>The comparison function for g_ptr_array_sort_with_data()
+ * doesn't take the pointers from the array as arguments, it takes
+ * pointers to the pointers in the array.</para></note>
+ **/
+void
+g_ptr_array_sort_with_data (GPtrArray        *array,
+                           GCompareDataFunc  compare_func,
+                           gpointer          user_data)
+{
+  g_return_if_fail (array != NULL);
+
+  g_qsort_with_data (array->pdata,
+                    array->len,
+                    sizeof (gpointer),
+                    compare_func,
+                    user_data);
+}
+
+/**
+ * g_ptr_array_foreach:
+ * @array: a #GPtrArray
+ * @func: the function to call for each array element
+ * @user_data: user data to pass to the function
+ * 
+ * Calls a function for each element of a #GPtrArray.
+ *
+ * Since: 2.4
+ **/
+void
+g_ptr_array_foreach (GPtrArray *array,
+                     GFunc      func,
+                     gpointer   user_data)
+{
+  guint i;
+
+  g_return_if_fail (array);
+
+  for (i = 0; i < array->len; i++)
+    (*func) (array->pdata[i], user_data);
+}
+
+/**
+ * SECTION: arrays_byte
+ * @title: Byte Arrays
+ * @short_description: arrays of bytes, which grow automatically as
+ *                     elements are added
+ *
+ * #GByteArray is based on #GArray, to provide arrays of bytes which
+ * grow automatically as elements are added.
+ *
+ * To create a new #GByteArray use g_byte_array_new().
+ *
+ * To add elements to a #GByteArray, use g_byte_array_append(), and
+ * g_byte_array_prepend().
+ *
+ * To set the size of a #GByteArray, use g_byte_array_set_size().
+ *
+ * To free a #GByteArray, use g_byte_array_free().
+ *
+ * <example>
+ *  <title>Using a #GByteArray</title>
+ *  <programlisting>
+ *   GByteArray *gbarray;
+ *   gint i;
+ *
+ *   gbarray = g_byte_array_new (<!-- -->);
+ *   for (i = 0; i &lt; 10000; i++)
+ *     g_byte_array_append (gbarray, (guint8*) "abcd", 4);
+ *
+ *   for (i = 0; i &lt; 10000; i++)
+ *     {
+ *       g_assert (gbarray->data[4*i] == 'a');
+ *       g_assert (gbarray->data[4*i+1] == 'b');
+ *       g_assert (gbarray->data[4*i+2] == 'c');
+ *       g_assert (gbarray->data[4*i+3] == 'd');
+ *     }
+ *
+ *   g_byte_array_free (gbarray, TRUE);
+ *  </programlisting>
+ * </example>
+ **/
+
+/**
+ * GByteArray:
+ * @data: a pointer to the element data. The data may be moved as
+ *        elements are added to the #GByteArray.
+ * @len: the number of elements in the #GByteArray.
+ *
+ * The <structname>GByteArray</structname> struct allows access to the
+ * public fields of a <structname>GByteArray</structname>.
+ **/
+
+/**
+ * g_byte_array_new:
+ * @Returns: the new #GByteArray.
+ *
+ * Creates a new #GByteArray with a reference count of 1.
+ **/
+GByteArray* g_byte_array_new (void)
+{
+  return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, 0);
+}
+
+/**
+ * g_byte_array_sized_new:
+ * @reserved_size: number of bytes preallocated.
+ * @Returns: the new #GByteArray.
+ *
+ * Creates a new #GByteArray with @reserved_size bytes preallocated.
+ * This avoids frequent reallocation, if you are going to add many
+ * bytes to the array. Note however that the size of the array is still
+ * 0.
+ **/
+GByteArray* g_byte_array_sized_new (guint reserved_size)
+{
+  return (GByteArray*) g_array_sized_new (FALSE, FALSE, 1, reserved_size);
+}
+
+/**
+ * g_byte_array_free:
+ * @array: a #GByteArray.
+ * @free_segment: if %TRUE the actual byte data is freed as well.
+ * @Returns: the element data if @free_segment is %FALSE, otherwise
+ *           %NULL.  The element data should be freed using g_free().
+ *
+ * Frees the memory allocated by the #GByteArray. If @free_segment is
+ * %TRUE it frees the actual byte data. If the reference count of
+ * @array is greater than one, the #GByteArray wrapper is preserved but
+ * the size of @array will be set to zero.
+ **/
+guint8*            g_byte_array_free     (GByteArray *array,
+                                  gboolean    free_segment)
+{
+  return (guint8*) g_array_free ((GArray*) array, free_segment);
+}
+
+/**
+ * g_byte_array_ref:
+ * @array: A #GByteArray.
+ *
+ * Atomically increments the reference count of @array by one. This
+ * function is MT-safe and may be called from any thread.
+ *
+ * Returns: The passed in #GByteArray.
+ *
+ * Since: 2.22
+ **/
+GByteArray *
+g_byte_array_ref (GByteArray *array)
+{
+  return (GByteArray *) g_array_ref ((GArray *) array);
+}
+
+/**
+ * g_byte_array_unref:
+ * @array: A #GByteArray.
+ *
+ * Atomically decrements the reference count of @array by one. If the
+ * reference count drops to 0, all memory allocated by the array is
+ * released. This function is MT-safe and may be called from any
+ * thread.
+ *
+ * Since: 2.22
+ **/
+void
+g_byte_array_unref (GByteArray *array)
+{
+  g_array_unref ((GArray *) array);
+}
+
+/**
+ * g_byte_array_append:
+ * @array: a #GByteArray.
+ * @data: the byte data to be added.
+ * @len: the number of bytes to add.
+ * @Returns: the #GByteArray.
+ *
+ * Adds the given bytes to the end of the #GByteArray. The array will
+ * grow in size automatically if necessary.
+ **/
+GByteArray* g_byte_array_append   (GByteArray   *array,
+                                  const guint8 *data,
+                                  guint         len)
+{
+  g_array_append_vals ((GArray*) array, (guint8*)data, len);
+
+  return array;
+}
+
+/**
+ * g_byte_array_prepend:
+ * @array: a #GByteArray.
+ * @data: the byte data to be added.
+ * @len: the number of bytes to add.
+ * @Returns: the #GByteArray.
+ *
+ * Adds the given data to the start of the #GByteArray. The array will
+ * grow in size automatically if necessary.
+ **/
+GByteArray* g_byte_array_prepend  (GByteArray   *array,
+                                  const guint8 *data,
+                                  guint         len)
+{
+  g_array_prepend_vals ((GArray*) array, (guint8*)data, len);
+
+  return array;
+}
+
+/**
+ * g_byte_array_set_size:
+ * @array: a #GByteArray.
+ * @length: the new size of the #GByteArray.
+ * @Returns: the #GByteArray.
+ *
+ * Sets the size of the #GByteArray, expanding it if necessary.
+ **/
+GByteArray* g_byte_array_set_size (GByteArray *array,
+                                  guint       length)
+{
+  g_array_set_size ((GArray*) array, length);
+
+  return array;
+}
+
+/**
+ * g_byte_array_remove_index:
+ * @array: a #GByteArray.
+ * @index_: the index of the byte to remove.
+ * @Returns: the #GByteArray.
+ *
+ * Removes the byte at the given index from a #GByteArray. The
+ * following bytes are moved down one place.
+ **/
+GByteArray* g_byte_array_remove_index (GByteArray *array,
+                                      guint       index_)
+{
+  g_array_remove_index ((GArray*) array, index_);
+
+  return array;
+}
+
+/**
+ * g_byte_array_remove_index_fast:
+ * @array: a #GByteArray.
+ * @index_: the index of the byte to remove.
+ * @Returns: the #GByteArray.
+ *
+ * Removes the byte at the given index from a #GByteArray. The last
+ * element in the array is used to fill in the space, so this function
+ * does not preserve the order of the #GByteArray. But it is faster
+ * than g_byte_array_remove_index().
+ **/
+GByteArray* g_byte_array_remove_index_fast (GByteArray *array,
+                                           guint       index_)
+{
+  g_array_remove_index_fast ((GArray*) array, index_);
+
+  return array;
+}
+
+/**
+ * g_byte_array_remove_range:
+ * @array: a @GByteArray.
+ * @index_: the index of the first byte to remove.
+ * @length: the number of bytes to remove.
+ * @Returns: the #GByteArray.
+ *
+ * Removes the given number of bytes starting at the given index from a
+ * #GByteArray.  The following elements are moved to close the gap.
+ *
+ * Since: 2.4
+ **/
+GByteArray*
+g_byte_array_remove_range (GByteArray *array,
+                           guint       index_,
+                           guint       length)
+{
+  g_return_val_if_fail (array, NULL);
+  g_return_val_if_fail (index_ < array->len, NULL);
+  g_return_val_if_fail (index_ + length <= array->len, NULL);
+
+  return (GByteArray *)g_array_remove_range ((GArray*) array, index_, length);
+}
+
+/**
+ * g_byte_array_sort:
+ * @array: a #GByteArray.
+ * @compare_func: comparison function.
+ *
+ * Sorts a byte array, using @compare_func which should be a
+ * qsort()-style comparison function (returns less than zero for first
+ * arg is less than second arg, zero for equal, greater than zero if
+ * first arg is greater than second arg).
+ *
+ * If two array elements compare equal, their order in the sorted array
+ * is undefined.
+ **/
+void
+g_byte_array_sort (GByteArray   *array,
+                  GCompareFunc  compare_func)
+{
+  g_array_sort ((GArray *) array, compare_func);
+}
+
+/**
+ * g_byte_array_sort_with_data:
+ * @array: a #GByteArray.
+ * @compare_func: comparison function.
+ * @user_data: data to pass to @compare_func.
+ *
+ * Like g_byte_array_sort(), but the comparison function takes an extra
+ * user data argument.
+ **/
+void
+g_byte_array_sort_with_data (GByteArray       *array,
+                            GCompareDataFunc  compare_func,
+                            gpointer          user_data)
+{
+  g_array_sort_with_data ((GArray *) array, compare_func, user_data);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/garray.h b/resource/csdk/connectivity/lib/android/glib-master/glib/garray.h
new file mode 100644 (file)
index 0000000..6bc51f7
--- /dev/null
@@ -0,0 +1,179 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_ARRAY_H__
+#define __G_ARRAY_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GArray         GArray;
+typedef struct _GByteArray     GByteArray;
+typedef struct _GPtrArray      GPtrArray;
+
+struct _GArray
+{
+  gchar *data;
+  guint len;
+};
+
+struct _GByteArray
+{
+  guint8 *data;
+  guint          len;
+};
+
+struct _GPtrArray
+{
+  gpointer *pdata;
+  guint            len;
+};
+
+/* Resizable arrays. remove fills any cleared spot and shortens the
+ * array, while preserving the order. remove_fast will distort the
+ * order by moving the last element to the position of the removed.
+ */
+
+#define g_array_append_val(a,v)          g_array_append_vals (a, &(v), 1)
+#define g_array_prepend_val(a,v)  g_array_prepend_vals (a, &(v), 1)
+#define g_array_insert_val(a,i,v) g_array_insert_vals (a, i, &(v), 1)
+#define g_array_index(a,t,i)      (((t*) (void *) (a)->data) [(i)])
+
+GArray* g_array_new               (gboolean          zero_terminated,
+                                  gboolean          clear_,
+                                  guint             element_size);
+GArray* g_array_sized_new         (gboolean          zero_terminated,
+                                  gboolean          clear_,
+                                  guint             element_size,
+                                  guint             reserved_size);
+gchar*  g_array_free              (GArray           *array,
+                                  gboolean          free_segment);
+GArray *g_array_ref               (GArray           *array);
+void    g_array_unref             (GArray           *array);
+guint   g_array_get_element_size  (GArray           *array);
+GArray* g_array_append_vals       (GArray           *array,
+                                  gconstpointer     data,
+                                  guint             len);
+GArray* g_array_prepend_vals      (GArray           *array,
+                                  gconstpointer     data,
+                                  guint             len);
+GArray* g_array_insert_vals       (GArray           *array,
+                                  guint             index_,
+                                  gconstpointer     data,
+                                  guint             len);
+GArray* g_array_set_size          (GArray           *array,
+                                  guint             length);
+GArray* g_array_remove_index      (GArray           *array,
+                                  guint             index_);
+GArray* g_array_remove_index_fast (GArray           *array,
+                                  guint             index_);
+GArray* g_array_remove_range      (GArray           *array,
+                                  guint             index_,
+                                  guint             length);
+void    g_array_sort              (GArray           *array,
+                                  GCompareFunc      compare_func);
+void    g_array_sort_with_data    (GArray           *array,
+                                  GCompareDataFunc  compare_func,
+                                  gpointer          user_data);
+
+/* Resizable pointer array.  This interface is much less complicated
+ * than the above.  Add appends a pointer.  Remove fills any cleared 
+ * spot and shortens the array. remove_fast will again distort order.  
+ */
+#define    g_ptr_array_index(array,index_) ((array)->pdata)[index_]
+GPtrArray* g_ptr_array_new                (void);
+GPtrArray* g_ptr_array_new_with_free_func (GDestroyNotify    element_free_func);
+GPtrArray* g_ptr_array_sized_new          (guint             reserved_size);
+gpointer*  g_ptr_array_free               (GPtrArray        *array,
+                                          gboolean          free_seg);
+GPtrArray* g_ptr_array_ref                (GPtrArray        *array);
+void       g_ptr_array_unref              (GPtrArray        *array);
+void       g_ptr_array_set_free_func      (GPtrArray        *array,
+                                           GDestroyNotify    element_free_func);
+void       g_ptr_array_set_size           (GPtrArray        *array,
+                                          gint              length);
+gpointer   g_ptr_array_remove_index       (GPtrArray        *array,
+                                          guint             index_);
+gpointer   g_ptr_array_remove_index_fast  (GPtrArray        *array,
+                                          guint             index_);
+gboolean   g_ptr_array_remove             (GPtrArray        *array,
+                                          gpointer          data);
+gboolean   g_ptr_array_remove_fast        (GPtrArray        *array,
+                                          gpointer          data);
+void       g_ptr_array_remove_range       (GPtrArray        *array,
+                                          guint             index_,
+                                          guint             length);
+void       g_ptr_array_add                (GPtrArray        *array,
+                                          gpointer          data);
+void       g_ptr_array_sort               (GPtrArray        *array,
+                                          GCompareFunc      compare_func);
+void       g_ptr_array_sort_with_data     (GPtrArray        *array,
+                                          GCompareDataFunc  compare_func,
+                                          gpointer          user_data);
+void       g_ptr_array_foreach            (GPtrArray        *array,
+                                          GFunc             func,
+                                          gpointer          user_data);
+
+
+/* Byte arrays, an array of guint8.  Implemented as a GArray,
+ * but type-safe.
+ */
+
+GByteArray* g_byte_array_new               (void);
+GByteArray* g_byte_array_sized_new         (guint             reserved_size);
+guint8*     g_byte_array_free              (GByteArray       *array,
+                                           gboolean          free_segment);
+GByteArray *g_byte_array_ref               (GByteArray       *array);
+void        g_byte_array_unref             (GByteArray       *array);
+GByteArray* g_byte_array_append            (GByteArray       *array,
+                                           const guint8     *data,
+                                           guint             len);
+GByteArray* g_byte_array_prepend           (GByteArray       *array,
+                                           const guint8     *data,
+                                           guint             len);
+GByteArray* g_byte_array_set_size          (GByteArray       *array,
+                                           guint             length);
+GByteArray* g_byte_array_remove_index      (GByteArray       *array,
+                                           guint             index_);
+GByteArray* g_byte_array_remove_index_fast (GByteArray       *array,
+                                           guint             index_);
+GByteArray* g_byte_array_remove_range      (GByteArray       *array,
+                                           guint             index_,
+                                           guint             length);
+void        g_byte_array_sort              (GByteArray       *array,
+                                           GCompareFunc      compare_func);
+void        g_byte_array_sort_with_data    (GByteArray       *array,
+                                           GCompareDataFunc  compare_func,
+                                           gpointer          user_data);
+
+G_END_DECLS
+
+#endif /* __G_ARRAY_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gasyncqueue.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gasyncqueue.c
new file mode 100644 (file)
index 0000000..97672e7
--- /dev/null
@@ -0,0 +1,721 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * GAsyncQueue: asynchronous queue implementation, based on Gqueue.
+ * Copyright (C) 2000 Sebastian Wilhelmi; University of Karlsruhe
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "gasyncqueue.h"
+
+#include "gmem.h"
+#include "gqueue.h"
+#include "gtestutils.h"
+#include "gthread.h"
+
+
+/**
+ * SECTION: async_queues
+ * @title: Asynchronous Queues
+ * @short_description: asynchronous communication between threads
+ *
+ * Often you need to communicate between different threads. In general
+ * it's safer not to do this by shared memory, but by explicit message
+ * passing. These messages only make sense asynchronously for
+ * multi-threaded applications though, as a synchronous operation could
+ * as well be done in the same thread.
+ *
+ * Asynchronous queues are an exception from most other GLib data
+ * structures, as they can be used simultaneously from multiple threads
+ * without explicit locking and they bring their own builtin reference
+ * counting. This is because the nature of an asynchronous queue is that
+ * it will always be used by at least 2 concurrent threads.
+ *
+ * For using an asynchronous queue you first have to create one with
+ * g_async_queue_new(). A newly-created queue will get the reference
+ * count 1. Whenever another thread is creating a new reference of (that
+ * is, pointer to) the queue, it has to increase the reference count
+ * (using g_async_queue_ref()). Also, before removing this reference,
+ * the reference count has to be decreased (using g_async_queue_unref()).
+ * After that the queue might no longer exist so you must not access
+ * it after that point.
+ *
+ * A thread, which wants to send a message to that queue simply calls
+ * g_async_queue_push() to push the message to the queue.
+ *
+ * A thread, which is expecting messages from an asynchronous queue
+ * simply calls g_async_queue_pop() for that queue. If no message is
+ * available in the queue at that point, the thread is now put to sleep
+ * until a message arrives. The message will be removed from the queue
+ * and returned. The functions g_async_queue_try_pop() and
+ * g_async_queue_timed_pop() can be used to only check for the presence
+ * of messages or to only wait a certain time for messages respectively.
+ *
+ * For almost every function there exist two variants, one that locks
+ * the queue and one that doesn't. That way you can hold the queue lock
+ * (acquire it with g_async_queue_lock() and release it with
+ * g_async_queue_unlock()) over multiple queue accessing instructions.
+ * This can be necessary to ensure the integrity of the queue, but should
+ * only be used when really necessary, as it can make your life harder
+ * if used unwisely. Normally you should only use the locking function
+ * variants (those without the suffix _unlocked)
+ */
+
+/**
+ * GAsyncQueue:
+ *
+ * The GAsyncQueue struct is an opaque data structure, which represents
+ * an asynchronous queue. It should only be accessed through the
+ * <function>g_async_queue_*</function> functions.
+ */
+struct _GAsyncQueue
+{
+  GMutex *mutex;
+  GCond *cond;
+  GQueue queue;
+  GDestroyNotify item_free_func;
+  guint waiting_threads;
+  gint32 ref_count;
+};
+
+typedef struct {
+  GCompareDataFunc func;
+  gpointer         user_data;
+} SortData;
+
+/**
+ * g_async_queue_new:
+ * 
+ * Creates a new asynchronous queue with the initial reference count of 1.
+ * 
+ * Return value: the new #GAsyncQueue.
+ **/
+GAsyncQueue*
+g_async_queue_new (void)
+{
+  GAsyncQueue* retval = g_new (GAsyncQueue, 1);
+  retval->mutex = g_mutex_new ();
+  retval->cond = NULL;
+  g_queue_init (&retval->queue);
+  retval->waiting_threads = 0;
+  retval->ref_count = 1;
+  retval->item_free_func = NULL;
+  return retval;
+}
+
+/**
+ * g_async_queue_new_full:
+ * @item_free_func: function to free queue elements
+ * 
+ * Creates a new asynchronous queue with an initial reference count of 1 and
+ * sets up a destroy notify function that is used to free any remaining
+ * queue items when the queue is destroyed after the final unref.
+ *
+ * Return value: the new #GAsyncQueue.
+ *
+ * Since: 2.16
+ **/
+GAsyncQueue*
+g_async_queue_new_full (GDestroyNotify item_free_func)
+{
+  GAsyncQueue *async_queue = g_async_queue_new ();
+  async_queue->item_free_func = item_free_func;
+  return async_queue;
+}
+
+/**
+ * g_async_queue_ref:
+ * @queue: a #GAsyncQueue.
+ *
+ * Increases the reference count of the asynchronous @queue by 1. You
+ * do not need to hold the lock to call this function.
+ *
+ * Returns: the @queue that was passed in (since 2.6)
+ **/
+GAsyncQueue *
+g_async_queue_ref (GAsyncQueue *queue)
+{
+  g_return_val_if_fail (queue, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+  
+  g_atomic_int_inc (&queue->ref_count);
+
+  return queue;
+}
+
+/**
+ * g_async_queue_ref_unlocked:
+ * @queue: a #GAsyncQueue.
+ * 
+ * Increases the reference count of the asynchronous @queue by 1.
+ *
+ * @Deprecated: Since 2.8, reference counting is done atomically
+ * so g_async_queue_ref() can be used regardless of the @queue's
+ * lock.
+ **/
+void 
+g_async_queue_ref_unlocked (GAsyncQueue *queue)
+{
+  g_return_if_fail (queue);
+  g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+  
+  g_atomic_int_inc (&queue->ref_count);
+}
+
+/**
+ * g_async_queue_unref_and_unlock:
+ * @queue: a #GAsyncQueue.
+ * 
+ * Decreases the reference count of the asynchronous @queue by 1 and
+ * releases the lock. This function must be called while holding the
+ * @queue's lock. If the reference count went to 0, the @queue will be
+ * destroyed and the memory allocated will be freed.
+ *
+ * @Deprecated: Since 2.8, reference counting is done atomically
+ * so g_async_queue_unref() can be used regardless of the @queue's
+ * lock.
+ **/
+void 
+g_async_queue_unref_and_unlock (GAsyncQueue *queue)
+{
+  g_return_if_fail (queue);
+  g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+
+  g_mutex_unlock (queue->mutex);
+  g_async_queue_unref (queue);
+}
+
+/**
+ * g_async_queue_unref:
+ * @queue: a #GAsyncQueue.
+ * 
+ * Decreases the reference count of the asynchronous @queue by 1. If
+ * the reference count went to 0, the @queue will be destroyed and the
+ * memory allocated will be freed. So you are not allowed to use the
+ * @queue afterwards, as it might have disappeared. You do not need to
+ * hold the lock to call this function.
+ **/
+void 
+g_async_queue_unref (GAsyncQueue *queue)
+{
+  g_return_if_fail (queue);
+  g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+  
+  if (g_atomic_int_dec_and_test (&queue->ref_count))
+    {
+      g_return_if_fail (queue->waiting_threads == 0);
+      g_mutex_free (queue->mutex);
+      if (queue->cond)
+       g_cond_free (queue->cond);
+      if (queue->item_free_func)
+        g_queue_foreach (&queue->queue, (GFunc) queue->item_free_func, NULL);
+      g_queue_clear (&queue->queue);
+      g_free (queue);
+    }
+}
+
+/**
+ * g_async_queue_lock:
+ * @queue: a #GAsyncQueue.
+ * 
+ * Acquires the @queue's lock. After that you can only call the
+ * <function>g_async_queue_*_unlocked()</function> function variants on that
+ * @queue. Otherwise it will deadlock.
+ **/
+void
+g_async_queue_lock (GAsyncQueue *queue)
+{
+  g_return_if_fail (queue);
+  g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+
+  g_mutex_lock (queue->mutex);
+}
+
+/**
+ * g_async_queue_unlock:
+ * @queue: a #GAsyncQueue.
+ * 
+ * Releases the queue's lock.
+ **/
+void 
+g_async_queue_unlock (GAsyncQueue *queue)
+{
+  g_return_if_fail (queue);
+  g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+
+  g_mutex_unlock (queue->mutex);
+}
+
+/**
+ * g_async_queue_push:
+ * @queue: a #GAsyncQueue.
+ * @data: @data to push into the @queue.
+ *
+ * Pushes the @data into the @queue. @data must not be %NULL.
+ **/
+void
+g_async_queue_push (GAsyncQueue* queue, gpointer data)
+{
+  g_return_if_fail (queue);
+  g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+  g_return_if_fail (data);
+
+  g_mutex_lock (queue->mutex);
+  g_async_queue_push_unlocked (queue, data);
+  g_mutex_unlock (queue->mutex);
+}
+
+/**
+ * g_async_queue_push_unlocked:
+ * @queue: a #GAsyncQueue.
+ * @data: @data to push into the @queue.
+ * 
+ * Pushes the @data into the @queue. @data must not be %NULL. This
+ * function must be called while holding the @queue's lock.
+ **/
+void
+g_async_queue_push_unlocked (GAsyncQueue* queue, gpointer data)
+{
+  g_return_if_fail (queue);
+  g_return_if_fail (g_atomic_int_get (&queue->ref_count) > 0);
+  g_return_if_fail (data);
+
+  g_queue_push_head (&queue->queue, data);
+  if (queue->waiting_threads > 0)
+    g_cond_signal (queue->cond);
+}
+
+/**
+ * g_async_queue_push_sorted:
+ * @queue: a #GAsyncQueue
+ * @data: the @data to push into the @queue
+ * @func: the #GCompareDataFunc is used to sort @queue. This function
+ *     is passed two elements of the @queue. The function should return
+ *     0 if they are equal, a negative value if the first element
+ *     should be higher in the @queue or a positive value if the first
+ *     element should be lower in the @queue than the second element.
+ * @user_data: user data passed to @func.
+ * 
+ * Inserts @data into @queue using @func to determine the new
+ * position. 
+ * 
+ * This function requires that the @queue is sorted before pushing on
+ * new elements.
+ * 
+ * This function will lock @queue before it sorts the queue and unlock
+ * it when it is finished.
+ * 
+ * For an example of @func see g_async_queue_sort(). 
+ *
+ * Since: 2.10
+ **/
+void
+g_async_queue_push_sorted (GAsyncQueue      *queue,
+                          gpointer          data,
+                          GCompareDataFunc  func,
+                          gpointer          user_data)
+{
+  g_return_if_fail (queue != NULL);
+
+  g_mutex_lock (queue->mutex);
+  g_async_queue_push_sorted_unlocked (queue, data, func, user_data);
+  g_mutex_unlock (queue->mutex);
+}
+
+static gint 
+g_async_queue_invert_compare (gpointer  v1, 
+                             gpointer  v2, 
+                             SortData *sd)
+{
+  return -sd->func (v1, v2, sd->user_data);
+}
+
+/**
+ * g_async_queue_push_sorted_unlocked:
+ * @queue: a #GAsyncQueue
+ * @data: the @data to push into the @queue
+ * @func: the #GCompareDataFunc is used to sort @queue. This function
+ *     is passed two elements of the @queue. The function should return
+ *     0 if they are equal, a negative value if the first element
+ *     should be higher in the @queue or a positive value if the first
+ *     element should be lower in the @queue than the second element.
+ * @user_data: user data passed to @func.
+ * 
+ * Inserts @data into @queue using @func to determine the new
+ * position.
+ * 
+ * This function requires that the @queue is sorted before pushing on
+ * new elements.
+ * 
+ * This function is called while holding the @queue's lock.
+ * 
+ * For an example of @func see g_async_queue_sort(). 
+ *
+ * Since: 2.10
+ **/
+void
+g_async_queue_push_sorted_unlocked (GAsyncQueue      *queue,
+                                   gpointer          data,
+                                   GCompareDataFunc  func,
+                                   gpointer          user_data)
+{
+  SortData sd;
+  
+  g_return_if_fail (queue != NULL);
+
+  sd.func = func;
+  sd.user_data = user_data;
+
+  g_queue_insert_sorted (&queue->queue,
+                        data, 
+                        (GCompareDataFunc)g_async_queue_invert_compare, 
+                        &sd);
+  if (queue->waiting_threads > 0)
+    g_cond_signal (queue->cond);
+}
+
+static gpointer
+g_async_queue_pop_intern_unlocked (GAsyncQueue *queue, 
+                                  gboolean     try, 
+                                  GTimeVal    *end_time)
+{
+  gpointer retval;
+
+  if (!g_queue_peek_tail_link (&queue->queue))
+    {
+      if (try)
+       return NULL;
+      
+      if (!queue->cond)
+       queue->cond = g_cond_new ();
+
+      if (!end_time)
+        {
+          queue->waiting_threads++;
+         while (!g_queue_peek_tail_link (&queue->queue))
+            g_cond_wait (queue->cond, queue->mutex);
+          queue->waiting_threads--;
+        }
+      else
+        {
+          queue->waiting_threads++;
+          while (!g_queue_peek_tail_link (&queue->queue))
+            if (!g_cond_timed_wait (queue->cond, queue->mutex, end_time))
+              break;
+          queue->waiting_threads--;
+          if (!g_queue_peek_tail_link (&queue->queue))
+           return NULL;
+        }
+    }
+
+  retval = g_queue_pop_tail (&queue->queue);
+
+  g_assert (retval);
+
+  return retval;
+}
+
+/**
+ * g_async_queue_pop:
+ * @queue: a #GAsyncQueue.
+ * 
+ * Pops data from the @queue. This function blocks until data become
+ * available.
+ *
+ * Return value: data from the queue.
+ **/
+gpointer
+g_async_queue_pop (GAsyncQueue* queue)
+{
+  gpointer retval;
+
+  g_return_val_if_fail (queue, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+  g_mutex_lock (queue->mutex);
+  retval = g_async_queue_pop_intern_unlocked (queue, FALSE, NULL);
+  g_mutex_unlock (queue->mutex);
+
+  return retval;
+}
+
+/**
+ * g_async_queue_pop_unlocked:
+ * @queue: a #GAsyncQueue.
+ * 
+ * Pops data from the @queue. This function blocks until data become
+ * available. This function must be called while holding the @queue's
+ * lock.
+ *
+ * Return value: data from the queue.
+ **/
+gpointer
+g_async_queue_pop_unlocked (GAsyncQueue* queue)
+{
+  g_return_val_if_fail (queue, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+  return g_async_queue_pop_intern_unlocked (queue, FALSE, NULL);
+}
+
+/**
+ * g_async_queue_try_pop:
+ * @queue: a #GAsyncQueue.
+ * 
+ * Tries to pop data from the @queue. If no data is available, %NULL is
+ * returned.
+ *
+ * Return value: data from the queue or %NULL, when no data is
+ * available immediately.
+ **/
+gpointer
+g_async_queue_try_pop (GAsyncQueue* queue)
+{
+  gpointer retval;
+
+  g_return_val_if_fail (queue, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+  g_mutex_lock (queue->mutex);
+  retval = g_async_queue_pop_intern_unlocked (queue, TRUE, NULL);
+  g_mutex_unlock (queue->mutex);
+
+  return retval;
+}
+
+/**
+ * g_async_queue_try_pop_unlocked:
+ * @queue: a #GAsyncQueue.
+ * 
+ * Tries to pop data from the @queue. If no data is available, %NULL is
+ * returned. This function must be called while holding the @queue's
+ * lock.
+ *
+ * Return value: data from the queue or %NULL, when no data is
+ * available immediately.
+ **/
+gpointer
+g_async_queue_try_pop_unlocked (GAsyncQueue* queue)
+{
+  g_return_val_if_fail (queue, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+  return g_async_queue_pop_intern_unlocked (queue, TRUE, NULL);
+}
+
+/**
+ * g_async_queue_timed_pop:
+ * @queue: a #GAsyncQueue.
+ * @end_time: a #GTimeVal, determining the final time.
+ *
+ * Pops data from the @queue. If no data is received before @end_time,
+ * %NULL is returned.
+ *
+ * To easily calculate @end_time a combination of g_get_current_time()
+ * and g_time_val_add() can be used.
+ *
+ * Return value: data from the queue or %NULL, when no data is
+ * received before @end_time.
+ **/
+gpointer
+g_async_queue_timed_pop (GAsyncQueue* queue, GTimeVal *end_time)
+{
+  gpointer retval;
+
+  g_return_val_if_fail (queue, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+  g_mutex_lock (queue->mutex);
+  retval = g_async_queue_pop_intern_unlocked (queue, FALSE, end_time);
+  g_mutex_unlock (queue->mutex);
+
+  return retval;  
+}
+
+/**
+ * g_async_queue_timed_pop_unlocked:
+ * @queue: a #GAsyncQueue.
+ * @end_time: a #GTimeVal, determining the final time.
+ *
+ * Pops data from the @queue. If no data is received before @end_time,
+ * %NULL is returned. This function must be called while holding the
+ * @queue's lock.
+ *
+ * To easily calculate @end_time a combination of g_get_current_time()
+ * and g_time_val_add() can be used.
+ *
+ * Return value: data from the queue or %NULL, when no data is
+ * received before @end_time.
+ **/
+gpointer
+g_async_queue_timed_pop_unlocked (GAsyncQueue* queue, GTimeVal *end_time)
+{
+  g_return_val_if_fail (queue, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+  return g_async_queue_pop_intern_unlocked (queue, FALSE, end_time);
+}
+
+/**
+ * g_async_queue_length:
+ * @queue: a #GAsyncQueue.
+ * 
+ * Returns the length of the queue, negative values mean waiting
+ * threads, positive values mean available entries in the
+ * @queue. Actually this function returns the number of data items in
+ * the queue minus the number of waiting threads. Thus a return value
+ * of 0 could mean 'n' entries in the queue and 'n' thread waiting.
+ * That can happen due to locking of the queue or due to
+ * scheduling.  
+ *
+ * Return value: the length of the @queue.
+ **/
+gint
+g_async_queue_length (GAsyncQueue* queue)
+{
+  gint retval;
+
+  g_return_val_if_fail (queue, 0);
+  g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, 0);
+
+  g_mutex_lock (queue->mutex);
+  retval = queue->queue.length - queue->waiting_threads;
+  g_mutex_unlock (queue->mutex);
+
+  return retval;
+}
+
+/**
+ * g_async_queue_length_unlocked:
+ * @queue: a #GAsyncQueue.
+ * 
+ * Returns the length of the queue, negative values mean waiting
+ * threads, positive values mean available entries in the
+ * @queue. Actually this function returns the number of data items in
+ * the queue minus the number of waiting threads. Thus a return value
+ * of 0 could mean 'n' entries in the queue and 'n' thread waiting.
+ * That can happen due to locking of the queue or due to
+ * scheduling. This function must be called while holding the @queue's
+ * lock.
+ *
+ * Return value: the length of the @queue.
+ **/
+gint
+g_async_queue_length_unlocked (GAsyncQueue* queue)
+{
+  g_return_val_if_fail (queue, 0);
+  g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, 0);
+
+  return queue->queue.length - queue->waiting_threads;
+}
+
+/**
+ * g_async_queue_sort:
+ * @queue: a #GAsyncQueue
+ * @func: the #GCompareDataFunc is used to sort @queue. This
+ *     function is passed two elements of the @queue. The function
+ *     should return 0 if they are equal, a negative value if the
+ *     first element should be higher in the @queue or a positive
+ *     value if the first element should be lower in the @queue than
+ *     the second element. 
+ * @user_data: user data passed to @func
+ *
+ * Sorts @queue using @func. 
+ *
+ * This function will lock @queue before it sorts the queue and unlock
+ * it when it is finished.
+ *
+ * If you were sorting a list of priority numbers to make sure the
+ * lowest priority would be at the top of the queue, you could use:
+ * |[
+ *  gint32 id1;
+ *  gint32 id2;
+ *   
+ *  id1 = GPOINTER_TO_INT (element1);
+ *  id2 = GPOINTER_TO_INT (element2);
+ *   
+ *  return (id1 > id2 ? +1 : id1 == id2 ? 0 : -1);
+ * ]|
+ *
+ * Since: 2.10
+ **/
+void
+g_async_queue_sort (GAsyncQueue      *queue,
+                   GCompareDataFunc  func,
+                   gpointer          user_data)
+{
+  g_return_if_fail (queue != NULL);
+  g_return_if_fail (func != NULL);
+
+  g_mutex_lock (queue->mutex);
+  g_async_queue_sort_unlocked (queue, func, user_data);
+  g_mutex_unlock (queue->mutex);
+}
+
+/**
+ * g_async_queue_sort_unlocked:
+ * @queue: a #GAsyncQueue
+ * @func: the #GCompareDataFunc is used to sort @queue. This
+ *     function is passed two elements of the @queue. The function
+ *     should return 0 if they are equal, a negative value if the
+ *     first element should be higher in the @queue or a positive
+ *     value if the first element should be lower in the @queue than
+ *     the second element. 
+ * @user_data: user data passed to @func
+ *
+ * Sorts @queue using @func. 
+ *
+ * This function is called while holding the @queue's lock.
+ * 
+ * Since: 2.10
+ **/
+void
+g_async_queue_sort_unlocked (GAsyncQueue      *queue,
+                            GCompareDataFunc  func,
+                            gpointer          user_data)
+{
+  SortData sd;
+
+  g_return_if_fail (queue != NULL);
+  g_return_if_fail (func != NULL);
+
+  sd.func = func;
+  sd.user_data = user_data;
+
+  g_queue_sort (&queue->queue,
+               (GCompareDataFunc)g_async_queue_invert_compare, 
+               &sd);
+}
+
+/*
+ * Private API
+ */
+
+GMutex*
+_g_async_queue_get_mutex (GAsyncQueue* queue)
+{
+  g_return_val_if_fail (queue, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&queue->ref_count) > 0, NULL);
+
+  return queue->mutex;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gasyncqueue.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gasyncqueue.h
new file mode 100644 (file)
index 0000000..9da43e3
--- /dev/null
@@ -0,0 +1,120 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_ASYNCQUEUE_H__
+#define __G_ASYNCQUEUE_H__
+
+#include <glib/gthread.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GAsyncQueue GAsyncQueue;
+
+/* Asyncronous Queues, can be used to communicate between threads */
+
+/* Get a new GAsyncQueue with the ref_count 1 */
+GAsyncQueue*  g_async_queue_new                 (void);
+
+GAsyncQueue*  g_async_queue_new_full            (GDestroyNotify item_free_func);
+
+/* Lock and unlock a GAsyncQueue. All functions lock the queue for
+ * themselves, but in certain cirumstances you want to hold the lock longer,
+ * thus you lock the queue, call the *_unlocked functions and unlock it again.
+ */
+void         g_async_queue_lock                 (GAsyncQueue      *queue);
+void         g_async_queue_unlock               (GAsyncQueue      *queue);
+
+/* Ref and unref the GAsyncQueue. */
+GAsyncQueue* g_async_queue_ref                  (GAsyncQueue      *queue);
+void         g_async_queue_unref                (GAsyncQueue      *queue);
+
+#ifndef G_DISABLE_DEPRECATED
+/* You don't have to hold the lock for calling *_ref and *_unref anymore. */
+void         g_async_queue_ref_unlocked         (GAsyncQueue      *queue);
+void         g_async_queue_unref_and_unlock     (GAsyncQueue      *queue);
+#endif /* !G_DISABLE_DEPRECATED */
+
+/* Push data into the async queue. Must not be NULL. */
+void         g_async_queue_push                 (GAsyncQueue      *queue,
+                                                gpointer          data);
+void         g_async_queue_push_unlocked        (GAsyncQueue      *queue,
+                                                gpointer          data);
+
+void         g_async_queue_push_sorted          (GAsyncQueue      *queue,
+                                                gpointer          data,
+                                                GCompareDataFunc  func,
+                                                gpointer          user_data);
+void         g_async_queue_push_sorted_unlocked (GAsyncQueue      *queue,
+                                                gpointer          data,
+                                                GCompareDataFunc  func,
+                                                gpointer          user_data);
+
+/* Pop data from the async queue. When no data is there, the thread is blocked
+ * until data arrives.
+ */
+gpointer     g_async_queue_pop                  (GAsyncQueue      *queue);
+gpointer     g_async_queue_pop_unlocked         (GAsyncQueue      *queue);
+
+/* Try to pop data. NULL is returned in case of empty queue. */
+gpointer     g_async_queue_try_pop              (GAsyncQueue      *queue);
+gpointer     g_async_queue_try_pop_unlocked     (GAsyncQueue      *queue);
+
+
+
+/* Wait for data until at maximum until end_time is reached. NULL is returned
+ * in case of empty queue. 
+ */
+gpointer     g_async_queue_timed_pop            (GAsyncQueue      *queue,
+                                                GTimeVal         *end_time);
+gpointer     g_async_queue_timed_pop_unlocked   (GAsyncQueue      *queue,
+                                                GTimeVal         *end_time);
+
+/* Return the length of the queue. Negative values mean that threads
+ * are waiting, positve values mean that there are entries in the
+ * queue. Actually this function returns the length of the queue minus
+ * the number of waiting threads, g_async_queue_length == 0 could also
+ * mean 'n' entries in the queue and 'n' thread waiting. Such can
+ * happen due to locking of the queue or due to scheduling. 
+ */
+gint         g_async_queue_length               (GAsyncQueue      *queue);
+gint         g_async_queue_length_unlocked      (GAsyncQueue      *queue);
+void         g_async_queue_sort                 (GAsyncQueue      *queue,
+                                                GCompareDataFunc  func,
+                                                gpointer          user_data);
+void         g_async_queue_sort_unlocked        (GAsyncQueue      *queue,
+                                                GCompareDataFunc  func,
+                                                gpointer          user_data);
+
+/* Private API */
+GMutex*      _g_async_queue_get_mutex           (GAsyncQueue      *queue);
+
+G_END_DECLS
+
+#endif /* __G_ASYNCQUEUE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gatomic-gcc.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gatomic-gcc.c
new file mode 100644 (file)
index 0000000..9f28cee
--- /dev/null
@@ -0,0 +1,88 @@
+/* GLIB - Library of useful routines for C programming
+ * gatomic-gcc.c: atomic operations using GCC builtins.
+ * Copyright (C) 2009 Hiroyuki Ikezoe
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gatomic.h"
+
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                              gint           val)
+{
+  return __sync_fetch_and_add (atomic, val);
+}
+
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                 gint val)
+{
+  __sync_fetch_and_add (atomic, val);
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                                  gint           oldval,
+                                  gint           newval)
+{
+  return __sync_bool_compare_and_swap (atomic, oldval, newval);
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+                                      gpointer           oldval,
+                                      gpointer           newval)
+{
+  return __sync_bool_compare_and_swap (atomic, oldval, newval);
+}
+
+void
+_g_atomic_thread_init (void)
+{
+}
+
+gint
+(g_atomic_int_get) (volatile gint G_GNUC_MAY_ALIAS *atomic)
+{
+  __sync_synchronize ();
+  return *atomic;
+}
+
+void
+(g_atomic_int_set) (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                   gint           newval)
+{
+  *atomic = newval;
+  __sync_synchronize ();
+}
+
+gpointer
+(g_atomic_pointer_get) (volatile gpointer G_GNUC_MAY_ALIAS *atomic)
+{
+  __sync_synchronize ();
+  return *atomic;
+}
+
+void
+(g_atomic_pointer_set) (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+                       gpointer           newval)
+{
+  *atomic = newval;
+  __sync_synchronize ();
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gatomic.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gatomic.c
new file mode 100644 (file)
index 0000000..b6944d3
--- /dev/null
@@ -0,0 +1,1186 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * g_atomic_*: atomic operations.
+ * Copyright (C) 2003 Sebastian Wilhelmi
+ * Copyright (C) 2007 Nokia Corporation
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#if defined (G_ATOMIC_ARM)
+#include <sched.h>
+#endif
+
+#include "gatomic.h"
+#include "gthreadprivate.h"
+
+/**
+ * SECTION:atomic_operations
+ * @title: Atomic Operations
+ * @short_description: basic atomic integer and pointer operations
+ * @see_also: #GMutex
+ *
+ * The following functions can be used to atomically access integers and
+ * pointers. They are implemented as inline assembler function on most
+ * platforms and use slower fall-backs otherwise. Using them can sometimes
+ * save you from using a performance-expensive #GMutex to protect the
+ * integer or pointer.
+ *
+ * The most important usage is reference counting. Using
+ * g_atomic_int_inc() and g_atomic_int_dec_and_test() makes reference
+ * counting a very fast operation.
+ *
+ * <note><para>You must not directly read integers or pointers concurrently
+ * accessed by multiple threads, but use the atomic accessor functions
+ * instead. That is, always use g_atomic_int_get() and g_atomic_pointer_get()
+ * for read outs. They provide the neccessary synchonization mechanisms
+ * like memory barriers to access memory locations concurrently.
+ * </para></note>
+ *
+ * <note><para>If you are using those functions for anything apart from
+ * simple reference counting, you should really be aware of the implications
+ * of doing that. There are literally thousands of ways to shoot yourself
+ * in the foot. So if in doubt, use a #GMutex. If you don't know, what
+ * memory barriers are, do not use anything but g_atomic_int_inc() and
+ * g_atomic_int_dec_and_test().
+ * </para></note>
+ *
+ * <note><para>It is not safe to set an integer or pointer just by assigning
+ * to it, when it is concurrently accessed by other threads with the following
+ * functions. Use g_atomic_int_compare_and_exchange() or
+ * g_atomic_pointer_compare_and_exchange() respectively.
+ * </para></note>
+ */
+
+#if defined (__GNUC__)
+# if defined (G_ATOMIC_I486)
+/* Adapted from CVS version 1.10 of glibc's sysdeps/i386/i486/bits/atomic.h 
+ */
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                              gint           val)
+{
+  gint result;
+
+  __asm__ __volatile__ ("lock; xaddl %0,%1"
+                        : "=r" (result), "=m" (*atomic) 
+                       : "0" (val), "m" (*atomic));
+  return result;
+}
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                 gint           val)
+{
+  __asm__ __volatile__ ("lock; addl %1,%0"
+                       : "=m" (*atomic) 
+                       : "ir" (val), "m" (*atomic));
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                                  gint           oldval, 
+                                  gint           newval)
+{
+  gint result;
+  __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+                       : "=a" (result), "=m" (*atomic)
+                       : "r" (newval), "m" (*atomic), "0" (oldval)); 
+
+  return result == oldval;
+}
+
+/* The same code as above, as on i386 gpointer is 32 bit as well.
+ * Duplicating the code here seems more natural than casting the
+ * arguments and calling the former function */
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic, 
+                                      gpointer           oldval, 
+                                      gpointer           newval)
+{
+  gpointer result;
+  __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+                       : "=a" (result), "=m" (*atomic)
+                       : "r" (newval), "m" (*atomic), "0" (oldval)); 
+
+  return result == oldval;
+}
+
+# elif defined (G_ATOMIC_SPARCV9)
+/* Adapted from CVS version 1.3 of glibc's sysdeps/sparc/sparc64/bits/atomic.h
+ */
+#  define ATOMIC_INT_CMP_XCHG(atomic, oldval, newval)                  \
+  ({                                                                   \
+     gint __result;                                                    \
+     __asm__ __volatile__ ("cas [%4], %2, %0"                          \
+                           : "=r" (__result), "=m" (*(atomic))         \
+                           : "r" (oldval), "m" (*(atomic)), "r" (atomic),\
+                           "0" (newval));                              \
+     __result == oldval;                                               \
+  })
+
+#  if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic, 
+                                      gpointer           oldval, 
+                                      gpointer           newval)
+{
+  gpointer result;
+  __asm__ __volatile__ ("cas [%4], %2, %0"
+                       : "=r" (result), "=m" (*atomic)
+                       : "r" (oldval), "m" (*atomic), "r" (atomic),
+                       "0" (newval));
+  return result == oldval;
+}
+#  elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic, 
+                                      gpointer           oldval, 
+                                      gpointer           newval)
+{
+  gpointer result;
+  gpointer *a = atomic;
+  __asm__ __volatile__ ("casx [%4], %2, %0"
+                       : "=r" (result), "=m" (*a)
+                       : "r" (oldval), "m" (*a), "r" (a),
+                       "0" (newval));
+  return result == oldval;
+}
+#  else /* What's that */
+#    error "Your system has an unsupported pointer size"
+#  endif /* GLIB_SIZEOF_VOID_P */
+#  define G_ATOMIC_MEMORY_BARRIER                                      \
+  __asm__ __volatile__ ("membar #LoadLoad | #LoadStore"                        \
+                        " | #StoreLoad | #StoreStore" : : : "memory")
+
+# elif defined (G_ATOMIC_ALPHA)
+/* Adapted from CVS version 1.3 of glibc's sysdeps/alpha/bits/atomic.h
+ */
+#  define ATOMIC_INT_CMP_XCHG(atomic, oldval, newval)                  \
+  ({                                                                   \
+     gint __result;                                                    \
+     gint __prev;                                                      \
+     __asm__ __volatile__ (                                            \
+        "       mb\n"                                                  \
+        "1:     ldl_l   %0,%2\n"                                       \
+        "       cmpeq   %0,%3,%1\n"                                    \
+        "       beq     %1,2f\n"                                       \
+        "       mov     %4,%1\n"                                       \
+        "       stl_c   %1,%2\n"                                       \
+        "       beq     %1,1b\n"                                       \
+        "       mb\n"                                                  \
+        "2:"                                                           \
+        : "=&r" (__prev),                                              \
+          "=&r" (__result)                                             \
+        : "m" (*(atomic)),                                             \
+          "Ir" (oldval),                                               \
+          "Ir" (newval)                                                        \
+        : "memory");                                                   \
+     __result != 0;                                                    \
+  })
+#  if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic, 
+                                      gpointer           oldval, 
+                                      gpointer           newval)
+{
+  gint result;
+  gpointer prev;
+  __asm__ __volatile__ (
+        "       mb\n"
+        "1:     ldl_l   %0,%2\n"
+        "       cmpeq   %0,%3,%1\n"
+        "       beq     %1,2f\n"
+        "       mov     %4,%1\n"
+        "       stl_c   %1,%2\n"
+        "       beq     %1,1b\n"
+        "       mb\n"
+        "2:"
+        : "=&r" (prev), 
+          "=&r" (result)
+        : "m" (*atomic),
+          "Ir" (oldval),
+          "Ir" (newval)
+        : "memory");
+  return result != 0;
+}
+#  elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic, 
+                                      gpointer           oldval, 
+                                      gpointer           newval)
+{
+  gint result;
+  gpointer prev;
+  __asm__ __volatile__ (
+        "       mb\n"
+        "1:     ldq_l   %0,%2\n"
+        "       cmpeq   %0,%3,%1\n"
+        "       beq     %1,2f\n"
+        "       mov     %4,%1\n"
+        "       stq_c   %1,%2\n"
+        "       beq     %1,1b\n"
+        "       mb\n"
+        "2:"
+        : "=&r" (prev), 
+          "=&r" (result)
+        : "m" (*atomic),
+          "Ir" (oldval),
+          "Ir" (newval)
+        : "memory");
+  return result != 0;
+}
+#  else /* What's that */
+#   error "Your system has an unsupported pointer size"
+#  endif /* GLIB_SIZEOF_VOID_P */
+#  define G_ATOMIC_MEMORY_BARRIER  __asm__ ("mb" : : : "memory")
+# elif defined (G_ATOMIC_X86_64)
+/* Adapted from CVS version 1.9 of glibc's sysdeps/x86_64/bits/atomic.h 
+ */
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                              gint           val)
+{
+  gint result;
+
+  __asm__ __volatile__ ("lock; xaddl %0,%1"
+                        : "=r" (result), "=m" (*atomic) 
+                       : "0" (val), "m" (*atomic));
+  return result;
+}
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                 gint           val)
+{
+  __asm__ __volatile__ ("lock; addl %1,%0"
+                       : "=m" (*atomic) 
+                       : "ir" (val), "m" (*atomic));
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                                  gint           oldval, 
+                                  gint           newval)
+{
+  gint result;
+  __asm__ __volatile__ ("lock; cmpxchgl %2, %1"
+                       : "=a" (result), "=m" (*atomic)
+                       : "r" (newval), "m" (*atomic), "0" (oldval)); 
+
+  return result == oldval;
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic, 
+                                      gpointer           oldval, 
+                                      gpointer           newval)
+{
+  gpointer result;
+  __asm__ __volatile__ ("lock; cmpxchgq %q2, %1"
+                       : "=a" (result), "=m" (*atomic)
+                       : "r" (newval), "m" (*atomic), "0" (oldval)); 
+
+  return result == oldval;
+}
+
+# elif defined (G_ATOMIC_POWERPC)
+/* Adapted from CVS version 1.16 of glibc's sysdeps/powerpc/bits/atomic.h 
+ * and CVS version 1.4 of glibc's sysdeps/powerpc/powerpc32/bits/atomic.h 
+ * and CVS version 1.7 of glibc's sysdeps/powerpc/powerpc64/bits/atomic.h 
+ */
+#   ifdef __OPTIMIZE__
+/* Non-optimizing compile bails on the following two asm statements
+ * for reasons unknown to the author */
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                              gint           val)
+{
+  gint result, temp;
+#if ASM_NUMERIC_LABELS
+  __asm__ __volatile__ ("1:       lwarx   %0,0,%3\n"
+                       "         add     %1,%0,%4\n"
+                       "         stwcx.  %1,0,%3\n"
+                       "         bne-    1b"
+                       : "=&b" (result), "=&r" (temp), "=m" (*atomic)
+                       : "b" (atomic), "r" (val), "m" (*atomic)
+                       : "cr0", "memory");
+#else
+  __asm__ __volatile__ (".Lieaa%=:       lwarx   %0,0,%3\n"
+                       "         add     %1,%0,%4\n"
+                       "         stwcx.  %1,0,%3\n"
+                       "         bne-    .Lieaa%="
+                       : "=&b" (result), "=&r" (temp), "=m" (*atomic)
+                       : "b" (atomic), "r" (val), "m" (*atomic)
+                       : "cr0", "memory");
+#endif
+  return result;
+}
+/* The same as above, to save a function call repeated here */
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                 gint           val)
+{
+  gint result, temp;  
+#if ASM_NUMERIC_LABELS
+  __asm__ __volatile__ ("1:       lwarx   %0,0,%3\n"
+                       "         add     %1,%0,%4\n"
+                       "         stwcx.  %1,0,%3\n"
+                       "         bne-    1b"
+                       : "=&b" (result), "=&r" (temp), "=m" (*atomic)
+                       : "b" (atomic), "r" (val), "m" (*atomic)
+                       : "cr0", "memory");
+#else
+  __asm__ __volatile__ (".Lia%=:       lwarx   %0,0,%3\n"
+                       "         add     %1,%0,%4\n"
+                       "         stwcx.  %1,0,%3\n"
+                       "         bne-    .Lia%="
+                       : "=&b" (result), "=&r" (temp), "=m" (*atomic)
+                       : "b" (atomic), "r" (val), "m" (*atomic)
+                       : "cr0", "memory");
+#endif
+}
+#   else /* !__OPTIMIZE__ */
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                              gint           val)
+{
+  gint result;
+  do
+    result = *atomic;
+  while (!g_atomic_int_compare_and_exchange (atomic, result, result + val));
+
+  return result;
+}
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                 gint           val)
+{
+  gint result;
+  do
+    result = *atomic;
+  while (!g_atomic_int_compare_and_exchange (atomic, result, result + val));
+}
+#   endif /* !__OPTIMIZE__ */
+
+#   if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                                  gint           oldval, 
+                                  gint           newval)
+{
+  gint result;
+#if ASM_NUMERIC_LABELS
+  __asm__ __volatile__ ("sync\n"
+                       "1: lwarx   %0,0,%1\n"
+                       "   subf.   %0,%2,%0\n"
+                       "   bne     2f\n"
+                       "   stwcx.  %3,0,%1\n"
+                       "   bne-    1b\n"
+                       "2: isync"
+                       : "=&r" (result)
+                       : "b" (atomic), "r" (oldval), "r" (newval)
+                       : "cr0", "memory"); 
+#else
+  __asm__ __volatile__ ("sync\n"
+                       ".L1icae%=: lwarx   %0,0,%1\n"
+                       "   subf.   %0,%2,%0\n"
+                       "   bne     .L2icae%=\n"
+                       "   stwcx.  %3,0,%1\n"
+                       "   bne-    .L1icae%=\n"
+                       ".L2icae%=: isync"
+                       : "=&r" (result)
+                       : "b" (atomic), "r" (oldval), "r" (newval)
+                       : "cr0", "memory"); 
+#endif
+  return result == 0;
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic, 
+                                      gpointer           oldval, 
+                                      gpointer           newval)
+{
+  gpointer result;
+#if ASM_NUMERIC_LABELS
+  __asm__ __volatile__ ("sync\n"
+                       "1: lwarx   %0,0,%1\n"
+                       "   subf.   %0,%2,%0\n"
+                       "   bne     2f\n"
+                       "   stwcx.  %3,0,%1\n"
+                       "   bne-    1b\n"
+                       "2: isync"
+                       : "=&r" (result)
+                       : "b" (atomic), "r" (oldval), "r" (newval)
+                       : "cr0", "memory"); 
+#else
+  __asm__ __volatile__ ("sync\n"
+                       ".L1pcae%=: lwarx   %0,0,%1\n"
+                       "   subf.   %0,%2,%0\n"
+                       "   bne     .L2pcae%=\n"
+                       "   stwcx.  %3,0,%1\n"
+                       "   bne-    .L1pcae%=\n"
+                       ".L2pcae%=: isync"
+                       : "=&r" (result)
+                       : "b" (atomic), "r" (oldval), "r" (newval)
+                       : "cr0", "memory"); 
+#endif
+  return result == 0;
+}
+#   elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                                  gint           oldval, 
+                                  gint           newval)
+{
+  gpointer result;
+#if ASM_NUMERIC_LABELS
+  __asm__ __volatile__ ("sync\n"
+                       "1: lwarx   %0,0,%1\n"
+                       "   extsw   %0,%0\n"
+                       "   subf.   %0,%2,%0\n"
+                       "   bne     2f\n"
+                       "   stwcx.  %3,0,%1\n"
+                       "   bne-    1b\n"
+                       "2: isync"
+                       : "=&r" (result)
+                       : "b" (atomic), "r" (oldval), "r" (newval)
+                       : "cr0", "memory"); 
+#else
+  __asm__ __volatile__ ("sync\n"
+                       ".L1icae%=: lwarx   %0,0,%1\n"
+                       "   extsw   %0,%0\n"
+                       "   subf.   %0,%2,%0\n"
+                       "   bne     .L2icae%=\n"
+                       "   stwcx.  %3,0,%1\n"
+                       "   bne-    .L1icae%=\n"
+                       ".L2icae%=: isync"
+                       : "=&r" (result)
+                       : "b" (atomic), "r" (oldval), "r" (newval)
+                       : "cr0", "memory"); 
+#endif
+  return result == 0;
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic, 
+                                      gpointer           oldval, 
+                                      gpointer           newval)
+{
+  gpointer result;
+#if ASM_NUMERIC_LABELS
+  __asm__ __volatile__ ("sync\n"
+                       "1: ldarx   %0,0,%1\n"
+                       "   subf.   %0,%2,%0\n"
+                       "   bne     2f\n"
+                       "   stdcx.  %3,0,%1\n"
+                       "   bne-    1b\n"
+                       "2: isync"
+                       : "=&r" (result)
+                       : "b" (atomic), "r" (oldval), "r" (newval)
+                       : "cr0", "memory"); 
+#else
+  __asm__ __volatile__ ("sync\n"
+                       ".L1pcae%=: ldarx   %0,0,%1\n"
+                       "   subf.   %0,%2,%0\n"
+                       "   bne     .L2pcae%=\n"
+                       "   stdcx.  %3,0,%1\n"
+                       "   bne-    .L1pcae%=\n"
+                       ".L2pcae%=: isync"
+                       : "=&r" (result)
+                       : "b" (atomic), "r" (oldval), "r" (newval)
+                       : "cr0", "memory"); 
+#endif
+  return result == 0;
+}
+#  else /* What's that */
+#   error "Your system has an unsupported pointer size"
+#  endif /* GLIB_SIZEOF_VOID_P */
+
+#  define G_ATOMIC_MEMORY_BARRIER __asm__ ("sync" : : : "memory")
+
+# elif defined (G_ATOMIC_IA64)
+/* Adapted from CVS version 1.8 of glibc's sysdeps/ia64/bits/atomic.h
+ */
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                              gint           val)
+{
+  return __sync_fetch_and_add (atomic, val);
+}
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                 gint val)
+{
+  __sync_fetch_and_add (atomic, val);
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                                  gint           oldval, 
+                                  gint           newval)
+{
+  return __sync_bool_compare_and_swap (atomic, oldval, newval);
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+                                      gpointer           oldval, 
+                                      gpointer           newval)
+{
+  return __sync_bool_compare_and_swap ((long *)atomic, 
+                                      (long)oldval, (long)newval);
+}
+
+#  define G_ATOMIC_MEMORY_BARRIER __sync_synchronize ()
+# elif defined (G_ATOMIC_S390)
+/* Adapted from glibc's sysdeps/s390/bits/atomic.h
+ */
+#  define ATOMIC_INT_CMP_XCHG(atomic, oldval, newval)                  \
+  ({                                                                   \
+     gint __result = oldval;                                   \
+     __asm__ __volatile__ ("cs %0, %2, %1"                             \
+                           : "+d" (__result), "=Q" (*(atomic))         \
+                           : "d" (newval), "m" (*(atomic)) : "cc" );   \
+     __result == oldval;                                               \
+  })
+
+#  if GLIB_SIZEOF_VOID_P == 4 /* 32-bit system */
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+                                      gpointer           oldval,
+                                      gpointer           newval)
+{
+  gpointer result = oldval;
+  __asm__ __volatile__ ("cs %0, %2, %1"
+                       : "+d" (result), "=Q" (*(atomic))
+                       : "d" (newval), "m" (*(atomic)) : "cc" );
+  return result == oldval;
+}
+#  elif GLIB_SIZEOF_VOID_P == 8 /* 64-bit system */
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+                                      gpointer           oldval,
+                                      gpointer           newval)
+{
+  gpointer result = oldval;
+  gpointer *a = atomic;
+  __asm__ __volatile__ ("csg %0, %2, %1"
+                       : "+d" (result), "=Q" (*a)
+                       : "d" ((long)(newval)), "m" (*a) : "cc" );
+  return result == oldval;
+}
+#  else /* What's that */
+#    error "Your system has an unsupported pointer size"
+#  endif /* GLIB_SIZEOF_VOID_P */
+# elif defined (G_ATOMIC_ARM)
+static volatile int atomic_spin = 0;
+
+static int atomic_spin_trylock (void)
+{
+  int result;
+
+  asm volatile (
+    "swp %0, %1, [%2]\n"
+    : "=&r,&r" (result)
+    : "r,0" (1), "r,r" (&atomic_spin)
+    : "memory");
+  if (result == 0)
+    return 0;
+  else
+    return -1;
+}
+
+static void atomic_spin_lock (void)
+{
+  while (atomic_spin_trylock())
+    sched_yield();
+}
+
+static void atomic_spin_unlock (void)
+{
+  atomic_spin = 0;
+}
+
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                              gint           val)
+{
+  gint result;
+  atomic_spin_lock();  
+  result = *atomic;
+  *atomic += val;
+  atomic_spin_unlock();
+
+  return result;
+}
+
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                 gint           val)
+{
+  atomic_spin_lock();
+  *atomic += val;
+  atomic_spin_unlock();
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                                  gint           oldval, 
+                                  gint           newval)
+{
+  gboolean result;
+
+  atomic_spin_lock();
+  if (*atomic == oldval)
+    {
+      result = TRUE;
+      *atomic = newval;
+    }
+  else
+    result = FALSE;
+  atomic_spin_unlock();
+
+  return result;
+}
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic, 
+                                      gpointer           oldval, 
+                                      gpointer           newval)
+{
+  gboolean result;
+  atomic_spin_lock();
+  if (*atomic == oldval)
+    {
+      result = TRUE;
+      *atomic = newval;
+    }
+  else
+    result = FALSE;
+  atomic_spin_unlock();
+
+  return result;
+}
+# elif defined (G_ATOMIC_CRIS) || defined (G_ATOMIC_CRISV32)
+#  ifdef G_ATOMIC_CRIS
+#   define CRIS_ATOMIC_INT_CMP_XCHG(atomic, oldval, newval)            \
+  ({                                                                   \
+     gboolean __result;                                                        \
+     __asm__ __volatile__ ("\n"                                                \
+                           "0:\tclearf\n\t"                            \
+                           "cmp.d [%[Atomic]], %[OldVal]\n\t"          \
+                           "bne 1f\n\t"                                        \
+                           "ax\n\t"                                    \
+                           "move.d %[NewVal], [%[Atomic]]\n\t"         \
+                           "bwf 0b\n"                                  \
+                           "1:\tseq %[Result]"                         \
+                           : [Result] "=&r" (__result),                        \
+                                      "=m" (*(atomic))                 \
+                           : [Atomic] "r" (atomic),                    \
+                             [OldVal] "r" (oldval),                    \
+                             [NewVal] "r" (newval),                    \
+                                      "g" (*(gpointer*) (atomic))      \
+                           : "memory");                                        \
+     __result;                                                         \
+  })
+#  else
+#   define CRIS_ATOMIC_INT_CMP_XCHG(atomic, oldval, newval)            \
+  ({                                                                   \
+     gboolean __result;                                                        \
+     __asm__ __volatile__ ("\n"                                                \
+                           "0:\tclearf p\n\t"                          \
+                           "cmp.d [%[Atomic]], %[OldVal]\n\t"          \
+                           "bne 1f\n\t"                                        \
+                           "ax\n\t"                                    \
+                           "move.d %[NewVal], [%[Atomic]]\n\t"         \
+                           "bcs 0b\n"                                  \
+                           "1:\tseq %[Result]"                         \
+                           : [Result] "=&r" (__result),                        \
+                                      "=m" (*(atomic))                 \
+                           : [Atomic] "r" (atomic),                    \
+                             [OldVal] "r" (oldval),                    \
+                             [NewVal] "r" (newval),                    \
+                                      "g" (*(gpointer*) (atomic))      \
+                           : "memory");                                        \
+     __result;                                                         \
+  })
+#  endif
+
+#define CRIS_CACHELINE_SIZE 32
+#define CRIS_ATOMIC_BREAKS_CACHELINE(atomic) \
+  (((gulong)(atomic) & (CRIS_CACHELINE_SIZE - 1)) > (CRIS_CACHELINE_SIZE - sizeof (atomic)))
+
+gint     __g_atomic_int_exchange_and_add         (volatile gint   G_GNUC_MAY_ALIAS *atomic,
+                                                 gint             val);
+void     __g_atomic_int_add                      (volatile gint   G_GNUC_MAY_ALIAS *atomic,
+                                                 gint             val);
+gboolean __g_atomic_int_compare_and_exchange     (volatile gint   G_GNUC_MAY_ALIAS *atomic,
+                                                 gint             oldval,
+                                                 gint             newval);
+gboolean __g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+                                                 gpointer         oldval,
+                                                 gpointer         newval);
+
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+                                      gpointer           oldval,
+                                      gpointer           newval)
+{
+  if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
+    return __g_atomic_pointer_compare_and_exchange (atomic, oldval, newval);
+
+  return CRIS_ATOMIC_INT_CMP_XCHG (atomic, oldval, newval);
+}
+
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                                  gint           oldval,
+                                  gint           newval)
+{
+  if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
+    return __g_atomic_int_compare_and_exchange (atomic, oldval, newval);
+
+  return CRIS_ATOMIC_INT_CMP_XCHG (atomic, oldval, newval);
+}
+
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                              gint           val)
+{
+  gint result;
+
+  if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
+    return __g_atomic_int_exchange_and_add (atomic, val);
+
+  do
+    result = *atomic;
+  while (!CRIS_ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
+
+  return result;
+}
+
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                 gint           val)
+{
+  gint result;
+
+  if (G_UNLIKELY (CRIS_ATOMIC_BREAKS_CACHELINE (atomic)))
+    return __g_atomic_int_add (atomic, val);
+
+  do
+    result = *atomic;
+  while (!CRIS_ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
+}
+
+/* We need the atomic mutex for atomic operations where the atomic variable
+ * breaks the 32 byte cache line since the CRIS architecture does not support
+ * atomic operations on such variables. Fortunately this should be rare.
+ */
+#  define DEFINE_WITH_MUTEXES
+#  define g_atomic_int_exchange_and_add __g_atomic_int_exchange_and_add
+#  define g_atomic_int_add __g_atomic_int_add
+#  define g_atomic_int_compare_and_exchange __g_atomic_int_compare_and_exchange
+#  define g_atomic_pointer_compare_and_exchange __g_atomic_pointer_compare_and_exchange
+
+# else /* !G_ATOMIC_* */
+#  define DEFINE_WITH_MUTEXES
+# endif /* G_ATOMIC_* */
+#else /* !__GNUC__ */
+# ifdef G_PLATFORM_WIN32
+#  define DEFINE_WITH_WIN32_INTERLOCKED
+# else
+#  define DEFINE_WITH_MUTEXES
+# endif
+#endif /* __GNUC__ */
+
+#ifdef DEFINE_WITH_WIN32_INTERLOCKED
+# include <windows.h>
+/* Following indicates that InterlockedCompareExchangePointer is
+ * declared in winbase.h (included by windows.h) and needs to be
+ * commented out if not true. It is defined iff WINVER > 0x0400,
+ * which is usually correct but can be wrong if WINVER is set before
+ * windows.h is included.
+ */
+# if WINVER > 0x0400
+#  define HAVE_INTERLOCKED_COMPARE_EXCHANGE_POINTER
+# endif
+
+gint32
+g_atomic_int_exchange_and_add (volatile gint32 G_GNUC_MAY_ALIAS *atomic,
+                              gint32           val)
+{
+  return InterlockedExchangeAdd (atomic, val);
+}
+
+void     
+g_atomic_int_add (volatile gint32 G_GNUC_MAY_ALIAS *atomic, 
+                 gint32           val)
+{
+  InterlockedExchangeAdd (atomic, val);
+}
+
+gboolean 
+g_atomic_int_compare_and_exchange (volatile gint32 G_GNUC_MAY_ALIAS *atomic,
+                                  gint32           oldval,
+                                  gint32           newval)
+{
+#ifndef HAVE_INTERLOCKED_COMPARE_EXCHANGE_POINTER
+  return (guint32) InterlockedCompareExchange ((PVOID*)atomic, 
+                                               (PVOID)newval, 
+                                               (PVOID)oldval) == oldval;
+#else
+  return InterlockedCompareExchange (atomic, 
+                                     newval, 
+                                     oldval) == oldval;
+#endif
+}
+
+gboolean 
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+                                      gpointer           oldval,
+                                      gpointer           newval)
+{
+# ifdef HAVE_INTERLOCKED_COMPARE_EXCHANGE_POINTER
+  return InterlockedCompareExchangePointer (atomic, newval, oldval) == oldval;
+# else
+#  if GLIB_SIZEOF_VOID_P != 4 /* no 32-bit system */
+#   error "InterlockedCompareExchangePointer needed"
+#  else
+   return InterlockedCompareExchange (atomic, newval, oldval) == oldval;
+#  endif
+# endif
+}
+#endif /* DEFINE_WITH_WIN32_INTERLOCKED */
+
+#ifdef DEFINE_WITH_MUTEXES
+#include "gthread.h"
+/* We have to use the slow, but safe locking method */
+static GMutex *g_atomic_mutex; 
+
+/**
+ * g_atomic_int_exchange_and_add:
+ * @atomic: a pointer to an integer
+ * @val: the value to add to *@atomic
+ *
+ * Atomically adds @val to the integer pointed to by @atomic.
+ * It returns the value of *@atomic just before the addition
+ * took place. Also acts as a memory barrier.
+ *
+ * Returns: the value of *@atomic before the addition.
+ *
+ * Since: 2.4
+ */
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                              gint           val)
+{
+  gint result;
+    
+  g_mutex_lock (g_atomic_mutex);
+  result = *atomic;
+  *atomic += val;
+  g_mutex_unlock (g_atomic_mutex);
+
+  return result;
+}
+
+/**
+ * g_atomic_int_add:
+ * @atomic: a pointer to an integer
+ * @val: the value to add to *@atomic
+ *
+ * Atomically adds @val to the integer pointed to by @atomic.
+ * Also acts as a memory barrier.
+ *
+ * Since: 2.4
+ */
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                 gint           val)
+{
+  g_mutex_lock (g_atomic_mutex);
+  *atomic += val;
+  g_mutex_unlock (g_atomic_mutex);
+}
+
+/**
+ * g_atomic_int_compare_and_exchange:
+ * @atomic: a pointer to an integer
+ * @oldval: the assumed old value of *@atomic
+ * @newval: the new value of *@atomic
+ *
+ * Compares @oldval with the integer pointed to by @atomic and
+ * if they are equal, atomically exchanges *@atomic with @newval.
+ * Also acts as a memory barrier.
+ *
+ * Returns: %TRUE, if *@atomic was equal @oldval. %FALSE otherwise.
+ *
+ * Since: 2.4
+ */
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic, 
+                                  gint           oldval, 
+                                  gint           newval)
+{
+  gboolean result;
+    
+  g_mutex_lock (g_atomic_mutex);
+  if (*atomic == oldval)
+    {
+      result = TRUE;
+      *atomic = newval;
+    }
+  else
+    result = FALSE;
+  g_mutex_unlock (g_atomic_mutex);
+
+  return result;
+}
+
+/**
+ * g_atomic_pointer_compare_and_exchange:
+ * @atomic: a pointer to a #gpointer
+ * @oldval: the assumed old value of *@atomic
+ * @newval: the new value of *@atomic
+ *
+ * Compares @oldval with the pointer pointed to by @atomic and
+ * if they are equal, atomically exchanges *@atomic with @newval.
+ * Also acts as a memory barrier.
+ *
+ * Returns: %TRUE, if *@atomic was equal @oldval. %FALSE otherwise.
+ *
+ * Since: 2.4
+ */
+gboolean
+g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic, 
+                                      gpointer           oldval, 
+                                      gpointer           newval)
+{
+  gboolean result;
+    
+  g_mutex_lock (g_atomic_mutex);
+  if (*atomic == oldval)
+    {
+      result = TRUE;
+      *atomic = newval;
+    }
+  else
+    result = FALSE;
+  g_mutex_unlock (g_atomic_mutex);
+
+  return result;
+}
+
+#ifdef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED
+
+/**
+ * g_atomic_int_get:
+ * @atomic: a pointer to an integer
+ *
+ * Reads the value of the integer pointed to by @atomic.
+ * Also acts as a memory barrier.
+ *
+ * Returns: the value of *@atomic
+ *
+ * Since: 2.4
+ */
+gint
+(g_atomic_int_get) (volatile gint G_GNUC_MAY_ALIAS *atomic)
+{
+  gint result;
+
+  g_mutex_lock (g_atomic_mutex);
+  result = *atomic;
+  g_mutex_unlock (g_atomic_mutex);
+
+  return result;
+}
+
+/**
+ * g_atomic_int_set:
+ * @atomic: a pointer to an integer
+ * @newval: the new value
+ *
+ * Sets the value of the integer pointed to by @atomic.
+ * Also acts as a memory barrier.
+ *
+ * Since: 2.10
+ */
+void
+(g_atomic_int_set) (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                  gint           newval)
+{
+  g_mutex_lock (g_atomic_mutex);
+  *atomic = newval;
+  g_mutex_unlock (g_atomic_mutex);
+}
+
+/**
+ * g_atomic_pointer_get:
+ * @atomic: a pointer to a #gpointer.
+ *
+ * Reads the value of the pointer pointed to by @atomic.
+ * Also acts as a memory barrier.
+ *
+ * Returns: the value to add to *@atomic.
+ *
+ * Since: 2.4
+ */
+gpointer
+(g_atomic_pointer_get) (volatile gpointer G_GNUC_MAY_ALIAS *atomic)
+{
+  gpointer result;
+
+  g_mutex_lock (g_atomic_mutex);
+  result = *atomic;
+  g_mutex_unlock (g_atomic_mutex);
+
+  return result;
+}
+
+/**
+ * g_atomic_pointer_set:
+ * @atomic: a pointer to a #gpointer
+ * @newval: the new value
+ *
+ * Sets the value of the pointer pointed to by @atomic.
+ * Also acts as a memory barrier.
+ *
+ * Since: 2.10
+ */
+void
+(g_atomic_pointer_set) (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+                      gpointer           newval)
+{
+  g_mutex_lock (g_atomic_mutex);
+  *atomic = newval;
+  g_mutex_unlock (g_atomic_mutex);
+}
+#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */   
+#elif defined (G_ATOMIC_OP_MEMORY_BARRIER_NEEDED)
+gint
+(g_atomic_int_get) (volatile gint G_GNUC_MAY_ALIAS *atomic)
+{
+  G_ATOMIC_MEMORY_BARRIER;
+  return *atomic;
+}
+
+void
+(g_atomic_int_set) (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                  gint           newval)
+{
+  *atomic = newval;
+  G_ATOMIC_MEMORY_BARRIER; 
+}
+
+gpointer
+(g_atomic_pointer_get) (volatile gpointer G_GNUC_MAY_ALIAS *atomic)
+{
+  G_ATOMIC_MEMORY_BARRIER;
+  return *atomic;
+}   
+
+void
+(g_atomic_pointer_set) (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+                      gpointer           newval)
+{
+  *atomic = newval;
+  G_ATOMIC_MEMORY_BARRIER; 
+}
+#endif /* DEFINE_WITH_MUTEXES || G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
+
+#ifdef ATOMIC_INT_CMP_XCHG
+gboolean
+g_atomic_int_compare_and_exchange (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                                  gint           oldval,
+                                  gint           newval)
+{
+  return ATOMIC_INT_CMP_XCHG (atomic, oldval, newval);
+}
+
+gint
+g_atomic_int_exchange_and_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                              gint           val)
+{
+  gint result;
+  do
+    result = *atomic;
+  while (!ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
+
+  return result;
+}
+void
+g_atomic_int_add (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                 gint           val)
+{
+  gint result;
+  do
+    result = *atomic;
+  while (!ATOMIC_INT_CMP_XCHG (atomic, result, result + val));
+}
+#endif /* ATOMIC_INT_CMP_XCHG */
+
+void 
+_g_atomic_thread_init (void)
+{
+#ifdef DEFINE_WITH_MUTEXES
+  g_atomic_mutex = g_mutex_new ();
+#endif /* DEFINE_WITH_MUTEXES */
+}
+
+#ifndef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED
+gint
+(g_atomic_int_get) (volatile gint G_GNUC_MAY_ALIAS *atomic)
+{
+  return g_atomic_int_get (atomic);
+}
+
+void
+(g_atomic_int_set) (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                   gint           newval)
+{
+  g_atomic_int_set (atomic, newval);
+}
+
+gpointer
+(g_atomic_pointer_get) (volatile gpointer G_GNUC_MAY_ALIAS *atomic)
+{
+  return g_atomic_pointer_get (atomic);
+}
+
+void
+(g_atomic_pointer_set) (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+                       gpointer           newval)
+{
+  g_atomic_pointer_set (atomic, newval);
+}
+#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gatomic.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gatomic.h
new file mode 100644 (file)
index 0000000..ddd39b8
--- /dev/null
@@ -0,0 +1,105 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * g_atomic_*: atomic operations.
+ * Copyright (C) 2003 Sebastian Wilhelmi
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_ATOMIC_H__
+#define __G_ATOMIC_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+gint     g_atomic_int_exchange_and_add         (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                                               gint               val);
+void     g_atomic_int_add                      (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                                               gint               val);
+gboolean g_atomic_int_compare_and_exchange     (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                                               gint               oldval,
+                                               gint               newval);
+gboolean g_atomic_pointer_compare_and_exchange (volatile gpointer G_GNUC_MAY_ALIAS *atomic, 
+                                               gpointer           oldval, 
+                                               gpointer           newval);
+
+gint     g_atomic_int_get                      (volatile gint G_GNUC_MAY_ALIAS *atomic);
+void     g_atomic_int_set                      (volatile gint G_GNUC_MAY_ALIAS *atomic,
+                                               gint               newval);
+gpointer g_atomic_pointer_get                  (volatile gpointer G_GNUC_MAY_ALIAS *atomic);
+void     g_atomic_pointer_set                  (volatile gpointer G_GNUC_MAY_ALIAS *atomic,
+                                               gpointer           newval);
+
+#ifndef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED
+# define g_atomic_int_get(atomic)              ((gint)*(atomic))
+# define g_atomic_int_set(atomic, newval)      ((void) (*(atomic) = (newval)))
+# define g_atomic_pointer_get(atomic)          ((gpointer)*(atomic))
+# define g_atomic_pointer_set(atomic, newval)  ((void) (*(atomic) = (newval)))
+#else
+# define g_atomic_int_get(atomic) \
+ ((void) sizeof (gchar [sizeof (*(atomic)) == sizeof (gint) ? 1 : -1]), \
+  (g_atomic_int_get) ((volatile gint G_GNUC_MAY_ALIAS *) (volatile void *) (atomic)))
+# define g_atomic_int_set(atomic, newval) \
+ ((void) sizeof (gchar [sizeof (*(atomic)) == sizeof (gint) ? 1 : -1]), \
+  (g_atomic_int_set) ((volatile gint G_GNUC_MAY_ALIAS *) (volatile void *) (atomic), (newval)))
+# define g_atomic_pointer_get(atomic) \
+ ((void) sizeof (gchar [sizeof (*(atomic)) == sizeof (gpointer) ? 1 : -1]), \
+  (g_atomic_pointer_get) ((volatile gpointer G_GNUC_MAY_ALIAS *) (volatile void *) (atomic)))
+# define g_atomic_pointer_set(atomic, newval) \
+ ((void) sizeof (gchar [sizeof (*(atomic)) == sizeof (gpointer) ? 1 : -1]), \
+  (g_atomic_pointer_set) ((volatile gpointer G_GNUC_MAY_ALIAS *) (volatile void *) (atomic), (newval)))
+#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
+
+/**
+ * g_atomic_int_inc:
+ * @atomic: a pointer to an integer.
+ *
+ * Atomically increments the integer pointed to by @atomic by 1.
+ *
+ * Since: 2.4
+ */
+#define g_atomic_int_inc(atomic) (g_atomic_int_add ((atomic), 1))
+
+/**
+ * g_atomic_int_dec_and_test:
+ * @atomic: a pointer to an integer
+ *
+ * Atomically decrements the integer pointed to by @atomic by 1.
+ *
+ * Returns: %TRUE if the integer pointed to by @atomic is 0
+ *     after decrementing it
+ *
+ * Since: 2.4
+ */
+#define g_atomic_int_dec_and_test(atomic) \
+  (g_atomic_int_exchange_and_add ((atomic), -1) == 1)
+
+G_END_DECLS
+
+#endif /* __G_ATOMIC_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gbacktrace.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gbacktrace.c
new file mode 100644 (file)
index 0000000..ae16ef8
--- /dev/null
@@ -0,0 +1,310 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe ; except for g_on_error_stack_trace, but who wants thread safety
+ * then
+ */
+
+#include "config.h"
+#include "glibconfig.h"
+
+#include <signal.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif
+#ifdef HAVE_SYS_TIMES_H
+#include <sys/times.h>
+#endif
+#include <sys/types.h>
+#ifdef HAVE_SYS_WAIT_H
+#include <sys/wait.h>
+#endif
+
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H */
+
+#include <string.h> /* for bzero on BSD systems */
+
+#ifdef G_OS_WIN32
+#  define STRICT                /* Strict typing, please */
+#  define _WIN32_WINDOWS 0x0401 /* to get IsDebuggerPresent */
+#  include <windows.h>
+#  undef STRICT
+#endif
+
+#include "gbacktrace.h"
+
+#include "gtypes.h"
+#include "gmain.h"
+#include "gprintfint.h"
+
+
+#ifndef NO_FD_SET
+#  define SELECT_MASK fd_set
+#else
+#  if defined(_IBMR2)
+#    define SELECT_MASK void
+#  else
+#    define SELECT_MASK int
+#  endif
+#endif
+
+
+#ifndef G_OS_WIN32
+static void stack_trace (char **args);
+#endif
+
+extern volatile gboolean glib_on_error_halt;
+volatile gboolean glib_on_error_halt = TRUE;
+
+void
+g_on_error_query (const gchar *prg_name)
+{
+#ifndef G_OS_WIN32
+  static const gchar * const query1 = "[E]xit, [H]alt";
+  static const gchar * const query2 = ", show [S]tack trace";
+  static const gchar * const query3 = " or [P]roceed";
+  gchar buf[16];
+
+  if (!prg_name)
+    prg_name = g_get_prgname ();
+
+ retry:
+
+  if (prg_name)
+    _g_fprintf (stdout,
+                "%s (pid:%u): %s%s%s: ",
+                prg_name,
+                (guint) getpid (),
+                query1,
+                query2,
+                query3);
+  else
+    _g_fprintf (stdout,
+                "(process:%u): %s%s: ",
+                (guint) getpid (),
+                query1,
+                query3);
+  fflush (stdout);
+
+  if (isatty(0) && isatty(1))
+    fgets (buf, 8, stdin);
+  else
+    strcpy (buf, "E\n");
+
+  if ((buf[0] == 'E' || buf[0] == 'e')
+      && buf[1] == '\n')
+    _exit (0);
+  else if ((buf[0] == 'P' || buf[0] == 'p')
+           && buf[1] == '\n')
+    return;
+  else if (prg_name
+           && (buf[0] == 'S' || buf[0] == 's')
+           && buf[1] == '\n')
+    {
+      g_on_error_stack_trace (prg_name);
+      goto retry;
+    }
+  else if ((buf[0] == 'H' || buf[0] == 'h')
+           && buf[1] == '\n')
+    {
+      while (glib_on_error_halt)
+        ;
+      glib_on_error_halt = TRUE;
+      return;
+    }
+  else
+    goto retry;
+#else
+  if (!prg_name)
+    prg_name = g_get_prgname ();
+
+  MessageBox (NULL, "g_on_error_query called, program terminating",
+              (prg_name && *prg_name) ? prg_name : NULL,
+              MB_OK|MB_ICONERROR);
+  _exit(0);
+#endif
+}
+
+void
+g_on_error_stack_trace (const gchar *prg_name)
+{
+#if defined(G_OS_UNIX) || defined(G_OS_BEOS)
+  pid_t pid;
+  gchar buf[16];
+  gchar *args[4] = { "gdb", NULL, NULL, NULL };
+  int status;
+
+  if (!prg_name)
+    return;
+
+  _g_sprintf (buf, "%u", (guint) getpid ());
+
+  args[1] = (gchar*) prg_name;
+  args[2] = buf;
+
+  pid = fork ();
+  if (pid == 0)
+    {
+      stack_trace (args);
+      _exit (0);
+    }
+  else if (pid == (pid_t) -1)
+    {
+      perror ("unable to fork gdb");
+      return;
+    }
+
+  waitpid (pid, &status, 0);
+#else
+  if (IsDebuggerPresent ())
+    G_BREAKPOINT ();
+  else
+    abort ();
+#endif
+}
+
+#ifndef G_OS_WIN32
+
+static gboolean stack_trace_done = FALSE;
+
+static void
+stack_trace_sigchld (int signum)
+{
+  stack_trace_done = TRUE;
+}
+
+static void
+stack_trace (char **args)
+{
+  pid_t pid;
+  int in_fd[2];
+  int out_fd[2];
+  SELECT_MASK fdset;
+  SELECT_MASK readset;
+  struct timeval tv;
+  int sel, idx, state;
+  char buffer[256];
+  char c;
+
+  stack_trace_done = FALSE;
+  signal (SIGCHLD, stack_trace_sigchld);
+
+  if ((pipe (in_fd) == -1) || (pipe (out_fd) == -1))
+    {
+      perror ("unable to open pipe");
+      _exit (0);
+    }
+
+  pid = fork ();
+  if (pid == 0)
+    {
+      close (0); dup (in_fd[0]);   /* set the stdin to the in pipe */
+      close (1); dup (out_fd[1]);  /* set the stdout to the out pipe */
+      close (2); dup (out_fd[1]);  /* set the stderr to the out pipe */
+
+      execvp (args[0], args);      /* exec gdb */
+      perror ("exec failed");
+      _exit (0);
+    }
+  else if (pid == (pid_t) -1)
+    {
+      perror ("unable to fork");
+      _exit (0);
+    }
+
+  FD_ZERO (&fdset);
+  FD_SET (out_fd[0], &fdset);
+
+  write (in_fd[1], "backtrace\n", 10);
+  write (in_fd[1], "p x = 0\n", 8);
+  write (in_fd[1], "quit\n", 5);
+
+  idx = 0;
+  state = 0;
+
+  while (1)
+    {
+      readset = fdset;
+      tv.tv_sec = 1;
+      tv.tv_usec = 0;
+
+      sel = select (FD_SETSIZE, &readset, NULL, NULL, &tv);
+      if (sel == -1)
+        break;
+
+      if ((sel > 0) && (FD_ISSET (out_fd[0], &readset)))
+        {
+          if (read (out_fd[0], &c, 1))
+            {
+              switch (state)
+                {
+                case 0:
+                  if (c == '#')
+                    {
+                      state = 1;
+                      idx = 0;
+                      buffer[idx++] = c;
+                    }
+                  break;
+                case 1:
+                  buffer[idx++] = c;
+                  if ((c == '\n') || (c == '\r'))
+                    {
+                      buffer[idx] = 0;
+                      _g_fprintf (stdout, "%s", buffer);
+                      state = 0;
+                      idx = 0;
+                    }
+                  break;
+                default:
+                  break;
+                }
+            }
+        }
+      else if (stack_trace_done)
+        break;
+    }
+
+  close (in_fd[0]);
+  close (in_fd[1]);
+  close (out_fd[0]);
+  close (out_fd[1]);
+  _exit (0);
+}
+
+#endif /* !G_OS_WIN32 */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gbacktrace.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gbacktrace.h
new file mode 100644 (file)
index 0000000..43a0c46
--- /dev/null
@@ -0,0 +1,68 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_BACKTRACE_H__
+#define __G_BACKTRACE_H__
+
+#include <glib/gtypes.h>
+#include <signal.h>
+
+G_BEGIN_DECLS
+
+/* Fatal error handlers.
+ * g_on_error_query() will prompt the user to either
+ * [E]xit, [H]alt, [P]roceed or show [S]tack trace.
+ * g_on_error_stack_trace() invokes gdb, which attaches to the current
+ * process and shows a stack trace.
+ * These function may cause different actions on non-unix platforms.
+ * The prg_name arg is required by gdb to find the executable, if it is
+ * passed as NULL, g_on_error_query() will try g_get_prgname().
+ */
+void g_on_error_query (const gchar *prg_name);
+void g_on_error_stack_trace (const gchar *prg_name);
+
+/* Hacker macro to place breakpoints for selected machines.
+ * Actual use is strongly discouraged of course ;)
+ */
+#if (defined (__i386__) || defined (__x86_64__)) && defined (__GNUC__) && __GNUC__ >= 2
+#  define G_BREAKPOINT()        G_STMT_START{ __asm__ __volatile__ ("int $03"); }G_STMT_END
+#elif (defined (_MSC_VER) || defined (__DMC__)) && defined (_M_IX86)
+#  define G_BREAKPOINT()        G_STMT_START{ __asm int 3h }G_STMT_END
+#elif defined (_MSC_VER)
+#  define G_BREAKPOINT()        G_STMT_START{ __debugbreak(); }G_STMT_END
+#elif defined (__alpha__) && !defined(__osf__) && defined (__GNUC__) && __GNUC__ >= 2
+#  define G_BREAKPOINT()        G_STMT_START{ __asm__ __volatile__ ("bpt"); }G_STMT_END
+#else   /* !__i386__ && !__alpha__ */
+#  define G_BREAKPOINT()        G_STMT_START{ raise (SIGTRAP); }G_STMT_END
+#endif  /* __i386__ */
+
+G_END_DECLS
+
+#endif /* __G_BACKTRACE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gbase64.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gbase64.c
new file mode 100644 (file)
index 0000000..8a492de
--- /dev/null
@@ -0,0 +1,440 @@
+/* gbase64.c - Base64 encoding/decoding
+ *
+ *  Copyright (C) 2006 Alexander Larsson <alexl@redhat.com>
+ *  Copyright (C) 2000-2003 Ximian Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * This is based on code in camel, written by:
+ *    Michael Zucchi <notzed@ximian.com>
+ *    Jeffrey Stedfast <fejj@ximian.com>
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gbase64.h"
+#include "gtestutils.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION:base64
+ * @title: Base64 Encoding
+ * @short_description: encodes and decodes data in Base64 format
+ *
+ * Base64 is an encoding that allows a sequence of arbitrary bytes to be
+ * encoded as a sequence of printable ASCII characters. For the definition
+ * of Base64, see <ulink url="http://www.ietf.org/rfc/rfc1421.txt">RFC
+ * 1421</ulink> or <ulink url="http://www.ietf.org/rfc/rfc2045.txt">RFC
+ * 2045</ulink>. Base64 is most commonly used as a MIME transfer encoding
+ * for email.
+ *
+ * GLib supports incremental encoding using g_base64_encode_step() and
+ * g_base64_encode_close(). Incremental decoding can be done with
+ * g_base64_decode_step(). To encode or decode data in one go, use
+ * g_base64_encode() or g_base64_decode(). To avoid memory allocation when
+ * decoding, you can use g_base64_decode_inplace().
+ *
+ * Support for Base64 encoding has been added in GLib 2.12.
+ */
+
+static const char base64_alphabet[] =
+        "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
+
+/**
+ * g_base64_encode_step:
+ * @in: the binary data to encode
+ * @len: the length of @in
+ * @break_lines: whether to break long lines
+ * @out: pointer to destination buffer
+ * @state: Saved state between steps, initialize to 0
+ * @save: Saved state between steps, initialize to 0
+ *
+ * Incrementally encode a sequence of binary data into its Base-64 stringified
+ * representation. By calling this function multiple times you can convert
+ * data in chunks to avoid having to have the full encoded data in memory.
+ *
+ * When all of the data has been converted you must call
+ * g_base64_encode_close() to flush the saved state.
+ *
+ * The output buffer must be large enough to fit all the data that will
+ * be written to it. Due to the way base64 encodes you will need
+ * at least: (@len / 3 + 1) * 4 + 4 bytes (+ 4 may be needed in case of
+ * non-zero state). If you enable line-breaking you will need at least:
+ * ((@len / 3 + 1) * 4 + 4) / 72 + 1 bytes of extra space.
+ *
+ * @break_lines is typically used when putting base64-encoded data in emails.
+ * It breaks the lines at 72 columns instead of putting all of the text on
+ * the same line. This avoids problems with long lines in the email system.
+ *
+ * Return value: The number of bytes of output that was written
+ *
+ * Since: 2.12
+ */
+gsize
+g_base64_encode_step (const guchar *in,
+                      gsize         len,
+                      gboolean      break_lines,
+                      gchar        *out,
+                      gint         *state,
+                      gint         *save)
+{
+  char *outptr;
+  const guchar *inptr;
+
+  g_return_val_if_fail (in != NULL, 0);
+  g_return_val_if_fail (out != NULL, 0);
+  g_return_val_if_fail (state != NULL, 0);
+  g_return_val_if_fail (save != NULL, 0);
+
+  if (len <= 0)
+    return 0;
+
+  inptr = in;
+  outptr = out;
+
+  if (len + ((char *) save) [0] > 2)
+    {
+      const guchar *inend = in+len-2;
+      int c1, c2, c3;
+      int already;
+
+      already = *state;
+
+      switch (((char *) save) [0])
+        {
+        case 1:
+          c1 = ((unsigned char *) save) [1];
+          goto skip1;
+        case 2:
+          c1 = ((unsigned char *) save) [1];
+          c2 = ((unsigned char *) save) [2];
+          goto skip2;
+        }
+
+      /*
+       * yes, we jump into the loop, no i'm not going to change it,
+       * it's beautiful!
+       */
+      while (inptr < inend)
+        {
+          c1 = *inptr++;
+        skip1:
+          c2 = *inptr++;
+        skip2:
+          c3 = *inptr++;
+          *outptr++ = base64_alphabet [ c1 >> 2 ];
+          *outptr++ = base64_alphabet [ c2 >> 4 |
+                                        ((c1&0x3) << 4) ];
+          *outptr++ = base64_alphabet [ ((c2 &0x0f) << 2) |
+                                        (c3 >> 6) ];
+          *outptr++ = base64_alphabet [ c3 & 0x3f ];
+          /* this is a bit ugly ... */
+          if (break_lines && (++already) >= 19)
+            {
+              *outptr++ = '\n';
+              already = 0;
+            }
+        }
+
+      ((char *)save)[0] = 0;
+      len = 2 - (inptr - inend);
+      *state = already;
+    }
+
+  if (len>0)
+    {
+      char *saveout;
+
+      /* points to the slot for the next char to save */
+      saveout = & (((char *)save)[1]) + ((char *)save)[0];
+
+      /* len can only be 0 1 or 2 */
+      switch(len)
+        {
+        case 2: *saveout++ = *inptr++;
+        case 1: *saveout++ = *inptr++;
+        }
+      ((char *)save)[0] += len;
+    }
+
+  return outptr - out;
+}
+
+/**
+ * g_base64_encode_close:
+ * @break_lines: whether to break long lines
+ * @out: pointer to destination buffer
+ * @state: Saved state from g_base64_encode_step()
+ * @save: Saved state from g_base64_encode_step()
+ *
+ * Flush the status from a sequence of calls to g_base64_encode_step().
+ *
+ * The output buffer must be large enough to fit all the data that will
+ * be written to it. It will need up to 4 bytes, or up to 5 bytes if
+ * line-breaking is enabled.
+ *
+ * Return value: The number of bytes of output that was written
+ *
+ * Since: 2.12
+ */
+gsize
+g_base64_encode_close (gboolean  break_lines,
+                       gchar    *out,
+                       gint     *state,
+                       gint     *save)
+{
+  int c1, c2;
+  char *outptr = out;
+
+  g_return_val_if_fail (out != NULL, 0);
+  g_return_val_if_fail (state != NULL, 0);
+  g_return_val_if_fail (save != NULL, 0);
+
+  c1 = ((unsigned char *) save) [1];
+  c2 = ((unsigned char *) save) [2];
+
+  switch (((char *) save) [0])
+    {
+    case 2:
+      outptr [2] = base64_alphabet[ ( (c2 &0x0f) << 2 ) ];
+      g_assert (outptr [2] != 0);
+      goto skip;
+    case 1:
+      outptr[2] = '=';
+    skip:
+      outptr [0] = base64_alphabet [ c1 >> 2 ];
+      outptr [1] = base64_alphabet [ c2 >> 4 | ( (c1&0x3) << 4 )];
+      outptr [3] = '=';
+      outptr += 4;
+      break;
+    }
+  if (break_lines)
+    *outptr++ = '\n';
+
+  *save = 0;
+  *state = 0;
+
+  return outptr - out;
+}
+
+/**
+ * g_base64_encode:
+ * @data: the binary data to encode
+ * @len: the length of @data
+ *
+ * Encode a sequence of binary data into its Base-64 stringified
+ * representation.
+ *
+ * Return value: a newly allocated, zero-terminated Base-64 encoded
+ *               string representing @data. The returned string must
+ *               be freed with g_free().
+ *
+ * Since: 2.12
+ */
+gchar *
+g_base64_encode (const guchar *data,
+                 gsize         len)
+{
+  gchar *out;
+  gint state = 0, outlen;
+  gint save = 0;
+
+  g_return_val_if_fail (data != NULL || len == 0, NULL);
+
+  /* We can use a smaller limit here, since we know the saved state is 0,
+     +1 is needed for trailing \0, also check for unlikely integer overflow */
+  if (len >= ((G_MAXSIZE - 1) / 4 - 1) * 3)
+    g_error("%s: input too large for Base64 encoding (%"G_GSIZE_FORMAT" chars)",
+        G_STRLOC, len);
+
+  out = g_malloc ((len / 3 + 1) * 4 + 1);
+
+  outlen = g_base64_encode_step (data, len, FALSE, out, &state, &save);
+  outlen += g_base64_encode_close (FALSE, out + outlen, &state, &save);
+  out[outlen] = '\0';
+
+  return (gchar *) out;
+}
+
+static const unsigned char mime_base64_rank[256] = {
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255, 62,255,255,255, 63,
+   52, 53, 54, 55, 56, 57, 58, 59, 60, 61,255,255,255,  0,255,255,
+  255,  0,  1,  2,  3,  4,  5,  6,  7,  8,  9, 10, 11, 12, 13, 14,
+   15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25,255,255,255,255,255,
+  255, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
+   41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+  255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
+};
+
+/**
+ * g_base64_decode_step:
+ * @in: binary input data
+ * @len: max length of @in data to decode
+ * @out: output buffer
+ * @state: Saved state between steps, initialize to 0
+ * @save: Saved state between steps, initialize to 0
+ *
+ * Incrementally decode a sequence of binary data from its Base-64 stringified
+ * representation. By calling this function multiple times you can convert
+ * data in chunks to avoid having to have the full encoded data in memory.
+ *
+ * The output buffer must be large enough to fit all the data that will
+ * be written to it. Since base64 encodes 3 bytes in 4 chars you need
+ * at least: (@len / 4) * 3 + 3 bytes (+ 3 may be needed in case of non-zero
+ * state).
+ *
+ * Return value: The number of bytes of output that was written
+ *
+ * Since: 2.12
+ **/
+gsize
+g_base64_decode_step (const gchar  *in,
+                      gsize         len,
+                      guchar       *out,
+                      gint         *state,
+                      guint        *save)
+{
+  const guchar *inptr;
+  guchar *outptr;
+  const guchar *inend;
+  guchar c, rank;
+  guchar last[2];
+  unsigned int v;
+  int i;
+
+  g_return_val_if_fail (in != NULL, 0);
+  g_return_val_if_fail (out != NULL, 0);
+  g_return_val_if_fail (state != NULL, 0);
+  g_return_val_if_fail (save != NULL, 0);
+
+  if (len <= 0)
+    return 0;
+
+  inend = (const guchar *)in+len;
+  outptr = out;
+
+  /* convert 4 base64 bytes to 3 normal bytes */
+  v=*save;
+  i=*state;
+  inptr = (const guchar *)in;
+  last[0] = last[1] = 0;
+  while (inptr < inend)
+    {
+      c = *inptr++;
+      rank = mime_base64_rank [c];
+      if (rank != 0xff)
+        {
+          last[1] = last[0];
+          last[0] = c;
+          v = (v<<6) | rank;
+          i++;
+          if (i==4)
+            {
+              *outptr++ = v>>16;
+              if (last[1] != '=')
+                *outptr++ = v>>8;
+              if (last[0] != '=')
+                *outptr++ = v;
+              i=0;
+            }
+        }
+    }
+
+  *save = v;
+  *state = i;
+
+  return outptr - out;
+}
+
+/**
+ * g_base64_decode:
+ * @text: zero-terminated string with base64 text to decode
+ * @out_len: The length of the decoded data is written here
+ *
+ * Decode a sequence of Base-64 encoded text into binary data
+ *
+ * Return value: a newly allocated buffer containing the binary data
+ *               that @text represents. The returned buffer must
+ *               be freed with g_free().
+ *
+ * Since: 2.12
+ */
+guchar *
+g_base64_decode (const gchar *text,
+                 gsize       *out_len)
+{
+  guchar *ret;
+  gsize input_length;
+  gint state = 0;
+  guint save = 0;
+
+  g_return_val_if_fail (text != NULL, NULL);
+  g_return_val_if_fail (out_len != NULL, NULL);
+
+  input_length = strlen (text);
+
+  /* We can use a smaller limit here, since we know the saved state is 0,
+     +1 used to avoid calling g_malloc0(0), and hence retruning NULL */
+  ret = g_malloc0 ((input_length / 4) * 3 + 1);
+
+  *out_len = g_base64_decode_step (text, input_length, ret, &state, &save);
+
+  return ret;
+}
+
+/**
+ * g_base64_decode_inplace:
+ * @text: zero-terminated string with base64 text to decode
+ * @out_len: The length of the decoded data is written here
+ *
+ * Decode a sequence of Base-64 encoded text into binary data
+ * by overwriting the input data.
+ *
+ * Return value: The binary data that @text responds. This pointer
+ *               is the same as the input @text.
+ *
+ * Since: 2.20
+ */
+guchar *
+g_base64_decode_inplace (gchar *text,
+                         gsize *out_len)
+{
+  gint input_length, state = 0;
+  guint save = 0;
+
+  g_return_val_if_fail (text != NULL, NULL);
+  g_return_val_if_fail (out_len != NULL, NULL);
+
+  input_length = strlen (text);
+
+  g_return_val_if_fail (input_length > 1, NULL);
+
+  *out_len = g_base64_decode_step (text, input_length, (guchar *) text, &state, &save);
+
+  return (guchar *) text;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gbase64.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gbase64.h
new file mode 100644 (file)
index 0000000..930389a
--- /dev/null
@@ -0,0 +1,57 @@
+/* gbase64.h - Base64 coding functions
+ *
+ *  Copyright (C) 2005  Alexander Larsson <alexl@redhat.com>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_BASE64_H__
+#define __G_BASE64_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+gsize   g_base64_encode_step    (const guchar *in,
+                                 gsize         len,
+                                 gboolean      break_lines,
+                                 gchar        *out,
+                                 gint         *state,
+                                 gint         *save);
+gsize   g_base64_encode_close   (gboolean      break_lines,
+                                 gchar        *out,
+                                 gint         *state,
+                                 gint         *save);
+gchar*  g_base64_encode         (const guchar *data,
+                                 gsize         len) G_GNUC_MALLOC;
+gsize   g_base64_decode_step    (const gchar  *in,
+                                 gsize         len,
+                                 guchar       *out,
+                                 gint         *state,
+                                 guint        *save);
+guchar *g_base64_decode         (const gchar  *text,
+                                 gsize        *out_len) G_GNUC_MALLOC;
+guchar *g_base64_decode_inplace (gchar        *text,
+                                 gsize        *out_len);
+
+
+G_END_DECLS
+
+#endif /* __G_BASE64_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gbitlock.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gbitlock.c
new file mode 100644 (file)
index 0000000..1b8c417
--- /dev/null
@@ -0,0 +1,296 @@
+/*
+ * Copyright © 2008 Ryan Lortie
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "gbitlock.h"
+
+#include <glib/gatomic.h>
+#include <glib/gslist.h>
+#include <glib/gthread.h>
+
+#include "gthreadprivate.h"
+#include "config.h"
+
+
+#ifdef G_BIT_LOCK_FORCE_FUTEX_EMULATION
+#undef HAVE_FUTEX
+#endif
+
+#ifndef HAVE_FUTEX
+static GSList *g_futex_address_list = NULL;
+static GMutex *g_futex_mutex = NULL;
+#endif
+
+void
+_g_futex_thread_init (void) {
+#ifndef HAVE_FUTEX
+  g_futex_mutex = g_mutex_new ();
+#endif
+}
+
+#ifdef HAVE_FUTEX
+/*
+ * We have headers for futex(2) on the build machine.  This does not
+ * imply that every system that ever runs the resulting glib will have
+ * kernel support for futex, but you'd have to have a pretty old
+ * kernel in order for that not to be the case.
+ *
+ * If anyone actually gets bit by this, please file a bug. :)
+ */
+#include <linux/futex.h>
+#include <syscall.h>
+#include <unistd.h>
+
+/* < private >
+ * g_futex_wait:
+ * @address: a pointer to an integer
+ * @value: the value that should be at @address
+ *
+ * Atomically checks that the value stored at @address is equal to
+ * @value and then blocks.  If the value stored at @address is not
+ * equal to @value then this function returns immediately.
+ *
+ * To unblock, call g_futex_wake() on @address.
+ *
+ * This call may spuriously unblock (for example, in response to the
+ * process receiving a signal) but this is not guaranteed.  Unlike the
+ * Linux system call of a similar name, there is no guarantee that a
+ * waiting process will unblock due to a g_futex_wake() call in a
+ * separate process.
+ */
+static void
+g_futex_wait (const volatile gint *address,
+              gint                 value)
+{
+  syscall (SYS_futex, address, (gsize) FUTEX_WAIT, (gsize) value, NULL);
+}
+
+/* < private >
+ * g_futex_wake:
+ * @address: a pointer to an integer
+ *
+ * Nominally, wakes one thread that is blocked in g_futex_wait() on
+ * @address (if any thread is currently waiting).
+ *
+ * As mentioned in the documention for g_futex_wait(), spurious
+ * wakeups may occur.  As such, this call may result in more than one
+ * thread being woken up.
+ */
+static void
+g_futex_wake (const volatile gint *address)
+{
+  syscall (SYS_futex, address, (gsize) FUTEX_WAKE, (gsize) 1, NULL);
+}
+
+#else
+
+/* emulate futex(2) */
+typedef struct
+{
+  const volatile gint *address;
+  gint                 ref_count;
+  GCond               *wait_queue;
+} WaitAddress;
+
+static WaitAddress *
+g_futex_find_address (const volatile gint *address)
+{
+  GSList *node;
+
+  for (node = g_futex_address_list; node; node = node->next)
+    {
+      WaitAddress *waiter = node->data;
+
+      if (waiter->address == address)
+        return waiter;
+    }
+
+  return NULL;
+}
+
+static void
+g_futex_wait (const volatile gint *address,
+              gint                 value)
+{
+  g_mutex_lock (g_futex_mutex);
+  if G_LIKELY (g_atomic_int_get (address) == value)
+    {
+      WaitAddress *waiter;
+
+      if ((waiter = g_futex_find_address (address)) == NULL)
+        {
+          waiter = g_slice_new (WaitAddress);
+          waiter->address = address;
+          waiter->wait_queue = g_cond_new ();
+          waiter->ref_count = 0;
+          g_futex_address_list =
+            g_slist_prepend (g_futex_address_list, waiter);
+        }
+
+      waiter->ref_count++;
+      g_cond_wait (waiter->wait_queue, g_futex_mutex);
+
+      if (!--waiter->ref_count)
+        {
+          g_futex_address_list =
+            g_slist_remove (g_futex_address_list, waiter);
+          g_cond_free (waiter->wait_queue);
+          g_slice_free (WaitAddress, waiter);
+        }
+    }
+  g_mutex_unlock (g_futex_mutex);
+}
+
+static void
+g_futex_wake (const volatile gint *address)
+{
+  WaitAddress *waiter;
+
+  /* need to lock here for two reasons:
+   *   1) need to acquire/release lock to ensure waiter is not in
+   *      the process of registering a wait
+   *   2) need to -stay- locked until the end to ensure a wake()
+   *      in another thread doesn't cause 'waiter' to stop existing
+   */
+  g_mutex_lock (g_futex_mutex);
+  if ((waiter = g_futex_find_address (address)))
+    g_cond_signal (waiter->wait_queue);
+  g_mutex_unlock (g_futex_mutex);
+}
+#endif
+
+#define CONTENTION_CLASSES 11
+static volatile gint g_bit_lock_contended[CONTENTION_CLASSES];
+
+/**
+ * g_bit_lock:
+ * @address: a pointer to an integer
+ * @lock_bit: a bit value between 0 and 31
+ *
+ * Sets the indicated @lock_bit in @address.  If the bit is already
+ * set, this call will block until g_bit_unlock() unsets the
+ * corresponding bit.
+ *
+ * Attempting to lock on two different bits within the same integer is
+ * not supported and will very probably cause deadlocks.
+ *
+ * The value of the bit that is set is (1u << @bit).  If @bit is not
+ * between 0 and 31 then the result is undefined.
+ *
+ * This function accesses @address atomically.  All other accesses to
+ * @address must be atomic in order for this function to work
+ * reliably.
+ *
+ * Since: 2.24
+ **/
+void
+g_bit_lock (volatile gint *address,
+            gint           lock_bit)
+{
+  guint v;
+
+ retry:
+  v = g_atomic_int_get (address);
+  if (v & (1u << lock_bit))
+    /* already locked */
+    {
+      guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended);
+
+      g_atomic_int_add (&g_bit_lock_contended[class], +1);
+      g_futex_wait (address, v);
+      g_atomic_int_add (&g_bit_lock_contended[class], -1);
+
+      goto retry;
+    }
+
+  if (!g_atomic_int_compare_and_exchange (address, v, v | (1u << lock_bit)))
+    goto retry;
+}
+
+/**
+ * g_bit_trylock:
+ * @address: a pointer to an integer
+ * @lock_bit: a bit value between 0 and 31
+ * @returns: %TRUE if the lock was acquired
+ *
+ * Sets the indicated @lock_bit in @address, returning %TRUE if
+ * successful.  If the bit is already set, returns %FALSE immediately.
+ *
+ * Attempting to lock on two different bits within the same integer is
+ * not supported.
+ *
+ * The value of the bit that is set is (1u << @bit).  If @bit is not
+ * between 0 and 31 then the result is undefined.
+ *
+ * This function accesses @address atomically.  All other accesses to
+ * @address must be atomic in order for this function to work
+ * reliably.
+ *
+ * Since: 2.24
+ **/
+gboolean
+g_bit_trylock (volatile gint *address,
+               gint           lock_bit)
+{
+  guint v;
+
+ retry:
+  v = g_atomic_int_get (address);
+  if (v & (1u << lock_bit))
+    /* already locked */
+    return FALSE;
+
+  if (!g_atomic_int_compare_and_exchange (address, v, v | (1u << lock_bit)))
+    goto retry;
+
+  return TRUE;
+}
+
+/**
+ * g_bit_unlock:
+ * @address: a pointer to an integer
+ * @lock_bit: a bit value between 0 and 31
+ *
+ * Clears the indicated @lock_bit in @address.  If another thread is
+ * currently blocked in g_bit_lock() on this same bit then it will be
+ * woken up.
+ *
+ * This function accesses @address atomically.  All other accesses to
+ * @address must be atomic in order for this function to work
+ * reliably.
+ *
+ * Since: 2.24
+ **/
+void
+g_bit_unlock (volatile gint *address,
+              gint           lock_bit)
+{
+  guint class = ((gsize) address) % G_N_ELEMENTS (g_bit_lock_contended);
+  guint v;
+
+ retry:
+  v = g_atomic_int_get (address);
+  if (!g_atomic_int_compare_and_exchange (address, v, v & ~(1u << lock_bit)))
+    goto retry;
+
+  if (g_atomic_int_get (&g_bit_lock_contended[class]))
+    g_futex_wake (address);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gbitlock.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gbitlock.h
new file mode 100644 (file)
index 0000000..5f6a67f
--- /dev/null
@@ -0,0 +1,43 @@
+/*
+ * Copyright © 2008 Ryan Lortie
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __G_BITLOCK_H__
+#define __G_BITLOCK_H__
+
+#include <glib/gtypes.h>
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+G_BEGIN_DECLS
+
+void      g_bit_lock                      (volatile gint *address,
+                                           gint           lock_bit);
+gboolean  g_bit_trylock                   (volatile gint *address,
+                                           gint           lock_bit);
+void      g_bit_unlock                    (volatile gint *address,
+                                           gint           lock_bit);
+
+G_END_DECLS
+
+#endif /* __G_BITLOCK_H_ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gbookmarkfile.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gbookmarkfile.c
new file mode 100644 (file)
index 0000000..db2a8bc
--- /dev/null
@@ -0,0 +1,3747 @@
+/* gbookmarkfile.c: parsing and building desktop bookmarks
+ *
+ * Copyright (C) 2005-2006 Emmanuele Bassi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ */
+
+#include "config.h"
+
+#include "gbookmarkfile.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <time.h>
+#include <stdarg.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "gconvert.h"
+#include "gdataset.h"
+#include "gerror.h"
+#include "gfileutils.h"
+#include "ghash.h"
+#include "glibintl.h"
+#include "glist.h"
+#include "gslist.h"
+#include "gmain.h"
+#include "gmarkup.h"
+#include "gmem.h"
+#include "gmessages.h"
+#include "gshell.h"
+#include "gslice.h"
+#include "gstdio.h"
+#include "gstring.h"
+#include "gstrfuncs.h"
+#include "gtimer.h"
+#include "gutils.h"
+
+
+/**
+ * SECTION:bookmarkfile
+ * @title: Bookmark file parser
+ * @short_description: parses files containing bookmarks
+ *
+ * GBookmarkFile lets you parse, edit or create files containing bookmarks
+ * to URI, along with some meta-data about the resource pointed by the URI
+ * like its MIME type, the application that is registering the bookmark and
+ * the icon that should be used to represent the bookmark. The data is stored
+ * using the
+ * <ulink url="http://www.gnome.org/~ebassi/bookmark-spec">Desktop Bookmark
+ * Specification</ulink>.
+ *
+ * The syntax of the bookmark files is described in detail inside the Desktop
+ * Bookmark Specification, here is a quick summary: bookmark files use a
+ * sub-class of the <ulink url="">XML Bookmark Exchange Language</ulink>
+ * specification, consisting of valid UTF-8 encoded XML, under the
+ * <literal>xbel</literal> root element; each bookmark is stored inside a
+ * <literal>bookmark</literal> element, using its URI: no relative paths can
+ * be used inside a bookmark file. The bookmark may have a user defined title
+ * and description, to be used instead of the URI. Under the
+ * <literal>metadata</literal> element, with its <literal>owner</literal>
+ * attribute set to <literal>http://freedesktop.org</literal>, is stored the
+ * meta-data about a resource pointed by its URI. The meta-data consists of
+ * the resource's MIME type; the applications that have registered a bookmark;
+ * the groups to which a bookmark belongs to; a visibility flag, used to set
+ * the bookmark as "private" to the applications and groups that has it
+ * registered; the URI and MIME type of an icon, to be used when displaying
+ * the bookmark inside a GUI.
+ * |[<xi:include xmlns:xi="http://www.w3.org/2001/XInclude" parse="text" href="../../../../glib/tests/bookmarks.xbel"><xi:fallback>FIXME: MISSING XINCLUDE CONTENT</xi:fallback></xi:include>]|
+ *
+ * A bookmark file might contain more than one bookmark; each bookmark
+ * is accessed through its URI.
+ *
+ * The important caveat of bookmark files is that when you add a new
+ * bookmark you must also add the application that is registering it, using
+ * g_bookmark_file_add_application() or g_bookmark_file_set_app_info().
+ * If a bookmark has no applications then it won't be dumped when creating
+ * the on disk representation, using g_bookmark_file_to_data() or
+ * g_bookmark_file_to_file().
+ *
+ * The #GBookmarkFile parser was added in GLib 2.12.
+ */
+
+/* XBEL 1.0 standard entities */
+#define XBEL_VERSION           "1.0"
+#define XBEL_DTD_NICK          "xbel"
+#define XBEL_DTD_SYSTEM                "+//IDN python.org//DTD XML Bookmark " \
+                               "Exchange Language 1.0//EN//XML"
+
+#define XBEL_DTD_URI           "http://www.python.org/topics/xml/dtds/xbel-1.0.dtd"
+
+#define XBEL_ROOT_ELEMENT      "xbel"
+#define XBEL_FOLDER_ELEMENT    "folder"        /* unused */
+#define XBEL_BOOKMARK_ELEMENT  "bookmark"
+#define XBEL_ALIAS_ELEMENT     "alias"         /* unused */
+#define XBEL_SEPARATOR_ELEMENT "separator"     /* unused */
+#define XBEL_TITLE_ELEMENT     "title"
+#define XBEL_DESC_ELEMENT      "desc"
+#define XBEL_INFO_ELEMENT      "info"
+#define XBEL_METADATA_ELEMENT  "metadata"
+
+#define XBEL_VERSION_ATTRIBUTE "version"
+#define XBEL_FOLDED_ATTRIBUTE  "folded"        /* unused */
+#define XBEL_OWNER_ATTRIBUTE   "owner"
+#define XBEL_ADDED_ATTRIBUTE   "added"
+#define XBEL_VISITED_ATTRIBUTE "visited"
+#define XBEL_MODIFIED_ATTRIBUTE "modified"
+#define XBEL_ID_ATTRIBUTE      "id"
+#define XBEL_HREF_ATTRIBUTE    "href"
+#define XBEL_REF_ATTRIBUTE     "ref"           /* unused */
+
+#define XBEL_YES_VALUE         "yes"
+#define XBEL_NO_VALUE          "no"
+
+/* Desktop bookmark spec entities */
+#define BOOKMARK_METADATA_OWNER        "http://freedesktop.org"
+
+#define BOOKMARK_NAMESPACE_NAME        "bookmark"
+#define BOOKMARK_NAMESPACE_URI         "http://www.freedesktop.org/standards/desktop-bookmarks"
+
+#define BOOKMARK_GROUPS_ELEMENT                "groups"
+#define BOOKMARK_GROUP_ELEMENT         "group"
+#define BOOKMARK_APPLICATIONS_ELEMENT  "applications"
+#define BOOKMARK_APPLICATION_ELEMENT   "application"
+#define BOOKMARK_ICON_ELEMENT          "icon"
+#define BOOKMARK_PRIVATE_ELEMENT       "private"
+
+#define BOOKMARK_NAME_ATTRIBUTE                "name"
+#define BOOKMARK_EXEC_ATTRIBUTE                "exec"
+#define BOOKMARK_COUNT_ATTRIBUTE       "count"
+#define BOOKMARK_TIMESTAMP_ATTRIBUTE   "timestamp"     /* deprecated by "modified" */
+#define BOOKMARK_MODIFIED_ATTRIBUTE     "modified"
+#define BOOKMARK_HREF_ATTRIBUTE        "href"
+#define BOOKMARK_TYPE_ATTRIBUTE        "type"
+
+/* Shared MIME Info entities */
+#define MIME_NAMESPACE_NAME            "mime"
+#define MIME_NAMESPACE_URI             "http://www.freedesktop.org/standards/shared-mime-info"
+#define MIME_TYPE_ELEMENT              "mime-type"
+#define MIME_TYPE_ATTRIBUTE            "type"
+
+
+typedef struct _BookmarkAppInfo  BookmarkAppInfo;
+typedef struct _BookmarkMetadata BookmarkMetadata;
+typedef struct _BookmarkItem     BookmarkItem;
+typedef struct _ParseData        ParseData;
+
+struct _BookmarkAppInfo
+{
+  gchar *name;
+  gchar *exec;
+  
+  guint count;
+  
+  time_t stamp;
+};
+
+struct _BookmarkMetadata
+{
+  gchar *mime_type;
+  
+  GList *groups;
+  
+  GList *applications;
+  GHashTable *apps_by_name;
+  
+  gchar *icon_href;
+  gchar *icon_mime;
+  
+  guint is_private : 1;
+};
+
+struct _BookmarkItem
+{
+  gchar *uri;
+
+  gchar *title;
+  gchar *description;
+
+  time_t added;
+  time_t modified;
+  time_t visited;
+
+  BookmarkMetadata *metadata;
+};
+
+struct _GBookmarkFile
+{
+  gchar *title;
+  gchar *description;
+
+  /* we store our items in a list and keep a copy inside
+   * an hash table for faster lookup performances
+   */
+  GList *items;
+  GHashTable *items_by_uri;
+};
+
+/* parser state machine */
+enum
+{
+  STATE_STARTED        = 0,
+  
+  STATE_ROOT,
+  STATE_BOOKMARK,
+  STATE_TITLE,
+  STATE_DESC,
+  STATE_INFO,
+  STATE_METADATA,
+  STATE_APPLICATIONS,
+  STATE_APPLICATION,
+  STATE_GROUPS,
+  STATE_GROUP,
+  STATE_MIME,
+  STATE_ICON,
+  
+  STATE_FINISHED
+};
+
+static void          g_bookmark_file_init        (GBookmarkFile  *bookmark);
+static void          g_bookmark_file_clear       (GBookmarkFile  *bookmark);
+static gboolean      g_bookmark_file_parse       (GBookmarkFile  *bookmark,
+                                                 const gchar    *buffer,
+                                                 gsize           length,
+                                                 GError        **error);
+static gchar *       g_bookmark_file_dump        (GBookmarkFile  *bookmark,
+                                                 gsize          *length,
+                                                 GError        **error);
+static BookmarkItem *g_bookmark_file_lookup_item (GBookmarkFile  *bookmark,
+                                                 const gchar    *uri);
+static void          g_bookmark_file_add_item    (GBookmarkFile  *bookmark,
+                                                 BookmarkItem   *item,
+                                                 GError        **error);
+                                                      
+static time_t  timestamp_from_iso8601 (const gchar *iso_date);
+static gchar * timestamp_to_iso8601   (time_t       timestamp);
+
+/********************************
+ * BookmarkAppInfo              *
+ *                              *
+ * Application metadata storage *
+ ********************************/
+static BookmarkAppInfo *
+bookmark_app_info_new (const gchar *name)
+{
+  BookmarkAppInfo *retval;
+  g_warn_if_fail (name != NULL);
+  
+  retval = g_slice_new (BookmarkAppInfo);
+  
+  retval->name = g_strdup (name);
+  retval->exec = NULL;
+  retval->count = 0;
+  retval->stamp = 0;
+  
+  return retval;
+}
+
+static void
+bookmark_app_info_free (BookmarkAppInfo *app_info)
+{
+  if (!app_info)
+    return;
+  
+  g_free (app_info->name);
+  g_free (app_info->exec);
+  
+  g_slice_free (BookmarkAppInfo, app_info);
+}
+
+static gchar *
+bookmark_app_info_dump (BookmarkAppInfo *app_info)
+{
+  gchar *retval;
+  gchar *name, *exec, *modified, *count;
+
+  g_warn_if_fail (app_info != NULL);
+
+  if (app_info->count == 0)
+    return NULL;
+
+  name = g_markup_escape_text (app_info->name, -1);
+  exec = g_markup_escape_text (app_info->exec, -1);
+  modified = timestamp_to_iso8601 (app_info->stamp);
+  count = g_strdup_printf ("%u", app_info->count);
+
+  retval = g_strconcat ("          "
+                        "<" BOOKMARK_NAMESPACE_NAME ":" BOOKMARK_APPLICATION_ELEMENT
+                        " " BOOKMARK_NAME_ATTRIBUTE "=\"", name, "\""
+                        " " BOOKMARK_EXEC_ATTRIBUTE "=\"", exec, "\""
+                        " " BOOKMARK_MODIFIED_ATTRIBUTE "=\"", modified, "\""
+                        " " BOOKMARK_COUNT_ATTRIBUTE "=\"", count, "\"/>\n",
+                        NULL);
+
+  g_free (name);
+  g_free (exec);
+  g_free (modified);
+  g_free (count);
+
+  return retval;
+}
+
+
+/***********************
+ * BookmarkMetadata    *
+ *                     *
+ * Metadata storage    *
+ ***********************/
+static BookmarkMetadata *
+bookmark_metadata_new (void)
+{
+  BookmarkMetadata *retval;
+  
+  retval = g_slice_new (BookmarkMetadata);
+
+  retval->mime_type = NULL;
+  
+  retval->groups = NULL;
+  
+  retval->applications = NULL;
+  retval->apps_by_name = g_hash_table_new_full (g_str_hash,
+                                                g_str_equal,
+                                                NULL,
+                                                NULL);
+  
+  retval->is_private = FALSE;
+  
+  retval->icon_href = NULL;
+  retval->icon_mime = NULL;
+  
+  return retval;
+}
+
+static void
+bookmark_metadata_free (BookmarkMetadata *metadata)
+{
+  if (!metadata)
+    return;
+  
+  g_free (metadata->mime_type);
+    
+  if (metadata->groups)
+    {
+      g_list_foreach (metadata->groups,
+                     (GFunc) g_free,
+                     NULL);
+      g_list_free (metadata->groups);
+    }
+  
+  if (metadata->applications)
+    {
+      g_list_foreach (metadata->applications,
+                     (GFunc) bookmark_app_info_free,
+                     NULL);
+      g_list_free (metadata->applications);
+    }
+
+  g_hash_table_destroy (metadata->apps_by_name);
+
+  g_free (metadata->icon_href);
+  g_free (metadata->icon_mime);
+  
+  g_slice_free (BookmarkMetadata, metadata);
+}
+
+static gchar *
+bookmark_metadata_dump (BookmarkMetadata *metadata)
+{
+  GString *retval;
+  gchar *buffer;
+  if (!metadata->applications)
+    return NULL;
+  
+  retval = g_string_sized_new (1024);
+  
+  /* metadata container */
+  g_string_append (retval,
+                  "      "
+                  "<" XBEL_METADATA_ELEMENT
+                  " " XBEL_OWNER_ATTRIBUTE "=\"" BOOKMARK_METADATA_OWNER
+                  "\">\n");
+
+  /* mime type */
+  if (metadata->mime_type) {
+    buffer = g_strconcat ("        "
+                         "<" MIME_NAMESPACE_NAME ":" MIME_TYPE_ELEMENT " "
+                         MIME_TYPE_ATTRIBUTE "=\"", metadata->mime_type, "\"/>\n",
+                         NULL);    
+    g_string_append (retval, buffer);
+    g_free (buffer);
+  }
+
+  if (metadata->groups)
+    {
+      GList *l;
+      
+      /* open groups container */
+      g_string_append (retval,
+                      "        "
+                      "<" BOOKMARK_NAMESPACE_NAME
+                      ":" BOOKMARK_GROUPS_ELEMENT ">\n");
+      
+      for (l = g_list_last (metadata->groups); l != NULL; l = l->prev)
+        {
+          gchar *group_name;
+
+         group_name = g_markup_escape_text ((gchar *) l->data, -1);
+         buffer = g_strconcat ("          "
+                               "<" BOOKMARK_NAMESPACE_NAME
+                               ":" BOOKMARK_GROUP_ELEMENT ">",
+                               group_name,
+                               "</" BOOKMARK_NAMESPACE_NAME
+                               ":"  BOOKMARK_GROUP_ELEMENT ">\n", NULL);
+         g_string_append (retval, buffer);
+
+         g_free (buffer);
+         g_free (group_name);
+        }
+      
+      /* close groups container */
+      g_string_append (retval,
+                      "        "
+                      "</" BOOKMARK_NAMESPACE_NAME
+                      ":" BOOKMARK_GROUPS_ELEMENT ">\n");
+    }
+  
+  if (metadata->applications)
+    {
+      GList *l;
+      
+      /* open applications container */
+      g_string_append (retval,
+                      "        "
+                      "<" BOOKMARK_NAMESPACE_NAME
+                      ":" BOOKMARK_APPLICATIONS_ELEMENT ">\n");
+      
+      for (l = g_list_last (metadata->applications); l != NULL; l = l->prev)
+        {
+          BookmarkAppInfo *app_info = (BookmarkAppInfo *) l->data;
+          gchar *app_data;
+
+         g_warn_if_fail (app_info != NULL);
+          
+          app_data = bookmark_app_info_dump (app_info);
+
+         if (app_data)
+            {
+              retval = g_string_append (retval, app_data);
+
+             g_free (app_data);
+           }
+        }
+      
+      /* close applications container */
+      g_string_append (retval,
+                      "        "
+                      "</" BOOKMARK_NAMESPACE_NAME
+                      ":" BOOKMARK_APPLICATIONS_ELEMENT ">\n");
+    }
+  
+  /* icon */
+  if (metadata->icon_href)
+    {
+      if (!metadata->icon_mime)
+        metadata->icon_mime = g_strdup ("application/octet-stream");
+
+      buffer = g_strconcat ("       "
+                           "<" BOOKMARK_NAMESPACE_NAME
+                           ":" BOOKMARK_ICON_ELEMENT
+                           " " BOOKMARK_HREF_ATTRIBUTE "=\"", metadata->icon_href,
+                           "\" " BOOKMARK_TYPE_ATTRIBUTE "=\"", metadata->icon_mime, "\"/>\n", NULL);
+      g_string_append (retval, buffer);
+
+      g_free (buffer);
+    }
+  
+  /* private hint */
+  if (metadata->is_private)
+    g_string_append (retval,
+                    "        "
+                    "<" BOOKMARK_NAMESPACE_NAME
+                    ":" BOOKMARK_PRIVATE_ELEMENT "/>\n");
+  
+  /* close metadata container */
+  g_string_append (retval,
+                  "      "
+                  "</" XBEL_METADATA_ELEMENT ">\n");
+                          
+  return g_string_free (retval, FALSE);
+}
+
+/******************************************************
+ * BookmarkItem                                       *
+ *                                                    *
+ * Storage for a single bookmark item inside the list *
+ ******************************************************/
+static BookmarkItem *
+bookmark_item_new (const gchar *uri)
+{
+  BookmarkItem *item;
+  g_warn_if_fail (uri != NULL);
+  
+  item = g_slice_new (BookmarkItem);
+  item->uri = g_strdup (uri);
+  
+  item->title = NULL;
+  item->description = NULL;
+  
+  item->added = (time_t) -1;
+  item->modified = (time_t) -1;
+  item->visited = (time_t) -1;
+  
+  item->metadata = NULL;
+  
+  return item;
+}
+
+static void
+bookmark_item_free (BookmarkItem *item)
+{
+  if (!item)
+    return;
+
+  g_free (item->uri);
+  g_free (item->title);
+  g_free (item->description);
+  
+  if (item->metadata)
+    bookmark_metadata_free (item->metadata);
+  
+  g_slice_free (BookmarkItem, item);
+}
+
+static gchar *
+bookmark_item_dump (BookmarkItem *item)
+{
+  GString *retval;
+  gchar *added, *visited, *modified;
+  gchar *escaped_uri;
+  gchar *buffer;
+  /* at this point, we must have at least a registered application; if we don't
+   * we don't screw up the bookmark file, and just skip this item
+   */
+  if (!item->metadata || !item->metadata->applications)
+    {
+      g_warning ("Item for URI '%s' has no registered applications: skipping.\n", item->uri);
+      return NULL;
+    }
+  
+  retval = g_string_sized_new (4096);
+  
+  added = timestamp_to_iso8601 (item->added);
+  modified = timestamp_to_iso8601 (item->modified);
+  visited = timestamp_to_iso8601 (item->visited);
+
+  escaped_uri = g_markup_escape_text (item->uri, -1);
+
+  buffer = g_strconcat ("  <"
+                        XBEL_BOOKMARK_ELEMENT
+                        " "
+                        XBEL_HREF_ATTRIBUTE "=\"", escaped_uri, "\" "
+                        XBEL_ADDED_ATTRIBUTE "=\"", added, "\" "
+                        XBEL_MODIFIED_ATTRIBUTE "=\"", modified, "\" "
+                        XBEL_VISITED_ATTRIBUTE "=\"", visited, "\">\n",
+                        NULL);
+
+  g_string_append (retval, buffer);
+
+  g_free (escaped_uri);
+  g_free (visited);
+  g_free (modified);
+  g_free (added);
+  g_free (buffer);
+  
+  if (item->title)
+    {
+      gchar *escaped_title;
+      
+      escaped_title = g_markup_escape_text (item->title, -1);
+      buffer = g_strconcat ("    "
+                            "<" XBEL_TITLE_ELEMENT ">",
+                            escaped_title,
+                            "</" XBEL_TITLE_ELEMENT ">\n",
+                            NULL);
+      g_string_append (retval, buffer);
+
+      g_free (escaped_title);
+      g_free (buffer);
+    }
+  
+  if (item->description)
+    {
+      gchar *escaped_desc;
+      
+      escaped_desc = g_markup_escape_text (item->description, -1);
+      buffer = g_strconcat ("    "
+                            "<" XBEL_DESC_ELEMENT ">",
+                            escaped_desc,
+                            "</" XBEL_DESC_ELEMENT ">\n",
+                            NULL);
+      g_string_append (retval, buffer);
+
+      g_free (escaped_desc);
+      g_free (buffer);
+    }
+  
+  if (item->metadata)
+    {
+      gchar *metadata;
+      
+      metadata = bookmark_metadata_dump (item->metadata);
+      if (metadata)
+        {
+          buffer = g_strconcat ("    "
+                                "<" XBEL_INFO_ELEMENT ">\n",
+                                metadata,
+                                "    "
+                               "</" XBEL_INFO_ELEMENT ">\n",
+                                NULL);
+          retval = g_string_append (retval, buffer);
+
+          g_free (buffer);
+         g_free (metadata);
+       }
+    }
+
+  g_string_append (retval, "  </" XBEL_BOOKMARK_ELEMENT ">\n");
+  
+  return g_string_free (retval, FALSE);
+}
+
+static BookmarkAppInfo *
+bookmark_item_lookup_app_info (BookmarkItem *item,
+                              const gchar  *app_name)
+{
+  g_warn_if_fail (item != NULL && app_name != NULL);
+
+  if (!item->metadata)
+    return NULL;
+  
+  return g_hash_table_lookup (item->metadata->apps_by_name, app_name);
+}
+
+/*************************
+ *    GBookmarkFile    *
+ *************************/
+static void
+g_bookmark_file_init (GBookmarkFile *bookmark)
+{
+  bookmark->title = NULL;
+  bookmark->description = NULL;
+  
+  bookmark->items = NULL;
+  bookmark->items_by_uri = g_hash_table_new_full (g_str_hash,
+                                                  g_str_equal,
+                                                  NULL,
+                                                  NULL);
+}
+
+static void
+g_bookmark_file_clear (GBookmarkFile *bookmark)
+{
+  g_free (bookmark->title);
+  g_free (bookmark->description);
+
+  if (bookmark->items)
+    {
+      g_list_foreach (bookmark->items,
+                     (GFunc) bookmark_item_free,
+                     NULL);
+      g_list_free (bookmark->items);
+      
+      bookmark->items = NULL;
+    }
+  
+  if (bookmark->items_by_uri)
+    {
+      g_hash_table_destroy (bookmark->items_by_uri);
+      
+      bookmark->items_by_uri = NULL;
+    }
+}
+
+struct _ParseData
+{
+  gint state;
+  
+  GHashTable *namespaces;
+  
+  GBookmarkFile *bookmark_file;
+  BookmarkItem *current_item;
+};
+
+static ParseData *
+parse_data_new (void)
+{
+  ParseData *retval;
+  
+  retval = g_new (ParseData, 1);
+  
+  retval->state = STATE_STARTED;
+  retval->namespaces = g_hash_table_new_full (g_str_hash, g_str_equal,
+                                             (GDestroyNotify) g_free,
+                                             (GDestroyNotify) g_free);
+  retval->bookmark_file = NULL;
+  retval->current_item = NULL;
+  
+  return retval;
+}
+
+static void
+parse_data_free (ParseData *parse_data)
+{
+  g_hash_table_destroy (parse_data->namespaces);
+  
+  g_free (parse_data);
+}
+
+#define IS_ATTRIBUTE(s,a)      ((0 == strcmp ((s), (a))))
+
+static void
+parse_bookmark_element (GMarkupParseContext  *context,
+                       ParseData            *parse_data,
+                       const gchar         **attribute_names,
+                       const gchar         **attribute_values,
+                       GError              **error)
+{
+  const gchar *uri, *added, *modified, *visited;
+  const gchar *attr;
+  gint i;
+  BookmarkItem *item;
+  GError *add_error;
+  g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_BOOKMARK));
+  
+  i = 0;
+  uri = added = modified = visited = NULL;
+  for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i])
+    {
+      if (IS_ATTRIBUTE (attr, XBEL_HREF_ATTRIBUTE))
+        uri = attribute_values[i];
+      else if (IS_ATTRIBUTE (attr, XBEL_ADDED_ATTRIBUTE))
+        added = attribute_values[i];
+      else if (IS_ATTRIBUTE (attr, XBEL_MODIFIED_ATTRIBUTE))
+        modified = attribute_values[i];
+      else if (IS_ATTRIBUTE (attr, XBEL_VISITED_ATTRIBUTE))
+        visited = attribute_values[i];
+      else
+        {
+          /* bookmark is defined by the XBEL spec, so we need
+           * to error out if the element has different or
+           * missing attributes
+           */
+          g_set_error (error, G_MARKUP_ERROR,
+                      G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
+                      _("Unexpected attribute '%s' for element '%s'"),
+                      attr,
+                      XBEL_BOOKMARK_ELEMENT);
+          return;
+        }
+    }
+  
+  if (!uri)
+    {
+      g_set_error (error, G_MARKUP_ERROR,
+                  G_MARKUP_ERROR_INVALID_CONTENT,
+                  _("Attribute '%s' of element '%s' not found"),
+                  XBEL_HREF_ATTRIBUTE,
+                  XBEL_BOOKMARK_ELEMENT);
+      return;
+    }
+  
+  g_warn_if_fail (parse_data->current_item == NULL);
+  
+  item = bookmark_item_new (uri);
+  
+  if (added)
+    item->added = timestamp_from_iso8601 (added);
+  
+  if (modified)
+    item->modified = timestamp_from_iso8601 (modified);
+  
+  if (visited)
+    item->visited = timestamp_from_iso8601 (visited);
+
+  add_error = NULL;
+  g_bookmark_file_add_item (parse_data->bookmark_file,
+                           item,
+                           &add_error);
+  if (add_error)
+    {
+      bookmark_item_free (item);
+      
+      g_propagate_error (error, add_error);
+      
+      return;
+    }                                
+  
+  parse_data->current_item = item;
+}
+
+static void
+parse_application_element (GMarkupParseContext  *context,
+                          ParseData            *parse_data,
+                          const gchar         **attribute_names,
+                          const gchar         **attribute_values,
+                          GError              **error)
+{
+  const gchar *name, *exec, *count, *stamp, *modified;
+  const gchar *attr;
+  gint i;
+  BookmarkItem *item;
+  BookmarkAppInfo *ai;
+  
+  g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_APPLICATION));
+
+  i = 0;
+  name = exec = count = stamp = modified = NULL;
+  for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i])
+    {
+      if (IS_ATTRIBUTE (attr, BOOKMARK_NAME_ATTRIBUTE))
+        name = attribute_values[i];
+      else if (IS_ATTRIBUTE (attr, BOOKMARK_EXEC_ATTRIBUTE))
+        exec = attribute_values[i];
+      else if (IS_ATTRIBUTE (attr, BOOKMARK_COUNT_ATTRIBUTE))
+        count = attribute_values[i];
+      else if (IS_ATTRIBUTE (attr, BOOKMARK_TIMESTAMP_ATTRIBUTE))
+        stamp = attribute_values[i];
+      else if (IS_ATTRIBUTE (attr, BOOKMARK_MODIFIED_ATTRIBUTE))
+        modified = attribute_values[i];
+    }
+
+  /* the "name" and "exec" attributes are mandatory */
+  if (!name)
+    {
+      g_set_error (error, G_MARKUP_ERROR,
+                  G_MARKUP_ERROR_INVALID_CONTENT,
+                  _("Attribute '%s' of element '%s' not found"),
+                  BOOKMARK_NAME_ATTRIBUTE,
+                  BOOKMARK_APPLICATION_ELEMENT);
+      return;
+    }
+  
+  if (!exec)
+    {
+      g_set_error (error, G_MARKUP_ERROR,
+                  G_MARKUP_ERROR_INVALID_CONTENT,
+                  _("Attribute '%s' of element '%s' not found"),
+                  BOOKMARK_EXEC_ATTRIBUTE,
+                  BOOKMARK_APPLICATION_ELEMENT);
+      return;
+    }
+
+  g_warn_if_fail (parse_data->current_item != NULL);  
+  item = parse_data->current_item;
+    
+  ai = bookmark_item_lookup_app_info (item, name);
+  if (!ai)
+    {
+      ai = bookmark_app_info_new (name);
+      
+      if (!item->metadata)
+       item->metadata = bookmark_metadata_new ();
+      
+      item->metadata->applications = g_list_prepend (item->metadata->applications, ai);
+      g_hash_table_replace (item->metadata->apps_by_name, ai->name, ai);
+    }
+      
+  ai->exec = g_strdup (exec);
+  
+  if (count)
+    ai->count = atoi (count);
+  else
+    ai->count = 1;
+
+  if (modified)
+    ai->stamp = timestamp_from_iso8601 (modified);
+  else
+    {
+      /* the timestamp attribute has been deprecated but we still parse
+       * it for backward compatibility
+       */
+      if (stamp)
+        ai->stamp = (time_t) atol (stamp);
+      else
+        ai->stamp = time (NULL);
+    }
+}
+
+static void
+parse_mime_type_element (GMarkupParseContext  *context,
+                        ParseData            *parse_data,
+                        const gchar         **attribute_names,
+                        const gchar         **attribute_values,
+                        GError              **error)
+{
+  const gchar *type;
+  const gchar *attr;
+  gint i;
+  BookmarkItem *item;
+  
+  g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_MIME));
+  
+  i = 0;
+  type = NULL;
+  for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i])
+    {
+      if (IS_ATTRIBUTE (attr, MIME_TYPE_ATTRIBUTE))
+        type = attribute_values[i];
+    }
+
+  if (!type)
+    type = "application/octet-stream";
+
+  g_warn_if_fail (parse_data->current_item != NULL);  
+  item = parse_data->current_item;
+    
+  if (!item->metadata)
+    item->metadata = bookmark_metadata_new ();
+  
+  item->metadata->mime_type = g_strdup (type);
+}
+
+static void
+parse_icon_element (GMarkupParseContext  *context,
+                   ParseData            *parse_data,
+                   const gchar         **attribute_names,
+                   const gchar         **attribute_values,
+                   GError              **error)
+{
+  const gchar *href;
+  const gchar *type;
+  const gchar *attr;
+  gint i;
+  BookmarkItem *item;
+  
+  g_warn_if_fail ((parse_data != NULL) && (parse_data->state == STATE_ICON));
+  
+  i = 0;
+  href = NULL;
+  type = NULL;
+  for (attr = attribute_names[i]; attr != NULL; attr = attribute_names[++i])
+    {
+      if (IS_ATTRIBUTE (attr, BOOKMARK_HREF_ATTRIBUTE))
+        href = attribute_values[i];
+      else if (IS_ATTRIBUTE (attr, BOOKMARK_TYPE_ATTRIBUTE))
+        type = attribute_values[i];
+    }
+
+  /* the "href" attribute is mandatory */       
+  if (!href)
+    {
+      g_set_error (error, G_MARKUP_ERROR,
+                  G_MARKUP_ERROR_INVALID_CONTENT,
+                  _("Attribute '%s' of element '%s' not found"),
+                  BOOKMARK_HREF_ATTRIBUTE,
+                  BOOKMARK_ICON_ELEMENT);
+      return;
+    }
+
+  if (!type)
+    type = "application/octet-stream";
+
+  g_warn_if_fail (parse_data->current_item != NULL);  
+  item = parse_data->current_item;
+    
+  if (!item->metadata)
+    item->metadata = bookmark_metadata_new ();
+  
+  item->metadata->icon_href = g_strdup (href);
+  item->metadata->icon_mime = g_strdup (type);
+}
+
+/* scans through the attributes of an element for the "xmlns" pragma, and
+ * adds any resulting namespace declaration to a per-parser hashtable, using
+ * the namespace name as a key for the namespace URI; if no key was found,
+ * the namespace is considered as default, and stored under the "default" key.
+ *
+ * FIXME: this works on the assumption that the generator of the XBEL file
+ * is either this code or is smart enough to place the namespace declarations
+ * inside the main root node or inside the metadata node and does not redefine 
+ * a namespace inside an inner node; this does *not* conform to the
+ * XML-NS standard, although is a close approximation.  In order to make this
+ * conformant to the XML-NS specification we should use a per-element
+ * namespace table inside GMarkup and ask it to resolve the namespaces for us.
+ */
+static void
+map_namespace_to_name (ParseData    *parse_data,
+                       const gchar **attribute_names,
+                      const gchar **attribute_values)
+{
+  const gchar *attr;
+  gint i;
+  g_warn_if_fail (parse_data != NULL);
+  
+  if (!attribute_names || !attribute_names[0])
+    return;
+  
+  i = 0;
+  for (attr = attribute_names[i]; attr; attr = attribute_names[++i])
+    {
+      if (g_str_has_prefix (attr, "xmlns"))
+        {
+          gchar *namespace_name, *namespace_uri;
+          gchar *p;
+          
+          p = g_utf8_strchr (attr, -1, ':');
+          if (p)
+            p = g_utf8_next_char (p);
+          else
+            p = "default";
+          
+          namespace_name = g_strdup (p);
+          namespace_uri = g_strdup (attribute_values[i]);
+          
+          g_hash_table_replace (parse_data->namespaces,
+                                namespace_name,
+                                namespace_uri);
+        }
+     }
+}
+
+/* checks whether @element_full is equal to @element.
+ *
+ * if @namespace is set, it tries to resolve the namespace to a known URI,
+ * and if found is prepended to the element name, from which is separated
+ * using the character specified in the @sep parameter.
+ */
+static gboolean
+is_element_full (ParseData   *parse_data,
+                 const gchar *element_full,
+                 const gchar *namespace,
+                 const gchar *element,
+                 const gchar  sep)
+{
+  gchar *ns_uri, *ns_name;
+  const gchar *p, *element_name;
+  gboolean retval;
+  g_warn_if_fail (parse_data != NULL);
+  g_warn_if_fail (element_full != NULL);
+  
+  if (!element)
+    return FALSE;
+    
+  /* no namespace requested: dumb element compare */
+  if (!namespace)
+    return (0 == strcmp (element_full, element));
+  
+  /* search for namespace separator; if none found, assume we are under the
+   * default namespace, and set ns_name to our "default" marker; if no default
+   * namespace has been set, just do a plain comparison between @full_element
+   * and @element.
+   */
+  p = g_utf8_strchr (element_full, -1, ':');
+  if (p)
+    {
+      ns_name = g_strndup (element_full, p - element_full);
+      element_name = g_utf8_next_char (p);
+    }
+  else
+    {
+      ns_name = g_strdup ("default");
+      element_name = element_full;
+    }
+  
+  ns_uri = g_hash_table_lookup (parse_data->namespaces, ns_name);  
+  if (!ns_uri)
+    {
+      /* no default namespace found */
+      g_free (ns_name);
+      
+      return (0 == strcmp (element_full, element));
+    }
+
+  retval = (0 == strcmp (ns_uri, namespace) &&
+            0 == strcmp (element_name, element));
+  
+  g_free (ns_name);
+  
+  return retval;
+}
+
+#define IS_ELEMENT(p,s,e)      (is_element_full ((p), (s), NULL, (e), '\0'))
+#define IS_ELEMENT_NS(p,s,n,e) (is_element_full ((p), (s), (n), (e), '|'))
+
+static void
+start_element_raw_cb (GMarkupParseContext *context,
+                      const gchar         *element_name,
+                      const gchar        **attribute_names,
+                      const gchar        **attribute_values,
+                      gpointer             user_data,
+                      GError             **error)
+{
+  ParseData *parse_data = (ParseData *) user_data;
+
+  /* we must check for namespace declarations first
+   * 
+   * XXX - we could speed up things by checking for namespace declarations
+   * only on the root node, where they usually are; this would probably break
+   * on streams not produced by us or by "smart" generators
+   */
+  map_namespace_to_name (parse_data, attribute_names, attribute_values);
+  
+  switch (parse_data->state)
+    {
+    case STATE_STARTED:
+      if (IS_ELEMENT (parse_data, element_name, XBEL_ROOT_ELEMENT))
+        {
+          const gchar *attr;
+          gint i;
+          
+          i = 0;
+          for (attr = attribute_names[i]; attr; attr = attribute_names[++i])
+            {
+              if ((IS_ATTRIBUTE (attr, XBEL_VERSION_ATTRIBUTE)) &&
+                  (0 == strcmp (attribute_values[i], XBEL_VERSION)))
+                parse_data->state = STATE_ROOT;
+            }
+       }
+      else
+        g_set_error (error, G_MARKUP_ERROR,
+                    G_MARKUP_ERROR_INVALID_CONTENT,
+                    _("Unexpected tag '%s', tag '%s' expected"),
+                    element_name, XBEL_ROOT_ELEMENT);
+      break;
+    case STATE_ROOT:
+      if (IS_ELEMENT (parse_data, element_name, XBEL_TITLE_ELEMENT))
+        parse_data->state = STATE_TITLE;
+      else if (IS_ELEMENT (parse_data, element_name, XBEL_DESC_ELEMENT))
+        parse_data->state = STATE_DESC;
+      else if (IS_ELEMENT (parse_data, element_name, XBEL_BOOKMARK_ELEMENT))
+        {
+          GError *inner_error = NULL;
+          
+          parse_data->state = STATE_BOOKMARK;
+          
+          parse_bookmark_element (context,
+                                 parse_data,
+                                 attribute_names,
+                                 attribute_values,
+                                 &inner_error);
+          if (inner_error)
+            g_propagate_error (error, inner_error);
+        }
+      else
+        g_set_error (error, G_MARKUP_ERROR,
+                    G_MARKUP_ERROR_INVALID_CONTENT,
+                    _("Unexpected tag '%s' inside '%s'"),
+                    element_name,
+                    XBEL_ROOT_ELEMENT);
+      break;
+    case STATE_BOOKMARK:
+      if (IS_ELEMENT (parse_data, element_name, XBEL_TITLE_ELEMENT))
+        parse_data->state = STATE_TITLE;
+      else if (IS_ELEMENT (parse_data, element_name, XBEL_DESC_ELEMENT))
+        parse_data->state = STATE_DESC;
+      else if (IS_ELEMENT (parse_data, element_name, XBEL_INFO_ELEMENT))
+        parse_data->state = STATE_INFO;
+      else
+        g_set_error (error, G_MARKUP_ERROR,
+                    G_MARKUP_ERROR_INVALID_CONTENT,
+                    _("Unexpected tag '%s' inside '%s'"),
+                    element_name,
+                    XBEL_BOOKMARK_ELEMENT);
+      break;
+    case STATE_INFO:
+      if (IS_ELEMENT (parse_data, element_name, XBEL_METADATA_ELEMENT))
+        {
+          const gchar *attr;
+          gint i;
+          
+          i = 0;
+          for (attr = attribute_names[i]; attr; attr = attribute_names[++i])
+            {
+              if ((IS_ATTRIBUTE (attr, XBEL_OWNER_ATTRIBUTE)) &&
+                  (0 == strcmp (attribute_values[i], BOOKMARK_METADATA_OWNER)))
+                {
+                  parse_data->state = STATE_METADATA;
+                  
+                  if (!parse_data->current_item->metadata)
+                    parse_data->current_item->metadata = bookmark_metadata_new ();
+                }
+            }
+        }
+      else
+        g_set_error (error, G_MARKUP_ERROR,
+                    G_MARKUP_ERROR_INVALID_CONTENT,
+                    _("Unexpected tag '%s', tag '%s' expected"),
+                    element_name,
+                    XBEL_METADATA_ELEMENT);
+      break;
+    case STATE_METADATA:
+      if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_APPLICATIONS_ELEMENT))
+        parse_data->state = STATE_APPLICATIONS;
+      else if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_GROUPS_ELEMENT))
+        parse_data->state = STATE_GROUPS;
+      else if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_PRIVATE_ELEMENT))
+        parse_data->current_item->metadata->is_private = TRUE;
+      else if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_ICON_ELEMENT))
+        {
+          GError *inner_error = NULL;
+          
+         parse_data->state = STATE_ICON;
+          
+          parse_icon_element (context,
+                             parse_data,
+                             attribute_names,
+                             attribute_values,
+                             &inner_error);
+          if (inner_error)
+            g_propagate_error (error, inner_error);
+        }
+      else if (IS_ELEMENT_NS (parse_data, element_name, MIME_NAMESPACE_URI, MIME_TYPE_ELEMENT))
+        {
+          GError *inner_error = NULL;
+          
+          parse_data->state = STATE_MIME;
+          
+          parse_mime_type_element (context,
+                                  parse_data,
+                                  attribute_names,
+                                  attribute_values,
+                                  &inner_error);
+          if (inner_error)
+            g_propagate_error (error, inner_error);
+        }
+      else
+        g_set_error (error, G_MARKUP_ERROR,
+                    G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                    _("Unexpected tag '%s' inside '%s'"),
+                    element_name,
+                    XBEL_METADATA_ELEMENT);
+      break;
+    case STATE_APPLICATIONS:
+      if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_APPLICATION_ELEMENT))
+        {
+          GError *inner_error = NULL;
+          
+          parse_data->state = STATE_APPLICATION;
+          
+          parse_application_element (context,
+                                    parse_data,
+                                    attribute_names,
+                                    attribute_values,
+                                    &inner_error);
+          if (inner_error)
+            g_propagate_error (error, inner_error);
+        }
+      else
+        g_set_error (error, G_MARKUP_ERROR,
+                    G_MARKUP_ERROR_INVALID_CONTENT,
+                    _("Unexpected tag '%s', tag '%s' expected"),
+                    element_name,
+                    BOOKMARK_APPLICATION_ELEMENT);
+      break;
+    case STATE_GROUPS:
+      if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_GROUP_ELEMENT))
+        parse_data->state = STATE_GROUP;
+      else
+        g_set_error (error, G_MARKUP_ERROR,
+                    G_MARKUP_ERROR_INVALID_CONTENT,
+                    _("Unexpected tag '%s', tag '%s' expected"),
+                    element_name,
+                    BOOKMARK_GROUP_ELEMENT);
+      break;
+    case STATE_ICON:
+      if (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_ICON_ELEMENT))
+        {
+          GError *inner_error = NULL;
+          
+          parse_icon_element (context,
+                             parse_data,
+                             attribute_names,
+                             attribute_values,
+                             &inner_error);
+          if (inner_error)
+            g_propagate_error (error, inner_error);
+        }
+      else
+        g_set_error (error, G_MARKUP_ERROR,
+                    G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+                    _("Unexpected tag '%s' inside '%s'"),
+                    element_name,
+                    XBEL_METADATA_ELEMENT);
+      break;
+    default:
+      g_warn_if_reached ();
+      break;
+    }
+}
+
+static void
+end_element_raw_cb (GMarkupParseContext *context,
+                    const gchar         *element_name,
+                    gpointer             user_data,
+                    GError             **error)
+{
+  ParseData *parse_data = (ParseData *) user_data;
+  
+  if (IS_ELEMENT (parse_data, element_name, XBEL_ROOT_ELEMENT))
+    parse_data->state = STATE_FINISHED;
+  else if (IS_ELEMENT (parse_data, element_name, XBEL_BOOKMARK_ELEMENT))
+    {
+      parse_data->current_item = NULL;
+      
+      parse_data->state = STATE_ROOT;
+    }
+  else if ((IS_ELEMENT (parse_data, element_name, XBEL_INFO_ELEMENT)) ||
+           (IS_ELEMENT (parse_data, element_name, XBEL_TITLE_ELEMENT)) ||
+           (IS_ELEMENT (parse_data, element_name, XBEL_DESC_ELEMENT)))
+    {
+      if (parse_data->current_item)
+        parse_data->state = STATE_BOOKMARK;
+      else
+        parse_data->state = STATE_ROOT;
+    }
+  else if (IS_ELEMENT (parse_data, element_name, XBEL_METADATA_ELEMENT))
+    parse_data->state = STATE_INFO;
+  else if (IS_ELEMENT_NS (parse_data, element_name,
+                          BOOKMARK_NAMESPACE_URI,
+                          BOOKMARK_APPLICATION_ELEMENT))
+    parse_data->state = STATE_APPLICATIONS;
+  else if (IS_ELEMENT_NS (parse_data, element_name,
+                          BOOKMARK_NAMESPACE_URI,
+                          BOOKMARK_GROUP_ELEMENT))
+    parse_data->state = STATE_GROUPS;
+  else if ((IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_APPLICATIONS_ELEMENT)) ||
+           (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_GROUPS_ELEMENT)) ||
+           (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_PRIVATE_ELEMENT)) ||
+           (IS_ELEMENT_NS (parse_data, element_name, BOOKMARK_NAMESPACE_URI, BOOKMARK_ICON_ELEMENT)) ||
+           (IS_ELEMENT_NS (parse_data, element_name, MIME_NAMESPACE_URI, MIME_TYPE_ELEMENT)))
+    parse_data->state = STATE_METADATA;
+}
+
+static void
+text_raw_cb (GMarkupParseContext *context,
+             const gchar         *text,
+             gsize                length,
+             gpointer             user_data,
+             GError             **error)
+{
+  ParseData *parse_data = (ParseData *) user_data;
+  gchar *payload;
+  
+  payload = g_strndup (text, length);
+  
+  switch (parse_data->state)
+    {
+    case STATE_TITLE:
+      if (parse_data->current_item)
+        {
+          g_free (parse_data->current_item->title);
+          parse_data->current_item->title = g_strdup (payload);
+        }
+      else
+        {
+          g_free (parse_data->bookmark_file->title);
+          parse_data->bookmark_file->title = g_strdup (payload);
+        }
+      break;
+    case STATE_DESC:
+      if (parse_data->current_item)
+        {
+          g_free (parse_data->current_item->description);
+          parse_data->current_item->description = g_strdup (payload);
+        }
+      else
+        {
+          g_free (parse_data->bookmark_file->description);
+          parse_data->bookmark_file->description = g_strdup (payload);
+        }
+      break;
+    case STATE_GROUP:
+      {
+      GList *groups;
+      
+      g_warn_if_fail (parse_data->current_item != NULL);
+      
+      if (!parse_data->current_item->metadata)
+        parse_data->current_item->metadata = bookmark_metadata_new ();
+      
+      groups = parse_data->current_item->metadata->groups;
+      parse_data->current_item->metadata->groups = g_list_prepend (groups, g_strdup (payload));
+      }
+      break;
+    case STATE_ROOT:
+    case STATE_BOOKMARK:
+    case STATE_INFO:
+    case STATE_METADATA:
+    case STATE_APPLICATIONS:
+    case STATE_APPLICATION:
+    case STATE_GROUPS:
+    case STATE_MIME:
+    case STATE_ICON:
+      break;
+    default:
+      g_warn_if_reached ();
+      break;
+    }
+  
+  g_free (payload);
+}
+
+static const GMarkupParser markup_parser =
+{
+  start_element_raw_cb, /* start_element */
+  end_element_raw_cb,   /* end_element */
+  text_raw_cb,          /* text */
+  NULL,                 /* passthrough */
+  NULL
+};
+
+static gboolean
+g_bookmark_file_parse (GBookmarkFile  *bookmark,
+                        const gchar      *buffer,
+                        gsize             length,
+                        GError          **error)
+{
+  GMarkupParseContext *context;
+  ParseData *parse_data;
+  GError *parse_error, *end_error;
+  gboolean retval;
+  
+  g_warn_if_fail (bookmark != NULL);
+
+  if (!buffer)
+    return FALSE;
+  
+  if (length == (gsize) -1)
+    length = strlen (buffer);
+
+  parse_data = parse_data_new ();
+  parse_data->bookmark_file = bookmark;
+  
+  context = g_markup_parse_context_new (&markup_parser,
+                                       0,
+                                       parse_data,
+                                       (GDestroyNotify) parse_data_free);
+  
+  parse_error = NULL;
+  retval = g_markup_parse_context_parse (context,
+                                        buffer,
+                                        length,
+                                        &parse_error);
+  if (!retval)
+    {
+      g_propagate_error (error, parse_error);
+      
+      return FALSE;
+    }
+  
+  end_error = NULL;
+  retval = g_markup_parse_context_end_parse (context, &end_error);
+  if (!retval)
+    {
+      g_propagate_error (error, end_error);
+      
+      return FALSE;
+    }
+  
+  g_markup_parse_context_free (context);
+  
+  return TRUE;
+}
+
+static gchar *
+g_bookmark_file_dump (GBookmarkFile  *bookmark,
+                     gsize          *length,
+                     GError        **error)
+{
+  GString *retval;
+  gchar *buffer;
+  GList *l;
+  
+  retval = g_string_sized_new (4096);
+
+  g_string_append (retval,
+                  "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
+#if 0
+                  /* XXX - do we really need the doctype? */
+                  "<!DOCTYPE " XBEL_DTD_NICK "\n"
+                  "  PUBLIC \"" XBEL_DTD_SYSTEM "\"\n"
+                  "         \"" XBEL_DTD_URI "\">\n"
+#endif
+                  "<" XBEL_ROOT_ELEMENT " " XBEL_VERSION_ATTRIBUTE "=\"" XBEL_VERSION "\"\n"
+                  "      xmlns:" BOOKMARK_NAMESPACE_NAME "=\"" BOOKMARK_NAMESPACE_URI "\"\n"
+                  "      xmlns:" MIME_NAMESPACE_NAME     "=\"" MIME_NAMESPACE_URI "\"\n>");
+  
+  if (bookmark->title)
+    {
+      gchar *escaped_title;
+      escaped_title = g_markup_escape_text (bookmark->title, -1);
+
+      buffer = g_strconcat ("  "
+                           "<" XBEL_TITLE_ELEMENT ">",
+                           escaped_title,
+                           "</" XBEL_TITLE_ELEMENT ">\n", NULL);
+      
+      g_string_append (retval, buffer);
+
+      g_free (buffer);
+      g_free (escaped_title);
+    }
+  
+  if (bookmark->description)
+    {
+      gchar *escaped_desc;
+      escaped_desc = g_markup_escape_text (bookmark->description, -1);
+
+      buffer = g_strconcat ("  "
+                           "<" XBEL_DESC_ELEMENT ">",
+                           escaped_desc,
+                           "</" XBEL_DESC_ELEMENT ">\n", NULL);
+      g_string_append (retval, buffer);
+
+      g_free (buffer);
+      g_free (escaped_desc);
+    }
+  
+  if (!bookmark->items)
+    goto out;
+  else
+    retval = g_string_append (retval, "\n");
+
+  /* the items are stored in reverse order */
+  for (l = g_list_last (bookmark->items);
+       l != NULL;
+       l = l->prev)
+    {
+      BookmarkItem *item = (BookmarkItem *) l->data;
+      gchar *item_dump;
+      
+      item_dump = bookmark_item_dump (item);
+      if (!item_dump)
+        continue;
+      
+      retval = g_string_append (retval, item_dump);
+      
+      g_free (item_dump);
+    }
+
+out:
+  g_string_append (retval, "</" XBEL_ROOT_ELEMENT ">");
+  
+  if (length)
+    *length = retval->len;
+  
+  return g_string_free (retval, FALSE);
+}
+
+/**************
+ *    Misc    *
+ **************/
+/* converts a Unix timestamp in a ISO 8601 compliant string; you
+ * should free the returned string.
+ */
+static gchar *
+timestamp_to_iso8601 (time_t timestamp)
+{
+  GTimeVal stamp;
+
+  if (timestamp == (time_t) -1)
+    g_get_current_time (&stamp);
+  else
+    {
+      stamp.tv_sec = timestamp;
+      stamp.tv_usec = 0;
+    }
+
+  return g_time_val_to_iso8601 (&stamp);
+}
+
+static time_t
+timestamp_from_iso8601 (const gchar *iso_date)
+{
+  GTimeVal stamp;
+
+  if (!g_time_val_from_iso8601 (iso_date, &stamp))
+    return (time_t) -1;
+
+  return (time_t) stamp.tv_sec;
+}
+
+
+
+GQuark
+g_bookmark_file_error_quark (void)
+{
+  return g_quark_from_static_string ("g-bookmark-file-error-quark");
+}
+
+
+
+/********************
+ *    Public API    *
+ ********************/
+
+/**
+ * g_bookmark_file_new:
+ *
+ * Creates a new empty #GBookmarkFile object.
+ *
+ * Use g_bookmark_file_load_from_file(), g_bookmark_file_load_from_data()
+ * or g_bookmark_file_load_from_data_dirs() to read an existing bookmark
+ * file.
+ *
+ * Return value: an empty #GBookmarkFile
+ *
+ * Since: 2.12
+ */
+GBookmarkFile *
+g_bookmark_file_new (void)
+{
+  GBookmarkFile *bookmark;
+  
+  bookmark = g_new (GBookmarkFile, 1);
+  
+  g_bookmark_file_init (bookmark);
+  
+  return bookmark;
+}
+
+/**
+ * g_bookmark_file_free:
+ * @bookmark: a #GBookmarkFile
+ *
+ * Frees a #GBookmarkFile.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_free (GBookmarkFile *bookmark)
+{
+  if (!bookmark)
+    return;
+  
+  g_bookmark_file_clear (bookmark);
+  
+  g_free (bookmark);  
+}
+
+/**
+ * g_bookmark_file_load_from_data:
+ * @bookmark: an empty #GBookmarkFile struct
+ * @data: desktop bookmarks loaded in memory
+ * @length: the length of @data in bytes
+ * @error: return location for a #GError, or %NULL
+ *
+ * Loads a bookmark file from memory into an empty #GBookmarkFile
+ * structure.  If the object cannot be created then @error is set to a
+ * #GBookmarkFileError.
+ *
+ * Return value: %TRUE if a desktop bookmark could be loaded.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_load_from_data (GBookmarkFile  *bookmark,
+                               const gchar    *data,
+                               gsize           length,
+                               GError        **error)
+{
+  GError *parse_error;
+  gboolean retval;
+  
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+
+  if (length == (gsize) -1)
+    length = strlen (data);
+
+  if (bookmark->items)
+    {
+      g_bookmark_file_clear (bookmark);
+      g_bookmark_file_init (bookmark);
+    }
+
+  parse_error = NULL;
+  retval = g_bookmark_file_parse (bookmark, data, length, &parse_error);
+  if (!retval)
+    {
+      g_propagate_error (error, parse_error);
+      
+      return FALSE;
+    }
+  
+  return TRUE;
+}
+
+/**
+ * g_bookmark_file_load_from_file:
+ * @bookmark: an empty #GBookmarkFile struct
+ * @filename: the path of a filename to load, in the GLib file name encoding
+ * @error: return location for a #GError, or %NULL
+ *
+ * Loads a desktop bookmark file into an empty #GBookmarkFile structure.
+ * If the file could not be loaded then @error is set to either a #GFileError
+ * or #GBookmarkFileError.
+ *
+ * Return value: %TRUE if a desktop bookmark file could be loaded
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_load_from_file (GBookmarkFile  *bookmark,
+                               const gchar    *filename,
+                               GError        **error)
+{
+  gchar *buffer;
+  gsize len;
+  GError *read_error;
+  gboolean retval;
+       
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (filename != NULL, FALSE);
+
+  read_error = NULL;
+  g_file_get_contents (filename, &buffer, &len, &read_error);
+  if (read_error)
+    {
+      g_propagate_error (error, read_error);
+
+      return FALSE;
+    }
+  
+  read_error = NULL;
+  retval = g_bookmark_file_load_from_data (bookmark,
+                                          buffer,
+                                          len,
+                                          &read_error);
+  if (read_error)
+    {
+      g_propagate_error (error, read_error);
+
+      g_free (buffer);
+
+      return FALSE;
+    }
+
+  g_free (buffer);
+
+  return retval;
+}
+
+
+/* Iterates through all the directories in *dirs trying to
+ * find file.  When it successfully locates file, returns a
+ * string its absolute path.  It also leaves the unchecked
+ * directories in *dirs.  You should free the returned string
+ *
+ * Adapted from gkeyfile.c
+ */
+static gchar *
+find_file_in_data_dirs (const gchar   *file,
+                        gchar       ***dirs,
+                        GError       **error)
+{
+  gchar **data_dirs, *data_dir, *path;
+
+  path = NULL;
+
+  if (dirs == NULL)
+    return NULL;
+
+  data_dirs = *dirs;
+  path = NULL;
+  while (data_dirs && (data_dir = *data_dirs) && !path)
+    {
+      gchar *candidate_file, *sub_dir;
+
+      candidate_file = (gchar *) file;
+      sub_dir = g_strdup ("");
+      while (candidate_file != NULL && !path)
+        {
+          gchar *p;
+
+          path = g_build_filename (data_dir, sub_dir,
+                                   candidate_file, NULL);
+
+          candidate_file = strchr (candidate_file, '-');
+
+          if (candidate_file == NULL)
+            break;
+
+          candidate_file++;
+
+          g_free (sub_dir);
+          sub_dir = g_strndup (file, candidate_file - file - 1);
+
+          for (p = sub_dir; *p != '\0'; p++)
+            {
+              if (*p == '-')
+                *p = G_DIR_SEPARATOR;
+            }
+        }
+      g_free (sub_dir);
+      data_dirs++;
+    }
+
+  *dirs = data_dirs;
+
+  if (!path)
+    {
+      g_set_error_literal (error, G_BOOKMARK_FILE_ERROR,
+                           G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND,
+                           _("No valid bookmark file found in data dirs"));
+      
+      return NULL;
+    }
+  
+  return path;
+}
+
+
+/**
+ * g_bookmark_file_load_from_data_dirs:
+ * @bookmark: a #GBookmarkFile
+ * @file: a relative path to a filename to open and parse
+ * @full_path: return location for a string containing the full path
+ *   of the file, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * This function looks for a desktop bookmark file named @file in the
+ * paths returned from g_get_user_data_dir() and g_get_system_data_dirs(), 
+ * loads the file into @bookmark and returns the file's full path in 
+ * @full_path.  If the file could not be loaded then an %error is
+ * set to either a #GFileError or #GBookmarkFileError.
+ *
+ * Return value: %TRUE if a key file could be loaded, %FALSE othewise
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_load_from_data_dirs (GBookmarkFile  *bookmark,
+                                    const gchar    *file,
+                                    gchar         **full_path,
+                                    GError        **error)
+{
+  GError *file_error = NULL;
+  gchar **all_data_dirs, **data_dirs;
+  const gchar *user_data_dir;
+  const gchar * const * system_data_dirs;
+  gsize i, j;
+  gchar *output_path;
+  gboolean found_file;
+  
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (!g_path_is_absolute (file), FALSE);
+  
+  user_data_dir = g_get_user_data_dir ();
+  system_data_dirs = g_get_system_data_dirs ();
+  all_data_dirs = g_new0 (gchar *, g_strv_length ((gchar **)system_data_dirs) + 2);
+
+  i = 0;
+  all_data_dirs[i++] = g_strdup (user_data_dir);
+
+  j = 0;
+  while (system_data_dirs[j] != NULL)
+    all_data_dirs[i++] = g_strdup (system_data_dirs[j++]);
+
+  found_file = FALSE;
+  data_dirs = all_data_dirs;
+  output_path = NULL;
+  while (*data_dirs != NULL && !found_file)
+    {
+      g_free (output_path);
+
+      output_path = find_file_in_data_dirs (file, &data_dirs, &file_error);
+      
+      if (file_error)
+        {
+          g_propagate_error (error, file_error);
+         break;
+        }
+
+      found_file = g_bookmark_file_load_from_file (bookmark,
+                                                  output_path,
+                                                  &file_error);
+      if (file_error)
+        {
+         g_propagate_error (error, file_error);
+         break;
+        }
+    }
+
+  if (found_file && full_path)
+    *full_path = output_path;
+  else 
+    g_free (output_path);
+
+  g_strfreev (all_data_dirs);
+
+  return found_file;
+}
+
+
+/**
+ * g_bookmark_file_to_data:
+ * @bookmark: a #GBookmarkFile
+ * @length: return location for the length of the returned string, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * This function outputs @bookmark as a string.
+ *
+ * Return value: a newly allocated string holding
+ *   the contents of the #GBookmarkFile
+ *
+ * Since: 2.12
+ */
+gchar *
+g_bookmark_file_to_data (GBookmarkFile  *bookmark,
+                        gsize          *length,
+                        GError        **error)
+{
+  GError *write_error = NULL;
+  gchar *retval;
+  
+  g_return_val_if_fail (bookmark != NULL, NULL);
+  
+  retval = g_bookmark_file_dump (bookmark, length, &write_error);
+  if (write_error)
+    {
+      g_propagate_error (error, write_error);
+      
+      return NULL;
+    }
+      
+  return retval;
+}
+
+/**
+ * g_bookmark_file_to_file:
+ * @bookmark: a #GBookmarkFile
+ * @filename: path of the output file
+ * @error: return location for a #GError, or %NULL
+ *
+ * This function outputs @bookmark into a file.  The write process is
+ * guaranteed to be atomic by using g_file_set_contents() internally.
+ *
+ * Return value: %TRUE if the file was successfully written.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_to_file (GBookmarkFile  *bookmark,
+                        const gchar    *filename,
+                        GError        **error)
+{
+  gchar *data;
+  GError *data_error, *write_error;
+  gsize len;
+  gboolean retval;
+
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (filename != NULL, FALSE);
+  
+  data_error = NULL;
+  data = g_bookmark_file_to_data (bookmark, &len, &data_error);
+  if (data_error)
+    {
+      g_propagate_error (error, data_error);
+      
+      return FALSE;
+    }
+
+  write_error = NULL;
+  g_file_set_contents (filename, data, len, &write_error);
+  if (write_error)
+    {
+      g_propagate_error (error, write_error);
+      
+      retval = FALSE;
+    }
+  else
+    retval = TRUE;
+
+  g_free (data);
+  
+  return retval;
+}
+
+static BookmarkItem *
+g_bookmark_file_lookup_item (GBookmarkFile *bookmark,
+                            const gchar   *uri)
+{
+  g_warn_if_fail (bookmark != NULL && uri != NULL);
+  
+  return g_hash_table_lookup (bookmark->items_by_uri, uri);
+}
+
+/* this function adds a new item to the list */
+static void
+g_bookmark_file_add_item (GBookmarkFile  *bookmark,
+                         BookmarkItem   *item,
+                         GError        **error)
+{
+  g_warn_if_fail (bookmark != NULL);
+  g_warn_if_fail (item != NULL);
+
+  /* this should never happen; and if it does, then we are
+   * screwing up something big time.
+   */
+  if (G_UNLIKELY (g_bookmark_file_has_item (bookmark, item->uri)))
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_INVALID_URI,
+                  _("A bookmark for URI '%s' already exists"),
+                  item->uri);
+      return;
+    }
+  
+  bookmark->items = g_list_prepend (bookmark->items, item);
+  
+  g_hash_table_replace (bookmark->items_by_uri,
+                       item->uri,
+                       item);
+
+  if (item->added == (time_t) -1)
+    item->added = time (NULL);
+  
+  if (item->modified == (time_t) -1)
+    item->modified = time (NULL);
+}
+
+/**
+ * g_bookmark_file_remove_item:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Removes the bookmark for @uri from the bookmark file @bookmark.
+ *
+ * Return value: %TRUE if the bookmark was removed successfully.
+ * 
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_remove_item (GBookmarkFile  *bookmark,
+                            const gchar    *uri,
+                            GError        **error)
+{
+  BookmarkItem *item;
+  
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (uri != NULL, FALSE);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return FALSE;
+    }
+
+  bookmark->items = g_list_remove (bookmark->items, item);
+  g_hash_table_remove (bookmark->items_by_uri, item->uri);  
+  
+  bookmark_item_free (item);
+
+  return TRUE;
+}
+
+/**
+ * g_bookmark_file_has_item:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ *
+ * Looks whether the desktop bookmark has an item with its URI set to @uri.
+ *
+ * Return value: %TRUE if @uri is inside @bookmark, %FALSE otherwise
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_has_item (GBookmarkFile *bookmark,
+                         const gchar   *uri)
+{
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (uri != NULL, FALSE);
+  
+  return (NULL != g_hash_table_lookup (bookmark->items_by_uri, uri));
+}
+
+/**
+ * g_bookmark_file_get_uris:
+ * @bookmark: a #GBookmarkFile
+ * @length: return location for the number of returned URIs, or %NULL
+ *
+ * Returns all URIs of the bookmarks in the bookmark file @bookmark.
+ * The array of returned URIs will be %NULL-terminated, so @length may
+ * optionally be %NULL.
+ *
+ * Return value: a newly allocated %NULL-terminated array of strings.
+ *   Use g_strfreev() to free it.
+ *
+ * Since: 2.12
+ */
+gchar **
+g_bookmark_file_get_uris (GBookmarkFile *bookmark,
+                         gsize         *length)
+{
+  GList *l;
+  gchar **uris;
+  gsize i, n_items;
+  
+  g_return_val_if_fail (bookmark != NULL, NULL);
+  
+  n_items = g_list_length (bookmark->items); 
+  uris = g_new0 (gchar *, n_items + 1);
+
+  /* the items are stored in reverse order, so we walk the list backward */
+  for (l = g_list_last (bookmark->items), i = 0; l != NULL; l = l->prev)
+    {
+      BookmarkItem *item = (BookmarkItem *) l->data;
+      
+      g_warn_if_fail (item != NULL);
+      
+      uris[i++] = g_strdup (item->uri);
+    }
+  uris[i] = NULL;
+  
+  if (length)
+    *length = i;
+  
+  return uris;
+}
+
+/**
+ * g_bookmark_file_set_title:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI or %NULL
+ * @title: a UTF-8 encoded string
+ *
+ * Sets @title as the title of the bookmark for @uri inside the
+ * bookmark file @bookmark.
+ *
+ * If @uri is %NULL, the title of @bookmark is set.
+ *
+ * If a bookmark for @uri cannot be found then it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_title (GBookmarkFile *bookmark,
+                          const gchar   *uri,
+                          const gchar   *title)
+{
+  g_return_if_fail (bookmark != NULL);
+  
+  if (!uri)
+    {
+      g_free (bookmark->title);
+      bookmark->title = g_strdup (title);
+    }
+  else
+    {
+      BookmarkItem *item;
+      
+      item = g_bookmark_file_lookup_item (bookmark, uri);
+      if (!item)
+        {
+          item = bookmark_item_new (uri);
+          g_bookmark_file_add_item (bookmark, item, NULL);
+        }
+      
+      g_free (item->title);
+      item->title = g_strdup (title);
+      
+      item->modified = time (NULL);
+    }
+}
+
+/**
+ * g_bookmark_file_get_title:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns the title of the bookmark for @uri.
+ *
+ * If @uri is %NULL, the title of @bookmark is returned.
+ *
+ * In the event the URI cannot be found, %NULL is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: a newly allocated string or %NULL if the specified
+ *   URI cannot be found.
+ *
+ * Since: 2.12
+ */
+gchar *
+g_bookmark_file_get_title (GBookmarkFile  *bookmark,
+                          const gchar    *uri,
+                          GError        **error)
+{
+  BookmarkItem *item;
+  
+  g_return_val_if_fail (bookmark != NULL, NULL);
+  
+  if (!uri)
+    return g_strdup (bookmark->title);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return NULL;
+    }
+  
+  return g_strdup (item->title);
+}
+
+/**
+ * g_bookmark_file_set_description:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI or %NULL
+ * @description: a string
+ *
+ * Sets @description as the description of the bookmark for @uri.
+ *
+ * If @uri is %NULL, the description of @bookmark is set.
+ *
+ * If a bookmark for @uri cannot be found then it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_description (GBookmarkFile *bookmark,
+                                const gchar   *uri,
+                                const gchar   *description)
+{
+  g_return_if_fail (bookmark != NULL);
+
+  if (!uri)
+    {
+      g_free (bookmark->description); 
+      bookmark->description = g_strdup (description);
+    }
+  else
+    {
+      BookmarkItem *item;
+      
+      item = g_bookmark_file_lookup_item (bookmark, uri);
+      if (!item)
+        {
+          item = bookmark_item_new (uri);
+          g_bookmark_file_add_item (bookmark, item, NULL);
+        }
+      
+      g_free (item->description);
+      item->description = g_strdup (description);
+      
+      item->modified = time (NULL);
+    }
+}
+
+/**
+ * g_bookmark_file_get_description:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Retrieves the description of the bookmark for @uri.
+ *
+ * In the event the URI cannot be found, %NULL is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: a newly allocated string or %NULL if the specified
+ *   URI cannot be found.
+ *
+ * Since: 2.12
+ */
+gchar *
+g_bookmark_file_get_description (GBookmarkFile  *bookmark,
+                                const gchar    *uri,
+                                GError        **error)
+{
+  BookmarkItem *item;
+  
+  g_return_val_if_fail (bookmark != NULL, NULL);
+
+  if (!uri)
+    return g_strdup (bookmark->description);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return NULL;
+    }
+  
+  return g_strdup (item->description);
+}
+
+/**
+ * g_bookmark_file_set_mime_type:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @mime_type: a MIME type
+ *
+ * Sets @mime_type as the MIME type of the bookmark for @uri.
+ *
+ * If a bookmark for @uri cannot be found then it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_mime_type (GBookmarkFile *bookmark,
+                              const gchar   *uri,
+                              const gchar   *mime_type)
+{
+  BookmarkItem *item;
+  
+  g_return_if_fail (bookmark != NULL);
+  g_return_if_fail (uri != NULL);
+  g_return_if_fail (mime_type != NULL);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      item = bookmark_item_new (uri);
+      g_bookmark_file_add_item (bookmark, item, NULL);
+    }
+  
+  if (!item->metadata)
+    item->metadata = bookmark_metadata_new ();
+  
+  g_free (item->metadata->mime_type);
+  
+  item->metadata->mime_type = g_strdup (mime_type);
+  item->modified = time (NULL);
+}
+
+/**
+ * g_bookmark_file_get_mime_type:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Retrieves the MIME type of the resource pointed by @uri.
+ *
+ * In the event the URI cannot be found, %NULL is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.  In the
+ * event that the MIME type cannot be found, %NULL is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: a newly allocated string or %NULL if the specified
+ *   URI cannot be found.
+ *
+ * Since: 2.12
+ */
+gchar *
+g_bookmark_file_get_mime_type (GBookmarkFile  *bookmark,
+                              const gchar    *uri,
+                              GError        **error)
+{
+  BookmarkItem *item;
+  
+  g_return_val_if_fail (bookmark != NULL, NULL);
+  g_return_val_if_fail (uri != NULL, NULL);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return NULL;
+    }
+  
+  if (!item->metadata)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_INVALID_VALUE,
+                  _("No MIME type defined in the bookmark for URI '%s'"),
+                  uri);
+      return NULL;
+    }
+  
+  return g_strdup (item->metadata->mime_type);
+}
+
+/**
+ * g_bookmark_file_set_is_private:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @is_private: %TRUE if the bookmark should be marked as private
+ *
+ * Sets the private flag of the bookmark for @uri.
+ *
+ * If a bookmark for @uri cannot be found then it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_is_private (GBookmarkFile *bookmark,
+                               const gchar   *uri,
+                               gboolean       is_private)
+{
+  BookmarkItem *item;
+  
+  g_return_if_fail (bookmark != NULL);
+  g_return_if_fail (uri != NULL);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      item = bookmark_item_new (uri);
+      g_bookmark_file_add_item (bookmark, item, NULL);
+    }
+  
+  if (!item->metadata)
+    item->metadata = bookmark_metadata_new ();
+  
+  item->metadata->is_private = (is_private == TRUE);
+  item->modified = time (NULL);
+}
+
+/**
+ * g_bookmark_file_get_is_private:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets whether the private flag of the bookmark for @uri is set.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.  In the
+ * event that the private flag cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: %TRUE if the private flag is set, %FALSE otherwise.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_get_is_private (GBookmarkFile  *bookmark,
+                               const gchar    *uri,
+                               GError        **error)
+{
+  BookmarkItem *item;
+  
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (uri != NULL, FALSE);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return FALSE;
+    }
+  
+  if (!item->metadata)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_INVALID_VALUE,
+                  _("No private flag has been defined in bookmark for URI '%s'"),
+                   uri);
+      return FALSE;
+    }
+  
+  return item->metadata->is_private;
+}
+
+/**
+ * g_bookmark_file_set_added:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @added: a timestamp or -1 to use the current time
+ *
+ * Sets the time the bookmark for @uri was added into @bookmark.
+ *
+ * If no bookmark for @uri is found then it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_added (GBookmarkFile *bookmark,
+                          const gchar   *uri,
+                          time_t         added)
+{
+  BookmarkItem *item;
+  
+  g_return_if_fail (bookmark != NULL);
+  g_return_if_fail (uri != NULL);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      item = bookmark_item_new (uri);
+      g_bookmark_file_add_item (bookmark, item, NULL);
+    }
+
+  if (added == (time_t) -1)
+    time (&added);
+  
+  item->added = added;
+  item->modified = added;
+}
+
+/**
+ * g_bookmark_file_get_added:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the time the bookmark for @uri was added to @bookmark
+ *
+ * In the event the URI cannot be found, -1 is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: a timestamp
+ *
+ * Since: 2.12
+ */
+time_t
+g_bookmark_file_get_added (GBookmarkFile  *bookmark,
+                          const gchar    *uri,
+                          GError        **error)
+{
+  BookmarkItem *item;
+  
+  g_return_val_if_fail (bookmark != NULL, (time_t) -1);
+  g_return_val_if_fail (uri != NULL, (time_t) -1);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return (time_t) -1;
+    }
+  
+  return item->added;
+}
+
+/**
+ * g_bookmark_file_set_modified:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @modified: a timestamp or -1 to use the current time
+ *
+ * Sets the last time the bookmark for @uri was last modified.
+ *
+ * If no bookmark for @uri is found then it is created.
+ *
+ * The "modified" time should only be set when the bookmark's meta-data
+ * was actually changed.  Every function of #GBookmarkFile that
+ * modifies a bookmark also changes the modification time, except for
+ * g_bookmark_file_set_visited().
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_modified (GBookmarkFile *bookmark,
+                             const gchar   *uri,
+                             time_t         modified)
+{
+  BookmarkItem *item;
+  
+  g_return_if_fail (bookmark != NULL);
+  g_return_if_fail (uri != NULL);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      item = bookmark_item_new (uri);
+      g_bookmark_file_add_item (bookmark, item, NULL);
+    }
+  
+  if (modified == (time_t) -1)
+    time (&modified);
+  
+  item->modified = modified;
+}
+
+/**
+ * g_bookmark_file_get_modified:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the time when the bookmark for @uri was last modified.
+ *
+ * In the event the URI cannot be found, -1 is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: a timestamp
+ *
+ * Since: 2.12
+ */
+time_t
+g_bookmark_file_get_modified (GBookmarkFile  *bookmark,
+                             const gchar    *uri,
+                             GError        **error)
+{
+  BookmarkItem *item;
+  
+  g_return_val_if_fail (bookmark != NULL, (time_t) -1);
+  g_return_val_if_fail (uri != NULL, (time_t) -1);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return (time_t) -1;
+    }
+  
+  return item->modified;
+}
+
+/**
+ * g_bookmark_file_set_visited:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @visited: a timestamp or -1 to use the current time
+ *
+ * Sets the time the bookmark for @uri was last visited.
+ *
+ * If no bookmark for @uri is found then it is created.
+ *
+ * The "visited" time should only be set if the bookmark was launched, 
+ * either using the command line retrieved by g_bookmark_file_get_app_info()
+ * or by the default application for the bookmark's MIME type, retrieved
+ * using g_bookmark_file_get_mime_type().  Changing the "visited" time
+ * does not affect the "modified" time.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_visited (GBookmarkFile *bookmark,
+                            const gchar   *uri,
+                            time_t         visited)
+{
+  BookmarkItem *item;
+  
+  g_return_if_fail (bookmark != NULL);
+  g_return_if_fail (uri != NULL);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      item = bookmark_item_new (uri);
+      g_bookmark_file_add_item (bookmark, item, NULL);
+    }
+
+  if (visited == (time_t) -1)
+    time (&visited);
+  
+  item->visited = visited;
+}
+
+/**
+ * g_bookmark_file_get_visited:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the time the bookmark for @uri was last visited.
+ *
+ * In the event the URI cannot be found, -1 is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: a timestamp.
+ *
+ * Since: 2.12
+ */
+time_t
+g_bookmark_file_get_visited (GBookmarkFile  *bookmark,
+                            const gchar    *uri,
+                            GError        **error)
+{
+  BookmarkItem *item;
+  
+  g_return_val_if_fail (bookmark != NULL, (time_t) -1);
+  g_return_val_if_fail (uri != NULL, (time_t) -1);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return (time_t) -1;
+    }
+  
+  return item->visited;
+}
+
+/**
+ * g_bookmark_file_has_group:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @group: the group name to be searched
+ * @error: return location for a #GError, or %NULL
+ *
+ * Checks whether @group appears in the list of groups to which
+ * the bookmark for @uri belongs to.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: %TRUE if @group was found.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_has_group (GBookmarkFile  *bookmark,
+                          const gchar    *uri,
+                          const gchar    *group,
+                          GError        **error)
+{
+  BookmarkItem *item;
+  GList *l;
+  
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (uri != NULL, FALSE);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return FALSE;
+    }
+  
+  if (!item->metadata)
+    return FALSE;
+   
+  for (l = item->metadata->groups; l != NULL; l = l->next)
+    {
+      if (strcmp (l->data, group) == 0)
+        return TRUE;
+    }
+  
+  return FALSE;
+
+}
+
+/**
+ * g_bookmark_file_add_group:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @group: the group name to be added
+ *
+ * Adds @group to the list of groups to which the bookmark for @uri
+ * belongs to.
+ *
+ * If no bookmark for @uri is found then it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_add_group (GBookmarkFile *bookmark,
+                          const gchar   *uri,
+                          const gchar   *group)
+{
+  BookmarkItem *item;
+  
+  g_return_if_fail (bookmark != NULL);
+  g_return_if_fail (uri != NULL);
+  g_return_if_fail (group != NULL && group[0] != '\0');
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      item = bookmark_item_new (uri);
+      g_bookmark_file_add_item (bookmark, item, NULL);
+    }
+  
+  if (!item->metadata)
+    item->metadata = bookmark_metadata_new ();
+  
+  if (!g_bookmark_file_has_group (bookmark, uri, group, NULL))
+    {
+      item->metadata->groups = g_list_prepend (item->metadata->groups,
+                                               g_strdup (group));
+      
+      item->modified = time (NULL);
+    }
+}
+
+/**
+ * g_bookmark_file_remove_group:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @group: the group name to be removed
+ * @error: return location for a #GError, or %NULL
+ *
+ * Removes @group from the list of groups to which the bookmark
+ * for @uri belongs to.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ * In the event no group was defined, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: %TRUE if @group was successfully removed.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_remove_group (GBookmarkFile  *bookmark,
+                             const gchar    *uri,
+                             const gchar    *group,
+                             GError        **error)
+{
+  BookmarkItem *item;
+  GList *l;
+  
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (uri != NULL, FALSE);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return FALSE;
+    }
+  
+  if (!item->metadata)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                   G_BOOKMARK_FILE_ERROR_INVALID_VALUE,
+                   _("No groups set in bookmark for URI '%s'"),
+                   uri);
+      return FALSE;
+    }
+  
+  for (l = item->metadata->groups; l != NULL; l = l->next)
+    {
+      if (strcmp (l->data, group) == 0)
+        {
+          item->metadata->groups = g_list_remove_link (item->metadata->groups, l);
+          g_free (l->data);
+         g_list_free_1 (l);
+          
+          item->modified = time (NULL);          
+          
+          return TRUE;
+        }
+    }
+  
+  return FALSE;
+}
+
+/**
+ * g_bookmark_file_set_groups:
+ * @bookmark: a #GBookmarkFile
+ * @uri: an item's URI
+ * @groups: an array of group names, or %NULL to remove all groups
+ * @length: number of group name values in @groups
+ *
+ * Sets a list of group names for the item with URI @uri.  Each previously
+ * set group name list is removed.
+ *
+ * If @uri cannot be found then an item for it is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_groups (GBookmarkFile  *bookmark,
+                           const gchar    *uri,
+                           const gchar   **groups,
+                           gsize           length)
+{
+  BookmarkItem *item;
+  gsize i;
+  
+  g_return_if_fail (bookmark != NULL);
+  g_return_if_fail (uri != NULL);
+  g_return_if_fail (groups != NULL);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      item = bookmark_item_new (uri);
+      g_bookmark_file_add_item (bookmark, item, NULL);
+    }
+  
+  if (!item->metadata)
+    item->metadata = bookmark_metadata_new ();
+
+  if (item->metadata->groups != NULL)
+    {
+      g_list_foreach (item->metadata->groups,
+                     (GFunc) g_free,
+                     NULL);
+      g_list_free (item->metadata->groups);
+      item->metadata->groups = NULL;
+    }
+  
+  if (groups)
+    {
+      for (i = 0; groups[i] != NULL && i < length; i++)
+        item->metadata->groups = g_list_append (item->metadata->groups,
+                                               g_strdup (groups[i]));
+    }
+
+  item->modified = time (NULL);
+}
+
+/**
+ * g_bookmark_file_get_groups:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @length: return location for the length of the returned string, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Retrieves the list of group names of the bookmark for @uri.
+ *
+ * In the event the URI cannot be found, %NULL is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * The returned array is %NULL terminated, so @length may optionally
+ * be %NULL.
+ *
+ * Return value: a newly allocated %NULL-terminated array of group names.
+ *   Use g_strfreev() to free it.
+ *
+ * Since: 2.12
+ */
+gchar **
+g_bookmark_file_get_groups (GBookmarkFile  *bookmark,
+                           const gchar    *uri,
+                           gsize          *length,
+                           GError        **error)
+{
+  BookmarkItem *item;
+  GList *l;
+  gsize len, i;
+  gchar **retval;
+  
+  g_return_val_if_fail (bookmark != NULL, NULL);
+  g_return_val_if_fail (uri != NULL, NULL);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return NULL;
+    }
+  
+  if (!item->metadata)
+    {
+      if (length)
+       *length = 0;
+      
+      return NULL;
+    }
+  
+  len = g_list_length (item->metadata->groups);
+  retval = g_new0 (gchar *, len + 1);
+  for (l = g_list_last (item->metadata->groups), i = 0;
+       l != NULL;
+       l = l->prev)
+    {
+      gchar *group_name = (gchar *) l->data;
+      
+      g_warn_if_fail (group_name != NULL);
+      
+      retval[i++] = g_strdup (group_name);
+    }
+  retval[i] = NULL;
+  
+  if (length)
+    *length = len;
+  
+  return retval;
+}
+
+/**
+ * g_bookmark_file_add_application:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @name: the name of the application registering the bookmark
+ *   or %NULL
+ * @exec: command line to be used to launch the bookmark or %NULL
+ *
+ * Adds the application with @name and @exec to the list of
+ * applications that have registered a bookmark for @uri into
+ * @bookmark.
+ *
+ * Every bookmark inside a #GBookmarkFile must have at least an
+ * application registered.  Each application must provide a name, a
+ * command line useful for launching the bookmark, the number of times
+ * the bookmark has been registered by the application and the last
+ * time the application registered this bookmark.
+ *
+ * If @name is %NULL, the name of the application will be the
+ * same returned by g_get_application_name(); if @exec is %NULL, the
+ * command line will be a composition of the program name as
+ * returned by g_get_prgname() and the "%u" modifier, which will be
+ * expanded to the bookmark's URI.
+ *
+ * This function will automatically take care of updating the
+ * registrations count and timestamping in case an application
+ * with the same @name had already registered a bookmark for
+ * @uri inside @bookmark.
+ *
+ * If no bookmark for @uri is found, one is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_add_application (GBookmarkFile *bookmark,
+                                const gchar   *uri,
+                                const gchar   *name,
+                                const gchar   *exec)
+{
+  BookmarkItem *item;
+  gchar *app_name, *app_exec;
+  
+  g_return_if_fail (bookmark != NULL);
+  g_return_if_fail (uri != NULL);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      item = bookmark_item_new (uri);
+      g_bookmark_file_add_item (bookmark, item, NULL);
+    }
+  
+  if (name && name[0] != '\0')
+    app_name = g_strdup (name);
+  else
+    app_name = g_strdup (g_get_application_name ());
+  
+  if (exec && exec[0] != '\0')
+    app_exec = g_strdup (exec);
+  else
+    app_exec = g_strjoin (" ", g_get_prgname(), "%u", NULL);
+
+  g_bookmark_file_set_app_info (bookmark, uri,
+                                app_name,
+                                app_exec,
+                                -1,
+                                (time_t) -1,
+                                NULL);
+  
+  g_free (app_exec);
+  g_free (app_name);
+}
+
+/**
+ * g_bookmark_file_remove_application:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @name: the name of the application
+ * @error: return location for a #GError or %NULL
+ *
+ * Removes application registered with @name from the list of applications
+ * that have registered a bookmark for @uri inside @bookmark.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ * In the event that no application with name @app_name has registered
+ * a bookmark for @uri,  %FALSE is returned and error is set to
+ * #G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED.
+ *
+ * Return value: %TRUE if the application was successfully removed.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_remove_application (GBookmarkFile  *bookmark,
+                                   const gchar    *uri,
+                                   const gchar    *name,
+                                   GError        **error)
+{
+  GError *set_error;
+  gboolean retval;
+    
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (uri != NULL, FALSE);
+  g_return_val_if_fail (name != NULL, FALSE);
+  
+  set_error = NULL;
+  retval = g_bookmark_file_set_app_info (bookmark, uri,
+                                        name,
+                                        "",
+                                        0,
+                                        (time_t) -1,
+                                        &set_error);
+  if (set_error)
+    {
+      g_propagate_error (error, set_error);
+      
+      return FALSE;
+    }
+  
+  return retval;
+}
+
+/**
+ * g_bookmark_file_has_application:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @name: the name of the application
+ * @error: return location for a #GError or %NULL
+ *
+ * Checks whether the bookmark for @uri inside @bookmark has been
+ * registered by application @name.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: %TRUE if the application @name was found
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_has_application (GBookmarkFile  *bookmark,
+                                const gchar    *uri,
+                                const gchar    *name,
+                                GError        **error)
+{
+  BookmarkItem *item;
+  
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (uri != NULL, FALSE);
+  g_return_val_if_fail (name != NULL, FALSE);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return FALSE;
+    }
+  
+  return (NULL != bookmark_item_lookup_app_info (item, name));
+}
+
+/**
+ * g_bookmark_file_set_app_info:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @name: an application's name
+ * @exec: an application's command line
+ * @count: the number of registrations done for this application
+ * @stamp: the time of the last registration for this application
+ * @error: return location for a #GError or %NULL
+ *
+ * Sets the meta-data of application @name inside the list of
+ * applications that have registered a bookmark for @uri inside
+ * @bookmark.
+ *
+ * You should rarely use this function; use g_bookmark_file_add_application()
+ * and g_bookmark_file_remove_application() instead.
+ *
+ * @name can be any UTF-8 encoded string used to identify an
+ * application.
+ * @exec can have one of these two modifiers: "%f", which will
+ * be expanded as the local file name retrieved from the bookmark's
+ * URI; "%u", which will be expanded as the bookmark's URI.
+ * The expansion is done automatically when retrieving the stored
+ * command line using the g_bookmark_file_get_app_info() function.
+ * @count is the number of times the application has registered the
+ * bookmark; if is < 0, the current registration count will be increased
+ * by one, if is 0, the application with @name will be removed from
+ * the list of registered applications.
+ * @stamp is the Unix time of the last registration; if it is -1, the
+ * current time will be used.
+ *
+ * If you try to remove an application by setting its registration count to
+ * zero, and no bookmark for @uri is found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND; similarly,
+ * in the event that no application @name has registered a bookmark
+ * for @uri,  %FALSE is returned and error is set to
+ * #G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED.  Otherwise, if no bookmark
+ * for @uri is found, one is created.
+ *
+ * Return value: %TRUE if the application's meta-data was successfully
+ *   changed.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_set_app_info (GBookmarkFile  *bookmark,
+                             const gchar    *uri,
+                             const gchar    *name,
+                             const gchar    *exec,
+                             gint            count,
+                             time_t          stamp,
+                             GError        **error)
+{
+  BookmarkItem *item;
+  BookmarkAppInfo *ai;
+  
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (uri != NULL, FALSE);
+  g_return_val_if_fail (name != NULL, FALSE);
+  g_return_val_if_fail (exec != NULL, FALSE);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      if (count == 0)
+        {
+          g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                      G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                      _("No bookmark found for URI '%s'"),
+                      uri);
+         return FALSE;
+       }
+      else
+        {
+          item = bookmark_item_new (uri);
+         g_bookmark_file_add_item (bookmark, item, NULL);
+       }
+    }
+  
+  ai = bookmark_item_lookup_app_info (item, name);
+  if (!ai)
+    {
+      if (count == 0)
+        {
+          g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                      G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED,
+                      _("No application with name '%s' registered a bookmark for '%s'"),
+                      name,
+                      uri);
+          return FALSE;
+        }
+      else
+        {
+          ai = bookmark_app_info_new (name);
+          
+          item->metadata->applications = g_list_prepend (item->metadata->applications, ai);
+          g_hash_table_replace (item->metadata->apps_by_name, ai->name, ai);
+        }
+    }
+
+  if (count == 0)
+    {
+      item->metadata->applications = g_list_remove (item->metadata->applications, ai);
+      g_hash_table_remove (item->metadata->apps_by_name, ai->name);
+      bookmark_app_info_free (ai);
+
+      item->modified = time (NULL);
+          
+      return TRUE;
+    }
+  else if (count > 0)
+    ai->count = count;
+  else
+    ai->count += 1;
+      
+  if (stamp != (time_t) -1)
+    ai->stamp = stamp;
+  else
+    ai->stamp = time (NULL);
+  
+  if (exec && exec[0] != '\0')
+    {
+      g_free (ai->exec);
+      ai->exec = g_shell_quote (exec);
+    }
+  
+  item->modified = time (NULL);
+  
+  return TRUE;
+}
+
+/* expands the application's command line */
+static gchar *
+expand_exec_line (const gchar *exec_fmt,
+                 const gchar *uri)
+{
+  GString *exec;
+  gchar ch;
+  
+  exec = g_string_sized_new (512);
+  while ((ch = *exec_fmt++) != '\0')
+   {
+     if (ch != '%')
+       {
+         exec = g_string_append_c (exec, ch);
+         continue;
+       }
+     
+     ch = *exec_fmt++;
+     switch (ch)
+       {
+       case '\0':
+        goto out;
+       case 'U':
+       case 'u':
+         g_string_append (exec, uri);
+         break;
+       case 'F':
+       case 'f':
+         {
+          gchar *file = g_filename_from_uri (uri, NULL, NULL);
+           if (file)
+             {
+              g_string_append (exec, file);
+              g_free (file);
+             }
+           else
+             {
+               g_string_free (exec, TRUE);
+               return NULL;
+             }
+         }
+         break;
+       case '%':
+       default:
+         exec = g_string_append_c (exec, ch);
+         break;
+       }
+   }
+   
+ out:
+  return g_string_free (exec, FALSE);
+}
+
+/**
+ * g_bookmark_file_get_app_info:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @name: an application's name
+ * @exec: location for the command line of the application, or %NULL
+ * @count: return location for the registration count, or %NULL
+ * @stamp: return location for the last registration time, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Gets the registration informations of @app_name for the bookmark for
+ * @uri.  See g_bookmark_file_set_app_info() for more informations about
+ * the returned data.
+ *
+ * The string returned in @app_exec must be freed.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.  In the
+ * event that no application with name @app_name has registered a bookmark
+ * for @uri,  %FALSE is returned and error is set to
+ * #G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED. In the event that unquoting
+ * the command line fails, an error of the #G_SHELL_ERROR domain is
+ * set and %FALSE is returned.
+ *
+ * Return value: %TRUE on success.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_get_app_info (GBookmarkFile  *bookmark,
+                             const gchar    *uri,
+                             const gchar    *name,
+                             gchar         **exec,
+                             guint          *count,
+                             time_t         *stamp,
+                             GError        **error)
+{
+  BookmarkItem *item;
+  BookmarkAppInfo *ai;
+  
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (uri != NULL, FALSE);
+  g_return_val_if_fail (name != NULL, FALSE);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return FALSE;
+    }
+  
+  ai = bookmark_item_lookup_app_info (item, name);
+  if (!ai)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED,
+                  _("No application with name '%s' registered a bookmark for '%s'"),
+                  name,
+                  uri);
+      return FALSE;
+    }
+  
+  if (exec)
+    {
+      GError *unquote_error = NULL;
+      gchar *command_line;
+      
+      command_line = g_shell_unquote (ai->exec, &unquote_error);
+      if (unquote_error)
+        {
+          g_propagate_error (error, unquote_error);
+          return FALSE;
+        }
+
+      *exec = expand_exec_line (command_line, uri);
+      if (!*exec)
+        {
+          g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                      G_BOOKMARK_FILE_ERROR_INVALID_URI,
+                      _("Failed to expand exec line '%s' with URI '%s'"),
+                    ai->exec, uri);
+          g_free (command_line);
+
+          return FALSE;
+        }
+      else
+        g_free (command_line);
+    } 
+
+  if (count)
+    *count = ai->count;
+  
+  if (stamp)
+    *stamp = ai->stamp;
+  
+  return TRUE;
+}
+
+/**
+ * g_bookmark_file_get_applications:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @length: return location of the length of the returned list, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Retrieves the names of the applications that have registered the
+ * bookmark for @uri.
+ * 
+ * In the event the URI cannot be found, %NULL is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: a newly allocated %NULL-terminated array of strings.
+ *   Use g_strfreev() to free it.
+ *
+ * Since: 2.12
+ */
+gchar **
+g_bookmark_file_get_applications (GBookmarkFile  *bookmark,
+                                 const gchar    *uri,
+                                 gsize          *length,
+                                 GError        **error)
+{
+  BookmarkItem *item;
+  GList *l;
+  gchar **apps;
+  gsize i, n_apps;
+  
+  g_return_val_if_fail (bookmark != NULL, NULL);
+  g_return_val_if_fail (uri != NULL, NULL);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return NULL;
+    }
+  
+  if (!item->metadata)
+    {     
+      if (length)
+       *length = 0;
+      
+      return NULL;
+    }
+  
+  n_apps = g_list_length (item->metadata->applications);
+  apps = g_new0 (gchar *, n_apps + 1);
+  
+  for (l = g_list_last (item->metadata->applications), i = 0;
+       l != NULL;
+       l = l->prev)
+    {
+      BookmarkAppInfo *ai;
+      
+      ai = (BookmarkAppInfo *) l->data;
+      
+      g_warn_if_fail (ai != NULL);
+      g_warn_if_fail (ai->name != NULL);
+      
+      apps[i++] = g_strdup (ai->name);
+    }
+  apps[i] = NULL;
+  
+  if (length)
+    *length = i;
+  
+  return apps;
+}
+
+/**
+ * g_bookmark_file_get_size:
+ * @bookmark: a #GBookmarkFile
+ * 
+ * Gets the number of bookmarks inside @bookmark.
+ * 
+ * Return value: the number of bookmarks
+ *
+ * Since: 2.12
+ */
+gint
+g_bookmark_file_get_size (GBookmarkFile *bookmark)
+{
+  g_return_val_if_fail (bookmark != NULL, 0);
+
+  return g_list_length (bookmark->items);
+}
+
+/**
+ * g_bookmark_file_move_item:
+ * @bookmark: a #GBookmarkFile
+ * @old_uri: a valid URI
+ * @new_uri: a valid URI, or %NULL
+ * @error: return location for a #GError or %NULL
+ *
+ * Changes the URI of a bookmark item from @old_uri to @new_uri.  Any
+ * existing bookmark for @new_uri will be overwritten.  If @new_uri is
+ * %NULL, then the bookmark is removed.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: %TRUE if the URI was successfully changed
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_move_item (GBookmarkFile  *bookmark,
+                          const gchar    *old_uri,
+                          const gchar    *new_uri,
+                          GError        **error)
+{
+  BookmarkItem *item;
+  GError *remove_error;
+  
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (old_uri != NULL, FALSE);
+
+  item = g_bookmark_file_lookup_item (bookmark, old_uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  old_uri);
+      return FALSE;
+    }
+
+  if (new_uri && new_uri[0] != '\0')
+    {
+      if (g_bookmark_file_has_item (bookmark, new_uri))
+        {
+          remove_error = NULL;
+          g_bookmark_file_remove_item (bookmark, new_uri, &remove_error);
+          if (remove_error)
+            {
+              g_propagate_error (error, remove_error);
+              
+              return FALSE;
+            }
+        }
+
+      g_hash_table_steal (bookmark->items_by_uri, item->uri);
+      
+      g_free (item->uri);
+      item->uri = g_strdup (new_uri);
+      item->modified = time (NULL);
+
+      g_hash_table_replace (bookmark->items_by_uri, item->uri, item);
+
+      return TRUE;
+    }
+  else
+    {
+      remove_error = NULL;
+      g_bookmark_file_remove_item (bookmark, old_uri, &remove_error);
+      if (remove_error)
+        {
+          g_propagate_error (error, remove_error);
+          
+          return FALSE;
+        }
+
+      return TRUE;
+    }
+}
+
+/**
+ * g_bookmark_file_set_icon:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @href: the URI of the icon for the bookmark, or %NULL
+ * @mime_type: the MIME type of the icon for the bookmark
+ *
+ * Sets the icon for the bookmark for @uri. If @href is %NULL, unsets
+ * the currently set icon. @href can either be a full URL for the icon
+ * file or the icon name following the Icon Naming specification.
+ *
+ * If no bookmark for @uri is found one is created.
+ *
+ * Since: 2.12
+ */
+void
+g_bookmark_file_set_icon (GBookmarkFile *bookmark,
+                         const gchar   *uri,
+                         const gchar   *href,
+                         const gchar   *mime_type)
+{
+  BookmarkItem *item;
+  
+  g_return_if_fail (bookmark != NULL);
+  g_return_if_fail (uri != NULL);
+
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      item = bookmark_item_new (uri);
+      g_bookmark_file_add_item (bookmark, item, NULL);
+    }
+  
+  if (!item->metadata)
+    item->metadata = bookmark_metadata_new ();
+  
+  g_free (item->metadata->icon_href);
+  g_free (item->metadata->icon_mime);
+  
+  item->metadata->icon_href = g_strdup (href);
+  
+  if (mime_type && mime_type[0] != '\0')
+    item->metadata->icon_mime = g_strdup (mime_type);
+  else
+    item->metadata->icon_mime = g_strdup ("application/octet-stream");
+  
+  item->modified = time (NULL);
+}
+
+/**
+ * g_bookmark_file_get_icon:
+ * @bookmark: a #GBookmarkFile
+ * @uri: a valid URI
+ * @href: return location for the icon's location or %NULL
+ * @mime_type: return location for the icon's MIME type or %NULL
+ * @error: return location for a #GError or %NULL
+ *
+ * Gets the icon of the bookmark for @uri.
+ *
+ * In the event the URI cannot be found, %FALSE is returned and
+ * @error is set to #G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND.
+ *
+ * Return value: %TRUE if the icon for the bookmark for the URI was found.
+ *   You should free the returned strings.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_bookmark_file_get_icon (GBookmarkFile  *bookmark,
+                         const gchar    *uri,
+                         gchar         **href,
+                         gchar         **mime_type,
+                         GError        **error)
+{
+  BookmarkItem *item;
+  
+  g_return_val_if_fail (bookmark != NULL, FALSE);
+  g_return_val_if_fail (uri != NULL, FALSE);
+  
+  item = g_bookmark_file_lookup_item (bookmark, uri);
+  if (!item)
+    {
+      g_set_error (error, G_BOOKMARK_FILE_ERROR,
+                  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+                  _("No bookmark found for URI '%s'"),
+                  uri);
+      return FALSE;
+    }
+  
+  if ((!item->metadata) || (!item->metadata->icon_href))
+    return FALSE;
+  
+  if (href)
+    *href = g_strdup (item->metadata->icon_href);
+  
+  if (mime_type)
+    *mime_type = g_strdup (item->metadata->icon_mime);
+  
+  return TRUE;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gbookmarkfile.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gbookmarkfile.h
new file mode 100644 (file)
index 0000000..f663ebf
--- /dev/null
@@ -0,0 +1,215 @@
+/* gbookmarkfile.h: parsing and building desktop bookmarks
+ *
+ * Copyright (C) 2005-2006 Emmanuele Bassi
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_BOOKMARK_FILE_H__
+#define __G_BOOKMARK_FILE_H__
+
+#include <glib/gerror.h>
+#include <time.h>
+
+G_BEGIN_DECLS
+
+/**
+ * G_BOOKMARK_FILE_ERROR:
+ *
+ * Error domain for bookmark file parsing.
+ * Errors in this domain will be from the #GBookmarkFileError
+ * enumeration. See #GError for information on error domains.
+ */
+#define G_BOOKMARK_FILE_ERROR  (g_bookmark_file_error_quark ())
+
+
+/**
+ * GBookmarkFileError:
+ * @G_BOOKMARK_FILE_ERROR_INVALID_URI: URI was ill-formed
+ * @G_BOOKMARK_FILE_ERROR_INVALID_VALUE: a requested field was not found
+ * @G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED: a requested application did
+ *     not register a bookmark
+ * @G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND: a requested URI was not found
+ * @G_BOOKMARK_FILE_ERROR_READ: document was ill formed
+ * @G_BOOKMARK_FILE_ERROR_UNKNOWN_ENCODING: the text being parsed was
+ *     in an unknown encoding
+ * @G_BOOKMARK_FILE_ERROR_WRITE: an error occurred while writing
+ * @G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND: requested file was not found
+ *
+ * Error codes returned by bookmark file parsing.
+ */
+typedef enum
+{
+  G_BOOKMARK_FILE_ERROR_INVALID_URI,
+  G_BOOKMARK_FILE_ERROR_INVALID_VALUE,
+  G_BOOKMARK_FILE_ERROR_APP_NOT_REGISTERED,
+  G_BOOKMARK_FILE_ERROR_URI_NOT_FOUND,
+  G_BOOKMARK_FILE_ERROR_READ,
+  G_BOOKMARK_FILE_ERROR_UNKNOWN_ENCODING,
+  G_BOOKMARK_FILE_ERROR_WRITE,
+  G_BOOKMARK_FILE_ERROR_FILE_NOT_FOUND
+} GBookmarkFileError;
+
+GQuark g_bookmark_file_error_quark (void);
+
+/**
+ * GBookmarkFile:
+ *
+ * The <structname>GBookmarkFile</structname> struct contains only
+ * private data and should not be directly accessed.
+ */
+typedef struct _GBookmarkFile GBookmarkFile;
+
+GBookmarkFile *g_bookmark_file_new                 (void);
+void           g_bookmark_file_free                (GBookmarkFile  *bookmark);
+
+gboolean       g_bookmark_file_load_from_file      (GBookmarkFile  *bookmark,
+                                                   const gchar    *filename,
+                                                   GError        **error);
+gboolean       g_bookmark_file_load_from_data      (GBookmarkFile  *bookmark,
+                                                   const gchar    *data,
+                                                   gsize           length,
+                                                   GError        **error);
+gboolean       g_bookmark_file_load_from_data_dirs (GBookmarkFile  *bookmark,
+                                                   const gchar    *file,
+                                                   gchar         **full_path,
+                                                   GError        **error);
+gchar *        g_bookmark_file_to_data             (GBookmarkFile  *bookmark,
+                                                   gsize          *length,
+                                                   GError        **error) G_GNUC_MALLOC;
+gboolean       g_bookmark_file_to_file             (GBookmarkFile  *bookmark,
+                                                   const gchar    *filename,
+                                                   GError        **error);
+
+void           g_bookmark_file_set_title           (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   const gchar    *title);
+gchar *        g_bookmark_file_get_title           (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   GError        **error) G_GNUC_MALLOC;
+void           g_bookmark_file_set_description     (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   const gchar    *description);
+gchar *        g_bookmark_file_get_description     (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   GError        **error) G_GNUC_MALLOC;
+void           g_bookmark_file_set_mime_type       (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   const gchar    *mime_type);
+gchar *        g_bookmark_file_get_mime_type       (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   GError        **error) G_GNUC_MALLOC;
+void           g_bookmark_file_set_groups          (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   const gchar   **groups,
+                                                   gsize           length);
+void           g_bookmark_file_add_group           (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   const gchar    *group);
+gboolean       g_bookmark_file_has_group           (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   const gchar    *group,
+                                                   GError        **error);
+gchar **       g_bookmark_file_get_groups          (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   gsize          *length,
+                                                   GError        **error) G_GNUC_MALLOC;
+void           g_bookmark_file_add_application     (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   const gchar    *name,
+                                                   const gchar    *exec);
+gboolean       g_bookmark_file_has_application     (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   const gchar    *name,
+                                                   GError        **error);
+gchar **       g_bookmark_file_get_applications    (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   gsize          *length,
+                                                   GError        **error) G_GNUC_MALLOC;
+gboolean       g_bookmark_file_set_app_info        (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   const gchar    *name,
+                                                   const gchar    *exec,
+                                                   gint            count,
+                                                   time_t          stamp,
+                                                   GError        **error);
+gboolean       g_bookmark_file_get_app_info        (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   const gchar    *name,
+                                                   gchar         **exec,
+                                                   guint          *count,
+                                                   time_t         *stamp,
+                                                   GError        **error);
+void           g_bookmark_file_set_is_private      (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   gboolean        is_private);
+gboolean       g_bookmark_file_get_is_private      (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   GError        **error);
+void           g_bookmark_file_set_icon            (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   const gchar    *href,
+                                                   const gchar    *mime_type);
+gboolean       g_bookmark_file_get_icon            (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   gchar         **href,
+                                                   gchar         **mime_type,
+                                                   GError        **error);
+void           g_bookmark_file_set_added           (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   time_t          added);
+time_t         g_bookmark_file_get_added           (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   GError        **error);
+void           g_bookmark_file_set_modified        (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   time_t          modified);
+time_t         g_bookmark_file_get_modified        (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   GError        **error);
+void           g_bookmark_file_set_visited         (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   time_t          visited);
+time_t         g_bookmark_file_get_visited         (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri, 
+                                                   GError        **error);
+gboolean       g_bookmark_file_has_item            (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri);
+gint           g_bookmark_file_get_size            (GBookmarkFile  *bookmark);
+gchar **       g_bookmark_file_get_uris            (GBookmarkFile  *bookmark,
+                                                   gsize          *length) G_GNUC_MALLOC;
+gboolean       g_bookmark_file_remove_group        (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   const gchar    *group,
+                                                   GError        **error);
+gboolean       g_bookmark_file_remove_application  (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   const gchar    *name,
+                                                   GError        **error);
+gboolean       g_bookmark_file_remove_item         (GBookmarkFile  *bookmark,
+                                                   const gchar    *uri,
+                                                   GError        **error);
+gboolean       g_bookmark_file_move_item           (GBookmarkFile  *bookmark,
+                                                   const gchar    *old_uri,
+                                                   const gchar    *new_uri,
+                                                   GError        **error);
+
+G_END_DECLS
+
+#endif /* __G_BOOKMARK_FILE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gbsearcharray.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gbsearcharray.h
new file mode 100644 (file)
index 0000000..1ad893c
--- /dev/null
@@ -0,0 +1,303 @@
+/* GBSearchArray - Binary Searchable Array implementation
+ * Copyright (C) 2000-2003 Tim Janik
+ *
+ * This software is provided "as is"; redistribution and modification
+ * is permitted, provided that the following disclaimer is retained.
+ *
+ * This software 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.
+ * In no event shall the authors or contributors 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.
+ */
+#ifndef __G_BSEARCH_ARRAY_H__
+#define __G_BSEARCH_ARRAY_H__
+
+#include <glib.h>
+#include <string.h>
+
+
+G_BEGIN_DECLS   /* c++ guards */
+
+/* this implementation is intended to be usable in third-party code
+ * simply by pasting the contents of this file. as such, the
+ * implementation needs to be self-contained within this file.
+ */
+
+/* convenience macro to avoid signed overflow for value comparisions */
+#define G_BSEARCH_ARRAY_CMP(v1,v2) ((v1) > (v2) ? +1 : (v1) == (v2) ? 0 : -1)
+
+
+/* --- typedefs --- */
+typedef gint  (*GBSearchCompareFunc) (gconstpointer bsearch_node1, /* key */
+                                      gconstpointer bsearch_node2);
+typedef enum
+{
+  G_BSEARCH_ARRAY_ALIGN_POWER2  = 1 << 0, /* align memory to power2 sizes */
+  G_BSEARCH_ARRAY_AUTO_SHRINK  = 1 << 1   /* shrink array upon removal */
+} GBSearchArrayFlags;
+
+
+/* --- structures --- */
+typedef struct
+{
+  guint               sizeof_node;
+  GBSearchCompareFunc cmp_nodes;
+  guint               flags;
+} GBSearchConfig;
+typedef union
+{
+  guint    n_nodes;
+  /*< private >*/
+  gpointer alignment_dummy1;
+  glong    alignment_dummy2;
+  gdouble  alignment_dummy3;
+} GBSearchArray;
+
+
+/* --- public API --- */
+static inline GBSearchArray*    g_bsearch_array_create    (const GBSearchConfig *bconfig);
+static inline gpointer          g_bsearch_array_get_nth   (GBSearchArray        *barray,
+                                                           const GBSearchConfig *bconfig,
+                                                           guint                 nth);
+static inline guint             g_bsearch_array_get_index (GBSearchArray        *barray,
+                                                           const GBSearchConfig *bconfig,
+                                                           gconstpointer         node_in_array);
+static inline GBSearchArray*    g_bsearch_array_remove    (GBSearchArray        *barray,
+                                                           const GBSearchConfig *bconfig,
+                                                           guint                 index_);
+/* provide uninitialized space at index for node insertion */
+static inline GBSearchArray*    g_bsearch_array_grow      (GBSearchArray        *barray,
+                                                           const GBSearchConfig *bconfig,
+                                                           guint                 index);
+/* insert key_node into array if it does not exist, otherwise do nothing */
+static inline GBSearchArray*    g_bsearch_array_insert    (GBSearchArray        *barray,
+                                                           const GBSearchConfig *bconfig,
+                                                           gconstpointer         key_node);
+/* insert key_node into array if it does not exist,
+ * otherwise replace the existing node's contents with key_node
+ */
+static inline GBSearchArray*    g_bsearch_array_replace   (GBSearchArray        *barray,
+                                                           const GBSearchConfig *bconfig,
+                                                           gconstpointer         key_node);
+static inline void              g_bsearch_array_free      (GBSearchArray        *barray,
+                                                           const GBSearchConfig *bconfig);
+#define g_bsearch_array_get_n_nodes(barray)     (((GBSearchArray*) (barray))->n_nodes)
+
+/* g_bsearch_array_lookup():
+ * return NULL or exact match node
+ */
+#define g_bsearch_array_lookup(barray, bconfig, key_node)       \
+    g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 0)
+
+/* g_bsearch_array_lookup_sibling():
+ * return NULL for barray->n_nodes==0, otherwise return the
+ * exact match node, or, if there's no such node, return the
+ * node last visited, which is pretty close to an exact match
+ * (will be one off into either direction).
+ */
+#define g_bsearch_array_lookup_sibling(barray, bconfig, key_node)       \
+    g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 1)
+
+/* g_bsearch_array_lookup_insertion():
+ * return NULL for barray->n_nodes==0 or exact match, otherwise
+ * return the node where key_node should be inserted (may be one
+ * after end, i.e. g_bsearch_array_get_index(result) <= barray->n_nodes).
+ */
+#define g_bsearch_array_lookup_insertion(barray, bconfig, key_node)     \
+    g_bsearch_array_lookup_fuzzy ((barray), (bconfig), (key_node), 2)
+
+
+/* --- implementation --- */
+/* helper macro to cut down realloc()s */
+#ifdef  DISABLE_MEM_POOLS
+#define G_BSEARCH_UPPER_POWER2(n)       (n)
+#else   /* !DISABLE_MEM_POOLS */
+#define G_BSEARCH_UPPER_POWER2(n)       ((n) ? 1 << g_bit_storage ((n) - 1) : 0)
+#endif  /* !DISABLE_MEM_POOLS */
+#define G_BSEARCH_ARRAY_NODES(barray)    (((guint8*) (barray)) + sizeof (GBSearchArray))
+static inline GBSearchArray*
+g_bsearch_array_create (const GBSearchConfig *bconfig)
+{
+  GBSearchArray *barray;
+  guint size;
+
+  g_return_val_if_fail (bconfig != NULL, NULL);
+
+  size = sizeof (GBSearchArray) + bconfig->sizeof_node;
+  if (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2)
+    size = G_BSEARCH_UPPER_POWER2 (size);
+  barray = (GBSearchArray *) g_malloc (size);
+  memset (barray, 0, sizeof (GBSearchArray));
+
+  return barray;
+}
+static inline gpointer
+g_bsearch_array_lookup_fuzzy (GBSearchArray             *barray,
+                              const GBSearchConfig      *bconfig,
+                              gconstpointer              key_node,
+                              const guint                sibling_or_after);
+static inline gpointer
+g_bsearch_array_lookup_fuzzy (GBSearchArray        *barray,
+                              const GBSearchConfig *bconfig,
+                              gconstpointer         key_node,
+                              const guint           sibling_or_after)
+{
+  GBSearchCompareFunc cmp_nodes = bconfig->cmp_nodes;
+  guint8 *check = NULL, *nodes = G_BSEARCH_ARRAY_NODES (barray);
+  guint n_nodes = barray->n_nodes, offs = 0;
+  guint sizeof_node = bconfig->sizeof_node;
+  gint cmp = 0;
+
+  while (offs < n_nodes)
+    {
+      guint i = (offs + n_nodes) >> 1;
+
+      check = nodes + i * sizeof_node;
+      cmp = cmp_nodes (key_node, check);
+      if (cmp == 0)
+        return sibling_or_after > 1 ? NULL : check;
+      else if (cmp < 0)
+        n_nodes = i;
+      else /* (cmp > 0) */
+        offs = i + 1;
+    }
+
+  /* check is last mismatch, cmp > 0 indicates greater key */
+  return G_LIKELY (!sibling_or_after) ? NULL : (sibling_or_after > 1 && cmp > 0) ? check + sizeof_node : check;
+}
+static inline gpointer
+g_bsearch_array_get_nth (GBSearchArray        *barray,
+                         const GBSearchConfig *bconfig,
+                         guint                 nth)
+{
+  return (G_LIKELY (nth < barray->n_nodes) ?
+          G_BSEARCH_ARRAY_NODES (barray) + nth * bconfig->sizeof_node :
+          NULL);
+}
+static inline guint
+g_bsearch_array_get_index (GBSearchArray        *barray,
+                           const GBSearchConfig *bconfig,
+                           gconstpointer         node_in_array)
+{
+  guint distance = ((guint8*) node_in_array) - G_BSEARCH_ARRAY_NODES (barray);
+
+  g_return_val_if_fail (node_in_array != NULL, barray->n_nodes);
+
+  distance /= bconfig->sizeof_node;
+
+  return MIN (distance, barray->n_nodes + 1); /* may return one after end */
+}
+static inline GBSearchArray*
+g_bsearch_array_grow (GBSearchArray        *barray,
+                      const GBSearchConfig *bconfig,
+                      guint                 index_)
+{
+  guint old_size = barray->n_nodes * bconfig->sizeof_node;
+  guint new_size = old_size + bconfig->sizeof_node;
+  guint8 *node;
+
+  g_return_val_if_fail (index_ <= barray->n_nodes, NULL);
+
+  if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2))
+    {
+      new_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + new_size);
+      old_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + old_size);
+      if (old_size != new_size)
+        barray = (GBSearchArray *) g_realloc (barray, new_size);
+    }
+  else
+    barray = (GBSearchArray *) g_realloc (barray, sizeof (GBSearchArray) + new_size);
+  node = G_BSEARCH_ARRAY_NODES (barray) + index_ * bconfig->sizeof_node;
+  g_memmove (node + bconfig->sizeof_node, node, (barray->n_nodes - index_) * bconfig->sizeof_node);
+  barray->n_nodes += 1;
+  return barray;
+}
+static inline GBSearchArray*
+g_bsearch_array_insert (GBSearchArray        *barray,
+                        const GBSearchConfig *bconfig,
+                        gconstpointer         key_node)
+{
+  guint8 *node;
+
+  if (G_UNLIKELY (!barray->n_nodes))
+    {
+      barray = g_bsearch_array_grow (barray, bconfig, 0);
+      node = G_BSEARCH_ARRAY_NODES (barray);
+    }
+  else
+    {
+      node = (guint8 *) g_bsearch_array_lookup_insertion (barray, bconfig, key_node);
+      if (G_LIKELY (node))
+        {
+          guint index_ = g_bsearch_array_get_index (barray, bconfig, node);
+
+          /* grow and insert */
+          barray = g_bsearch_array_grow (barray, bconfig, index_);
+          node = G_BSEARCH_ARRAY_NODES (barray) + index_ * bconfig->sizeof_node;
+        }
+      else /* no insertion needed, node already there */
+        return barray;
+    }
+  memcpy (node, key_node, bconfig->sizeof_node);
+  return barray;
+}
+static inline GBSearchArray*
+g_bsearch_array_replace (GBSearchArray        *barray,
+                         const GBSearchConfig *bconfig,
+                         gconstpointer         key_node)
+{
+  guint8 *node = (guint8 *) g_bsearch_array_lookup (barray, bconfig, key_node);
+  if (G_LIKELY (node))  /* expected path */
+    memcpy (node, key_node, bconfig->sizeof_node);
+  else                  /* revert to insertion */
+    barray = g_bsearch_array_insert (barray, bconfig, key_node);
+  return barray;
+}
+static inline GBSearchArray*
+g_bsearch_array_remove (GBSearchArray        *barray,
+                        const GBSearchConfig *bconfig,
+                        guint                 index_)
+{
+  guint8 *node;
+
+  g_return_val_if_fail (index_ < barray->n_nodes, NULL);
+
+  barray->n_nodes -= 1;
+  node = G_BSEARCH_ARRAY_NODES (barray) + index_ * bconfig->sizeof_node;
+  g_memmove (node, node + bconfig->sizeof_node, (barray->n_nodes - index_) * bconfig->sizeof_node);
+  if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_AUTO_SHRINK))
+    {
+      guint new_size = barray->n_nodes * bconfig->sizeof_node;
+      guint old_size = new_size + bconfig->sizeof_node;
+
+      if (G_UNLIKELY (bconfig->flags & G_BSEARCH_ARRAY_ALIGN_POWER2))
+        {
+          new_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + new_size);
+          old_size = G_BSEARCH_UPPER_POWER2 (sizeof (GBSearchArray) + old_size);
+          if (old_size != new_size)
+            barray = (GBSearchArray *) g_realloc (barray, new_size);
+        }
+      else
+        barray = (GBSearchArray *) g_realloc (barray, sizeof (GBSearchArray) + new_size);
+    }
+  return barray;
+}
+static inline void
+g_bsearch_array_free (GBSearchArray        *barray,
+                      const GBSearchConfig *bconfig)
+{
+  g_return_if_fail (barray != NULL);
+
+  g_free (barray);
+}
+
+G_END_DECLS     /* c++ guards */
+
+#endif  /* !__G_BSEARCH_ARRAY_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gbuffer.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gbuffer.c
new file mode 100644 (file)
index 0000000..f7e3044
--- /dev/null
@@ -0,0 +1,206 @@
+/*
+ * Copyright © 2009, 2010 Codethink Limited
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gbuffer.h"
+
+#include <glib/gstrfuncs.h>
+#include <glib/gatomic.h>
+#include <glib/gmem.h>
+
+
+typedef struct
+{
+  GBuffer buffer;
+
+  GDestroyNotify user_destroy;
+  gpointer user_data;
+} GUserNotifyBuffer;
+
+static void
+g_buffer_free_gfree (GBuffer *buffer)
+{
+  g_free ((gpointer) buffer->data);
+  g_slice_free (GBuffer, buffer);
+}
+
+/* < private >
+ * g_buffer_new_from_data:
+ * @data: the data to be used for the buffer
+ * @size: the size of @data
+ * @returns: a reference to a new #GBuffer
+ *
+ * Creates a new #GBuffer from @data.
+ *
+ * @data is copied.
+ */
+
+GBuffer *
+g_buffer_new_from_data (gconstpointer data,
+                        gsize         size)
+{
+  GBuffer *buffer;
+
+  buffer = g_slice_new (GBuffer);
+  buffer->data = g_memdup (data, size);
+  buffer->size = size;
+  buffer->free_func = g_buffer_free_gfree;
+  buffer->ref_count = 1;
+
+  return buffer;
+}
+
+/* < private >
+ * g_buffer_new_take_data:
+ * @data: the data to be used for the buffer
+ * @size: the size of @data
+ * returns: a reference to a new #GBuffer
+ *
+ * Creates a new #GBuffer from @data.
+ *
+ * @data must have been created by a call to g_malloc(), g_malloc0() or
+ * g_realloc() or by one of the many functions that wrap these calls
+ * (such as g_new(), g_strdup(), etc).
+ *
+ * After this call, @data belongs to the buffer and may no longer be
+ * modified by the caller.  g_free() will be called on @data when the
+ * buffer is no longer in use.
+ */
+GBuffer *
+g_buffer_new_take_data (gpointer data,
+                        gsize    size)
+{
+  GBuffer *buffer;
+
+  buffer = g_slice_new (GBuffer);
+  buffer->data = data;
+  buffer->size = size;
+  buffer->free_func = g_buffer_free_gfree;
+  buffer->ref_count = 1;
+
+  return buffer;
+}
+
+static void
+g_buffer_free (GBuffer *buffer)
+{
+  g_slice_free (GBuffer, buffer);
+}
+
+/* < private >
+ * g_buffer_new_from_static_data:
+ * @data: the data to be used for the buffer
+ * @size: the size of @data
+ * @returns: a reference to a new #GBuffer
+ *
+ * Creates a new #GBuffer from static data.
+ *
+ * @data must be static (ie: never modified or freed).
+ */
+GBuffer *
+g_buffer_new_from_static_data (gconstpointer data,
+                               gsize         size)
+{
+  GBuffer *buffer;
+
+  buffer = g_slice_new (GBuffer);
+  buffer->data = data;
+  buffer->size = size;
+  buffer->free_func = g_buffer_free;
+  buffer->ref_count = 1;
+
+  return buffer;
+}
+
+static void
+g_buffer_free_usernotify (GBuffer *buffer)
+{
+  GUserNotifyBuffer *ubuffer = (GUserNotifyBuffer *) buffer;
+
+  ubuffer->user_destroy (ubuffer->user_data);
+  g_slice_free (GUserNotifyBuffer, ubuffer);
+}
+
+/* < private >
+ * g_buffer_new_from_pointer:
+ * @data: the data to be used for the buffer
+ * @size: the size of @data
+ * @notify: the function to call to release the data
+ * @user_data: the data to pass to @notify
+ * @returns: a reference to a new #GBuffer
+ *
+ * Creates a #GBuffer from @data.
+ *
+ * When the last reference is dropped, @notify will be called on
+ * @user_data.
+ *
+ * @data must not be modified after this call is made, until @notify has
+ * been called to indicate that the buffer is no longer in use.
+ */
+GBuffer *
+g_buffer_new_from_pointer (gconstpointer  data,
+                           gsize          size,
+                           GDestroyNotify notify,
+                           gpointer       user_data)
+{
+  GUserNotifyBuffer *ubuffer;
+
+  ubuffer = g_slice_new (GUserNotifyBuffer);
+  ubuffer->buffer.data = data;
+  ubuffer->buffer.size = size;
+  ubuffer->buffer.free_func = g_buffer_free_usernotify;
+  ubuffer->buffer.ref_count = 1;
+  ubuffer->user_destroy = notify;
+  ubuffer->user_data = user_data;
+
+  return (GBuffer *) ubuffer;
+}
+
+/* < private >
+ * g_buffer_ref:
+ * @buffer: a #GBuffer
+ * @returns: @buffer
+ *
+ * Increase the reference count on @buffer.
+ */
+GBuffer *
+g_buffer_ref (GBuffer *buffer)
+{
+  g_atomic_int_inc (&buffer->ref_count);
+
+  return buffer;
+}
+
+/* < private >
+ * g_buffer_unref:
+ * @buffer: a #GBuffer
+ *
+ * Releases a reference on @buffer.  This may result in the buffer being
+ * freed.
+ */
+void
+g_buffer_unref (GBuffer *buffer)
+{
+  if (g_atomic_int_dec_and_test (&buffer->ref_count))
+    if (buffer->free_func != NULL)
+      buffer->free_func (buffer);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gbuffer.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gbuffer.h
new file mode 100644 (file)
index 0000000..6bb29b7
--- /dev/null
@@ -0,0 +1,88 @@
+/*
+ * Copyright © 2009, 2010 Codethink Limited
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __G_BUFFER_H__
+#define __G_BUFFER_H__
+
+#include <glib/gtypes.h>
+
+/* < private >
+ * GBuffer:
+ * @data: a pointer to the data held in the buffer
+ * @size: the size of @data
+ *
+ * A simple refcounted data type representing a byte sequence from an
+ * unspecified origin.
+ *
+ * The purpose of a #GBuffer is to keep the memory region that it holds
+ * alive for as long as anyone holds a reference to the buffer.  When
+ * the last reference count is dropped, the memory is released.
+ *
+ * A #GBuffer can come from many different origins that may have
+ * different procedures for freeing the memory region.  Examples are
+ * memory from g_malloc(), from memory slices, from a #GMappedFile or
+ * memory from other allocators.
+ */
+typedef struct _GBuffer GBuffer;
+
+/* < private >
+ * GBufferFreeFunc:
+ * @buffer: the #GBuffer to be freed
+ *
+ * This function is provided by creators of a #GBuffer.  It is the
+ * function to be called when the reference count of @buffer drops to
+ * zero.  It should free any memory associated with the buffer and free
+ * @buffer itself.
+ */
+typedef void (* GBufferFreeFunc)                (GBuffer        *buffer);
+
+struct _GBuffer
+{
+  gconstpointer data;
+  gsize size;
+
+  /*< protected >*/
+  GBufferFreeFunc free_func;
+
+  /*< private >*/
+  gint ref_count;
+};
+
+G_GNUC_INTERNAL
+GBuffer *       g_buffer_new_from_data          (gconstpointer   data,
+                                                 gsize           size);
+G_GNUC_INTERNAL
+GBuffer *       g_buffer_new_take_data          (gpointer        data,
+                                                 gsize           size);
+G_GNUC_INTERNAL
+GBuffer *       g_buffer_new_from_static_data   (gconstpointer   data,
+                                                 gsize           size);
+G_GNUC_INTERNAL
+GBuffer *       g_buffer_new_from_pointer       (gconstpointer   data,
+                                                 gsize           size,
+                                                 GDestroyNotify  notify,
+                                                 gpointer        user_data);
+G_GNUC_INTERNAL
+GBuffer *     g_buffer_ref                      (GBuffer        *buffer);
+G_GNUC_INTERNAL
+void          g_buffer_unref                    (GBuffer        *buffer);
+
+#endif /* __G_BUFFER_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gcache.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gcache.c
new file mode 100644 (file)
index 0000000..6a6163c
--- /dev/null
@@ -0,0 +1,330 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "gcache.h"
+
+#include "ghash.h"
+#include "gtestutils.h"
+
+/**
+ * SECTION: caches
+ * @title: Caches
+ * @short_description: caches allow sharing of complex data structures
+ *                     to save resources
+ *
+ * A #GCache allows sharing of complex data structures, in order to
+ * save system resources.
+ *
+ * GTK+ uses caches for #GtkStyles and #GdkGCs. These consume a lot of
+ * resources, so a #GCache is used to see if a #GtkStyle or #GdkGC with
+ * the required properties already exists. If it does, then the
+ * existing object is used instead of creating a new one.
+ *
+ * #GCache uses keys and values. A #GCache key describes the properties
+ * of a particular resource. A #GCache value is the actual resource.
+ **/
+
+typedef struct _GCacheNode  GCacheNode;
+
+struct _GCacheNode
+{
+  /* A reference counted node */
+  gpointer value;
+  gint ref_count;
+};
+
+/**
+ * GCache:
+ *
+ * The #GCache struct is an opaque data structure containing
+ * information about a #GCache. It should only be accessed via the
+ * following functions.
+ **/
+struct _GCache
+{
+  /* Called to create a value from a key */
+  GCacheNewFunc value_new_func;
+
+  /* Called to destroy a value */
+  GCacheDestroyFunc value_destroy_func;
+
+  /* Called to duplicate a key */
+  GCacheDupFunc key_dup_func;
+
+  /* Called to destroy a key */
+  GCacheDestroyFunc key_destroy_func;
+
+  /* Associates keys with nodes */
+  GHashTable *key_table;
+
+  /* Associates nodes with keys */
+  GHashTable *value_table;
+};
+
+static inline GCacheNode*
+g_cache_node_new (gpointer value)
+{
+  GCacheNode *node = g_slice_new (GCacheNode);
+  node->value = value;
+  node->ref_count = 1;
+  return node;
+}
+
+static inline void
+g_cache_node_destroy (GCacheNode *node)
+{
+  g_slice_free (GCacheNode, node);
+}
+
+/**
+ * g_cache_new:
+ * @value_new_func: a function to create a new object given a key.
+ *                  This is called by g_cache_insert() if an object
+ *                  with the given key does not already exist.
+ * @value_destroy_func: a function to destroy an object. It is called
+ *                      by g_cache_remove() when the object is no
+ *                      longer needed (i.e. its reference count drops
+ *                      to 0).
+ * @key_dup_func: a function to copy a key. It is called by
+ *                g_cache_insert() if the key does not already exist in
+ *                the #GCache.
+ * @key_destroy_func: a function to destroy a key. It is called by
+ *                    g_cache_remove() when the object is no longer
+ *                    needed (i.e. its reference count drops to 0).
+ * @hash_key_func: a function to create a hash value from a key.
+ * @hash_value_func: a function to create a hash value from a value.
+ * @key_equal_func: a function to compare two keys. It should return
+ *                  %TRUE if the two keys are equivalent.
+ * @Returns: a new #GCache.
+ *
+ * Creates a new #GCache.
+ **/
+/**
+ * GCacheNewFunc:
+ * @key: a #GCache key.
+ * @Returns: a new #GCache value corresponding to the key.
+ *
+ * Specifies the type of the @value_new_func function passed to
+ * g_cache_new(). It is passed a #GCache key and should create the
+ * value corresponding to the key.
+ **/
+/**
+ * GCacheDestroyFunc:
+ * @value: the #GCache value to destroy.
+ *
+ * Specifies the type of the @value_destroy_func and @key_destroy_func
+ * functions passed to g_cache_new(). The functions are passed a
+ * pointer to the #GCache key or #GCache value and should free any
+ * memory and other resources associated with it.
+ **/
+/**
+ * GCacheDupFunc:
+ * @value: the #GCache key to destroy (<emphasis>not</emphasis> a
+ *         #GCache value as it seems).
+ * @Returns: a copy of the #GCache key.
+ *
+ * Specifies the type of the @key_dup_func function passed to
+ * g_cache_new(). The function is passed a key
+ * (<emphasis>not</emphasis> a value as the prototype implies) and
+ * should return a duplicate of the key.
+ **/
+GCache*
+g_cache_new (GCacheNewFunc      value_new_func,
+             GCacheDestroyFunc  value_destroy_func,
+             GCacheDupFunc      key_dup_func,
+             GCacheDestroyFunc  key_destroy_func,
+             GHashFunc          hash_key_func,
+             GHashFunc          hash_value_func,
+             GEqualFunc         key_equal_func)
+{
+  GCache *cache;
+
+  g_return_val_if_fail (value_new_func != NULL, NULL);
+  g_return_val_if_fail (value_destroy_func != NULL, NULL);
+  g_return_val_if_fail (key_dup_func != NULL, NULL);
+  g_return_val_if_fail (key_destroy_func != NULL, NULL);
+  g_return_val_if_fail (hash_key_func != NULL, NULL);
+  g_return_val_if_fail (hash_value_func != NULL, NULL);
+  g_return_val_if_fail (key_equal_func != NULL, NULL);
+
+  cache = g_slice_new (GCache);
+  cache->value_new_func = value_new_func;
+  cache->value_destroy_func = value_destroy_func;
+  cache->key_dup_func = key_dup_func;
+  cache->key_destroy_func = key_destroy_func;
+  cache->key_table = g_hash_table_new (hash_key_func, key_equal_func);
+  cache->value_table = g_hash_table_new (hash_value_func, NULL);
+
+  return cache;
+}
+
+/**
+ * g_cache_destroy:
+ * @cache: a #GCache.
+ *
+ * Frees the memory allocated for the #GCache.
+ *
+ * Note that it does not destroy the keys and values which were
+ * contained in the #GCache.
+ **/
+void
+g_cache_destroy (GCache *cache)
+{
+  g_return_if_fail (cache != NULL);
+
+  g_hash_table_destroy (cache->key_table);
+  g_hash_table_destroy (cache->value_table);
+  g_slice_free (GCache, cache);
+}
+
+/**
+ * g_cache_insert:
+ * @cache: a #GCache.
+ * @key: a key describing a #GCache object.
+ * @Returns: a pointer to a #GCache value.
+ *
+ * Gets the value corresponding to the given key, creating it if
+ * necessary. It first checks if the value already exists in the
+ * #GCache, by using the @key_equal_func function passed to
+ * g_cache_new(). If it does already exist it is returned, and its
+ * reference count is increased by one. If the value does not currently
+ * exist, if is created by calling the @value_new_func. The key is
+ * duplicated by calling @key_dup_func and the duplicated key and value
+ * are inserted into the #GCache.
+ **/
+gpointer
+g_cache_insert (GCache   *cache,
+                gpointer  key)
+{
+  GCacheNode *node;
+  gpointer value;
+
+  g_return_val_if_fail (cache != NULL, NULL);
+
+  node = g_hash_table_lookup (cache->key_table, key);
+  if (node)
+    {
+      node->ref_count += 1;
+      return node->value;
+    }
+
+  key = (* cache->key_dup_func) (key);
+  value = (* cache->value_new_func) (key);
+  node = g_cache_node_new (value);
+
+  g_hash_table_insert (cache->key_table, key, node);
+  g_hash_table_insert (cache->value_table, value, key);
+
+  return node->value;
+}
+
+/**
+ * g_cache_remove:
+ * @cache: a #GCache.
+ * @value: the value to remove.
+ *
+ * Decreases the reference count of the given value. If it drops to 0
+ * then the value and its corresponding key are destroyed, using the
+ * @value_destroy_func and @key_destroy_func passed to g_cache_new().
+ **/
+void
+g_cache_remove (GCache        *cache,
+                gconstpointer  value)
+{
+  GCacheNode *node;
+  gpointer key;
+
+  g_return_if_fail (cache != NULL);
+
+  key = g_hash_table_lookup (cache->value_table, value);
+  node = g_hash_table_lookup (cache->key_table, key);
+
+  g_return_if_fail (node != NULL);
+
+  node->ref_count -= 1;
+  if (node->ref_count == 0)
+    {
+      g_hash_table_remove (cache->value_table, value);
+      g_hash_table_remove (cache->key_table, key);
+
+      (* cache->key_destroy_func) (key);
+      (* cache->value_destroy_func) (node->value);
+      g_cache_node_destroy (node);
+    }
+}
+
+/**
+ * g_cache_key_foreach:
+ * @cache: a #GCache.
+ * @func: the function to call with each #GCache key.
+ * @user_data: user data to pass to the function.
+ *
+ * Calls the given function for each of the keys in the #GCache.
+ *
+ * NOTE @func is passed three parameters, the value and key of a cache
+ * entry and the @user_data. The order of value and key is different
+ * from the order in which g_hash_table_foreach() passes key-value
+ * pairs to its callback function !
+ **/
+void
+g_cache_key_foreach (GCache   *cache,
+                     GHFunc    func,
+                     gpointer  user_data)
+{
+  g_return_if_fail (cache != NULL);
+  g_return_if_fail (func != NULL);
+
+  g_hash_table_foreach (cache->value_table, func, user_data);
+}
+
+/**
+ * g_cache_value_foreach:
+ * @cache: a #GCache.
+ * @func: the function to call with each #GCache value.
+ * @user_data: user data to pass to the function.
+ *
+ * Calls the given function for each of the values in the #GCache.
+ *
+ * Deprecated:2.10: The reason is that it passes pointers to internal
+ *                  data structures to @func; use g_cache_key_foreach()
+ *                  instead
+ **/
+void
+g_cache_value_foreach (GCache   *cache,
+                       GHFunc    func,
+                       gpointer  user_data)
+{
+  g_return_if_fail (cache != NULL);
+  g_return_if_fail (func != NULL);
+
+  g_hash_table_foreach (cache->key_table, func, user_data);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gcache.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gcache.h
new file mode 100644 (file)
index 0000000..7d60d58
--- /dev/null
@@ -0,0 +1,69 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_CACHE_H__
+#define __G_CACHE_H__
+
+#include <glib/glist.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GCache          GCache;
+
+typedef gpointer        (*GCacheNewFunc)        (gpointer       key);
+typedef gpointer        (*GCacheDupFunc)        (gpointer       value);
+typedef void            (*GCacheDestroyFunc)    (gpointer       value);
+
+/* Caches
+ */
+GCache*  g_cache_new           (GCacheNewFunc      value_new_func,
+                                GCacheDestroyFunc  value_destroy_func,
+                                GCacheDupFunc      key_dup_func,
+                                GCacheDestroyFunc  key_destroy_func,
+                                GHashFunc          hash_key_func,
+                                GHashFunc          hash_value_func,
+                                GEqualFunc         key_equal_func);
+void     g_cache_destroy       (GCache            *cache);
+gpointer g_cache_insert        (GCache            *cache,
+                                gpointer           key);
+void     g_cache_remove        (GCache            *cache,
+                                gconstpointer      value);
+void     g_cache_key_foreach   (GCache            *cache,
+                                GHFunc             func,
+                                gpointer           user_data);
+#ifndef G_DISABLE_DEPRECATED
+void     g_cache_value_foreach (GCache            *cache,
+                                GHFunc             func,
+                                gpointer           user_data);
+#endif
+
+G_END_DECLS
+
+#endif /* __G_CACHE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gchecksum.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gchecksum.c
new file mode 100644 (file)
index 0000000..b0d10c1
--- /dev/null
@@ -0,0 +1,1460 @@
+/* gchecksum.h - data hashing functions
+ *
+ * Copyright (C) 2007  Emmanuele Bassi  <ebassi@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gchecksum.h"
+
+#include "gmem.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "gtypes.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION: checksum
+ * @title: Data Checksums
+ * @short_description: Computes the checksum for data
+ *
+ * GLib provides a generic API for computing checksums (or "digests")
+ * for a sequence of arbitrary bytes, using various hashing algorithms
+ * like MD5, SHA-1 and SHA-256. Checksums are commonly used in various
+ * environments and specifications.
+ *
+ * GLib supports incremental checksums using the GChecksum data
+ * structure, by calling g_checksum_update() as long as there's data
+ * available and then using g_checksum_get_string() or
+ * g_checksum_get_digest() to compute the checksum and return it either
+ * as a string in hexadecimal form, or as a raw sequence of bytes. To
+ * compute the checksum for binary blobs and NUL-terminated strings in
+ * one go, use the convenience functions g_compute_checksum_for_data()
+ * and g_compute_checksum_for_string(), respectively.
+ *
+ * Support for checksums has been added in GLib 2.16
+ **/
+
+#define IS_VALID_TYPE(type)     ((type) >= G_CHECKSUM_MD5 && (type) <= G_CHECKSUM_SHA256)
+
+/* The fact that these are lower case characters is part of the ABI */
+static const gchar hex_digits[] = "0123456789abcdef";
+
+#define MD5_DATASIZE    64
+#define MD5_DIGEST_LEN  16
+
+typedef struct
+{
+  guint32 buf[4];
+  guint32 bits[2];
+
+  guchar data[MD5_DATASIZE];
+
+  guchar digest[MD5_DIGEST_LEN];
+} Md5sum;
+
+#define SHA1_DATASIZE   64
+#define SHA1_DIGEST_LEN 20
+
+typedef struct
+{
+  guint32 buf[5];
+  guint32 bits[2];
+
+  /* we pack 64 unsigned chars into 16 32-bit unsigned integers */
+  guint32 data[16];
+
+  guchar digest[SHA1_DIGEST_LEN];
+} Sha1sum;
+
+#define SHA256_DATASIZE         64
+#define SHA256_DIGEST_LEN       32
+
+typedef struct
+{
+  guint32 buf[8];
+  guint32 bits[2];
+
+  guint8 data[SHA256_DATASIZE];
+
+  guchar digest[SHA256_DIGEST_LEN];
+} Sha256sum;
+
+struct _GChecksum
+{
+  GChecksumType type;
+
+  gchar *digest_str;
+
+  union {
+    Md5sum md5;
+    Sha1sum sha1;
+    Sha256sum sha256;
+  } sum;
+};
+
+/* we need different byte swapping functions because MD5 expects buffers
+ * to be little-endian, while SHA1 and SHA256 expect them in big-endian
+ * form.
+ */
+
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+#define md5_byte_reverse(buffer,length)
+#else
+/* assume that the passed buffer is integer aligned */
+static inline void
+md5_byte_reverse (guchar *buffer,
+                  gulong  length)
+{
+  guint32 bit;
+
+  do
+    {
+      bit = (guint32) ((unsigned) buffer[3] << 8 | buffer[2]) << 16 |
+                      ((unsigned) buffer[1] << 8 | buffer[0]);
+      * (guint32 *) buffer = bit;
+      buffer += 4;
+    }
+  while (--length);
+}
+#endif /* G_BYTE_ORDER == G_LITTLE_ENDIAN */
+
+#if G_BYTE_ORDER == G_BIG_ENDIAN
+#define sha_byte_reverse(buffer,length)
+#else
+static inline void
+sha_byte_reverse (guint32 *buffer,
+                  gint     length)
+{
+  length /= sizeof (guint32);
+  while (length--)
+    {
+      *buffer = GUINT32_SWAP_LE_BE (*buffer);
+      ++buffer;
+    }
+}
+#endif /* G_BYTE_ORDER == G_BIG_ENDIAN */
+
+static gchar *
+digest_to_string (guint8 *digest,
+                  gsize   digest_len)
+{
+  gint len = digest_len * 2;
+  gint i;
+  gchar *retval;
+
+  retval = g_new (gchar, len + 1);
+
+  for (i = 0; i < digest_len; i++)
+    {
+      guint8 byte = digest[i];
+
+      retval[2 * i] = hex_digits[byte >> 4];
+      retval[2 * i + 1] = hex_digits[byte & 0xf];
+    }
+
+  retval[len] = 0;
+
+  return retval;
+}
+
+/*
+ * MD5 Checksum
+ */
+
+/* This MD5 digest computation is based on the equivalent code
+ * written by Colin Plumb. It came with this notice:
+ *
+ * This code implements the MD5 message-digest algorithm.
+ * The algorithm is due to Ron Rivest.  This code was
+ * written by Colin Plumb in 1993, no copyright is claimed.
+ * This code is in the public domain; do with it what you wish.
+ *
+ * Equivalent code is available from RSA Data Security, Inc.
+ * This code has been tested against that, and is equivalent,
+ * except that you don't need to include two pages of legalese
+ * with every copy.
+ */
+
+static void
+md5_sum_init (Md5sum *md5)
+{
+  /* arbitrary constants */
+  md5->buf[0] = 0x67452301;
+  md5->buf[1] = 0xefcdab89;
+  md5->buf[2] = 0x98badcfe;
+  md5->buf[3] = 0x10325476;
+
+  md5->bits[0] = md5->bits[1] = 0;
+}
+
+/*
+ * The core of the MD5 algorithm, this alters an existing MD5 hash to
+ * reflect the addition of 16 longwords of new data.  md5_sum_update()
+ * blocks the data and converts bytes into longwords for this routine.
+ */
+static void
+md5_transform (guint32       buf[4],
+               guint32 const in[16])
+{
+  register guint32 a, b, c, d;
+
+/* The four core functions - F1 is optimized somewhat */
+#define F1(x, y, z)     (z ^ (x & (y ^ z)))
+#define F2(x, y, z)     F1 (z, x, y)
+#define F3(x, y, z)     (x ^ y ^ z)
+#define F4(x, y, z)     (y ^ (x | ~z))
+
+/* This is the central step in the MD5 algorithm. */
+#define md5_step(f, w, x, y, z, data, s) \
+        ( w += f (x, y, z) + data,  w = w << s | w >> (32 - s),  w += x )
+
+  a = buf[0];
+  b = buf[1];
+  c = buf[2];
+  d = buf[3];
+
+  md5_step (F1, a, b, c, d, in[0]  + 0xd76aa478,  7);
+  md5_step (F1, d, a, b, c, in[1]  + 0xe8c7b756, 12);
+  md5_step (F1, c, d, a, b, in[2]  + 0x242070db, 17);
+  md5_step (F1, b, c, d, a, in[3]  + 0xc1bdceee, 22);
+  md5_step (F1, a, b, c, d, in[4]  + 0xf57c0faf,  7);
+  md5_step (F1, d, a, b, c, in[5]  + 0x4787c62a, 12);
+  md5_step (F1, c, d, a, b, in[6]  + 0xa8304613, 17);
+  md5_step (F1, b, c, d, a, in[7]  + 0xfd469501, 22);
+  md5_step (F1, a, b, c, d, in[8]  + 0x698098d8,  7);
+  md5_step (F1, d, a, b, c, in[9]  + 0x8b44f7af, 12);
+  md5_step (F1, c, d, a, b, in[10] + 0xffff5bb1, 17);
+  md5_step (F1, b, c, d, a, in[11] + 0x895cd7be, 22);
+  md5_step (F1, a, b, c, d, in[12] + 0x6b901122,  7);
+  md5_step (F1, d, a, b, c, in[13] + 0xfd987193, 12);
+  md5_step (F1, c, d, a, b, in[14] + 0xa679438e, 17);
+  md5_step (F1, b, c, d, a, in[15] + 0x49b40821, 22);
+        
+  md5_step (F2, a, b, c, d, in[1]  + 0xf61e2562,  5);
+  md5_step (F2, d, a, b, c, in[6]  + 0xc040b340,  9);
+  md5_step (F2, c, d, a, b, in[11] + 0x265e5a51, 14);
+  md5_step (F2, b, c, d, a, in[0]  + 0xe9b6c7aa, 20);
+  md5_step (F2, a, b, c, d, in[5]  + 0xd62f105d,  5);
+  md5_step (F2, d, a, b, c, in[10] + 0x02441453,  9);
+  md5_step (F2, c, d, a, b, in[15] + 0xd8a1e681, 14);
+  md5_step (F2, b, c, d, a, in[4]  + 0xe7d3fbc8, 20);
+  md5_step (F2, a, b, c, d, in[9]  + 0x21e1cde6,  5);
+  md5_step (F2, d, a, b, c, in[14] + 0xc33707d6,  9);
+  md5_step (F2, c, d, a, b, in[3]  + 0xf4d50d87, 14);
+  md5_step (F2, b, c, d, a, in[8]  + 0x455a14ed, 20);
+  md5_step (F2, a, b, c, d, in[13] + 0xa9e3e905,  5);
+  md5_step (F2, d, a, b, c, in[2]  + 0xfcefa3f8,  9);
+  md5_step (F2, c, d, a, b, in[7]  + 0x676f02d9, 14);
+  md5_step (F2, b, c, d, a, in[12] + 0x8d2a4c8a, 20);
+
+  md5_step (F3, a, b, c, d, in[5]  + 0xfffa3942,  4);
+  md5_step (F3, d, a, b, c, in[8]  + 0x8771f681, 11);
+  md5_step (F3, c, d, a, b, in[11] + 0x6d9d6122, 16);
+  md5_step (F3, b, c, d, a, in[14] + 0xfde5380c, 23);
+  md5_step (F3, a, b, c, d, in[1]  + 0xa4beea44,  4);
+  md5_step (F3, d, a, b, c, in[4]  + 0x4bdecfa9, 11);
+  md5_step (F3, c, d, a, b, in[7]  + 0xf6bb4b60, 16);
+  md5_step (F3, b, c, d, a, in[10] + 0xbebfbc70, 23);
+  md5_step (F3, a, b, c, d, in[13] + 0x289b7ec6,  4);
+  md5_step (F3, d, a, b, c, in[0]  + 0xeaa127fa, 11);
+  md5_step (F3, c, d, a, b, in[3]  + 0xd4ef3085, 16);
+  md5_step (F3, b, c, d, a, in[6]  + 0x04881d05, 23);
+  md5_step (F3, a, b, c, d, in[9]  + 0xd9d4d039,  4);
+  md5_step (F3, d, a, b, c, in[12] + 0xe6db99e5, 11);
+  md5_step (F3, c, d, a, b, in[15] + 0x1fa27cf8, 16);
+  md5_step (F3, b, c, d, a, in[2]  + 0xc4ac5665, 23);
+
+  md5_step (F4, a, b, c, d, in[0]  + 0xf4292244,  6);
+  md5_step (F4, d, a, b, c, in[7]  + 0x432aff97, 10);
+  md5_step (F4, c, d, a, b, in[14] + 0xab9423a7, 15);
+  md5_step (F4, b, c, d, a, in[5]  + 0xfc93a039, 21);
+  md5_step (F4, a, b, c, d, in[12] + 0x655b59c3,  6);
+  md5_step (F4, d, a, b, c, in[3]  + 0x8f0ccc92, 10);
+  md5_step (F4, c, d, a, b, in[10] + 0xffeff47d, 15);
+  md5_step (F4, b, c, d, a, in[1]  + 0x85845dd1, 21);
+  md5_step (F4, a, b, c, d, in[8]  + 0x6fa87e4f,  6);
+  md5_step (F4, d, a, b, c, in[15] + 0xfe2ce6e0, 10);
+  md5_step (F4, c, d, a, b, in[6]  + 0xa3014314, 15);
+  md5_step (F4, b, c, d, a, in[13] + 0x4e0811a1, 21);
+  md5_step (F4, a, b, c, d, in[4]  + 0xf7537e82,  6);
+  md5_step (F4, d, a, b, c, in[11] + 0xbd3af235, 10);
+  md5_step (F4, c, d, a, b, in[2]  + 0x2ad7d2bb, 15);
+  md5_step (F4, b, c, d, a, in[9]  + 0xeb86d391, 21);
+
+  buf[0] += a;
+  buf[1] += b;
+  buf[2] += c;
+  buf[3] += d;
+
+#undef F1
+#undef F2
+#undef F3
+#undef F4
+#undef md5_step
+}
+
+static void
+md5_sum_update (Md5sum       *md5,
+                const guchar *data,
+                gsize         length)
+{
+  guint32 bit;
+
+  bit = md5->bits[0];
+  md5->bits[0] = bit + ((guint32) length << 3);
+
+  /* carry from low to high */
+  if (md5->bits[0] < bit)
+    md5->bits[1] += 1;
+
+  md5->bits[1] += length >> 29;
+
+  /* bytes already in Md5sum->data */
+  bit = (bit >> 3) & 0x3f;
+
+  /* handle any leading odd-sized chunks */
+  if (bit)
+    {
+      guchar *p = (guchar *) md5->data + bit;
+
+      bit = MD5_DATASIZE - bit;
+      if (length < bit)
+        {
+          memcpy (p, data, length);
+          return;
+        }
+
+      memcpy (p, data, bit);
+
+      md5_byte_reverse (md5->data, 16);
+      md5_transform (md5->buf, (guint32 *) md5->data);
+
+      data += bit;
+      length -= bit;
+    }
+
+  /* process data in 64-byte chunks */
+  while (length >= MD5_DATASIZE)
+    {
+      memcpy (md5->data, data, MD5_DATASIZE);
+
+      md5_byte_reverse (md5->data, 16);
+      md5_transform (md5->buf, (guint32 *) md5->data);
+
+      data += MD5_DATASIZE;
+      length -= MD5_DATASIZE;
+    }
+
+  /* handle any remaining bytes of data */
+  memcpy (md5->data, data, length);
+}
+
+/* closes a checksum */
+static void
+md5_sum_close (Md5sum *md5)
+{
+  guint count;
+  guchar *p;
+
+  /* Compute number of bytes mod 64 */
+  count = (md5->bits[0] >> 3) & 0x3F;
+
+  /* Set the first char of padding to 0x80.
+   * This is safe since there is always at least one byte free
+   */
+  p = md5->data + count;
+  *p++ = 0x80;
+
+  /* Bytes of padding needed to make 64 bytes */
+  count = MD5_DATASIZE - 1 - count;
+
+  /* Pad out to 56 mod 64 */
+  if (count < 8)
+    {
+      /* Two lots of padding:  Pad the first block to 64 bytes */
+      memset (p, 0, count);
+
+      md5_byte_reverse (md5->data, 16);
+      md5_transform (md5->buf, (guint32 *) md5->data);
+
+      /* Now fill the next block with 56 bytes */
+      memset (md5->data, 0, MD5_DATASIZE - 8);
+    }
+  else
+    {
+      /* Pad block to 56 bytes */
+      memset (p, 0, count - 8);
+    }
+
+  md5_byte_reverse (md5->data, 14);
+
+  /* Append length in bits and transform */
+  ((guint32 *) md5->data)[14] = md5->bits[0];
+  ((guint32 *) md5->data)[15] = md5->bits[1];
+
+  md5_transform (md5->buf, (guint32 *) md5->data);
+  md5_byte_reverse ((guchar *) md5->buf, 4);
+
+  memcpy (md5->digest, md5->buf, 16);
+
+  /* Reset buffers in case they contain sensitive data */
+  memset (md5->buf, 0, sizeof (md5->buf));
+  memset (md5->data, 0, sizeof (md5->data));
+}
+
+static gchar *
+md5_sum_to_string (Md5sum *md5)
+{
+  return digest_to_string (md5->digest, MD5_DIGEST_LEN);
+}
+
+static void
+md5_sum_digest (Md5sum *md5,
+                guint8 *digest)
+{
+  gint i;
+
+  for (i = 0; i < MD5_DIGEST_LEN; i++)
+    digest[i] = md5->digest[i];
+}
+
+/*
+ * SHA-1 Checksum
+ */
+
+/* The following implementation comes from D-Bus dbus-sha.c. I've changed
+ * it to use GLib types and to work more like the MD5 implementation above.
+ * I left the comments to have an history of this code.
+ *      -- Emmanuele Bassi, ebassi@gnome.org
+ */
+
+/* The following comments have the history of where this code
+ * comes from. I actually copied it from GNet in GNOME CVS.
+ * - hp@redhat.com
+ */
+
+/*
+ *  sha.h : Implementation of the Secure Hash Algorithm
+ *
+ * Part of the Python Cryptography Toolkit, version 1.0.0
+ *
+ * Copyright (C) 1995, A.M. Kuchling
+ *
+ * Distribute and use freely; there are no restrictions on further
+ * dissemination and usage except those imposed by the laws of your
+ * country of residence.
+ *
+ */
+
+/* SHA: NIST's Secure Hash Algorithm */
+
+/* Based on SHA code originally posted to sci.crypt by Peter Gutmann
+   in message <30ajo5$oe8@ccu2.auckland.ac.nz>.
+   Modified to test for endianness on creation of SHA objects by AMK.
+   Also, the original specification of SHA was found to have a weakness
+   by NSA/NIST.  This code implements the fixed version of SHA.
+*/
+
+/* Here's the first paragraph of Peter Gutmann's posting:
+
+The following is my SHA (FIPS 180) code updated to allow use of the "fixed"
+SHA, thanks to Jim Gillogly and an anonymous contributor for the information on
+what's changed in the new version.  The fix is a simple change which involves
+adding a single rotate in the initial expansion function.  It is unknown
+whether this is an optimal solution to the problem which was discovered in the
+SHA or whether it's simply a bandaid which fixes the problem with a minimum of
+effort (for example the reengineering of a great many Capstone chips).
+*/
+
+static void
+sha1_sum_init (Sha1sum *sha1)
+{
+  /* initialize constants */
+  sha1->buf[0] = 0x67452301L;
+  sha1->buf[1] = 0xEFCDAB89L;
+  sha1->buf[2] = 0x98BADCFEL;
+  sha1->buf[3] = 0x10325476L;
+  sha1->buf[4] = 0xC3D2E1F0L;
+
+  /* initialize bits */
+  sha1->bits[0] = sha1->bits[1] = 0;
+}
+
+/* The SHA f()-functions. */
+
+#define f1(x,y,z)       (z ^ (x & (y ^ z)))             /* Rounds  0-19 */
+#define f2(x,y,z)       (x ^ y ^ z)                     /* Rounds 20-39 */
+#define f3(x,y,z)       (( x & y) | (z & (x | y)))      /* Rounds 40-59 */
+#define f4(x,y,z)       (x ^ y ^ z)                     /* Rounds 60-79 */
+
+/* The SHA Mysterious Constants */
+#define K1  0x5A827999L                                 /* Rounds  0-19 */
+#define K2  0x6ED9EBA1L                                 /* Rounds 20-39 */
+#define K3  0x8F1BBCDCL                                 /* Rounds 40-59 */
+#define K4  0xCA62C1D6L                                 /* Rounds 60-79 */
+
+/* 32-bit rotate left - kludged with shifts */
+#define ROTL(n,X) (((X) << n ) | ((X) >> (32 - n)))
+
+/* The initial expanding function.  The hash function is defined over an
+   80-word expanded input array W, where the first 16 are copies of the input
+   data, and the remaining 64 are defined by
+
+        W[ i ] = W[ i - 16 ] ^ W[ i - 14 ] ^ W[ i - 8 ] ^ W[ i - 3 ]
+
+   This implementation generates these values on the fly in a circular
+   buffer - thanks to Colin Plumb, colin@nyx10.cs.du.edu for this
+   optimization.
+
+   The updated SHA changes the expanding function by adding a rotate of 1
+   bit.  Thanks to Jim Gillogly, jim@rand.org, and an anonymous contributor
+   for this information */
+
+#define expand(W,i) (W[ i & 15 ] = ROTL (1, (W[ i       & 15] ^ \
+                                             W[(i - 14) & 15] ^ \
+                                             W[(i -  8) & 15] ^ \
+                                             W[(i -  3) & 15])))
+
+
+/* The prototype SHA sub-round.  The fundamental sub-round is:
+
+        a' = e + ROTL( 5, a ) + f( b, c, d ) + k + data;
+        b' = a;
+        c' = ROTL( 30, b );
+        d' = c;
+        e' = d;
+
+   but this is implemented by unrolling the loop 5 times and renaming the
+   variables ( e, a, b, c, d ) = ( a', b', c', d', e' ) each iteration.
+   This code is then replicated 20 times for each of the 4 functions, using
+   the next 20 values from the W[] array each time */
+
+#define subRound(a, b, c, d, e, f, k, data) \
+   (e += ROTL (5, a) + f(b, c, d) + k + data, b = ROTL (30, b))
+
+static void
+sha1_transform (guint32  buf[5],
+                guint32  in[16])
+{
+  guint32 A, B, C, D, E;
+
+  A = buf[0];
+  B = buf[1];
+  C = buf[2];
+  D = buf[3];
+  E = buf[4];
+
+  /* Heavy mangling, in 4 sub-rounds of 20 interations each. */
+  subRound (A, B, C, D, E, f1, K1, in[0]);
+  subRound (E, A, B, C, D, f1, K1, in[1]);
+  subRound (D, E, A, B, C, f1, K1, in[2]);
+  subRound (C, D, E, A, B, f1, K1, in[3]);
+  subRound (B, C, D, E, A, f1, K1, in[4]);
+  subRound (A, B, C, D, E, f1, K1, in[5]);
+  subRound (E, A, B, C, D, f1, K1, in[6]);
+  subRound (D, E, A, B, C, f1, K1, in[7]);
+  subRound (C, D, E, A, B, f1, K1, in[8]);
+  subRound (B, C, D, E, A, f1, K1, in[9]);
+  subRound (A, B, C, D, E, f1, K1, in[10]);
+  subRound (E, A, B, C, D, f1, K1, in[11]);
+  subRound (D, E, A, B, C, f1, K1, in[12]);
+  subRound (C, D, E, A, B, f1, K1, in[13]);
+  subRound (B, C, D, E, A, f1, K1, in[14]);
+  subRound (A, B, C, D, E, f1, K1, in[15]);
+  subRound (E, A, B, C, D, f1, K1, expand (in, 16));
+  subRound (D, E, A, B, C, f1, K1, expand (in, 17));
+  subRound (C, D, E, A, B, f1, K1, expand (in, 18));
+  subRound (B, C, D, E, A, f1, K1, expand (in, 19));
+
+  subRound (A, B, C, D, E, f2, K2, expand (in, 20));
+  subRound (E, A, B, C, D, f2, K2, expand (in, 21));
+  subRound (D, E, A, B, C, f2, K2, expand (in, 22));
+  subRound (C, D, E, A, B, f2, K2, expand (in, 23));
+  subRound (B, C, D, E, A, f2, K2, expand (in, 24));
+  subRound (A, B, C, D, E, f2, K2, expand (in, 25));
+  subRound (E, A, B, C, D, f2, K2, expand (in, 26));
+  subRound (D, E, A, B, C, f2, K2, expand (in, 27));
+  subRound (C, D, E, A, B, f2, K2, expand (in, 28));
+  subRound (B, C, D, E, A, f2, K2, expand (in, 29));
+  subRound (A, B, C, D, E, f2, K2, expand (in, 30));
+  subRound (E, A, B, C, D, f2, K2, expand (in, 31));
+  subRound (D, E, A, B, C, f2, K2, expand (in, 32));
+  subRound (C, D, E, A, B, f2, K2, expand (in, 33));
+  subRound (B, C, D, E, A, f2, K2, expand (in, 34));
+  subRound (A, B, C, D, E, f2, K2, expand (in, 35));
+  subRound (E, A, B, C, D, f2, K2, expand (in, 36));
+  subRound (D, E, A, B, C, f2, K2, expand (in, 37));
+  subRound (C, D, E, A, B, f2, K2, expand (in, 38));
+  subRound (B, C, D, E, A, f2, K2, expand (in, 39));
+
+  subRound (A, B, C, D, E, f3, K3, expand (in, 40));
+  subRound (E, A, B, C, D, f3, K3, expand (in, 41));
+  subRound (D, E, A, B, C, f3, K3, expand (in, 42));
+  subRound (C, D, E, A, B, f3, K3, expand (in, 43));
+  subRound (B, C, D, E, A, f3, K3, expand (in, 44));
+  subRound (A, B, C, D, E, f3, K3, expand (in, 45));
+  subRound (E, A, B, C, D, f3, K3, expand (in, 46));
+  subRound (D, E, A, B, C, f3, K3, expand (in, 47));
+  subRound (C, D, E, A, B, f3, K3, expand (in, 48));
+  subRound (B, C, D, E, A, f3, K3, expand (in, 49));
+  subRound (A, B, C, D, E, f3, K3, expand (in, 50));
+  subRound (E, A, B, C, D, f3, K3, expand (in, 51));
+  subRound (D, E, A, B, C, f3, K3, expand (in, 52));
+  subRound (C, D, E, A, B, f3, K3, expand (in, 53));
+  subRound (B, C, D, E, A, f3, K3, expand (in, 54));
+  subRound (A, B, C, D, E, f3, K3, expand (in, 55));
+  subRound (E, A, B, C, D, f3, K3, expand (in, 56));
+  subRound (D, E, A, B, C, f3, K3, expand (in, 57));
+  subRound (C, D, E, A, B, f3, K3, expand (in, 58));
+  subRound (B, C, D, E, A, f3, K3, expand (in, 59));
+
+  subRound (A, B, C, D, E, f4, K4, expand (in, 60));
+  subRound (E, A, B, C, D, f4, K4, expand (in, 61));
+  subRound (D, E, A, B, C, f4, K4, expand (in, 62));
+  subRound (C, D, E, A, B, f4, K4, expand (in, 63));
+  subRound (B, C, D, E, A, f4, K4, expand (in, 64));
+  subRound (A, B, C, D, E, f4, K4, expand (in, 65));
+  subRound (E, A, B, C, D, f4, K4, expand (in, 66));
+  subRound (D, E, A, B, C, f4, K4, expand (in, 67));
+  subRound (C, D, E, A, B, f4, K4, expand (in, 68));
+  subRound (B, C, D, E, A, f4, K4, expand (in, 69));
+  subRound (A, B, C, D, E, f4, K4, expand (in, 70));
+  subRound (E, A, B, C, D, f4, K4, expand (in, 71));
+  subRound (D, E, A, B, C, f4, K4, expand (in, 72));
+  subRound (C, D, E, A, B, f4, K4, expand (in, 73));
+  subRound (B, C, D, E, A, f4, K4, expand (in, 74));
+  subRound (A, B, C, D, E, f4, K4, expand (in, 75));
+  subRound (E, A, B, C, D, f4, K4, expand (in, 76));
+  subRound (D, E, A, B, C, f4, K4, expand (in, 77));
+  subRound (C, D, E, A, B, f4, K4, expand (in, 78));
+  subRound (B, C, D, E, A, f4, K4, expand (in, 79));
+
+  /* Build message digest */
+  buf[0] += A;
+  buf[1] += B;
+  buf[2] += C;
+  buf[3] += D;
+  buf[4] += E;
+}
+
+#undef K1
+#undef K2
+#undef K3
+#undef K4
+#undef f1
+#undef f2
+#undef f3
+#undef f4
+#undef ROTL
+#undef expand
+#undef subRound
+
+static void
+sha1_sum_update (Sha1sum      *sha1,
+                 const guchar *buffer,
+                 gsize         count)
+{
+  guint32 tmp;
+  guint dataCount;
+
+  /* Update bitcount */
+  tmp = sha1->bits[0];
+  if ((sha1->bits[0] = tmp + ((guint32) count << 3) ) < tmp)
+    sha1->bits[1] += 1;             /* Carry from low to high */
+  sha1->bits[1] += count >> 29;
+
+  /* Get count of bytes already in data */
+  dataCount = (guint) (tmp >> 3) & 0x3F;
+
+  /* Handle any leading odd-sized chunks */
+  if (dataCount)
+    {
+      guchar *p = (guchar *) sha1->data + dataCount;
+
+      dataCount = SHA1_DATASIZE - dataCount;
+      if (count < dataCount)
+        {
+          memcpy (p, buffer, count);
+          return;
+        }
+
+      memcpy (p, buffer, dataCount);
+
+      sha_byte_reverse (sha1->data, SHA1_DATASIZE);
+      sha1_transform (sha1->buf, sha1->data);
+
+      buffer += dataCount;
+      count -= dataCount;
+    }
+
+  /* Process data in SHA1_DATASIZE chunks */
+  while (count >= SHA1_DATASIZE)
+    {
+      memcpy (sha1->data, buffer, SHA1_DATASIZE);
+
+      sha_byte_reverse (sha1->data, SHA1_DATASIZE);
+      sha1_transform (sha1->buf, sha1->data);
+
+      buffer += SHA1_DATASIZE;
+      count -= SHA1_DATASIZE;
+    }
+
+  /* Handle any remaining bytes of data. */
+  memcpy (sha1->data, buffer, count);
+}
+
+/* Final wrapup - pad to SHA_DATASIZE-byte boundary with the bit pattern
+   1 0* (64-bit count of bits processed, MSB-first) */
+static void
+sha1_sum_close (Sha1sum *sha1)
+{
+  gint count;
+  guchar *data_p;
+
+  /* Compute number of bytes mod 64 */
+  count = (gint) ((sha1->bits[0] >> 3) & 0x3f);
+
+  /* Set the first char of padding to 0x80.  This is safe since there is
+     always at least one byte free */
+  data_p = (guchar *) sha1->data + count;
+  *data_p++ = 0x80;
+
+  /* Bytes of padding needed to make 64 bytes */
+  count = SHA1_DATASIZE - 1 - count;
+
+  /* Pad out to 56 mod 64 */
+  if (count < 8)
+    {
+      /* Two lots of padding:  Pad the first block to 64 bytes */
+      memset (data_p, 0, count);
+
+      sha_byte_reverse (sha1->data, SHA1_DATASIZE);
+      sha1_transform (sha1->buf, sha1->data);
+
+      /* Now fill the next block with 56 bytes */
+      memset (sha1->data, 0, SHA1_DATASIZE - 8);
+    }
+  else
+    {
+      /* Pad block to 56 bytes */
+      memset (data_p, 0, count - 8);
+    }
+
+  /* Append length in bits and transform */
+  sha1->data[14] = sha1->bits[1];
+  sha1->data[15] = sha1->bits[0];
+
+  sha_byte_reverse (sha1->data, SHA1_DATASIZE - 8);
+  sha1_transform (sha1->buf, sha1->data);
+  sha_byte_reverse (sha1->buf, SHA1_DIGEST_LEN);
+
+  memcpy (sha1->digest, sha1->buf, SHA1_DIGEST_LEN);
+
+  /* Reset buffers in case they contain sensitive data */
+  memset (sha1->buf, 0, sizeof (sha1->buf));
+  memset (sha1->data, 0, sizeof (sha1->data));
+}
+
+static gchar *
+sha1_sum_to_string (Sha1sum *sha1)
+{
+  return digest_to_string (sha1->digest, SHA1_DIGEST_LEN);
+}
+
+static void
+sha1_sum_digest (Sha1sum *sha1,
+                 guint8  *digest)
+{
+  gint i;
+
+  for (i = 0; i < SHA1_DIGEST_LEN; i++)
+    digest[i] = sha1->digest[i];
+}
+
+/*
+ * SHA-256 Checksum
+ */
+
+/* adapted from the SHA256 implementation in gsk/src/hash/gskhash.c.
+ *
+ * Copyright (C) 2006 Dave Benson
+ * Released under the terms of the GNU Lesser General Public License
+ */
+
+static void
+sha256_sum_init (Sha256sum *sha256)
+{
+  sha256->buf[0] = 0x6a09e667;
+  sha256->buf[1] = 0xbb67ae85;
+  sha256->buf[2] = 0x3c6ef372;
+  sha256->buf[3] = 0xa54ff53a;
+  sha256->buf[4] = 0x510e527f;
+  sha256->buf[5] = 0x9b05688c;
+  sha256->buf[6] = 0x1f83d9ab;
+  sha256->buf[7] = 0x5be0cd19;
+
+  sha256->bits[0] = sha256->bits[1] = 0;
+}
+
+#define GET_UINT32(n,b,i)               G_STMT_START{   \
+    (n) = ((guint32) (b)[(i)    ] << 24)                \
+        | ((guint32) (b)[(i) + 1] << 16)                \
+        | ((guint32) (b)[(i) + 2] <<  8)                \
+        | ((guint32) (b)[(i) + 3]      ); } G_STMT_END
+
+#define PUT_UINT32(n,b,i)               G_STMT_START{   \
+    (b)[(i)    ] = (guint8) ((n) >> 24);                \
+    (b)[(i) + 1] = (guint8) ((n) >> 16);                \
+    (b)[(i) + 2] = (guint8) ((n) >>  8);                \
+    (b)[(i) + 3] = (guint8) ((n)      ); } G_STMT_END
+
+static void
+sha256_transform (guint32      buf[8],
+                  guint8 const data[64])
+{
+  guint32 temp1, temp2, W[64];
+  guint32 A, B, C, D, E, F, G, H;
+
+  GET_UINT32 (W[0],  data,  0);
+  GET_UINT32 (W[1],  data,  4);
+  GET_UINT32 (W[2],  data,  8);
+  GET_UINT32 (W[3],  data, 12);
+  GET_UINT32 (W[4],  data, 16);
+  GET_UINT32 (W[5],  data, 20);
+  GET_UINT32 (W[6],  data, 24);
+  GET_UINT32 (W[7],  data, 28);
+  GET_UINT32 (W[8],  data, 32);
+  GET_UINT32 (W[9],  data, 36);
+  GET_UINT32 (W[10], data, 40);
+  GET_UINT32 (W[11], data, 44);
+  GET_UINT32 (W[12], data, 48);
+  GET_UINT32 (W[13], data, 52);
+  GET_UINT32 (W[14], data, 56);
+  GET_UINT32 (W[15], data, 60);
+
+#define SHR(x,n)        ((x & 0xFFFFFFFF) >> n)
+#define ROTR(x,n)       (SHR (x,n) | (x << (32 - n)))
+
+#define S0(x) (ROTR (x, 7) ^ ROTR (x,18) ^  SHR (x, 3))
+#define S1(x) (ROTR (x,17) ^ ROTR (x,19) ^  SHR (x,10))
+#define S2(x) (ROTR (x, 2) ^ ROTR (x,13) ^ ROTR (x,22))
+#define S3(x) (ROTR (x, 6) ^ ROTR (x,11) ^ ROTR (x,25))
+
+#define F0(x,y,z) ((x & y) | (z & (x | y)))
+#define F1(x,y,z) (z ^ (x & (y ^ z)))
+
+#define R(t)    (W[t] = S1(W[t -  2]) + W[t -  7] + \
+                        S0(W[t - 15]) + W[t - 16])
+
+#define P(a,b,c,d,e,f,g,h,x,K)          G_STMT_START {  \
+        temp1 = h + S3(e) + F1(e,f,g) + K + x;          \
+        temp2 = S2(a) + F0(a,b,c);                      \
+        d += temp1; h = temp1 + temp2; } G_STMT_END
+
+  A = buf[0];
+  B = buf[1];
+  C = buf[2];
+  D = buf[3];
+  E = buf[4];
+  F = buf[5];
+  G = buf[6];
+  H = buf[7];
+
+  P (A, B, C, D, E, F, G, H, W[ 0], 0x428A2F98);
+  P (H, A, B, C, D, E, F, G, W[ 1], 0x71374491);
+  P (G, H, A, B, C, D, E, F, W[ 2], 0xB5C0FBCF);
+  P (F, G, H, A, B, C, D, E, W[ 3], 0xE9B5DBA5);
+  P (E, F, G, H, A, B, C, D, W[ 4], 0x3956C25B);
+  P (D, E, F, G, H, A, B, C, W[ 5], 0x59F111F1);
+  P (C, D, E, F, G, H, A, B, W[ 6], 0x923F82A4);
+  P (B, C, D, E, F, G, H, A, W[ 7], 0xAB1C5ED5);
+  P (A, B, C, D, E, F, G, H, W[ 8], 0xD807AA98);
+  P (H, A, B, C, D, E, F, G, W[ 9], 0x12835B01);
+  P (G, H, A, B, C, D, E, F, W[10], 0x243185BE);
+  P (F, G, H, A, B, C, D, E, W[11], 0x550C7DC3);
+  P (E, F, G, H, A, B, C, D, W[12], 0x72BE5D74);
+  P (D, E, F, G, H, A, B, C, W[13], 0x80DEB1FE);
+  P (C, D, E, F, G, H, A, B, W[14], 0x9BDC06A7);
+  P (B, C, D, E, F, G, H, A, W[15], 0xC19BF174);
+  P (A, B, C, D, E, F, G, H, R(16), 0xE49B69C1);
+  P (H, A, B, C, D, E, F, G, R(17), 0xEFBE4786);
+  P (G, H, A, B, C, D, E, F, R(18), 0x0FC19DC6);
+  P (F, G, H, A, B, C, D, E, R(19), 0x240CA1CC);
+  P (E, F, G, H, A, B, C, D, R(20), 0x2DE92C6F);
+  P (D, E, F, G, H, A, B, C, R(21), 0x4A7484AA);
+  P (C, D, E, F, G, H, A, B, R(22), 0x5CB0A9DC);
+  P (B, C, D, E, F, G, H, A, R(23), 0x76F988DA);
+  P (A, B, C, D, E, F, G, H, R(24), 0x983E5152);
+  P (H, A, B, C, D, E, F, G, R(25), 0xA831C66D);
+  P (G, H, A, B, C, D, E, F, R(26), 0xB00327C8);
+  P (F, G, H, A, B, C, D, E, R(27), 0xBF597FC7);
+  P (E, F, G, H, A, B, C, D, R(28), 0xC6E00BF3);
+  P (D, E, F, G, H, A, B, C, R(29), 0xD5A79147);
+  P (C, D, E, F, G, H, A, B, R(30), 0x06CA6351);
+  P (B, C, D, E, F, G, H, A, R(31), 0x14292967);
+  P (A, B, C, D, E, F, G, H, R(32), 0x27B70A85);
+  P (H, A, B, C, D, E, F, G, R(33), 0x2E1B2138);
+  P (G, H, A, B, C, D, E, F, R(34), 0x4D2C6DFC);
+  P (F, G, H, A, B, C, D, E, R(35), 0x53380D13);
+  P (E, F, G, H, A, B, C, D, R(36), 0x650A7354);
+  P (D, E, F, G, H, A, B, C, R(37), 0x766A0ABB);
+  P (C, D, E, F, G, H, A, B, R(38), 0x81C2C92E);
+  P (B, C, D, E, F, G, H, A, R(39), 0x92722C85);
+  P (A, B, C, D, E, F, G, H, R(40), 0xA2BFE8A1);
+  P (H, A, B, C, D, E, F, G, R(41), 0xA81A664B);
+  P (G, H, A, B, C, D, E, F, R(42), 0xC24B8B70);
+  P (F, G, H, A, B, C, D, E, R(43), 0xC76C51A3);
+  P (E, F, G, H, A, B, C, D, R(44), 0xD192E819);
+  P (D, E, F, G, H, A, B, C, R(45), 0xD6990624);
+  P (C, D, E, F, G, H, A, B, R(46), 0xF40E3585);
+  P (B, C, D, E, F, G, H, A, R(47), 0x106AA070);
+  P (A, B, C, D, E, F, G, H, R(48), 0x19A4C116);
+  P (H, A, B, C, D, E, F, G, R(49), 0x1E376C08);
+  P (G, H, A, B, C, D, E, F, R(50), 0x2748774C);
+  P (F, G, H, A, B, C, D, E, R(51), 0x34B0BCB5);
+  P (E, F, G, H, A, B, C, D, R(52), 0x391C0CB3);
+  P (D, E, F, G, H, A, B, C, R(53), 0x4ED8AA4A);
+  P (C, D, E, F, G, H, A, B, R(54), 0x5B9CCA4F);
+  P (B, C, D, E, F, G, H, A, R(55), 0x682E6FF3);
+  P (A, B, C, D, E, F, G, H, R(56), 0x748F82EE);
+  P (H, A, B, C, D, E, F, G, R(57), 0x78A5636F);
+  P (G, H, A, B, C, D, E, F, R(58), 0x84C87814);
+  P (F, G, H, A, B, C, D, E, R(59), 0x8CC70208);
+  P (E, F, G, H, A, B, C, D, R(60), 0x90BEFFFA);
+  P (D, E, F, G, H, A, B, C, R(61), 0xA4506CEB);
+  P (C, D, E, F, G, H, A, B, R(62), 0xBEF9A3F7);
+  P (B, C, D, E, F, G, H, A, R(63), 0xC67178F2);
+
+#undef SHR
+#undef ROTR
+#undef S0
+#undef S1
+#undef S2
+#undef S3
+#undef F0
+#undef F1
+#undef R
+#undef P
+
+  buf[0] += A;
+  buf[1] += B;
+  buf[2] += C;
+  buf[3] += D;
+  buf[4] += E;
+  buf[5] += F;
+  buf[6] += G;
+  buf[7] += H;
+}
+
+static void
+sha256_sum_update (Sha256sum    *sha256,
+                   const guchar *buffer,
+                   gsize         length)
+{
+  guint32 left, fill;
+  const guint8 *input = buffer;
+
+  if (length == 0)
+    return;
+
+  left = sha256->bits[0] & 0x3F;
+  fill = 64 - left;
+
+  sha256->bits[0] += length;
+  sha256->bits[0] &= 0xFFFFFFFF;
+
+  if (sha256->bits[0] < length)
+      sha256->bits[1]++;
+
+  if (left > 0 && length >= fill)
+    {
+      memcpy ((sha256->data + left), input, fill);
+
+      sha256_transform (sha256->buf, sha256->data);
+      length -= fill;
+      input += fill;
+
+      left = 0;
+    }
+
+  while (length >= SHA256_DATASIZE)
+    {
+      sha256_transform (sha256->buf, input);
+
+      length -= 64;
+      input += 64;
+    }
+
+  if (length)
+    memcpy (sha256->data + left, input, length);
+}
+
+static guint8 sha256_padding[64] =
+{
+ 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+};
+
+static void
+sha256_sum_close (Sha256sum *sha256)
+{
+  guint32 last, padn;
+  guint32 high, low;
+  guint8 msglen[8];
+
+  high = (sha256->bits[0] >> 29)
+       | (sha256->bits[1] <<  3);
+  low  = (sha256->bits[0] <<  3);
+
+  PUT_UINT32 (high, msglen, 0);
+  PUT_UINT32 (low, msglen, 4);
+
+  last = sha256->bits[0] & 0x3F;
+  padn = (last < 56) ? (56 - last) : (120 - last);
+
+  sha256_sum_update (sha256, sha256_padding, padn);
+  sha256_sum_update (sha256, msglen, 8);
+
+  PUT_UINT32 (sha256->buf[0], sha256->digest,  0);
+  PUT_UINT32 (sha256->buf[1], sha256->digest,  4);
+  PUT_UINT32 (sha256->buf[2], sha256->digest,  8);
+  PUT_UINT32 (sha256->buf[3], sha256->digest, 12);
+  PUT_UINT32 (sha256->buf[4], sha256->digest, 16);
+  PUT_UINT32 (sha256->buf[5], sha256->digest, 20);
+  PUT_UINT32 (sha256->buf[6], sha256->digest, 24);
+  PUT_UINT32 (sha256->buf[7], sha256->digest, 28);
+}
+
+#undef PUT_UINT32
+#undef GET_UINT32
+
+static gchar *
+sha256_sum_to_string (Sha256sum *sha256)
+{
+  return digest_to_string (sha256->digest, SHA256_DIGEST_LEN);
+}
+
+static void
+sha256_sum_digest (Sha256sum *sha256,
+                   guint8    *digest)
+{
+  gint i;
+
+  for (i = 0; i < SHA256_DIGEST_LEN; i++)
+    digest[i] = sha256->digest[i];
+}
+
+
+/*
+ * Public API
+ */
+
+/**
+ * g_checksum_type_get_length:
+ * @checksum_type: a #GChecksumType
+ *
+ * Gets the length in bytes of digests of type @checksum_type
+ *
+ * Return value: the checksum length, or -1 if @checksum_type is
+ * not supported.
+ *
+ * Since: 2.16
+ */
+gssize
+g_checksum_type_get_length (GChecksumType checksum_type)
+{
+  gssize len = -1;
+
+  switch (checksum_type)
+    {
+    case G_CHECKSUM_MD5:
+      len = MD5_DIGEST_LEN;
+      break;
+    case G_CHECKSUM_SHA1:
+      len = SHA1_DIGEST_LEN;
+      break;
+    case G_CHECKSUM_SHA256:
+      len = SHA256_DIGEST_LEN;
+      break;
+    default:
+      len = -1;
+      break;
+    }
+
+  return len;
+}
+
+/**
+ * g_checksum_new:
+ * @checksum_type: the desired type of checksum
+ *
+ * Creates a new #GChecksum, using the checksum algorithm @checksum_type.
+ * If the @checksum_type is not known, %NULL is returned.
+ * A #GChecksum can be used to compute the checksum, or digest, of an
+ * arbitrary binary blob, using different hashing algorithms.
+ *
+ * A #GChecksum works by feeding a binary blob through g_checksum_update()
+ * until there is data to be checked; the digest can then be extracted
+ * using g_checksum_get_string(), which will return the checksum as a
+ * hexadecimal string; or g_checksum_get_digest(), which will return a
+ * vector of raw bytes. Once either g_checksum_get_string() or
+ * g_checksum_get_digest() have been called on a #GChecksum, the checksum
+ * will be closed and it won't be possible to call g_checksum_update()
+ * on it anymore.
+ *
+ * Return value: the newly created #GChecksum, or %NULL.
+ *   Use g_checksum_free() to free the memory allocated by it.
+ *
+ * Since: 2.16
+ */
+GChecksum *
+g_checksum_new (GChecksumType checksum_type)
+{
+  GChecksum *checksum;
+
+  if (! IS_VALID_TYPE (checksum_type))
+    return NULL;
+
+  checksum = g_slice_new0 (GChecksum);
+  checksum->type = checksum_type;
+
+  g_checksum_reset (checksum);
+
+  return checksum;
+}
+
+/**
+ * g_checksum_reset:
+ * @checksum: the #GChecksum to reset
+ *
+ * Resets the state of the @checksum back to its initial state.
+ *
+ * Since: 2.18
+ **/
+void
+g_checksum_reset (GChecksum *checksum)
+{
+  g_return_if_fail (checksum != NULL);
+
+  g_free (checksum->digest_str);
+  checksum->digest_str = NULL;
+
+  switch (checksum->type)
+    {
+    case G_CHECKSUM_MD5:
+      md5_sum_init (&(checksum->sum.md5));
+      break;
+    case G_CHECKSUM_SHA1:
+      sha1_sum_init (&(checksum->sum.sha1));
+      break;
+    case G_CHECKSUM_SHA256:
+      sha256_sum_init (&(checksum->sum.sha256));
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+}
+
+/**
+ * g_checksum_copy:
+ * @checksum: the #GChecksum to copy
+ *
+ * Copies a #GChecksum. If @checksum has been closed, by calling
+ * g_checksum_get_string() or g_checksum_get_digest(), the copied
+ * checksum will be closed as well.
+ *
+ * Return value: the copy of the passed #GChecksum. Use g_checksum_free()
+ *   when finished using it.
+ *
+ * Since: 2.16
+ */
+GChecksum *
+g_checksum_copy (const GChecksum *checksum)
+{
+  GChecksum *copy;
+
+  g_return_val_if_fail (checksum != NULL, NULL);
+
+  copy = g_slice_new (GChecksum);
+  *copy = *checksum;
+
+  copy->digest_str = g_strdup (checksum->digest_str);
+
+  return copy;
+}
+
+/**
+ * g_checksum_free:
+ * @checksum: a #GChecksum
+ *
+ * Frees the memory allocated for @checksum.
+ *
+ * Since: 2.16
+ */
+void
+g_checksum_free (GChecksum *checksum)
+{
+  if (G_LIKELY (checksum))
+    {
+      g_free (checksum->digest_str);
+
+      g_slice_free (GChecksum, checksum);
+    }
+}
+
+/**
+ * g_checksum_update:
+ * @checksum: a #GChecksum
+ * @data: buffer used to compute the checksum
+ * @length: size of the buffer, or -1 if it is a null-terminated string.
+ *
+ * Feeds @data into an existing #GChecksum. The checksum must still be
+ * open, that is g_checksum_get_string() or g_checksum_get_digest() must
+ * not have been called on @checksum.
+ *
+ * Since: 2.16
+ */
+void
+g_checksum_update (GChecksum    *checksum,
+                   const guchar *data,
+                   gssize        length)
+{
+  g_return_if_fail (checksum != NULL);
+  g_return_if_fail (length == 0 || data != NULL);
+
+  if (length < 0)
+    length = strlen ((const gchar *) data);
+
+  if (checksum->digest_str)
+    {
+      g_warning ("The checksum `%s' has been closed and cannot be updated "
+                 "anymore.",
+                 checksum->digest_str);
+      return;
+    }
+
+  switch (checksum->type)
+    {
+    case G_CHECKSUM_MD5:
+      md5_sum_update (&(checksum->sum.md5), data, length);
+      break;
+    case G_CHECKSUM_SHA1:
+      sha1_sum_update (&(checksum->sum.sha1), data, length);
+      break;
+    case G_CHECKSUM_SHA256:
+      sha256_sum_update (&(checksum->sum.sha256), data, length);
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+}
+
+/**
+ * g_checksum_get_string:
+ * @checksum: a #GChecksum
+ *
+ * Gets the digest as an hexadecimal string.
+ *
+ * Once this function has been called the #GChecksum can no longer be
+ * updated with g_checksum_update().
+ *
+ * The hexadecimal characters will be lower case.
+ *
+ * Return value: the hexadecimal representation of the checksum. The
+ *   returned string is owned by the checksum and should not be modified
+ *   or freed.
+ *
+ * Since: 2.16
+ */
+G_CONST_RETURN gchar *
+g_checksum_get_string (GChecksum *checksum)
+{
+  gchar *str = NULL;
+
+  g_return_val_if_fail (checksum != NULL, NULL);
+
+  if (checksum->digest_str)
+    return checksum->digest_str;
+
+  switch (checksum->type)
+    {
+    case G_CHECKSUM_MD5:
+      md5_sum_close (&(checksum->sum.md5));
+      str = md5_sum_to_string (&(checksum->sum.md5));
+      break;
+    case G_CHECKSUM_SHA1:
+      sha1_sum_close (&(checksum->sum.sha1));
+      str = sha1_sum_to_string (&(checksum->sum.sha1));
+      break;
+    case G_CHECKSUM_SHA256:
+      sha256_sum_close (&(checksum->sum.sha256));
+      str = sha256_sum_to_string (&(checksum->sum.sha256));
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+
+  checksum->digest_str = str;
+
+  return checksum->digest_str;
+}
+
+/**
+ * g_checksum_get_digest:
+ * @checksum: a #GChecksum
+ * @buffer: output buffer
+ * @digest_len: an inout parameter. The caller initializes it to the size of @buffer.
+ *   After the call it contains the length of the digest.
+ *
+ * Gets the digest from @checksum as a raw binary vector and places it
+ * into @buffer. The size of the digest depends on the type of checksum.
+ *
+ * Once this function has been called, the #GChecksum is closed and can
+ * no longer be updated with g_checksum_update().
+ *
+ * Since: 2.16
+ */
+void
+g_checksum_get_digest (GChecksum  *checksum,
+                       guint8     *buffer,
+                       gsize      *digest_len)
+{
+  gboolean checksum_open = FALSE;
+  gchar *str = NULL;
+  gsize len;
+
+  g_return_if_fail (checksum != NULL);
+
+  len = g_checksum_type_get_length (checksum->type);
+  g_return_if_fail (*digest_len >= len);
+
+  checksum_open = !!(checksum->digest_str == NULL);
+
+  switch (checksum->type)
+    {
+    case G_CHECKSUM_MD5:
+      if (checksum_open)
+        {
+          md5_sum_close (&(checksum->sum.md5));
+          str = md5_sum_to_string (&(checksum->sum.md5));
+        }
+      md5_sum_digest (&(checksum->sum.md5), buffer);
+      break;
+    case G_CHECKSUM_SHA1:
+      if (checksum_open)
+        {
+          sha1_sum_close (&(checksum->sum.sha1));
+          str = sha1_sum_to_string (&(checksum->sum.sha1));
+        }
+      sha1_sum_digest (&(checksum->sum.sha1), buffer);
+      break;
+    case G_CHECKSUM_SHA256:
+      if (checksum_open)
+        {
+          sha256_sum_close (&(checksum->sum.sha256));
+          str = sha256_sum_to_string (&(checksum->sum.sha256));
+        }
+      sha256_sum_digest (&(checksum->sum.sha256), buffer);
+      break;
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+
+  if (str)
+    checksum->digest_str = str;
+
+  *digest_len = len;
+}
+
+/**
+ * g_compute_checksum_for_data:
+ * @checksum_type: a #GChecksumType
+ * @data: binary blob to compute the digest of
+ * @length: length of @data
+ *
+ * Computes the checksum for a binary @data of @length. This is a
+ * convenience wrapper for g_checksum_new(), g_checksum_get_string()
+ * and g_checksum_free().
+ *
+ * The hexadecimal string returned will be in lower case.
+ *
+ * Return value: the digest of the binary data as a string in hexadecimal.
+ *   The returned string should be freed with g_free() when done using it.
+ *
+ * Since: 2.16
+ */
+gchar *
+g_compute_checksum_for_data (GChecksumType  checksum_type,
+                             const guchar  *data,
+                             gsize          length)
+{
+  GChecksum *checksum;
+  gchar *retval;
+
+  g_return_val_if_fail (IS_VALID_TYPE (checksum_type), NULL);
+  g_return_val_if_fail (length == 0 || data != NULL, NULL);
+
+  checksum = g_checksum_new (checksum_type);
+  if (!checksum)
+    return NULL;
+
+  g_checksum_update (checksum, data, length);
+  retval = g_strdup (g_checksum_get_string (checksum));
+  g_checksum_free (checksum);
+
+  return retval;
+}
+
+/**
+ * g_compute_checksum_for_string:
+ * @checksum_type: a #GChecksumType
+ * @str: the string to compute the checksum of
+ * @length: the length of the string, or -1 if the string is null-terminated.
+ *
+ * Computes the checksum of a string.
+ *
+ * The hexadecimal string returned will be in lower case.
+ *
+ * Return value: the checksum as a hexadecimal string. The returned string
+ *   should be freed with g_free() when done using it.
+ *
+ * Since: 2.16
+ */
+gchar *
+g_compute_checksum_for_string (GChecksumType  checksum_type,
+                               const gchar   *str,
+                               gssize         length)
+{
+  g_return_val_if_fail (IS_VALID_TYPE (checksum_type), NULL);
+  g_return_val_if_fail (length == 0 || str != NULL, NULL);
+
+  if (length < 0)
+    length = strlen (str);
+
+  return g_compute_checksum_for_data (checksum_type, (const guchar *) str, length);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gchecksum.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gchecksum.h
new file mode 100644 (file)
index 0000000..57aea10
--- /dev/null
@@ -0,0 +1,86 @@
+/* gchecksum.h - data hashing functions
+ *
+ * Copyright (C) 2007  Emmanuele Bassi  <ebassi@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_CHECKSUM_H__
+#define __G_CHECKSUM_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GChecksumType:
+ * @G_CHECKSUM_MD5: Use the MD5 hashing algorithm
+ * @G_CHECKSUM_SHA1: Use the SHA-1 hashing algorithm
+ * @G_CHECKSUM_SHA256: Use the SHA-256 hashing algorithm
+ *
+ * The hashing algorithm to be used by #GChecksum when performing the
+ * digest of some data.
+ *
+ * Note that the #GChecksumType enumeration may be extended at a later
+ * date to include new hashing algorithm types.
+ *
+ * Since: 2.16
+ */
+typedef enum {
+  G_CHECKSUM_MD5,
+  G_CHECKSUM_SHA1,
+  G_CHECKSUM_SHA256
+} GChecksumType;
+
+/**
+ * GChecksum:
+ *
+ * An opaque structure representing a checksumming operation.
+ * To create a new GChecksum, use g_checksum_new(). To free
+ * a GChecksum, use g_checksum_free().
+ *
+ * Since: 2.16
+ */
+typedef struct _GChecksum       GChecksum;
+
+gssize                g_checksum_type_get_length    (GChecksumType    checksum_type);
+
+GChecksum *           g_checksum_new                (GChecksumType    checksum_type);
+void                  g_checksum_reset              (GChecksum       *checksum);
+GChecksum *           g_checksum_copy               (const GChecksum *checksum);
+void                  g_checksum_free               (GChecksum       *checksum);
+void                  g_checksum_update             (GChecksum       *checksum,
+                                                     const guchar    *data,
+                                                     gssize           length);
+G_CONST_RETURN gchar *g_checksum_get_string         (GChecksum       *checksum);
+void                  g_checksum_get_digest         (GChecksum       *checksum,
+                                                     guint8          *buffer,
+                                                     gsize           *digest_len);
+
+gchar                *g_compute_checksum_for_data   (GChecksumType    checksum_type,
+                                                     const guchar    *data,
+                                                     gsize            length);
+gchar                *g_compute_checksum_for_string (GChecksumType    checksum_type,
+                                                     const gchar     *str,
+                                                     gssize           length);
+
+G_END_DECLS
+
+#endif /* __G_CHECKSUM_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gcompletion.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gcompletion.c
new file mode 100644 (file)
index 0000000..710e6c0
--- /dev/null
@@ -0,0 +1,491 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/* 
+ * MT safe
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gstrfuncs.h"
+#include "gmessages.h"
+#include "gunicode.h"
+
+#undef G_DISABLE_DEPRECATED
+
+#include "gcompletion.h"
+
+/**
+ * SECTION: completion
+ * @title: Automatic String Completion
+ * @short_description: support for automatic completion using a group
+ *                     of target strings
+ *
+ * #GCompletion provides support for automatic completion of a string
+ * using any group of target strings. It is typically used for file
+ * name completion as is common in many UNIX shells.
+ *
+ * A #GCompletion is created using g_completion_new(). Target items are
+ * added and removed with g_completion_add_items(),
+ * g_completion_remove_items() and g_completion_clear_items(). A
+ * completion attempt is requested with g_completion_complete() or
+ * g_completion_complete_utf8(). When no longer needed, the
+ * #GCompletion is freed with g_completion_free().
+ *
+ * Items in the completion can be simple strings (e.g. filenames), or
+ * pointers to arbitrary data structures. If data structures are used
+ * you must provide a #GCompletionFunc in g_completion_new(), which
+ * retrieves the item's string from the data structure. You can change
+ * the way in which strings are compared by setting a different
+ * #GCompletionStrncmpFunc in g_completion_set_compare().
+ *
+ * GCompletion has been marked as deprecated, since this API is rarely
+ * used and not very actively maintained.
+ **/
+
+/**
+ * GCompletion:
+ * @items: list of target items (strings or data structures).
+ * @func: function which is called to get the string associated with a
+ *        target item. It is %NULL if the target items are strings.
+ * @prefix: the last prefix passed to g_completion_complete() or
+ *          g_completion_complete_utf8().
+ * @cache: the list of items which begin with @prefix.
+ * @strncmp_func: The function to use when comparing strings.  Use
+ *                g_completion_set_compare() to modify this function.
+ *
+ * The data structure used for automatic completion.
+ **/
+
+/**
+ * GCompletionFunc:
+ * @Param1: the completion item.
+ * @Returns: the string corresponding to the item.
+ *
+ * Specifies the type of the function passed to g_completion_new(). It
+ * should return the string corresponding to the given target item.
+ * This is used when you use data structures as #GCompletion items.
+ **/
+
+/**
+ * GCompletionStrncmpFunc:
+ * @s1: string to compare with @s2.
+ * @s2: string to compare with @s1.
+ * @n: maximal number of bytes to compare.
+ * @Returns: an integer less than, equal to, or greater than zero if
+ *           the first @n bytes of @s1 is found, respectively, to be
+ *           less than, to match, or to be greater than the first @n
+ *           bytes of @s2.
+ *
+ * Specifies the type of the function passed to
+ * g_completion_set_compare(). This is used when you use strings as
+ * #GCompletion items.
+ **/
+
+static void completion_check_cache (GCompletion* cmp,
+                                   gchar**      new_prefix);
+
+/**
+ * g_completion_new:
+ * @func: the function to be called to return the string representing
+ *        an item in the #GCompletion, or %NULL if strings are going to
+ *        be used as the #GCompletion items.
+ * @Returns: the new #GCompletion.
+ *
+ * Creates a new #GCompletion.
+ **/
+GCompletion* 
+g_completion_new (GCompletionFunc func)
+{
+  GCompletion* gcomp;
+  
+  gcomp = g_new (GCompletion, 1);
+  gcomp->items = NULL;
+  gcomp->cache = NULL;
+  gcomp->prefix = NULL;
+  gcomp->func = func;
+  gcomp->strncmp_func = strncmp;
+
+  return gcomp;
+}
+
+/**
+ * g_completion_add_items:
+ * @cmp: the #GCompletion.
+ * @items: the list of items to add.
+ *
+ * Adds items to the #GCompletion.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+void 
+g_completion_add_items (GCompletion* cmp,
+                       GList*       items)
+{
+  GList* it;
+  
+  g_return_if_fail (cmp != NULL);
+  
+  /* optimize adding to cache? */
+  if (cmp->cache)
+    {
+      g_list_free (cmp->cache);
+      cmp->cache = NULL;
+    }
+
+  if (cmp->prefix)
+    {
+      g_free (cmp->prefix);
+      cmp->prefix = NULL;
+    }
+  
+  it = items;
+  while (it)
+    {
+      cmp->items = g_list_prepend (cmp->items, it->data);
+      it = it->next;
+    }
+}
+
+/**
+ * g_completion_remove_items:
+ * @cmp: the #GCompletion.
+ * @items: the items to remove.
+ *
+ * Removes items from a #GCompletion.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+void 
+g_completion_remove_items (GCompletion* cmp,
+                          GList*       items)
+{
+  GList* it;
+  
+  g_return_if_fail (cmp != NULL);
+  
+  it = items;
+  while (cmp->items && it)
+    {
+      cmp->items = g_list_remove (cmp->items, it->data);
+      it = it->next;
+    }
+
+  it = items;
+  while (cmp->cache && it)
+    {
+      cmp->cache = g_list_remove(cmp->cache, it->data);
+      it = it->next;
+    }
+}
+
+/**
+ * g_completion_clear_items:
+ * @cmp: the #GCompletion.
+ *
+ * Removes all items from the #GCompletion.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+void 
+g_completion_clear_items (GCompletion* cmp)
+{
+  g_return_if_fail (cmp != NULL);
+  
+  g_list_free (cmp->items);
+  cmp->items = NULL;
+  g_list_free (cmp->cache);
+  cmp->cache = NULL;
+  g_free (cmp->prefix);
+  cmp->prefix = NULL;
+}
+
+static void   
+completion_check_cache (GCompletion* cmp,
+                       gchar**      new_prefix)
+{
+  register GList* list;
+  register gsize len;  
+  register gsize i;
+  register gsize plen;
+  gchar* postfix;
+  gchar* s;
+  
+  if (!new_prefix)
+    return;
+  if (!cmp->cache)
+    {
+      *new_prefix = NULL;
+      return;
+    }
+  
+  len = strlen(cmp->prefix);
+  list = cmp->cache;
+  s = cmp->func ? cmp->func (list->data) : (gchar*) list->data;
+  postfix = s + len;
+  plen = strlen (postfix);
+  list = list->next;
+  
+  while (list && plen)
+    {
+      s = cmp->func ? cmp->func (list->data) : (gchar*) list->data;
+      s += len;
+      for (i = 0; i < plen; ++i)
+       {
+         if (postfix[i] != s[i])
+           break;
+       }
+      plen = i;
+      list = list->next;
+    }
+  
+  *new_prefix = g_new0 (gchar, len + plen + 1);
+  strncpy (*new_prefix, cmp->prefix, len);
+  strncpy (*new_prefix + len, postfix, plen);
+}
+
+/**
+ * g_completion_complete_utf8:
+ * @cmp: the #GCompletion
+ * @prefix: the prefix string, typically used by the user, which is compared
+ *    with each of the items
+ * @new_prefix: if non-%NULL, returns the longest prefix which is common to all
+ *    items that matched @prefix, or %NULL if no items matched @prefix.
+ *    This string should be freed when no longer needed.
+ *
+ * Attempts to complete the string @prefix using the #GCompletion target items.
+ * In contrast to g_completion_complete(), this function returns the largest common
+ * prefix that is a valid UTF-8 string, omitting a possible common partial 
+ * character.
+ *
+ * You should use this function instead of g_completion_complete() if your 
+ * items are UTF-8 strings.
+ *
+ * Return value: the list of items whose strings begin with @prefix. This should
+ * not be changed.
+ *
+ * Since: 2.4
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+GList*
+g_completion_complete_utf8 (GCompletion  *cmp,
+                           const gchar  *prefix,
+                           gchar       **new_prefix)
+{
+  GList *list;
+  gchar *p, *q;
+
+  list = g_completion_complete (cmp, prefix, new_prefix);
+
+  if (new_prefix && *new_prefix)
+    {
+      p = *new_prefix + strlen (*new_prefix);
+      q = g_utf8_find_prev_char (*new_prefix, p);
+      
+      switch (g_utf8_get_char_validated (q, p - q))
+       {
+       case (gunichar)-2:
+       case (gunichar)-1:
+         *q = 0;
+         break;
+       default: ;
+       }
+
+    }
+
+  return list;
+}
+
+/**
+ * g_completion_complete:
+ * @cmp: the #GCompletion.
+ * @prefix: the prefix string, typically typed by the user, which is
+ *          compared with each of the items.
+ * @new_prefix: if non-%NULL, returns the longest prefix which is
+ *              common to all items that matched @prefix, or %NULL if
+ *              no items matched @prefix.  This string should be freed
+ *              when no longer needed.
+ * @Returns: the list of items whose strings begin with @prefix. This
+ *           should not be changed.
+ *
+ * Attempts to complete the string @prefix using the #GCompletion
+ * target items.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+GList* 
+g_completion_complete (GCompletion* cmp,
+                      const gchar* prefix,
+                      gchar**      new_prefix)
+{
+  gsize plen, len;
+  gboolean done = FALSE;
+  GList* list;
+  
+  g_return_val_if_fail (cmp != NULL, NULL);
+  g_return_val_if_fail (prefix != NULL, NULL);
+  
+  len = strlen (prefix);
+  if (cmp->prefix && cmp->cache)
+    {
+      plen = strlen (cmp->prefix);
+      if (plen <= len && ! cmp->strncmp_func (prefix, cmp->prefix, plen))
+       { 
+         /* use the cache */
+         list = cmp->cache;
+         while (list)
+           {
+             GList *next = list->next;
+             
+             if (cmp->strncmp_func (prefix,
+                                    cmp->func ? cmp->func (list->data) : (gchar*) list->data,
+                                    len))
+               cmp->cache = g_list_delete_link (cmp->cache, list);
+
+             list = next;
+           }
+         done = TRUE;
+       }
+    }
+  
+  if (!done)
+    {
+      /* normal code */
+      g_list_free (cmp->cache);
+      cmp->cache = NULL;
+      list = cmp->items;
+      while (*prefix && list)
+       {
+         if (!cmp->strncmp_func (prefix,
+                       cmp->func ? cmp->func (list->data) : (gchar*) list->data,
+                       len))
+           cmp->cache = g_list_prepend (cmp->cache, list->data);
+         list = list->next;
+       }
+    }
+  if (cmp->prefix)
+    {
+      g_free (cmp->prefix);
+      cmp->prefix = NULL;
+    }
+  if (cmp->cache)
+    cmp->prefix = g_strdup (prefix);
+  completion_check_cache (cmp, new_prefix);
+  
+  return *prefix ? cmp->cache : cmp->items;
+}
+
+/**
+ * g_completion_free:
+ * @cmp: the #GCompletion.
+ *
+ * Frees all memory used by the #GCompletion.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+void 
+g_completion_free (GCompletion* cmp)
+{
+  g_return_if_fail (cmp != NULL);
+  
+  g_completion_clear_items (cmp);
+  g_free (cmp);
+}
+
+/**
+ * g_completion_set_compare:
+ * @cmp: a #GCompletion.
+ * @strncmp_func: the string comparison function.
+ *
+ * Sets the function to use for string comparisons. The default string
+ * comparison function is strncmp().
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+void
+g_completion_set_compare(GCompletion *cmp,
+                        GCompletionStrncmpFunc strncmp_func)
+{
+  cmp->strncmp_func = strncmp_func;
+}
+
+#ifdef TEST_COMPLETION
+#include <stdio.h>
+int
+main (int   argc,
+      char* argv[])
+{
+  FILE *file;
+  gchar buf[1024];
+  GList *list;
+  GList *result;
+  GList *tmp;
+  GCompletion *cmp;
+  gint i;
+  gchar *longp = NULL;
+  
+  if (argc < 3)
+    {
+      g_warning ("Usage: %s filename prefix1 [prefix2 ...]\n", argv[0]);
+      return 1;
+    }
+  
+  file = fopen (argv[1], "r");
+  if (!file)
+    {
+      g_warning ("Cannot open %s\n", argv[1]);
+      return 1;
+    }
+  
+  cmp = g_completion_new (NULL);
+  list = g_list_alloc ();
+  while (fgets (buf, 1024, file))
+    {
+      list->data = g_strdup (buf);
+      g_completion_add_items (cmp, list);
+    }
+  fclose (file);
+  
+  for (i = 2; i < argc; ++i)
+    {
+      printf ("COMPLETING: %s\n", argv[i]);
+      result = g_completion_complete (cmp, argv[i], &longp);
+      g_list_foreach (result, (GFunc) printf, NULL);
+      printf ("LONG MATCH: %s\n", longp);
+      g_free (longp);
+      longp = NULL;
+    }
+  
+  g_list_foreach (cmp->items, (GFunc) g_free, NULL);
+  g_completion_free (cmp);
+  g_list_free (list);
+  
+  return 0;
+}
+#endif
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gcompletion.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gcompletion.h
new file mode 100644 (file)
index 0000000..04c024f
--- /dev/null
@@ -0,0 +1,81 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_COMPLETION_H__
+#define __G_COMPLETION_H__
+
+#include <glib/glist.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GCompletion     GCompletion;
+
+typedef gchar*          (*GCompletionFunc)      (gpointer);
+
+/* GCompletion
+ */
+
+typedef gint (*GCompletionStrncmpFunc) (const gchar *s1,
+                                       const gchar *s2,
+                                       gsize        n);
+
+struct _GCompletion
+{
+  GList* items;
+  GCompletionFunc func;
+  gchar* prefix;
+  GList* cache;
+  GCompletionStrncmpFunc strncmp_func;
+};
+
+#ifndef G_DISABLE_DEPRECATED
+
+GCompletion* g_completion_new           (GCompletionFunc func);
+void         g_completion_add_items     (GCompletion*    cmp,
+                                         GList*          items);
+void         g_completion_remove_items  (GCompletion*    cmp,
+                                         GList*          items);
+void         g_completion_clear_items   (GCompletion*    cmp);
+GList*       g_completion_complete      (GCompletion*    cmp,
+                                         const gchar*    prefix,
+                                         gchar**         new_prefix);
+GList*       g_completion_complete_utf8 (GCompletion  *cmp,
+                                         const gchar*    prefix,
+                                         gchar**         new_prefix);
+void         g_completion_set_compare   (GCompletion *cmp,
+                                        GCompletionStrncmpFunc strncmp_func);
+void         g_completion_free          (GCompletion*    cmp);
+
+#endif
+
+G_END_DECLS
+
+#endif /* __G_COMPLETION_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gconvert.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gconvert.c
new file mode 100644 (file)
index 0000000..687f661
--- /dev/null
@@ -0,0 +1,2278 @@
+/* GLIB - Library of useful routines for C programming
+ *
+ * gconvert.c: Convert between character sets using iconv
+ * Copyright Red Hat Inc., 2000
+ * Authors: Havoc Pennington <hp@redhat.com>, Owen Taylor <otaylor@redhat.com>
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "glibconfig.h"
+
+#ifdef G_OS_WIN32
+#include "win_iconv.c"
+#else
+#ifdef USE_LIBICONV_GNU
+#include <iconv.h>
+#endif
+#endif
+
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#include "gprintfint.h"
+#include "gthreadprivate.h"
+#include "gunicode.h"
+
+#ifdef G_PLATFORM_WIN32
+#define STRICT
+#include <windows.h>
+#undef STRICT
+#endif
+
+#include "gconvert.h"
+
+#include "gprintfint.h"
+#include "gslist.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "gthread.h"
+#include "gthreadprivate.h"
+#include "gunicode.h"
+
+#ifdef NEED_ICONV_CACHE
+#include "glist.h"
+#include "ghash.h"
+#endif
+
+#include "glibintl.h"
+
+#if defined(USE_LIBICONV_GNU) && !defined (_LIBICONV_H)
+#error GNU libiconv in use but included iconv.h not from libiconv
+#endif
+#if !defined(USE_LIBICONV_GNU) && defined (_LIBICONV_H)
+#error GNU libiconv not in use but included iconv.h is from libiconv
+#endif
+
+
+/**
+ * SECTION:conversions
+ * @title: Character Set Conversion
+ * @short_description: Convert strings between different character sets
+ *
+ * The g_convert() family of function wraps the functionality of iconv(). In
+ * addition to pure character set conversions, GLib has functions to deal
+ * with the extra complications of encodings for file names.
+ *
+ * <refsect2 id="file-name-encodings">
+ * <title>File Name Encodings</title>
+ * <para>
+ * Historically, Unix has not had a defined encoding for file
+ * names:  a file name is valid as long as it does not have path
+ * separators in it ("/").  However, displaying file names may
+ * require conversion:  from the character set in which they were
+ * created, to the character set in which the application
+ * operates.  Consider the Spanish file name
+ * "<filename>Presentaci&oacute;n.sxi</filename>".  If the
+ * application which created it uses ISO-8859-1 for its encoding,
+ * </para>
+ * <programlisting id="filename-iso8859-1">
+ * Character:  P  r  e  s  e  n  t  a  c  i  &oacute;  n  .  s  x  i
+ * Hex code:   50 72 65 73 65 6e 74 61 63 69 f3 6e 2e 73 78 69
+ * </programlisting>
+ * <para>
+ * However, if the application use UTF-8, the actual file name on
+ * disk would look like this:
+ * </para>
+ * <programlisting id="filename-utf-8">
+ * Character:  P  r  e  s  e  n  t  a  c  i  &oacute;     n  .  s  x  i
+ * Hex code:   50 72 65 73 65 6e 74 61 63 69 c3 b3 6e 2e 73 78 69
+ * </programlisting>
+ * <para>
+ * Glib uses UTF-8 for its strings, and GUI toolkits like GTK+
+ * that use Glib do the same thing.  If you get a file name from
+ * the file system, for example, from readdir(3) or from g_dir_read_name(),
+ * and you wish to display the file name to the user, you
+ * <emphasis>will</emphasis> need to convert it into UTF-8.  The
+ * opposite case is when the user types the name of a file he
+ * wishes to save:  the toolkit will give you that string in
+ * UTF-8 encoding, and you will need to convert it to the
+ * character set used for file names before you can create the
+ * file with open(2) or fopen(3).
+ * </para>
+ * <para>
+ * By default, Glib assumes that file names on disk are in UTF-8
+ * encoding.  This is a valid assumption for file systems which
+ * were created relatively recently:  most applications use UTF-8
+ * encoding for their strings, and that is also what they use for
+ * the file names they create.  However, older file systems may
+ * still contain file names created in "older" encodings, such as
+ * ISO-8859-1. In this case, for compatibility reasons, you may
+ * want to instruct Glib to use that particular encoding for file
+ * names rather than UTF-8.  You can do this by specifying the
+ * encoding for file names in the <link
+ * linkend="G_FILENAME_ENCODING"><envar>G_FILENAME_ENCODING</envar></link>
+ * environment variable.  For example, if your installation uses
+ * ISO-8859-1 for file names, you can put this in your
+ * <filename>~/.profile</filename>:
+ * </para>
+ * <programlisting>
+ * export G_FILENAME_ENCODING=ISO-8859-1
+ * </programlisting>
+ * <para>
+ * Glib provides the functions g_filename_to_utf8() and
+ * g_filename_from_utf8() to perform the necessary conversions. These
+ * functions convert file names from the encoding specified in
+ * <envar>G_FILENAME_ENCODING</envar> to UTF-8 and vice-versa.
+ * <xref linkend="file-name-encodings-diagram"/> illustrates how
+ * these functions are used to convert between UTF-8 and the
+ * encoding for file names in the file system.
+ * </para>
+ * <figure id="file-name-encodings-diagram">
+ * <title>Conversion between File Name Encodings</title>
+ * <graphic fileref="file-name-encodings.png" format="PNG"/>
+ * </figure>
+ * <refsect3 id="file-name-encodings-checklist">
+ * <title>Checklist for Application Writers</title>
+ * <para>
+ * This section is a practical summary of the detailed
+ * description above.  You can use this as a checklist of
+ * things to do to make sure your applications process file
+ * name encodings correctly.
+ * </para>
+ * <orderedlist>
+ * <listitem><para>
+ * If you get a file name from the file system from a function
+ * such as readdir(3) or gtk_file_chooser_get_filename(),
+ * you do not need to do any conversion to pass that
+ * file name to functions like open(2), rename(2), or
+ * fopen(3) &mdash; those are "raw" file names which the file
+ * system understands.
+ * </para></listitem>
+ * <listitem><para>
+ * If you need to display a file name, convert it to UTF-8 first by
+ * using g_filename_to_utf8(). If conversion fails, display a string like
+ * "<literal>Unknown file name</literal>". <emphasis>Do not</emphasis>
+ * convert this string back into the encoding used for file names if you
+ * wish to pass it to the file system; use the original file name instead.
+ * For example, the document window of a word processor could display
+ * "Unknown file name" in its title bar but still let the user save the
+ * file, as it would keep the raw file name internally. This can happen
+ * if the user has not set the <envar>G_FILENAME_ENCODING</envar>
+ * environment variable even though he has files whose names are not
+ * encoded in UTF-8.
+ * </para></listitem>
+ * <listitem><para>
+ * If your user interface lets the user type a file name for saving or
+ * renaming, convert it to the encoding used for file names in the file
+ * system by using g_filename_from_utf8(). Pass the converted file name
+ * to functions like fopen(3). If conversion fails, ask the user to enter
+ * a different file name. This can happen if the user types Japanese
+ * characters when <envar>G_FILENAME_ENCODING</envar> is set to
+ * <literal>ISO-8859-1</literal>, for example.
+ * </para></listitem>
+ * </orderedlist>
+ * </refsect3>
+ * </refsect2>
+ */
+
+/* We try to terminate strings in unknown charsets with this many zero bytes
+ * to ensure that multibyte strings really are nul-terminated when we return
+ * them from g_convert() and friends.
+ */
+#define NUL_TERMINATOR_LENGTH 4
+
+GQuark 
+g_convert_error_quark (void)
+{
+  return g_quark_from_static_string ("g_convert_error");
+}
+
+#ifdef USE_LIBICONV_GNU
+static gboolean
+try_conversion (const char *to_codeset,
+               const char *from_codeset,
+               iconv_t    *cd)
+{
+  *cd = iconv_open (to_codeset, from_codeset);
+
+  if (*cd == (iconv_t)-1 && errno == EINVAL)
+    return FALSE;
+  else
+    return TRUE;
+}
+
+static gboolean
+try_to_aliases (const char **to_aliases,
+               const char  *from_codeset,
+               iconv_t     *cd)
+{
+  if (to_aliases)
+    {
+      const char **p = to_aliases;
+      while (*p)
+       {
+         if (try_conversion (*p, from_codeset, cd))
+           return TRUE;
+
+         p++;
+       }
+    }
+
+  return FALSE;
+}
+#endif /* USE_LIBICONV_GNU */
+
+G_GNUC_INTERNAL extern const char ** 
+_g_charset_get_aliases (const char *canonical_name);
+
+/**
+ * g_iconv_open:
+ * @to_codeset: destination codeset
+ * @from_codeset: source codeset
+ * 
+ * Same as the standard UNIX routine iconv_open(), but
+ * may be implemented via libiconv on UNIX flavors that lack
+ * a native implementation.
+ * 
+ * GLib provides g_convert() and g_locale_to_utf8() which are likely
+ * more convenient than the raw iconv wrappers.
+ * 
+ * Return value: a "conversion descriptor", or (GIConv)-1 if
+ *  opening the converter failed.
+ **/
+GIConv
+g_iconv_open (const gchar  *to_codeset,
+             const gchar  *from_codeset)
+{
+#ifdef USE_LIBICONV_GNU
+  iconv_t cd;
+  
+  if (!try_conversion (to_codeset, from_codeset, &cd))
+    {
+      const char **to_aliases = _g_charset_get_aliases (to_codeset);
+      const char **from_aliases = _g_charset_get_aliases (from_codeset);
+
+      if (from_aliases)
+       {
+         const char **p = from_aliases;
+         while (*p)
+           {
+             if (try_conversion (to_codeset, *p, &cd))
+               goto out;
+
+             if (try_to_aliases (to_aliases, *p, &cd))
+               goto out;
+
+             p++;
+           }
+       }
+
+      if (try_to_aliases (to_aliases, from_codeset, &cd))
+       goto out;
+    }
+
+ out:
+  return (cd == (iconv_t)-1) ? (GIConv)-1 : (GIConv)cd;
+#else
+  return (GIConv)-1;
+#endif /* USE_LIBICONV_GNU */
+}
+
+/**
+ * g_iconv:
+ * @converter: conversion descriptor from g_iconv_open()
+ * @inbuf: bytes to convert
+ * @inbytes_left: inout parameter, bytes remaining to convert in @inbuf
+ * @outbuf: converted output bytes
+ * @outbytes_left: inout parameter, bytes available to fill in @outbuf
+ * 
+ * Same as the standard UNIX routine iconv(), but
+ * may be implemented via libiconv on UNIX flavors that lack
+ * a native implementation.
+ *
+ * GLib provides g_convert() and g_locale_to_utf8() which are likely
+ * more convenient than the raw iconv wrappers.
+ * 
+ * Return value: count of non-reversible conversions, or -1 on error
+ **/
+gsize 
+g_iconv (GIConv   converter,
+        gchar  **inbuf,
+        gsize   *inbytes_left,
+        gchar  **outbuf,
+        gsize   *outbytes_left)
+{
+#ifdef USE_LIBICONV_GNU
+  iconv_t cd = (iconv_t)converter;
+
+  return iconv (cd, inbuf, inbytes_left, outbuf, outbytes_left);
+#else
+  return -1;
+#endif /* USE_LIBICONV_GNU */
+}
+
+/**
+ * g_iconv_close:
+ * @converter: a conversion descriptor from g_iconv_open()
+ *
+ * Same as the standard UNIX routine iconv_close(), but
+ * may be implemented via libiconv on UNIX flavors that lack
+ * a native implementation. Should be called to clean up
+ * the conversion descriptor from g_iconv_open() when
+ * you are done converting things.
+ *
+ * GLib provides g_convert() and g_locale_to_utf8() which are likely
+ * more convenient than the raw iconv wrappers.
+ * 
+ * Return value: -1 on error, 0 on success
+ **/
+gint
+g_iconv_close (GIConv converter)
+{
+#ifdef USE_LIBICONV_GNU
+  iconv_t cd = (iconv_t)converter;
+
+  return iconv_close (cd);
+#else
+  return -1;
+#endif /* USE_LIBICONV_GNU */
+}
+
+
+#ifdef NEED_ICONV_CACHE
+#ifdef USE_LIBICONV_GNU
+
+#define ICONV_CACHE_SIZE   (16)
+
+struct _iconv_cache_bucket {
+  gchar *key;
+  guint32 refcount;
+  gboolean used;
+  GIConv cd;
+};
+
+static GList *iconv_cache_list;
+static GHashTable *iconv_cache;
+static GHashTable *iconv_open_hash;
+static guint iconv_cache_size = 0;
+G_LOCK_DEFINE_STATIC (iconv_cache_lock);
+
+/* caller *must* hold the iconv_cache_lock */
+static void
+iconv_cache_init (void)
+{
+  static gboolean initialized = FALSE;
+  
+  if (initialized)
+    return;
+  
+  iconv_cache_list = NULL;
+  iconv_cache = g_hash_table_new (g_str_hash, g_str_equal);
+  iconv_open_hash = g_hash_table_new (g_direct_hash, g_direct_equal);
+  
+  initialized = TRUE;
+}
+
+
+/*
+ * iconv_cache_bucket_new:
+ * @key: cache key
+ * @cd: iconv descriptor
+ *
+ * Creates a new cache bucket, inserts it into the cache and
+ * increments the cache size.
+ *
+ * This assumes ownership of @key.
+ *
+ * Returns a pointer to the newly allocated cache bucket.
+ **/
+static struct _iconv_cache_bucket *
+iconv_cache_bucket_new (gchar *key, GIConv cd)
+{
+  struct _iconv_cache_bucket *bucket;
+  
+  bucket = g_new (struct _iconv_cache_bucket, 1);
+  bucket->key = key;
+  bucket->refcount = 1;
+  bucket->used = TRUE;
+  bucket->cd = cd;
+  
+  g_hash_table_insert (iconv_cache, bucket->key, bucket);
+  
+  /* FIXME: if we sorted the list so items with few refcounts were
+     first, then we could expire them faster in iconv_cache_expire_unused () */
+  iconv_cache_list = g_list_prepend (iconv_cache_list, bucket);
+  
+  iconv_cache_size++;
+  
+  return bucket;
+}
+
+
+/*
+ * iconv_cache_bucket_expire:
+ * @node: cache bucket's node
+ * @bucket: cache bucket
+ *
+ * Expires a single cache bucket @bucket. This should only ever be
+ * called on a bucket that currently has no used iconv descriptors
+ * open.
+ *
+ * @node is not a required argument. If @node is not supplied, we
+ * search for it ourselves.
+ **/
+static void
+iconv_cache_bucket_expire (GList *node, struct _iconv_cache_bucket *bucket)
+{
+  g_hash_table_remove (iconv_cache, bucket->key);
+  
+  if (node == NULL)
+    node = g_list_find (iconv_cache_list, bucket);
+  
+  g_assert (node != NULL);
+  
+  if (node->prev)
+    {
+      node->prev->next = node->next;
+      if (node->next)
+        node->next->prev = node->prev;
+    }
+  else
+    {
+      iconv_cache_list = node->next;
+      if (node->next)
+        node->next->prev = NULL;
+    }
+  
+  g_list_free_1 (node);
+  
+  g_free (bucket->key);
+  g_iconv_close (bucket->cd);
+  g_free (bucket);
+  
+  iconv_cache_size--;
+}
+
+
+/*
+ * iconv_cache_expire_unused:
+ *
+ * Expires as many unused cache buckets as it needs to in order to get
+ * the total number of buckets < ICONV_CACHE_SIZE.
+ **/
+static void
+iconv_cache_expire_unused (void)
+{
+  struct _iconv_cache_bucket *bucket;
+  GList *node, *next;
+  
+  node = iconv_cache_list;
+  while (node && iconv_cache_size >= ICONV_CACHE_SIZE)
+    {
+      next = node->next;
+      
+      bucket = node->data;
+      if (bucket->refcount == 0)
+        iconv_cache_bucket_expire (node, bucket);
+      
+      node = next;
+    }
+}
+
+static GIConv
+open_converter (const gchar *to_codeset,
+               const gchar *from_codeset,
+               GError     **error)
+{
+  struct _iconv_cache_bucket *bucket;
+  gchar *key, *dyn_key, auto_key[80];
+  GIConv cd;
+  gsize len_from_codeset, len_to_codeset;
+  
+  /* create our key */
+  len_from_codeset = strlen (from_codeset);
+  len_to_codeset = strlen (to_codeset);
+  if (len_from_codeset + len_to_codeset + 2 < sizeof (auto_key))
+    {
+      key = auto_key;
+      dyn_key = NULL;
+    }
+  else
+    key = dyn_key = g_malloc (len_from_codeset + len_to_codeset + 2);
+  memcpy (key, from_codeset, len_from_codeset);
+  key[len_from_codeset] = ':';
+  strcpy (key + len_from_codeset + 1, to_codeset);
+
+  G_LOCK (iconv_cache_lock);
+  
+  /* make sure the cache has been initialized */
+  iconv_cache_init ();
+  
+  bucket = g_hash_table_lookup (iconv_cache, key);
+  if (bucket)
+    {
+      g_free (dyn_key);
+
+      if (bucket->used)
+        {
+          cd = g_iconv_open (to_codeset, from_codeset);
+          if (cd == (GIConv) -1)
+            goto error;
+        }
+      else
+        {
+         /* Apparently iconv on Solaris <= 7 segfaults if you pass in
+          * NULL for anything but inbuf; work around that. (NULL outbuf
+          * or NULL *outbuf is allowed by Unix98.)
+          */
+         gsize inbytes_left = 0;
+         gchar *outbuf = NULL;
+         gsize outbytes_left = 0;
+               
+          cd = bucket->cd;
+          bucket->used = TRUE;
+          
+          /* reset the descriptor */
+          g_iconv (cd, NULL, &inbytes_left, &outbuf, &outbytes_left);
+        }
+      
+      bucket->refcount++;
+    }
+  else
+    {
+      cd = g_iconv_open (to_codeset, from_codeset);
+      if (cd == (GIConv) -1) 
+       {
+         g_free (dyn_key);
+         goto error;
+       }
+      
+      iconv_cache_expire_unused ();
+
+      bucket = iconv_cache_bucket_new (dyn_key ? dyn_key : g_strdup (key), cd);
+    }
+  
+  g_hash_table_insert (iconv_open_hash, cd, bucket->key);
+  
+  G_UNLOCK (iconv_cache_lock);
+  
+  return cd;
+  
+ error:
+  
+  G_UNLOCK (iconv_cache_lock);
+  
+  /* Something went wrong.  */
+  if (error)
+    {
+      if (errno == EINVAL)
+       g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION,
+                    _("Conversion from character set '%s' to '%s' is not supported"),
+                    from_codeset, to_codeset);
+      else
+       g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+                    _("Could not open converter from '%s' to '%s'"),
+                    from_codeset, to_codeset);
+    }
+  
+  return cd;
+}
+
+static int
+close_converter (GIConv converter)
+{
+  struct _iconv_cache_bucket *bucket;
+  const gchar *key;
+  GIConv cd;
+  
+  cd = converter;
+  
+  if (cd == (GIConv) -1)
+    return 0;
+  
+  G_LOCK (iconv_cache_lock);
+  
+  key = g_hash_table_lookup (iconv_open_hash, cd);
+  if (key)
+    {
+      g_hash_table_remove (iconv_open_hash, cd);
+      
+      bucket = g_hash_table_lookup (iconv_cache, key);
+      g_assert (bucket);
+      
+      bucket->refcount--;
+      
+      if (cd == bucket->cd)
+        bucket->used = FALSE;
+      else
+        g_iconv_close (cd);
+      
+      if (!bucket->refcount && iconv_cache_size > ICONV_CACHE_SIZE)
+        {
+          /* expire this cache bucket */
+          iconv_cache_bucket_expire (NULL, bucket);
+        }
+    }
+  else
+    {
+      G_UNLOCK (iconv_cache_lock);
+      
+      g_warning ("This iconv context wasn't opened using open_converter");
+      
+      return g_iconv_close (converter);
+    }
+  
+  G_UNLOCK (iconv_cache_lock);
+  
+  return 0;
+}
+
+#endif /* USE_LIBICONV_GNU */
+#else  /* !NEED_ICONV_CACHE */
+
+static GIConv
+open_converter (const gchar *to_codeset,
+               const gchar *from_codeset,
+               GError     **error)
+{
+  GIConv cd;
+
+  cd = g_iconv_open (to_codeset, from_codeset);
+
+  if (cd == (GIConv) -1)
+    {
+      /* Something went wrong.  */
+      if (error)
+       {
+         if (errno == EINVAL)
+           g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION,
+                        _("Conversion from character set '%s' to '%s' is not supported"),
+                        from_codeset, to_codeset);
+         else
+           g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+                        _("Could not open converter from '%s' to '%s'"),
+                        from_codeset, to_codeset);
+       }
+    }
+  
+  return cd;
+}
+
+static int
+close_converter (GIConv cd)
+{
+  if (cd == (GIConv) -1)
+    return 0;
+  
+  return g_iconv_close (cd);  
+}
+
+#endif /* NEED_ICONV_CACHE */
+
+/**
+ * g_convert_with_iconv:
+ * @str:           the string to convert
+ * @len:           the length of the string, or -1 if the string is 
+ *                 nul-terminated<footnoteref linkend="nul-unsafe"/>. 
+ * @converter:     conversion descriptor from g_iconv_open()
+ * @bytes_read:    location to store the number of bytes in the
+ *                 input string that were successfully converted, or %NULL.
+ *                 Even if the conversion was successful, this may be 
+ *                 less than @len if there were partial characters
+ *                 at the end of the input. If the error
+ *                 #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
+ *                 stored will the byte offset after the last valid
+ *                 input sequence.
+ * @bytes_written: the number of bytes stored in the output buffer (not 
+ *                 including the terminating nul).
+ * @error:         location to store the error occuring, or %NULL to ignore
+ *                 errors. Any of the errors in #GConvertError may occur.
+ *
+ * Converts a string from one character set to another. 
+ * 
+ * Note that you should use g_iconv() for streaming 
+ * conversions<footnote id="streaming-state">
+ *  <para>
+ * Despite the fact that @byes_read can return information about partial 
+ * characters, the <literal>g_convert_...</literal> functions
+ * are not generally suitable for streaming. If the underlying converter 
+ * being used maintains internal state, then this won't be preserved 
+ * across successive calls to g_convert(), g_convert_with_iconv() or 
+ * g_convert_with_fallback(). (An example of this is the GNU C converter 
+ * for CP1255 which does not emit a base character until it knows that 
+ * the next character is not a mark that could combine with the base 
+ * character.)
+ *  </para>
+ * </footnote>. 
+ *
+ * Return value: If the conversion was successful, a newly allocated
+ *               nul-terminated string, which must be freed with
+ *               g_free(). Otherwise %NULL and @error will be set.
+ **/
+gchar*
+g_convert_with_iconv (const gchar *str,
+                     gssize       len,
+                     GIConv       converter,
+                     gsize       *bytes_read, 
+                     gsize       *bytes_written, 
+                     GError     **error)
+{
+  gchar *dest;
+  gchar *outp;
+  const gchar *p;
+  gsize inbytes_remaining;
+  gsize outbytes_remaining;
+  gsize err;
+  gsize outbuf_size;
+  gboolean have_error = FALSE;
+  gboolean done = FALSE;
+  gboolean reset = FALSE;
+  
+  g_return_val_if_fail (converter != (GIConv) -1, NULL);
+     
+  if (len < 0)
+    len = strlen (str);
+
+  p = str;
+  inbytes_remaining = len;
+  outbuf_size = len + NUL_TERMINATOR_LENGTH;
+  
+  outbytes_remaining = outbuf_size - NUL_TERMINATOR_LENGTH;
+  outp = dest = g_malloc (outbuf_size);
+
+  while (!done && !have_error)
+    {
+      if (reset)
+        err = g_iconv (converter, NULL, &inbytes_remaining, &outp, &outbytes_remaining);
+      else
+        err = g_iconv (converter, (char **)&p, &inbytes_remaining, &outp, &outbytes_remaining);
+
+      if (err == (gsize) -1)
+       {
+         switch (errno)
+           {
+           case EINVAL:
+             /* Incomplete text, do not report an error */
+             done = TRUE;
+             break;
+           case E2BIG:
+             {
+               gsize used = outp - dest;
+               
+               outbuf_size *= 2;
+               dest = g_realloc (dest, outbuf_size);
+               
+               outp = dest + used;
+               outbytes_remaining = outbuf_size - used - NUL_TERMINATOR_LENGTH;
+             }
+             break;
+           case EILSEQ:
+             if (error)
+               g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                                     _("Invalid byte sequence in conversion input"));
+             have_error = TRUE;
+             break;
+           default:
+              {
+                int errsv = errno;
+                
+                g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+                             _("Error during conversion: %s"),
+                             g_strerror (errsv));
+              }
+             have_error = TRUE;
+             break;
+           }
+       }
+      else 
+       {
+         if (!reset)
+           {
+             /* call g_iconv with NULL inbuf to cleanup shift state */
+             reset = TRUE;
+             inbytes_remaining = 0;
+           }
+         else
+           done = TRUE;
+       }
+    }
+
+  memset (outp, 0, NUL_TERMINATOR_LENGTH);
+  
+  if (bytes_read)
+    *bytes_read = p - str;
+  else
+    {
+      if ((p - str) != len) 
+       {
+          if (!have_error)
+            {
+             if (error)
+               g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
+                                     _("Partial character sequence at end of input"));
+              have_error = TRUE;
+            }
+       }
+    }
+
+  if (bytes_written)
+    *bytes_written = outp - dest;      /* Doesn't include '\0' */
+
+  if (have_error)
+    {
+      g_free (dest);
+      return NULL;
+    }
+  else
+    return dest;
+}
+
+/**
+ * g_convert:
+ * @str:           the string to convert
+ * @len:           the length of the string, or -1 if the string is 
+ *                 nul-terminated<footnote id="nul-unsafe">
+                     <para>
+                       Note that some encodings may allow nul bytes to 
+                       occur inside strings. In that case, using -1 for 
+                       the @len parameter is unsafe.
+                     </para>
+                   </footnote>. 
+ * @to_codeset:    name of character set into which to convert @str
+ * @from_codeset:  character set of @str.
+ * @bytes_read:    location to store the number of bytes in the
+ *                 input string that were successfully converted, or %NULL.
+ *                 Even if the conversion was successful, this may be 
+ *                 less than @len if there were partial characters
+ *                 at the end of the input. If the error
+ *                 #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
+ *                 stored will the byte offset after the last valid
+ *                 input sequence.
+ * @bytes_written: the number of bytes stored in the output buffer (not 
+ *                 including the terminating nul).
+ * @error:         location to store the error occuring, or %NULL to ignore
+ *                 errors. Any of the errors in #GConvertError may occur.
+ *
+ * Converts a string from one character set to another.
+ *
+ * Note that you should use g_iconv() for streaming 
+ * conversions<footnoteref linkend="streaming-state"/>.
+ *
+ * Return value: If the conversion was successful, a newly allocated
+ *               nul-terminated string, which must be freed with
+ *               g_free(). Otherwise %NULL and @error will be set.
+ **/
+gchar*
+g_convert (const gchar *str,
+           gssize       len,  
+           const gchar *to_codeset,
+           const gchar *from_codeset,
+           gsize       *bytes_read, 
+          gsize       *bytes_written, 
+          GError     **error)
+{
+  gchar *res;
+  GIConv cd;
+
+  g_return_val_if_fail (str != NULL, NULL);
+  g_return_val_if_fail (to_codeset != NULL, NULL);
+  g_return_val_if_fail (from_codeset != NULL, NULL);
+  
+  cd = open_converter (to_codeset, from_codeset, error);
+
+  if (cd == (GIConv) -1)
+    {
+      if (bytes_read)
+        *bytes_read = 0;
+      
+      if (bytes_written)
+        *bytes_written = 0;
+      
+      return NULL;
+    }
+
+  res = g_convert_with_iconv (str, len, cd,
+                             bytes_read, bytes_written,
+                             error);
+
+  close_converter (cd);
+
+  return res;
+}
+
+/**
+ * g_convert_with_fallback:
+ * @str:          the string to convert
+ * @len:          the length of the string, or -1 if the string is 
+ *                nul-terminated<footnoteref linkend="nul-unsafe"/>. 
+ * @to_codeset:   name of character set into which to convert @str
+ * @from_codeset: character set of @str.
+ * @fallback:     UTF-8 string to use in place of character not
+ *                present in the target encoding. (The string must be
+ *                representable in the target encoding). 
+                  If %NULL, characters not in the target encoding will 
+                  be represented as Unicode escapes \uxxxx or \Uxxxxyyyy.
+ * @bytes_read:   location to store the number of bytes in the
+ *                input string that were successfully converted, or %NULL.
+ *                Even if the conversion was successful, this may be 
+ *                less than @len if there were partial characters
+ *                at the end of the input.
+ * @bytes_written: the number of bytes stored in the output buffer (not 
+ *                including the terminating nul).
+ * @error:        location to store the error occuring, or %NULL to ignore
+ *                errors. Any of the errors in #GConvertError may occur.
+ *
+ * Converts a string from one character set to another, possibly
+ * including fallback sequences for characters not representable
+ * in the output. Note that it is not guaranteed that the specification
+ * for the fallback sequences in @fallback will be honored. Some
+ * systems may do an approximate conversion from @from_codeset
+ * to @to_codeset in their iconv() functions, 
+ * in which case GLib will simply return that approximate conversion.
+ *
+ * Note that you should use g_iconv() for streaming 
+ * conversions<footnoteref linkend="streaming-state"/>.
+ *
+ * Return value: If the conversion was successful, a newly allocated
+ *               nul-terminated string, which must be freed with
+ *               g_free(). Otherwise %NULL and @error will be set.
+ **/
+gchar*
+g_convert_with_fallback (const gchar *str,
+                        gssize       len,    
+                        const gchar *to_codeset,
+                        const gchar *from_codeset,
+                        const gchar *fallback,
+                        gsize       *bytes_read,
+                        gsize       *bytes_written,
+                        GError     **error)
+{
+  gchar *utf8;
+  gchar *dest;
+  gchar *outp;
+  const gchar *insert_str = NULL;
+  const gchar *p;
+  gsize inbytes_remaining;   
+  const gchar *save_p = NULL;
+  gsize save_inbytes = 0;
+  gsize outbytes_remaining; 
+  gsize err;
+  GIConv cd;
+  gsize outbuf_size;
+  gboolean have_error = FALSE;
+  gboolean done = FALSE;
+
+  GError *local_error = NULL;
+  
+  g_return_val_if_fail (str != NULL, NULL);
+  g_return_val_if_fail (to_codeset != NULL, NULL);
+  g_return_val_if_fail (from_codeset != NULL, NULL);
+     
+  if (len < 0)
+    len = strlen (str);
+  
+  /* Try an exact conversion; we only proceed if this fails
+   * due to an illegal sequence in the input string.
+   */
+  dest = g_convert (str, len, to_codeset, from_codeset, 
+                   bytes_read, bytes_written, &local_error);
+  if (!local_error)
+    return dest;
+
+  if (!g_error_matches (local_error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE))
+    {
+      g_propagate_error (error, local_error);
+      return NULL;
+    }
+  else
+    g_error_free (local_error);
+
+  local_error = NULL;
+  
+  /* No go; to proceed, we need a converter from "UTF-8" to
+   * to_codeset, and the string as UTF-8.
+   */
+  cd = open_converter (to_codeset, "UTF-8", error);
+  if (cd == (GIConv) -1)
+    {
+      if (bytes_read)
+        *bytes_read = 0;
+      
+      if (bytes_written)
+        *bytes_written = 0;
+      
+      return NULL;
+    }
+
+  utf8 = g_convert (str, len, "UTF-8", from_codeset, 
+                   bytes_read, &inbytes_remaining, error);
+  if (!utf8)
+    {
+      close_converter (cd);
+      if (bytes_written)
+        *bytes_written = 0;
+      return NULL;
+    }
+
+  /* Now the heart of the code. We loop through the UTF-8 string, and
+   * whenever we hit an offending character, we form fallback, convert
+   * the fallback to the target codeset, and then go back to
+   * converting the original string after finishing with the fallback.
+   *
+   * The variables save_p and save_inbytes store the input state
+   * for the original string while we are converting the fallback
+   */
+  p = utf8;
+
+  outbuf_size = len + NUL_TERMINATOR_LENGTH;
+  outbytes_remaining = outbuf_size - NUL_TERMINATOR_LENGTH;
+  outp = dest = g_malloc (outbuf_size);
+
+  while (!done && !have_error)
+    {
+      gsize inbytes_tmp = inbytes_remaining;
+      err = g_iconv (cd, (char **)&p, &inbytes_tmp, &outp, &outbytes_remaining);
+      inbytes_remaining = inbytes_tmp;
+
+      if (err == (gsize) -1)
+       {
+         switch (errno)
+           {
+           case EINVAL:
+             g_assert_not_reached();
+             break;
+           case E2BIG:
+             {
+               gsize used = outp - dest;
+
+               outbuf_size *= 2;
+               dest = g_realloc (dest, outbuf_size);
+               
+               outp = dest + used;
+               outbytes_remaining = outbuf_size - used - NUL_TERMINATOR_LENGTH;
+               
+               break;
+             }
+           case EILSEQ:
+             if (save_p)
+               {
+                 /* Error converting fallback string - fatal
+                  */
+                 g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                              _("Cannot convert fallback '%s' to codeset '%s'"),
+                              insert_str, to_codeset);
+                 have_error = TRUE;
+                 break;
+               }
+             else if (p)
+               {
+                 if (!fallback)
+                   { 
+                     gunichar ch = g_utf8_get_char (p);
+                     insert_str = g_strdup_printf (ch < 0x10000 ? "\\u%04x" : "\\U%08x",
+                                                   ch);
+                   }
+                 else
+                   insert_str = fallback;
+                 
+                 save_p = g_utf8_next_char (p);
+                 save_inbytes = inbytes_remaining - (save_p - p);
+                 p = insert_str;
+                 inbytes_remaining = strlen (p);
+                 break;
+               }
+             /* fall thru if p is NULL */
+           default:
+              {
+                int errsv = errno;
+
+                g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+                             _("Error during conversion: %s"),
+                             g_strerror (errsv));
+              }
+
+             have_error = TRUE;
+             break;
+           }
+       }
+      else
+       {
+         if (save_p)
+           {
+             if (!fallback)
+               g_free ((gchar *)insert_str);
+             p = save_p;
+             inbytes_remaining = save_inbytes;
+             save_p = NULL;
+           }
+         else if (p)
+           {
+             /* call g_iconv with NULL inbuf to cleanup shift state */
+             p = NULL;
+             inbytes_remaining = 0;
+           }
+         else
+           done = TRUE;
+       }
+    }
+
+  /* Cleanup
+   */
+  memset (outp, 0, NUL_TERMINATOR_LENGTH);
+  
+  close_converter (cd);
+
+  if (bytes_written)
+    *bytes_written = outp - dest;      /* Doesn't include '\0' */
+
+  g_free (utf8);
+
+  if (have_error)
+    {
+      if (save_p && !fallback)
+       g_free ((gchar *)insert_str);
+      g_free (dest);
+      return NULL;
+    }
+  else
+    return dest;
+}
+
+/*
+ * g_locale_to_utf8
+ *
+ * 
+ */
+
+static gchar *
+strdup_len (const gchar *string,
+           gssize       len,
+           gsize       *bytes_written,
+           gsize       *bytes_read,
+           GError      **error)
+        
+{
+  gsize real_len;
+
+  if (!g_utf8_validate (string, len, NULL))
+    {
+      if (bytes_read)
+       *bytes_read = 0;
+      if (bytes_written)
+       *bytes_written = 0;
+
+      g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                           _("Invalid byte sequence in conversion input"));
+      return NULL;
+    }
+  
+  if (len < 0)
+    real_len = strlen (string);
+  else
+    {
+      real_len = 0;
+      
+      while (real_len < len && string[real_len])
+       real_len++;
+    }
+  
+  if (bytes_read)
+    *bytes_read = real_len;
+  if (bytes_written)
+    *bytes_written = real_len;
+
+  return g_strndup (string, real_len);
+}
+
+/**
+ * g_locale_to_utf8:
+ * @opsysstring:   a string in the encoding of the current locale. On Windows
+ *                 this means the system codepage.
+ * @len:           the length of the string, or -1 if the string is
+ *                 nul-terminated<footnoteref linkend="nul-unsafe"/>. 
+ * @bytes_read:    location to store the number of bytes in the
+ *                 input string that were successfully converted, or %NULL.
+ *                 Even if the conversion was successful, this may be 
+ *                 less than @len if there were partial characters
+ *                 at the end of the input. If the error
+ *                 #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
+ *                 stored will the byte offset after the last valid
+ *                 input sequence.
+ * @bytes_written: the number of bytes stored in the output buffer (not 
+ *                 including the terminating nul).
+ * @error:         location to store the error occuring, or %NULL to ignore
+ *                 errors. Any of the errors in #GConvertError may occur.
+ * 
+ * Converts a string which is in the encoding used for strings by
+ * the C runtime (usually the same as that used by the operating
+ * system) in the <link linkend="setlocale">current locale</link> into a
+ * UTF-8 string.
+ * 
+ * Return value: The converted string, or %NULL on an error.
+ **/
+gchar *
+g_locale_to_utf8 (const gchar  *opsysstring,
+                 gssize        len,            
+                 gsize        *bytes_read,    
+                 gsize        *bytes_written,
+                 GError      **error)
+{
+  const char *charset;
+
+  if (g_get_charset (&charset))
+    return strdup_len (opsysstring, len, bytes_read, bytes_written, error);
+  else
+    return g_convert (opsysstring, len, 
+                     "UTF-8", charset, bytes_read, bytes_written, error);
+}
+
+/**
+ * g_locale_from_utf8:
+ * @utf8string:    a UTF-8 encoded string 
+ * @len:           the length of the string, or -1 if the string is
+ *                 nul-terminated<footnoteref linkend="nul-unsafe"/>. 
+ * @bytes_read:    location to store the number of bytes in the
+ *                 input string that were successfully converted, or %NULL.
+ *                 Even if the conversion was successful, this may be 
+ *                 less than @len if there were partial characters
+ *                 at the end of the input. If the error
+ *                 #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
+ *                 stored will the byte offset after the last valid
+ *                 input sequence.
+ * @bytes_written: the number of bytes stored in the output buffer (not 
+ *                 including the terminating nul).
+ * @error:         location to store the error occuring, or %NULL to ignore
+ *                 errors. Any of the errors in #GConvertError may occur.
+ * 
+ * Converts a string from UTF-8 to the encoding used for strings by
+ * the C runtime (usually the same as that used by the operating
+ * system) in the <link linkend="setlocale">current locale</link>. On
+ * Windows this means the system codepage.
+ * 
+ * Return value: The converted string, or %NULL on an error.
+ **/
+gchar *
+g_locale_from_utf8 (const gchar *utf8string,
+                   gssize       len,            
+                   gsize       *bytes_read,    
+                   gsize       *bytes_written,
+                   GError     **error)
+{
+  const gchar *charset;
+
+  if (g_get_charset (&charset))
+    return strdup_len (utf8string, len, bytes_read, bytes_written, error);
+  else
+    return g_convert (utf8string, len,
+                     charset, "UTF-8", bytes_read, bytes_written, error);
+}
+
+#ifndef G_PLATFORM_WIN32
+
+typedef struct _GFilenameCharsetCache GFilenameCharsetCache;
+
+struct _GFilenameCharsetCache {
+  gboolean is_utf8;
+  gchar *charset;
+  gchar **filename_charsets;
+};
+
+static void
+filename_charset_cache_free (gpointer data)
+{
+  GFilenameCharsetCache *cache = data;
+  g_free (cache->charset);
+  g_strfreev (cache->filename_charsets);
+  g_free (cache);
+}
+
+/**
+ * g_get_filename_charsets:
+ * @charsets: return location for the %NULL-terminated list of encoding names
+ *
+ * Determines the preferred character sets used for filenames.
+ * The first character set from the @charsets is the filename encoding, the
+ * subsequent character sets are used when trying to generate a displayable
+ * representation of a filename, see g_filename_display_name().
+ *
+ * On Unix, the character sets are determined by consulting the
+ * environment variables <envar>G_FILENAME_ENCODING</envar> and
+ * <envar>G_BROKEN_FILENAMES</envar>. On Windows, the character set
+ * used in the GLib API is always UTF-8 and said environment variables
+ * have no effect.
+ *
+ * <envar>G_FILENAME_ENCODING</envar> may be set to a comma-separated list 
+ * of character set names. The special token "&commat;locale" is taken to 
+ * mean the character set for the <link linkend="setlocale">current 
+ * locale</link>. If <envar>G_FILENAME_ENCODING</envar> is not set, but 
+ * <envar>G_BROKEN_FILENAMES</envar> is, the character set of the current 
+ * locale is taken as the filename encoding. If neither environment variable 
+ * is set, UTF-8 is taken as the filename encoding, but the character
+ * set of the current locale is also put in the list of encodings.
+ *
+ * The returned @charsets belong to GLib and must not be freed.
+ *
+ * Note that on Unix, regardless of the locale character set or
+ * <envar>G_FILENAME_ENCODING</envar> value, the actual file names present 
+ * on a system might be in any random encoding or just gibberish.
+ *
+ * Return value: %TRUE if the filename encoding is UTF-8.
+ * 
+ * Since: 2.6
+ */
+gboolean
+g_get_filename_charsets (G_CONST_RETURN gchar ***filename_charsets)
+{
+  static GStaticPrivate cache_private = G_STATIC_PRIVATE_INIT;
+  GFilenameCharsetCache *cache = g_static_private_get (&cache_private);
+  const gchar *charset;
+
+  if (!cache)
+    {
+      cache = g_new0 (GFilenameCharsetCache, 1);
+      g_static_private_set (&cache_private, cache, filename_charset_cache_free);
+    }
+
+  g_get_charset (&charset);
+
+  if (!(cache->charset && strcmp (cache->charset, charset) == 0))
+    {
+      const gchar *new_charset;
+      gchar *p;
+      gint i;
+
+      g_free (cache->charset);
+      g_strfreev (cache->filename_charsets);
+      cache->charset = g_strdup (charset);
+      
+      p = getenv ("G_FILENAME_ENCODING");
+      if (p != NULL && p[0] != '\0') 
+       {
+         cache->filename_charsets = g_strsplit (p, ",", 0);
+         cache->is_utf8 = (strcmp (cache->filename_charsets[0], "UTF-8") == 0);
+
+         for (i = 0; cache->filename_charsets[i]; i++)
+           {
+             if (strcmp ("@locale", cache->filename_charsets[i]) == 0)
+               {
+                 g_get_charset (&new_charset);
+                 g_free (cache->filename_charsets[i]);
+                 cache->filename_charsets[i] = g_strdup (new_charset);
+               }
+           }
+       }
+      else if (getenv ("G_BROKEN_FILENAMES") != NULL)
+       {
+         cache->filename_charsets = g_new0 (gchar *, 2);
+         cache->is_utf8 = g_get_charset (&new_charset);
+         cache->filename_charsets[0] = g_strdup (new_charset);
+       }
+      else 
+       {
+         cache->filename_charsets = g_new0 (gchar *, 3);
+         cache->is_utf8 = TRUE;
+         cache->filename_charsets[0] = g_strdup ("UTF-8");
+         if (!g_get_charset (&new_charset))
+           cache->filename_charsets[1] = g_strdup (new_charset);
+       }
+    }
+
+  if (filename_charsets)
+    *filename_charsets = (const gchar **)cache->filename_charsets;
+
+  return cache->is_utf8;
+}
+
+#else /* G_PLATFORM_WIN32 */
+
+gboolean
+g_get_filename_charsets (G_CONST_RETURN gchar ***filename_charsets) 
+{
+  static const gchar *charsets[] = {
+    "UTF-8",
+    NULL
+  };
+
+#ifdef G_OS_WIN32
+  /* On Windows GLib pretends that the filename charset is UTF-8 */
+  if (filename_charsets)
+    *filename_charsets = charsets;
+
+  return TRUE;
+#else
+  gboolean result;
+
+  /* Cygwin works like before */
+  result = g_get_charset (&(charsets[0]));
+
+  if (filename_charsets)
+    *filename_charsets = charsets;
+
+  return result;
+#endif
+}
+
+#endif /* G_PLATFORM_WIN32 */
+
+static gboolean
+get_filename_charset (const gchar **filename_charset)
+{
+  const gchar **charsets;
+  gboolean is_utf8;
+  
+  is_utf8 = g_get_filename_charsets (&charsets);
+
+  if (filename_charset)
+    *filename_charset = charsets[0];
+  
+  return is_utf8;
+}
+
+/* This is called from g_thread_init(). It's used to
+ * initialize some static data in a threadsafe way.
+ */
+void 
+_g_convert_thread_init (void)
+{
+  const gchar **dummy;
+  (void) g_get_filename_charsets (&dummy);
+}
+
+/**
+ * g_filename_to_utf8:
+ * @opsysstring:   a string in the encoding for filenames
+ * @len:           the length of the string, or -1 if the string is
+ *                 nul-terminated<footnoteref linkend="nul-unsafe"/>. 
+ * @bytes_read:    location to store the number of bytes in the
+ *                 input string that were successfully converted, or %NULL.
+ *                 Even if the conversion was successful, this may be 
+ *                 less than @len if there were partial characters
+ *                 at the end of the input. If the error
+ *                 #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
+ *                 stored will the byte offset after the last valid
+ *                 input sequence.
+ * @bytes_written: the number of bytes stored in the output buffer (not 
+ *                 including the terminating nul).
+ * @error:         location to store the error occuring, or %NULL to ignore
+ *                 errors. Any of the errors in #GConvertError may occur.
+ * 
+ * Converts a string which is in the encoding used by GLib for
+ * filenames into a UTF-8 string. Note that on Windows GLib uses UTF-8
+ * for filenames; on other platforms, this function indirectly depends on 
+ * the <link linkend="setlocale">current locale</link>.
+ * 
+ * Return value: The converted string, or %NULL on an error.
+ **/
+gchar*
+g_filename_to_utf8 (const gchar *opsysstring, 
+                   gssize       len,           
+                   gsize       *bytes_read,   
+                   gsize       *bytes_written,
+                   GError     **error)
+{
+  const gchar *charset;
+
+  if (get_filename_charset (&charset))
+    return strdup_len (opsysstring, len, bytes_read, bytes_written, error);
+  else
+    return g_convert (opsysstring, len, 
+                     "UTF-8", charset, bytes_read, bytes_written, error);
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+#undef g_filename_to_utf8
+
+/* Binary compatibility version. Not for newly compiled code. Also not needed for
+ * 64-bit versions as there should be no old deployed binaries that would use
+ * the old versions.
+ */
+
+gchar*
+g_filename_to_utf8 (const gchar *opsysstring, 
+                   gssize       len,           
+                   gsize       *bytes_read,   
+                   gsize       *bytes_written,
+                   GError     **error)
+{
+  const gchar *charset;
+
+  if (g_get_charset (&charset))
+    return strdup_len (opsysstring, len, bytes_read, bytes_written, error);
+  else
+    return g_convert (opsysstring, len, 
+                     "UTF-8", charset, bytes_read, bytes_written, error);
+}
+
+#endif
+
+/**
+ * g_filename_from_utf8:
+ * @utf8string:    a UTF-8 encoded string.
+ * @len:           the length of the string, or -1 if the string is
+ *                 nul-terminated.
+ * @bytes_read:    location to store the number of bytes in the
+ *                 input string that were successfully converted, or %NULL.
+ *                 Even if the conversion was successful, this may be 
+ *                 less than @len if there were partial characters
+ *                 at the end of the input. If the error
+ *                 #G_CONVERT_ERROR_ILLEGAL_SEQUENCE occurs, the value
+ *                 stored will the byte offset after the last valid
+ *                 input sequence.
+ * @bytes_written: the number of bytes stored in the output buffer (not 
+ *                 including the terminating nul).
+ * @error:         location to store the error occuring, or %NULL to ignore
+ *                 errors. Any of the errors in #GConvertError may occur.
+ * 
+ * Converts a string from UTF-8 to the encoding GLib uses for
+ * filenames. Note that on Windows GLib uses UTF-8 for filenames;
+ * on other platforms, this function indirectly depends on the 
+ * <link linkend="setlocale">current locale</link>.
+ * 
+ * Return value: The converted string, or %NULL on an error.
+ **/
+gchar*
+g_filename_from_utf8 (const gchar *utf8string,
+                     gssize       len,            
+                     gsize       *bytes_read,    
+                     gsize       *bytes_written,
+                     GError     **error)
+{
+  const gchar *charset;
+
+  if (get_filename_charset (&charset))
+    return strdup_len (utf8string, len, bytes_read, bytes_written, error);
+  else
+    return g_convert (utf8string, len,
+                     charset, "UTF-8", bytes_read, bytes_written, error);
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+#undef g_filename_from_utf8
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+gchar*
+g_filename_from_utf8 (const gchar *utf8string,
+                     gssize       len,            
+                     gsize       *bytes_read,    
+                     gsize       *bytes_written,
+                     GError     **error)
+{
+  const gchar *charset;
+
+  if (g_get_charset (&charset))
+    return strdup_len (utf8string, len, bytes_read, bytes_written, error);
+  else
+    return g_convert (utf8string, len,
+                     charset, "UTF-8", bytes_read, bytes_written, error);
+}
+
+#endif
+
+/* Test of haystack has the needle prefix, comparing case
+ * insensitive. haystack may be UTF-8, but needle must
+ * contain only ascii. */
+static gboolean
+has_case_prefix (const gchar *haystack, const gchar *needle)
+{
+  const gchar *h, *n;
+  
+  /* Eat one character at a time. */
+  h = haystack;
+  n = needle;
+
+  while (*n && *h &&
+        g_ascii_tolower (*n) == g_ascii_tolower (*h))
+    {
+      n++;
+      h++;
+    }
+  
+  return *n == '\0';
+}
+
+typedef enum {
+  UNSAFE_ALL        = 0x1,  /* Escape all unsafe characters   */
+  UNSAFE_ALLOW_PLUS = 0x2,  /* Allows '+'  */
+  UNSAFE_PATH       = 0x8,  /* Allows '/', '&', '=', ':', '@', '+', '$' and ',' */
+  UNSAFE_HOST       = 0x10, /* Allows '/' and ':' and '@' */
+  UNSAFE_SLASHES    = 0x20  /* Allows all characters except for '/' and '%' */
+} UnsafeCharacterSet;
+
+static const guchar acceptable[96] = {
+  /* A table of the ASCII chars from space (32) to DEL (127) */
+  /*      !    "    #    $    %    &    '    (    )    *    +    ,    -    .    / */ 
+  0x00,0x3F,0x20,0x20,0x28,0x00,0x2C,0x3F,0x3F,0x3F,0x3F,0x2A,0x28,0x3F,0x3F,0x1C,
+  /* 0    1    2    3    4    5    6    7    8    9    :    ;    <    =    >    ? */
+  0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x38,0x20,0x20,0x2C,0x20,0x20,
+  /* @    A    B    C    D    E    F    G    H    I    J    K    L    M    N    O */
+  0x38,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+  /* P    Q    R    S    T    U    V    W    X    Y    Z    [    \    ]    ^    _ */
+  0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x20,0x3F,
+  /* `    a    b    c    d    e    f    g    h    i    j    k    l    m    n    o */
+  0x20,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,
+  /* p    q    r    s    t    u    v    w    x    y    z    {    |    }    ~  DEL */
+  0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x3F,0x20,0x20,0x20,0x3F,0x20
+};
+
+static const gchar hex[16] = "0123456789ABCDEF";
+
+/* Note: This escape function works on file: URIs, but if you want to
+ * escape something else, please read RFC-2396 */
+static gchar *
+g_escape_uri_string (const gchar *string, 
+                    UnsafeCharacterSet mask)
+{
+#define ACCEPTABLE(a) ((a)>=32 && (a)<128 && (acceptable[(a)-32] & use_mask))
+
+  const gchar *p;
+  gchar *q;
+  gchar *result;
+  int c;
+  gint unacceptable;
+  UnsafeCharacterSet use_mask;
+  
+  g_return_val_if_fail (mask == UNSAFE_ALL
+                       || mask == UNSAFE_ALLOW_PLUS
+                       || mask == UNSAFE_PATH
+                       || mask == UNSAFE_HOST
+                       || mask == UNSAFE_SLASHES, NULL);
+  
+  unacceptable = 0;
+  use_mask = mask;
+  for (p = string; *p != '\0'; p++)
+    {
+      c = (guchar) *p;
+      if (!ACCEPTABLE (c)) 
+       unacceptable++;
+    }
+  
+  result = g_malloc (p - string + unacceptable * 2 + 1);
+  
+  use_mask = mask;
+  for (q = result, p = string; *p != '\0'; p++)
+    {
+      c = (guchar) *p;
+      
+      if (!ACCEPTABLE (c))
+       {
+         *q++ = '%'; /* means hex coming */
+         *q++ = hex[c >> 4];
+         *q++ = hex[c & 15];
+       }
+      else
+       *q++ = *p;
+    }
+  
+  *q = '\0';
+  
+  return result;
+}
+
+
+static gchar *
+g_escape_file_uri (const gchar *hostname,
+                  const gchar *pathname)
+{
+  char *escaped_hostname = NULL;
+  char *escaped_path;
+  char *res;
+
+#ifdef G_OS_WIN32
+  char *p, *backslash;
+
+  /* Turn backslashes into forward slashes. That's what Netscape
+   * does, and they are actually more or less equivalent in Windows.
+   */
+  
+  pathname = g_strdup (pathname);
+  p = (char *) pathname;
+  
+  while ((backslash = strchr (p, '\\')) != NULL)
+    {
+      *backslash = '/';
+      p = backslash + 1;
+    }
+#endif
+
+  if (hostname && *hostname != '\0')
+    {
+      escaped_hostname = g_escape_uri_string (hostname, UNSAFE_HOST);
+    }
+
+  escaped_path = g_escape_uri_string (pathname, UNSAFE_PATH);
+
+  res = g_strconcat ("file://",
+                    (escaped_hostname) ? escaped_hostname : "",
+                    (*escaped_path != '/') ? "/" : "",
+                    escaped_path,
+                    NULL);
+
+#ifdef G_OS_WIN32
+  g_free ((char *) pathname);
+#endif
+
+  g_free (escaped_hostname);
+  g_free (escaped_path);
+  
+  return res;
+}
+
+static int
+unescape_character (const char *scanner)
+{
+  int first_digit;
+  int second_digit;
+
+  first_digit = g_ascii_xdigit_value (scanner[0]);
+  if (first_digit < 0) 
+    return -1;
+  
+  second_digit = g_ascii_xdigit_value (scanner[1]);
+  if (second_digit < 0) 
+    return -1;
+  
+  return (first_digit << 4) | second_digit;
+}
+
+static gchar *
+g_unescape_uri_string (const char *escaped,
+                      int         len,
+                      const char *illegal_escaped_characters,
+                      gboolean    ascii_must_not_be_escaped)
+{
+  const gchar *in, *in_end;
+  gchar *out, *result;
+  int c;
+  
+  if (escaped == NULL)
+    return NULL;
+
+  if (len < 0)
+    len = strlen (escaped);
+
+  result = g_malloc (len + 1);
+  
+  out = result;
+  for (in = escaped, in_end = escaped + len; in < in_end; in++)
+    {
+      c = *in;
+
+      if (c == '%')
+       {
+         /* catch partial escape sequences past the end of the substring */
+         if (in + 3 > in_end)
+           break;
+
+         c = unescape_character (in + 1);
+
+         /* catch bad escape sequences and NUL characters */
+         if (c <= 0)
+           break;
+
+         /* catch escaped ASCII */
+         if (ascii_must_not_be_escaped && c <= 0x7F)
+           break;
+
+         /* catch other illegal escaped characters */
+         if (strchr (illegal_escaped_characters, c) != NULL)
+           break;
+
+         in += 2;
+       }
+
+      *out++ = c;
+    }
+  
+  g_assert (out - result <= len);
+  *out = '\0';
+
+  if (in != in_end)
+    {
+      g_free (result);
+      return NULL;
+    }
+
+  return result;
+}
+
+static gboolean
+is_asciialphanum (gunichar c)
+{
+  return c <= 0x7F && g_ascii_isalnum (c);
+}
+
+static gboolean
+is_asciialpha (gunichar c)
+{
+  return c <= 0x7F && g_ascii_isalpha (c);
+}
+
+/* allows an empty string */
+static gboolean
+hostname_validate (const char *hostname)
+{
+  const char *p;
+  gunichar c, first_char, last_char;
+
+  p = hostname;
+  if (*p == '\0')
+    return TRUE;
+  do
+    {
+      /* read in a label */
+      c = g_utf8_get_char (p);
+      p = g_utf8_next_char (p);
+      if (!is_asciialphanum (c))
+       return FALSE;
+      first_char = c;
+      do
+       {
+         last_char = c;
+         c = g_utf8_get_char (p);
+         p = g_utf8_next_char (p);
+       }
+      while (is_asciialphanum (c) || c == '-');
+      if (last_char == '-')
+       return FALSE;
+      
+      /* if that was the last label, check that it was a toplabel */
+      if (c == '\0' || (c == '.' && *p == '\0'))
+       return is_asciialpha (first_char);
+    }
+  while (c == '.');
+  return FALSE;
+}
+
+/**
+ * g_filename_from_uri:
+ * @uri: a uri describing a filename (escaped, encoded in ASCII).
+ * @hostname: Location to store hostname for the URI, or %NULL.
+ *            If there is no hostname in the URI, %NULL will be
+ *            stored in this location.
+ * @error: location to store the error occuring, or %NULL to ignore
+ *         errors. Any of the errors in #GConvertError may occur.
+ * 
+ * Converts an escaped ASCII-encoded URI to a local filename in the
+ * encoding used for filenames. 
+ * 
+ * Return value: a newly-allocated string holding the resulting
+ *               filename, or %NULL on an error.
+ **/
+gchar *
+g_filename_from_uri (const gchar *uri,
+                    gchar      **hostname,
+                    GError     **error)
+{
+  const char *path_part;
+  const char *host_part;
+  char *unescaped_hostname;
+  char *result;
+  char *filename;
+  int offs;
+#ifdef G_OS_WIN32
+  char *p, *slash;
+#endif
+
+  if (hostname)
+    *hostname = NULL;
+
+  if (!has_case_prefix (uri, "file:/"))
+    {
+      g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI,
+                  _("The URI '%s' is not an absolute URI using the \"file\" scheme"),
+                  uri);
+      return NULL;
+    }
+  
+  path_part = uri + strlen ("file:");
+  
+  if (strchr (path_part, '#') != NULL)
+    {
+      g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI,
+                  _("The local file URI '%s' may not include a '#'"),
+                  uri);
+      return NULL;
+    }
+       
+  if (has_case_prefix (path_part, "///")) 
+    path_part += 2;
+  else if (has_case_prefix (path_part, "//"))
+    {
+      path_part += 2;
+      host_part = path_part;
+
+      path_part = strchr (path_part, '/');
+
+      if (path_part == NULL)
+       {
+         g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI,
+                      _("The URI '%s' is invalid"),
+                      uri);
+         return NULL;
+       }
+
+      unescaped_hostname = g_unescape_uri_string (host_part, path_part - host_part, "", TRUE);
+
+      if (unescaped_hostname == NULL ||
+         !hostname_validate (unescaped_hostname))
+       {
+         g_free (unescaped_hostname);
+         g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI,
+                      _("The hostname of the URI '%s' is invalid"),
+                      uri);
+         return NULL;
+       }
+      
+      if (hostname)
+       *hostname = unescaped_hostname;
+      else
+       g_free (unescaped_hostname);
+    }
+
+  filename = g_unescape_uri_string (path_part, -1, "/", FALSE);
+
+  if (filename == NULL)
+    {
+      g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_BAD_URI,
+                  _("The URI '%s' contains invalidly escaped characters"),
+                  uri);
+      return NULL;
+    }
+
+  offs = 0;
+#ifdef G_OS_WIN32
+  /* Drop localhost */
+  if (hostname && *hostname != NULL &&
+      g_ascii_strcasecmp (*hostname, "localhost") == 0)
+    {
+      g_free (*hostname);
+      *hostname = NULL;
+    }
+
+  /* Turn slashes into backslashes, because that's the canonical spelling */
+  p = filename;
+  while ((slash = strchr (p, '/')) != NULL)
+    {
+      *slash = '\\';
+      p = slash + 1;
+    }
+
+  /* Windows URIs with a drive letter can be like "file://host/c:/foo"
+   * or "file://host/c|/foo" (some Netscape versions). In those cases, start
+   * the filename from the drive letter.
+   */
+  if (g_ascii_isalpha (filename[1]))
+    {
+      if (filename[2] == ':')
+       offs = 1;
+      else if (filename[2] == '|')
+       {
+         filename[2] = ':';
+         offs = 1;
+       }
+    }
+#endif
+
+  result = g_strdup (filename + offs);
+  g_free (filename);
+
+  return result;
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+#undef g_filename_from_uri
+
+gchar *
+g_filename_from_uri (const gchar *uri,
+                    gchar      **hostname,
+                    GError     **error)
+{
+  gchar *utf8_filename;
+  gchar *retval = NULL;
+
+  utf8_filename = g_filename_from_uri_utf8 (uri, hostname, error);
+  if (utf8_filename)
+    {
+      retval = g_locale_from_utf8 (utf8_filename, -1, NULL, NULL, error);
+      g_free (utf8_filename);
+    }
+  return retval;
+}
+
+#endif
+
+/**
+ * g_filename_to_uri:
+ * @filename: an absolute filename specified in the GLib file name encoding,
+ *            which is the on-disk file name bytes on Unix, and UTF-8 on 
+ *            Windows
+ * @hostname: A UTF-8 encoded hostname, or %NULL for none.
+ * @error: location to store the error occuring, or %NULL to ignore
+ *         errors. Any of the errors in #GConvertError may occur.
+ * 
+ * Converts an absolute filename to an escaped ASCII-encoded URI, with the path
+ * component following Section 3.3. of RFC 2396.
+ * 
+ * Return value: a newly-allocated string holding the resulting
+ *               URI, or %NULL on an error.
+ **/
+gchar *
+g_filename_to_uri (const gchar *filename,
+                  const gchar *hostname,
+                  GError     **error)
+{
+  char *escaped_uri;
+
+  g_return_val_if_fail (filename != NULL, NULL);
+
+  if (!g_path_is_absolute (filename))
+    {
+      g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NOT_ABSOLUTE_PATH,
+                  _("The pathname '%s' is not an absolute path"),
+                  filename);
+      return NULL;
+    }
+
+  if (hostname &&
+      !(g_utf8_validate (hostname, -1, NULL)
+       && hostname_validate (hostname)))
+    {
+      g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                           _("Invalid hostname"));
+      return NULL;
+    }
+  
+#ifdef G_OS_WIN32
+  /* Don't use localhost unnecessarily */
+  if (hostname && g_ascii_strcasecmp (hostname, "localhost") == 0)
+    hostname = NULL;
+#endif
+
+  escaped_uri = g_escape_file_uri (hostname, filename);
+
+  return escaped_uri;
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+#undef g_filename_to_uri
+
+gchar *
+g_filename_to_uri (const gchar *filename,
+                  const gchar *hostname,
+                  GError     **error)
+{
+  gchar *utf8_filename;
+  gchar *retval = NULL;
+
+  utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
+
+  if (utf8_filename)
+    {
+      retval = g_filename_to_uri_utf8 (utf8_filename, hostname, error);
+      g_free (utf8_filename);
+    }
+
+  return retval;
+}
+
+#endif
+
+/**
+ * g_uri_list_extract_uris:
+ * @uri_list: an URI list 
+ *
+ * Splits an URI list conforming to the text/uri-list
+ * mime type defined in RFC 2483 into individual URIs,
+ * discarding any comments. The URIs are not validated.
+ *
+ * Returns: a newly allocated %NULL-terminated list of
+ *   strings holding the individual URIs. The array should
+ *   be freed with g_strfreev().
+ *
+ * Since: 2.6
+ */
+gchar **
+g_uri_list_extract_uris (const gchar *uri_list)
+{
+  GSList *uris, *u;
+  const gchar *p, *q;
+  gchar **result;
+  gint n_uris = 0;
+
+  uris = NULL;
+
+  p = uri_list;
+
+  /* We don't actually try to validate the URI according to RFC
+   * 2396, or even check for allowed characters - we just ignore
+   * comments and trim whitespace off the ends.  We also
+   * allow LF delimination as well as the specified CRLF.
+   *
+   * We do allow comments like specified in RFC 2483.
+   */
+  while (p)
+    {
+      if (*p != '#')
+       {
+         while (g_ascii_isspace (*p))
+           p++;
+
+         q = p;
+         while (*q && (*q != '\n') && (*q != '\r'))
+           q++;
+
+         if (q > p)
+           {
+             q--;
+             while (q > p && g_ascii_isspace (*q))
+               q--;
+
+             if (q > p)
+               {
+                 uris = g_slist_prepend (uris, g_strndup (p, q - p + 1));
+                 n_uris++;
+               }
+           }
+       }
+      p = strchr (p, '\n');
+      if (p)
+       p++;
+    }
+
+  result = g_new (gchar *, n_uris + 1);
+
+  result[n_uris--] = NULL;
+  for (u = uris; u; u = u->next)
+    result[n_uris--] = u->data;
+
+  g_slist_free (uris);
+
+  return result;
+}
+
+/**
+ * g_filename_display_basename:
+ * @filename: an absolute pathname in the GLib file name encoding
+ *
+ * Returns the display basename for the particular filename, guaranteed
+ * to be valid UTF-8. The display name might not be identical to the filename,
+ * for instance there might be problems converting it to UTF-8, and some files
+ * can be translated in the display.
+ *
+ * If GLib can not make sense of the encoding of @filename, as a last resort it 
+ * replaces unknown characters with U+FFFD, the Unicode replacement character.
+ * You can search the result for the UTF-8 encoding of this character (which is
+ * "\357\277\275" in octal notation) to find out if @filename was in an invalid
+ * encoding.
+ *
+ * You must pass the whole absolute pathname to this functions so that
+ * translation of well known locations can be done.
+ *
+ * This function is preferred over g_filename_display_name() if you know the
+ * whole path, as it allows translation.
+ *
+ * Return value: a newly allocated string containing
+ *   a rendition of the basename of the filename in valid UTF-8
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_filename_display_basename (const gchar *filename)
+{
+  char *basename;
+  char *display_name;
+
+  g_return_val_if_fail (filename != NULL, NULL);
+  
+  basename = g_path_get_basename (filename);
+  display_name = g_filename_display_name (basename);
+  g_free (basename);
+  return display_name;
+}
+
+/**
+ * g_filename_display_name:
+ * @filename: a pathname hopefully in the GLib file name encoding
+ * 
+ * Converts a filename into a valid UTF-8 string. The conversion is 
+ * not necessarily reversible, so you should keep the original around 
+ * and use the return value of this function only for display purposes.
+ * Unlike g_filename_to_utf8(), the result is guaranteed to be non-%NULL 
+ * even if the filename actually isn't in the GLib file name encoding.
+ *
+ * If GLib can not make sense of the encoding of @filename, as a last resort it 
+ * replaces unknown characters with U+FFFD, the Unicode replacement character.
+ * You can search the result for the UTF-8 encoding of this character (which is
+ * "\357\277\275" in octal notation) to find out if @filename was in an invalid
+ * encoding.
+ *
+ * If you know the whole pathname of the file you should use
+ * g_filename_display_basename(), since that allows location-based
+ * translation of filenames.
+ *
+ * Return value: a newly allocated string containing
+ *   a rendition of the filename in valid UTF-8
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_filename_display_name (const gchar *filename)
+{
+  gint i;
+  const gchar **charsets;
+  gchar *display_name = NULL;
+  gboolean is_utf8;
+  is_utf8 = g_get_filename_charsets (&charsets);
+
+  if (is_utf8)
+    {
+      if (g_utf8_validate (filename, -1, NULL))
+       display_name = g_strdup (filename);
+    }
+  
+  if (!display_name)
+    {
+      /* Try to convert from the filename charsets to UTF-8.
+       * Skip the first charset if it is UTF-8.
+       */
+      for (i = is_utf8 ? 1 : 0; charsets[i]; i++)
+       {
+         display_name = g_convert (filename, -1, "UTF-8", charsets[i], 
+                                   NULL, NULL, NULL);
+
+         if (display_name)
+           break;
+       }
+    }
+  
+  /* if all conversions failed, we replace invalid UTF-8
+   * by a question mark
+   */
+  if (!display_name) 
+    display_name = _g_utf8_make_valid (filename);
+
+  return display_name;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gconvert.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gconvert.h
new file mode 100644 (file)
index 0000000..e4c20d7
--- /dev/null
@@ -0,0 +1,162 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_CONVERT_H__
+#define __G_CONVERT_H__
+
+#include <glib/gerror.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GConvertError:
+ * @G_CONVERT_ERROR_NO_CONVERSION: Conversion between the requested character
+ *     sets is not supported.
+ * @G_CONVERT_ERROR_ILLEGAL_SEQUENCE: Invalid byte sequence in conversion input.
+ * @G_CONVERT_ERROR_FAILED: Conversion failed for some reason.
+ * @G_CONVERT_ERROR_PARTIAL_INPUT: Partial character sequence at end of input.
+ * @G_CONVERT_ERROR_BAD_URI: URI is invalid.
+ * @G_CONVERT_ERROR_NOT_ABSOLUTE_PATH: Pathname is not an absolute path.
+ *
+ * Error codes returned by character set conversion routines.
+ */
+typedef enum
+{
+  G_CONVERT_ERROR_NO_CONVERSION,
+  G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+  G_CONVERT_ERROR_FAILED,
+  G_CONVERT_ERROR_PARTIAL_INPUT,
+  G_CONVERT_ERROR_BAD_URI,
+  G_CONVERT_ERROR_NOT_ABSOLUTE_PATH
+} GConvertError;
+
+/**
+ * G_CONVERT_ERROR:
+ *
+ * Error domain for character set conversions. Errors in this domain will
+ * be from the #GConvertError enumeration. See #GError for information on
+ * error domains.
+ */
+#define G_CONVERT_ERROR g_convert_error_quark()
+GQuark g_convert_error_quark (void);
+
+/**
+ * GIconv:
+ *
+ * The <structname>GIConv</structname> struct wraps an
+ * iconv() conversion descriptor. It contains private data
+ * and should only be accessed using the following functions.
+ */
+typedef struct _GIConv *GIConv;
+
+GIConv g_iconv_open   (const gchar  *to_codeset,
+                      const gchar  *from_codeset);
+gsize  g_iconv        (GIConv        converter,
+                      gchar       **inbuf,
+                      gsize        *inbytes_left,
+                      gchar       **outbuf,
+                      gsize        *outbytes_left);
+gint   g_iconv_close  (GIConv        converter);
+
+
+gchar* g_convert               (const gchar  *str,
+                               gssize        len,            
+                               const gchar  *to_codeset,
+                               const gchar  *from_codeset,
+                               gsize        *bytes_read,     
+                               gsize        *bytes_written,  
+                               GError      **error) G_GNUC_MALLOC;
+gchar* g_convert_with_iconv    (const gchar  *str,
+                               gssize        len,
+                               GIConv        converter,
+                               gsize        *bytes_read,     
+                               gsize        *bytes_written,  
+                               GError      **error) G_GNUC_MALLOC;
+gchar* g_convert_with_fallback (const gchar  *str,
+                               gssize        len,            
+                               const gchar  *to_codeset,
+                               const gchar  *from_codeset,
+                               const gchar  *fallback,
+                               gsize        *bytes_read,     
+                               gsize        *bytes_written,  
+                               GError      **error) G_GNUC_MALLOC;
+
+
+/* Convert between libc's idea of strings and UTF-8.
+ */
+gchar* g_locale_to_utf8   (const gchar  *opsysstring,
+                          gssize        len,            
+                          gsize        *bytes_read,     
+                          gsize        *bytes_written,  
+                          GError      **error) G_GNUC_MALLOC;
+gchar* g_locale_from_utf8 (const gchar  *utf8string,
+                          gssize        len,            
+                          gsize        *bytes_read,     
+                          gsize        *bytes_written,  
+                          GError      **error) G_GNUC_MALLOC;
+
+/* Convert between the operating system (or C runtime)
+ * representation of file names and UTF-8.
+ */
+#ifdef G_OS_WIN32
+#define g_filename_to_utf8 g_filename_to_utf8_utf8
+#define g_filename_from_utf8 g_filename_from_utf8_utf8
+#define g_filename_from_uri g_filename_from_uri_utf8
+#define g_filename_to_uri g_filename_to_uri_utf8 
+#endif
+
+gchar* g_filename_to_utf8   (const gchar  *opsysstring,
+                            gssize        len,            
+                            gsize        *bytes_read,     
+                            gsize        *bytes_written,  
+                            GError      **error) G_GNUC_MALLOC;
+gchar* g_filename_from_utf8 (const gchar  *utf8string,
+                            gssize        len,            
+                            gsize        *bytes_read,     
+                            gsize        *bytes_written,  
+                            GError      **error) G_GNUC_MALLOC;
+
+gchar *g_filename_from_uri (const gchar *uri,
+                           gchar      **hostname,
+                           GError     **error) G_GNUC_MALLOC;
+  
+gchar *g_filename_to_uri   (const gchar *filename,
+                           const gchar *hostname,
+                           GError     **error) G_GNUC_MALLOC;
+gchar *g_filename_display_name (const gchar *filename) G_GNUC_MALLOC;
+gboolean g_get_filename_charsets (G_CONST_RETURN gchar ***charsets);
+
+gchar *g_filename_display_basename (const gchar *filename) G_GNUC_MALLOC;
+
+gchar **g_uri_list_extract_uris (const gchar *uri_list) G_GNUC_MALLOC;
+
+G_END_DECLS
+
+#endif /* __G_CONVERT_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gdataset.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gdataset.c
new file mode 100644 (file)
index 0000000..cd3a51e
--- /dev/null
@@ -0,0 +1,1223 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gdataset.c: Generic dataset mechanism, similar to GtkObject data.
+ * Copyright (C) 1998 Tim Janik
+ *
+ * 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 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe ; except for g_data*_foreach()
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gdataset.h"
+
+#include "gdatasetprivate.h"
+#include "ghash.h"
+#include "gquark.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "gthread.h"
+#include "glib_trace.h"
+
+/**
+ * SECTION: datasets
+ * @title: Datasets
+ * @short_description: associate groups of data elements with
+ *                     particular memory locations
+ *
+ * Datasets associate groups of data elements with particular memory
+ * locations. These are useful if you need to associate data with a
+ * structure returned from an external library. Since you cannot modify
+ * the structure, you use its location in memory as the key into a
+ * dataset, where you can associate any number of data elements with it.
+ *
+ * There are two forms of most of the dataset functions. The first form
+ * uses strings to identify the data elements associated with a
+ * location. The second form uses #GQuark identifiers, which are
+ * created with a call to g_quark_from_string() or
+ * g_quark_from_static_string(). The second form is quicker, since it
+ * does not require looking up the string in the hash table of #GQuark
+ * identifiers.
+ *
+ * There is no function to create a dataset. It is automatically
+ * created as soon as you add elements to it.
+ *
+ * To add data elements to a dataset use g_dataset_id_set_data(),
+ * g_dataset_id_set_data_full(), g_dataset_set_data() and
+ * g_dataset_set_data_full().
+ *
+ * To get data elements from a dataset use g_dataset_id_get_data() and
+ * g_dataset_get_data().
+ *
+ * To iterate over all data elements in a dataset use
+ * g_dataset_foreach() (not thread-safe).
+ *
+ * To remove data elements from a dataset use
+ * g_dataset_id_remove_data() and g_dataset_remove_data().
+ *
+ * To destroy a dataset, use g_dataset_destroy().
+ **/
+
+/**
+ * SECTION: datalist
+ * @title: Keyed Data Lists
+ * @short_description: lists of data elements which are accessible by a
+ *                     string or GQuark identifier
+ *
+ * Keyed data lists provide lists of arbitrary data elements which can
+ * be accessed either with a string or with a #GQuark corresponding to
+ * the string.
+ *
+ * The #GQuark methods are quicker, since the strings have to be
+ * converted to #GQuarks anyway.
+ *
+ * Data lists are used for associating arbitrary data with #GObjects,
+ * using g_object_set_data() and related functions.
+ *
+ * To create a datalist, use g_datalist_init().
+ *
+ * To add data elements to a datalist use g_datalist_id_set_data(),
+ * g_datalist_id_set_data_full(), g_datalist_set_data() and
+ * g_datalist_set_data_full().
+ *
+ * To get data elements from a datalist use g_datalist_id_get_data()
+ * and g_datalist_get_data().
+ *
+ * To iterate over all data elements in a datalist use
+ * g_datalist_foreach() (not thread-safe).
+ *
+ * To remove data elements from a datalist use
+ * g_datalist_id_remove_data() and g_datalist_remove_data().
+ *
+ * To remove all data elements from a datalist, use g_datalist_clear().
+ **/
+
+/**
+ * GData:
+ *
+ * The #GData struct is an opaque data structure to represent a <link
+ * linkend="glib-Keyed-Data-Lists">Keyed Data List</link>. It should
+ * only be accessed via the following functions.
+ **/
+
+/**
+ * GDestroyNotify:
+ * @data: the data element.
+ *
+ * Specifies the type of function which is called when a data element
+ * is destroyed. It is passed the pointer to the data element and
+ * should free any memory and resources allocated for it.
+ **/
+
+/* --- defines --- */
+#define        G_QUARK_BLOCK_SIZE                      (512)
+
+/* datalist pointer accesses have to be carried out atomically */
+#define G_DATALIST_GET_POINTER(datalist)                                               \
+  ((GData*) ((gsize) g_atomic_pointer_get (datalist) & ~(gsize) G_DATALIST_FLAGS_MASK))
+
+#define G_DATALIST_SET_POINTER(datalist, pointer)       G_STMT_START {                  \
+  gpointer _oldv, _newv;                                                                \
+  do {                                                                                  \
+    _oldv = g_atomic_pointer_get (datalist);                                            \
+    _newv = (gpointer) (((gsize) _oldv & G_DATALIST_FLAGS_MASK) | (gsize) pointer);     \
+  } while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, _oldv, _newv));   \
+} G_STMT_END
+
+/* --- structures --- */
+typedef struct _GDataset GDataset;
+struct _GData
+{
+  GData *next;
+  GQuark id;
+  gpointer data;
+  GDestroyNotify destroy_func;
+};
+
+struct _GDataset
+{
+  gconstpointer location;
+  GData        *datalist;
+};
+
+
+/* --- prototypes --- */
+static inline GDataset*        g_dataset_lookup                (gconstpointer    dataset_location);
+static inline void     g_datalist_clear_i              (GData          **datalist);
+static void            g_dataset_destroy_internal      (GDataset        *dataset);
+static inline gpointer g_data_set_internal             (GData          **datalist,
+                                                        GQuark           key_id,
+                                                        gpointer         data,
+                                                        GDestroyNotify   destroy_func,
+                                                        GDataset        *dataset);
+static void            g_data_initialize               (void);
+static inline GQuark   g_quark_new                     (gchar          *string);
+
+
+/* --- variables --- */
+G_LOCK_DEFINE_STATIC (g_dataset_global);
+static GHashTable   *g_dataset_location_ht = NULL;
+static GDataset     *g_dataset_cached = NULL; /* should this be
+                                                threadspecific? */
+G_LOCK_DEFINE_STATIC (g_quark_global);
+static GHashTable   *g_quark_ht = NULL;
+static gchar       **g_quarks = NULL;
+static GQuark        g_quark_seq_id = 0;
+
+/* --- functions --- */
+
+/* HOLDS: g_dataset_global_lock */
+static inline void
+g_datalist_clear_i (GData **datalist)
+{
+  register GData *list;
+  
+  /* unlink *all* items before walking their destructors
+   */
+  list = G_DATALIST_GET_POINTER (datalist);
+  G_DATALIST_SET_POINTER (datalist, NULL);
+  
+  while (list)
+    {
+      register GData *prev;
+      
+      prev = list;
+      list = prev->next;
+      
+      if (prev->destroy_func)
+       {
+         G_UNLOCK (g_dataset_global);
+         prev->destroy_func (prev->data);
+         G_LOCK (g_dataset_global);
+       }
+      
+      g_slice_free (GData, prev);
+    }
+}
+
+/**
+ * g_datalist_clear:
+ * @datalist: a datalist.
+ *
+ * Frees all the data elements of the datalist. The data elements'
+ * destroy functions are called if they have been set.
+ **/
+void
+g_datalist_clear (GData **datalist)
+{
+  g_return_if_fail (datalist != NULL);
+  
+  G_LOCK (g_dataset_global);
+  if (!g_dataset_location_ht)
+    g_data_initialize ();
+
+  while (G_DATALIST_GET_POINTER (datalist))
+    g_datalist_clear_i (datalist);
+  G_UNLOCK (g_dataset_global);
+}
+
+/* HOLDS: g_dataset_global_lock */
+static inline GDataset*
+g_dataset_lookup (gconstpointer        dataset_location)
+{
+  register GDataset *dataset;
+  
+  if (g_dataset_cached && g_dataset_cached->location == dataset_location)
+    return g_dataset_cached;
+  
+  dataset = g_hash_table_lookup (g_dataset_location_ht, dataset_location);
+  if (dataset)
+    g_dataset_cached = dataset;
+  
+  return dataset;
+}
+
+/* HOLDS: g_dataset_global_lock */
+static void
+g_dataset_destroy_internal (GDataset *dataset)
+{
+  register gconstpointer dataset_location;
+  
+  dataset_location = dataset->location;
+  while (dataset)
+    {
+      if (!dataset->datalist)
+       {
+         if (dataset == g_dataset_cached)
+           g_dataset_cached = NULL;
+         g_hash_table_remove (g_dataset_location_ht, dataset_location);
+         g_slice_free (GDataset, dataset);
+         break;
+       }
+      
+      g_datalist_clear_i (&dataset->datalist);
+      dataset = g_dataset_lookup (dataset_location);
+    }
+}
+
+/**
+ * g_dataset_destroy:
+ * @dataset_location: the location identifying the dataset.
+ *
+ * Destroys the dataset, freeing all memory allocated, and calling any
+ * destroy functions set for data elements.
+ **/
+void
+g_dataset_destroy (gconstpointer  dataset_location)
+{
+  g_return_if_fail (dataset_location != NULL);
+  
+  G_LOCK (g_dataset_global);
+  if (g_dataset_location_ht)
+    {
+      register GDataset *dataset;
+
+      dataset = g_dataset_lookup (dataset_location);
+      if (dataset)
+       g_dataset_destroy_internal (dataset);
+    }
+  G_UNLOCK (g_dataset_global);
+}
+
+/* HOLDS: g_dataset_global_lock */
+static inline gpointer
+g_data_set_internal (GData       **datalist,
+                    GQuark         key_id,
+                    gpointer       data,
+                    GDestroyNotify destroy_func,
+                    GDataset      *dataset)
+{
+  register GData *list;
+  
+  list = G_DATALIST_GET_POINTER (datalist);
+  if (!data)
+    {
+      register GData *prev;
+      
+      prev = NULL;
+      while (list)
+       {
+         if (list->id == key_id)
+           {
+             gpointer ret_data = NULL;
+
+             if (prev)
+               prev->next = list->next;
+             else
+               {
+                 G_DATALIST_SET_POINTER (datalist, list->next);
+                 
+                 /* the dataset destruction *must* be done
+                  * prior to invocation of the data destroy function
+                  */
+                 if (!list->next && dataset)
+                   g_dataset_destroy_internal (dataset);
+               }
+             
+             /* the GData struct *must* already be unlinked
+              * when invoking the destroy function.
+              * we use (data==NULL && destroy_func!=NULL) as
+              * a special hint combination to "steal"
+              * data without destroy notification
+              */
+             if (list->destroy_func && !destroy_func)
+               {
+                 G_UNLOCK (g_dataset_global);
+                 list->destroy_func (list->data);
+                 G_LOCK (g_dataset_global);
+               }
+             else
+               ret_data = list->data;
+             
+              g_slice_free (GData, list);
+             
+             return ret_data;
+           }
+         
+         prev = list;
+         list = list->next;
+       }
+    }
+  else
+    {
+      while (list)
+       {
+         if (list->id == key_id)
+           {
+             if (!list->destroy_func)
+               {
+                 list->data = data;
+                 list->destroy_func = destroy_func;
+               }
+             else
+               {
+                 register GDestroyNotify dfunc;
+                 register gpointer ddata;
+                 
+                 dfunc = list->destroy_func;
+                 ddata = list->data;
+                 list->data = data;
+                 list->destroy_func = destroy_func;
+                 
+                 /* we need to have updated all structures prior to
+                  * invocation of the destroy function
+                  */
+                 G_UNLOCK (g_dataset_global);
+                 dfunc (ddata);
+                 G_LOCK (g_dataset_global);
+               }
+             
+             return NULL;
+           }
+         
+         list = list->next;
+       }
+      
+      list = g_slice_new (GData);
+      list->next = G_DATALIST_GET_POINTER (datalist);
+      list->id = key_id;
+      list->data = data;
+      list->destroy_func = destroy_func;
+      G_DATALIST_SET_POINTER (datalist, list);
+    }
+
+  return NULL;
+}
+
+/**
+ * g_dataset_id_set_data_full:
+ * @dataset_location: the location identifying the dataset.
+ * @key_id: the #GQuark id to identify the data element.
+ * @data: the data element.
+ * @destroy_func: the function to call when the data element is
+ *                removed. This function will be called with the data
+ *                element and can be used to free any memory allocated
+ *                for it.
+ *
+ * Sets the data element associated with the given #GQuark id, and also
+ * the function to call when the data element is destroyed. Any
+ * previous data with the same key is removed, and its destroy function
+ * is called.
+ **/
+/**
+ * g_dataset_set_data_full:
+ * @l: the location identifying the dataset.
+ * @k: the string to identify the data element.
+ * @d: the data element.
+ * @f: the function to call when the data element is removed. This
+ *     function will be called with the data element and can be used to
+ *     free any memory allocated for it.
+ *
+ * Sets the data corresponding to the given string identifier, and the
+ * function to call when the data element is destroyed.
+ **/
+/**
+ * g_dataset_id_set_data:
+ * @l: the location identifying the dataset.
+ * @k: the #GQuark id to identify the data element.
+ * @d: the data element.
+ *
+ * Sets the data element associated with the given #GQuark id. Any
+ * previous data with the same key is removed, and its destroy function
+ * is called.
+ **/
+/**
+ * g_dataset_set_data:
+ * @l: the location identifying the dataset.
+ * @k: the string to identify the data element.
+ * @d: the data element.
+ *
+ * Sets the data corresponding to the given string identifier.
+ **/
+/**
+ * g_dataset_id_remove_data:
+ * @l: the location identifying the dataset.
+ * @k: the #GQuark id identifying the data element.
+ *
+ * Removes a data element from a dataset. The data element's destroy
+ * function is called if it has been set.
+ **/
+/**
+ * g_dataset_remove_data:
+ * @l: the location identifying the dataset.
+ * @k: the string identifying the data element.
+ *
+ * Removes a data element corresponding to a string. Its destroy
+ * function is called if it has been set.
+ **/
+void
+g_dataset_id_set_data_full (gconstpointer  dataset_location,
+                           GQuark         key_id,
+                           gpointer       data,
+                           GDestroyNotify destroy_func)
+{
+  register GDataset *dataset;
+  
+  g_return_if_fail (dataset_location != NULL);
+  if (!data)
+    g_return_if_fail (destroy_func == NULL);
+  if (!key_id)
+    {
+      if (data)
+       g_return_if_fail (key_id > 0);
+      else
+       return;
+    }
+  
+  G_LOCK (g_dataset_global);
+  if (!g_dataset_location_ht)
+    g_data_initialize ();
+  dataset = g_dataset_lookup (dataset_location);
+  if (!dataset)
+    {
+      dataset = g_slice_new (GDataset);
+      dataset->location = dataset_location;
+      g_datalist_init (&dataset->datalist);
+      g_hash_table_insert (g_dataset_location_ht, 
+                          (gpointer) dataset->location,
+                          dataset);
+    }
+  
+  g_data_set_internal (&dataset->datalist, key_id, data, destroy_func, dataset);
+  G_UNLOCK (g_dataset_global);
+}
+
+/**
+ * g_datalist_id_set_data_full:
+ * @datalist: a datalist.
+ * @key_id: the #GQuark to identify the data element.
+ * @data: the data element or %NULL to remove any previous element
+ *        corresponding to @key_id.
+ * @destroy_func: the function to call when the data element is
+ *                removed. This function will be called with the data
+ *                element and can be used to free any memory allocated
+ *                for it. If @data is %NULL, then @destroy_func must
+ *                also be %NULL.
+ *
+ * Sets the data corresponding to the given #GQuark id, and the
+ * function to be called when the element is removed from the datalist.
+ * Any previous data with the same key is removed, and its destroy
+ * function is called.
+ **/
+/**
+ * g_datalist_set_data_full:
+ * @dl: a datalist.
+ * @k: the string to identify the data element.
+ * @d: the data element, or %NULL to remove any previous element
+ *     corresponding to @k.
+ * @f: the function to call when the data element is removed. This
+ *     function will be called with the data element and can be used to
+ *     free any memory allocated for it. If @d is %NULL, then @f must
+ *     also be %NULL.
+ *
+ * Sets the data element corresponding to the given string identifier,
+ * and the function to be called when the data element is removed.
+ **/
+/**
+ * g_datalist_id_set_data:
+ * @dl: a datalist.
+ * @q: the #GQuark to identify the data element.
+ * @d: the data element, or %NULL to remove any previous element
+ *     corresponding to @q.
+ *
+ * Sets the data corresponding to the given #GQuark id. Any previous
+ * data with the same key is removed, and its destroy function is
+ * called.
+ **/
+/**
+ * g_datalist_set_data:
+ * @dl: a datalist.
+ * @k: the string to identify the data element.
+ * @d: the data element, or %NULL to remove any previous element
+ *     corresponding to @k.
+ *
+ * Sets the data element corresponding to the given string identifier.
+ **/
+/**
+ * g_datalist_id_remove_data:
+ * @dl: a datalist.
+ * @q: the #GQuark identifying the data element.
+ *
+ * Removes an element, using its #GQuark identifier.
+ **/
+/**
+ * g_datalist_remove_data:
+ * @dl: a datalist.
+ * @k: the string identifying the data element.
+ *
+ * Removes an element using its string identifier. The data element's
+ * destroy function is called if it has been set.
+ **/
+void
+g_datalist_id_set_data_full (GData       **datalist,
+                            GQuark         key_id,
+                            gpointer       data,
+                            GDestroyNotify destroy_func)
+{
+  g_return_if_fail (datalist != NULL);
+  if (!data)
+    g_return_if_fail (destroy_func == NULL);
+  if (!key_id)
+    {
+      if (data)
+       g_return_if_fail (key_id > 0);
+      else
+       return;
+    }
+
+  G_LOCK (g_dataset_global);
+  if (!g_dataset_location_ht)
+    g_data_initialize ();
+  
+  g_data_set_internal (datalist, key_id, data, destroy_func, NULL);
+  G_UNLOCK (g_dataset_global);
+}
+
+/**
+ * g_dataset_id_remove_no_notify:
+ * @dataset_location: the location identifying the dataset.
+ * @key_id: the #GQuark ID identifying the data element.
+ * @Returns: the data previously stored at @key_id, or %NULL if none.
+ *
+ * Removes an element, without calling its destroy notification
+ * function.
+ **/
+/**
+ * g_dataset_remove_no_notify:
+ * @l: the location identifying the dataset.
+ * @k: the string identifying the data element.
+ *
+ * Removes an element, without calling its destroy notifier.
+ **/
+gpointer
+g_dataset_id_remove_no_notify (gconstpointer  dataset_location,
+                              GQuark         key_id)
+{
+  gpointer ret_data = NULL;
+
+  g_return_val_if_fail (dataset_location != NULL, NULL);
+  
+  G_LOCK (g_dataset_global);
+  if (key_id && g_dataset_location_ht)
+    {
+      GDataset *dataset;
+  
+      dataset = g_dataset_lookup (dataset_location);
+      if (dataset)
+       ret_data = g_data_set_internal (&dataset->datalist, key_id, NULL, (GDestroyNotify) 42, dataset);
+    } 
+  G_UNLOCK (g_dataset_global);
+
+  return ret_data;
+}
+
+/**
+ * g_datalist_id_remove_no_notify:
+ * @datalist: a datalist.
+ * @key_id: the #GQuark identifying a data element.
+ * @Returns: the data previously stored at @key_id, or %NULL if none.
+ *
+ * Removes an element, without calling its destroy notification
+ * function.
+ **/
+/**
+ * g_datalist_remove_no_notify:
+ * @dl: a datalist.
+ * @k: the string identifying the data element.
+ *
+ * Removes an element, without calling its destroy notifier.
+ **/
+gpointer
+g_datalist_id_remove_no_notify (GData  **datalist,
+                               GQuark    key_id)
+{
+  gpointer ret_data = NULL;
+
+  g_return_val_if_fail (datalist != NULL, NULL);
+
+  G_LOCK (g_dataset_global);
+  if (key_id && g_dataset_location_ht)
+    ret_data = g_data_set_internal (datalist, key_id, NULL, (GDestroyNotify) 42, NULL);
+  G_UNLOCK (g_dataset_global);
+
+  return ret_data;
+}
+
+/**
+ * g_dataset_id_get_data:
+ * @dataset_location: the location identifying the dataset.
+ * @key_id: the #GQuark id to identify the data element.
+ * @Returns: the data element corresponding to the #GQuark, or %NULL if
+ *           it is not found.
+ *
+ * Gets the data element corresponding to a #GQuark.
+ **/
+/**
+ * g_dataset_get_data:
+ * @l: the location identifying the dataset.
+ * @k: the string identifying the data element.
+ * @Returns: the data element corresponding to the string, or %NULL if
+ *           it is not found.
+ *
+ * Gets the data element corresponding to a string.
+ **/
+gpointer
+g_dataset_id_get_data (gconstpointer  dataset_location,
+                      GQuark         key_id)
+{
+  g_return_val_if_fail (dataset_location != NULL, NULL);
+  
+  G_LOCK (g_dataset_global);
+  if (key_id && g_dataset_location_ht)
+    {
+      register GDataset *dataset;
+      
+      dataset = g_dataset_lookup (dataset_location);
+      if (dataset)
+       {
+         register GData *list;
+         
+         for (list = dataset->datalist; list; list = list->next)
+           if (list->id == key_id)
+             {
+               G_UNLOCK (g_dataset_global);
+               return list->data;
+             }
+       }
+    }
+  G_UNLOCK (g_dataset_global);
+  return NULL;
+}
+
+/**
+ * g_datalist_id_get_data:
+ * @datalist: a datalist.
+ * @key_id: the #GQuark identifying a data element.
+ * @Returns: the data element, or %NULL if it is not found.
+ *
+ * Retrieves the data element corresponding to @key_id.
+ **/
+/**
+ * g_datalist_get_data:
+ * @dl: a datalist.
+ * @k: the string identifying a data element.
+ * @Returns: the data element, or %NULL if it is not found.
+ *
+ * Gets a data element, using its string identifer. This is slower than
+ * g_datalist_id_get_data() because the string is first converted to a
+ * #GQuark.
+ **/
+gpointer
+g_datalist_id_get_data (GData   **datalist,
+                       GQuark     key_id)
+{
+  gpointer data = NULL;
+  g_return_val_if_fail (datalist != NULL, NULL);
+  if (key_id)
+    {
+      register GData *list;
+      G_LOCK (g_dataset_global);
+      for (list = G_DATALIST_GET_POINTER (datalist); list; list = list->next)
+       if (list->id == key_id)
+         {
+            data = list->data;
+            break;
+          }
+      G_UNLOCK (g_dataset_global);
+    }
+  return data;
+}
+
+/**
+ * GDataForeachFunc:
+ * @key_id: the #GQuark id to identifying the data element.
+ * @data: the data element.
+ * @user_data: user data passed to g_dataset_foreach().
+ *
+ * Specifies the type of function passed to g_dataset_foreach(). It is
+ * called with each #GQuark id and associated data element, together
+ * with the @user_data parameter supplied to g_dataset_foreach().
+ **/
+
+/**
+ * g_dataset_foreach:
+ * @dataset_location: the location identifying the dataset.
+ * @func: the function to call for each data element.
+ * @user_data: user data to pass to the function.
+ *
+ * Calls the given function for each data element which is associated
+ * with the given location. Note that this function is NOT thread-safe.
+ * So unless @datalist can be protected from any modifications during
+ * invocation of this function, it should not be called.
+ **/
+void
+g_dataset_foreach (gconstpointer    dataset_location,
+                  GDataForeachFunc func,
+                  gpointer         user_data)
+{
+  register GDataset *dataset;
+  
+  g_return_if_fail (dataset_location != NULL);
+  g_return_if_fail (func != NULL);
+
+  G_LOCK (g_dataset_global);
+  if (g_dataset_location_ht)
+    {
+      dataset = g_dataset_lookup (dataset_location);
+      G_UNLOCK (g_dataset_global);
+      if (dataset)
+       {
+         register GData *list, *next;
+         
+         for (list = dataset->datalist; list; list = next)
+           {
+             next = list->next;
+             func (list->id, list->data, user_data);
+           }
+       }
+    }
+  else
+    {
+      G_UNLOCK (g_dataset_global);
+    }
+}
+
+/**
+ * g_datalist_foreach:
+ * @datalist: a datalist.
+ * @func: the function to call for each data element.
+ * @user_data: user data to pass to the function.
+ *
+ * Calls the given function for each data element of the datalist. The
+ * function is called with each data element's #GQuark id and data,
+ * together with the given @user_data parameter. Note that this
+ * function is NOT thread-safe. So unless @datalist can be protected
+ * from any modifications during invocation of this function, it should
+ * not be called.
+ **/
+void
+g_datalist_foreach (GData         **datalist,
+                   GDataForeachFunc func,
+                   gpointer         user_data)
+{
+  register GData *list, *next;
+
+  g_return_if_fail (datalist != NULL);
+  g_return_if_fail (func != NULL);
+  
+  for (list = G_DATALIST_GET_POINTER (datalist); list; list = next)
+    {
+      next = list->next;
+      func (list->id, list->data, user_data);
+    }
+}
+
+/**
+ * g_datalist_init:
+ * @datalist: a pointer to a pointer to a datalist.
+ *
+ * Resets the datalist to %NULL. It does not free any memory or call
+ * any destroy functions.
+ **/
+void
+g_datalist_init (GData **datalist)
+{
+  g_return_if_fail (datalist != NULL);
+
+  g_atomic_pointer_set (datalist, NULL);
+}
+
+/**
+ * g_datalist_set_flags:
+ * @datalist: pointer to the location that holds a list
+ * @flags: the flags to turn on. The values of the flags are
+ *   restricted by %G_DATALIST_FLAGS_MASK (currently
+ *   3; giving two possible boolean flags).
+ *   A value for @flags that doesn't fit within the mask is
+ *   an error.
+ * 
+ * Turns on flag values for a data list. This function is used
+ * to keep a small number of boolean flags in an object with
+ * a data list without using any additional space. It is
+ * not generally useful except in circumstances where space
+ * is very tight. (It is used in the base #GObject type, for
+ * example.)
+ *
+ * Since: 2.8
+ **/
+void
+g_datalist_set_flags (GData **datalist,
+                     guint   flags)
+{
+  gpointer oldvalue;
+  g_return_if_fail (datalist != NULL);
+  g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0);
+  
+  do
+    {
+      oldvalue = g_atomic_pointer_get (datalist);
+    }
+  while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, oldvalue,
+                                                 (gpointer) ((gsize) oldvalue | flags)));
+}
+
+/**
+ * g_datalist_unset_flags:
+ * @datalist: pointer to the location that holds a list
+ * @flags: the flags to turn off. The values of the flags are
+ *   restricted by %G_DATALIST_FLAGS_MASK (currently
+ *   3: giving two possible boolean flags).
+ *   A value for @flags that doesn't fit within the mask is
+ *   an error.
+ * 
+ * Turns off flag values for a data list. See g_datalist_unset_flags()
+ *
+ * Since: 2.8
+ **/
+void
+g_datalist_unset_flags (GData **datalist,
+                       guint   flags)
+{
+  gpointer oldvalue;
+  g_return_if_fail (datalist != NULL);
+  g_return_if_fail ((flags & ~G_DATALIST_FLAGS_MASK) == 0);
+  
+  do
+    {
+      oldvalue = g_atomic_pointer_get (datalist);
+    }
+  while (!g_atomic_pointer_compare_and_exchange ((void**) datalist, oldvalue,
+                                                 (gpointer) ((gsize) oldvalue & ~(gsize) flags)));
+}
+
+/**
+ * g_datalist_get_flags:
+ * @datalist: pointer to the location that holds a list
+ * 
+ * Gets flags values packed in together with the datalist.
+ * See g_datalist_set_flags().
+ * 
+ * Return value: the flags of the datalist
+ *
+ * Since: 2.8
+ **/
+guint
+g_datalist_get_flags (GData **datalist)
+{
+  g_return_val_if_fail (datalist != NULL, 0);
+  
+  return G_DATALIST_GET_FLAGS (datalist); /* atomic macro */
+}
+
+/* HOLDS: g_dataset_global_lock */
+static void
+g_data_initialize (void)
+{
+  g_return_if_fail (g_dataset_location_ht == NULL);
+
+  g_dataset_location_ht = g_hash_table_new (g_direct_hash, NULL);
+  g_dataset_cached = NULL;
+}
+
+/**
+ * SECTION: quarks
+ * @title: Quarks
+ * @short_description: a 2-way association between a string and a
+ *                     unique integer identifier
+ *
+ * Quarks are associations between strings and integer identifiers.
+ * Given either the string or the #GQuark identifier it is possible to
+ * retrieve the other.
+ *
+ * Quarks are used for both <link
+ * linkend="glib-datasets">Datasets</link> and <link
+ * linkend="glib-keyed-data-lists">Keyed Data Lists</link>.
+ *
+ * To create a new quark from a string, use g_quark_from_string() or
+ * g_quark_from_static_string().
+ *
+ * To find the string corresponding to a given #GQuark, use
+ * g_quark_to_string().
+ *
+ * To find the #GQuark corresponding to a given string, use
+ * g_quark_try_string().
+ *
+ * Another use for the string pool maintained for the quark functions
+ * is string interning, using g_intern_string() or
+ * g_intern_static_string(). An interned string is a canonical
+ * representation for a string. One important advantage of interned
+ * strings is that they can be compared for equality by a simple
+ * pointer comparision, rather than using strcmp().
+ **/
+
+/**
+ * GQuark:
+ *
+ * A GQuark is a non-zero integer which uniquely identifies a
+ * particular string. A GQuark value of zero is associated to %NULL.
+ **/
+
+/**
+ * g_quark_try_string:
+ * @string: a string.
+ * @Returns: the #GQuark associated with the string, or 0 if @string is
+ *           %NULL or there is no #GQuark associated with it.
+ *
+ * Gets the #GQuark associated with the given string, or 0 if string is
+ * %NULL or it has no associated #GQuark.
+ *
+ * If you want the GQuark to be created if it doesn't already exist,
+ * use g_quark_from_string() or g_quark_from_static_string().
+ **/
+GQuark
+g_quark_try_string (const gchar *string)
+{
+  GQuark quark = 0;
+
+  if (string == NULL)
+    return 0;
+
+  G_LOCK (g_quark_global);
+  if (g_quark_ht)
+    quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string));
+  G_UNLOCK (g_quark_global);
+  
+  return quark;
+}
+
+#define QUARK_STRING_BLOCK_SIZE (4096 - sizeof (gsize))
+static char *quark_block = NULL;
+static int quark_block_offset = 0;
+
+/* HOLDS: g_quark_global_lock */
+static char *
+quark_strdup(const gchar *string)
+{
+  gchar *copy;
+  gsize len;
+
+  len = strlen (string) + 1;
+
+  /* For strings longer than half the block size, fall back
+     to strdup so that we fill our blocks at least 50%. */
+  if (len > QUARK_STRING_BLOCK_SIZE / 2)
+    return g_strdup (string);
+
+  if (quark_block == NULL ||
+      QUARK_STRING_BLOCK_SIZE - quark_block_offset < len)
+    {
+      quark_block = g_malloc (QUARK_STRING_BLOCK_SIZE);
+      quark_block_offset = 0;
+    }
+
+  copy = quark_block + quark_block_offset;
+  memcpy (copy, string, len);
+  quark_block_offset += len;
+
+  return copy;
+}
+
+/* HOLDS: g_quark_global_lock */
+static inline GQuark
+g_quark_from_string_internal (const gchar *string, 
+                             gboolean     duplicate)
+{
+  GQuark quark = 0;
+  
+  if (g_quark_ht)
+    quark = GPOINTER_TO_UINT (g_hash_table_lookup (g_quark_ht, string));
+  
+  if (!quark)
+    {
+      quark = g_quark_new (duplicate ? quark_strdup (string) : (gchar *)string);
+      TRACE(GLIB_QUARK_NEW(string, quark));
+    }
+
+  return quark;
+}
+
+/**
+ * g_quark_from_string:
+ * @string: a string.
+ * @Returns: the #GQuark identifying the string, or 0 if @string is
+ *           %NULL.
+ *
+ * Gets the #GQuark identifying the given string. If the string does
+ * not currently have an associated #GQuark, a new #GQuark is created,
+ * using a copy of the string.
+ **/
+GQuark
+g_quark_from_string (const gchar *string)
+{
+  GQuark quark;
+  
+  if (!string)
+    return 0;
+  
+  G_LOCK (g_quark_global);
+  quark = g_quark_from_string_internal (string, TRUE);
+  G_UNLOCK (g_quark_global);
+  
+  return quark;
+}
+
+/**
+ * g_quark_from_static_string:
+ * @string: a string.
+ * @Returns: the #GQuark identifying the string, or 0 if @string is
+ *           %NULL.
+ *
+ * Gets the #GQuark identifying the given (static) string. If the
+ * string does not currently have an associated #GQuark, a new #GQuark
+ * is created, linked to the given string.
+ *
+ * Note that this function is identical to g_quark_from_string() except
+ * that if a new #GQuark is created the string itself is used rather
+ * than a copy. This saves memory, but can only be used if the string
+ * will <emphasis>always</emphasis> exist. It can be used with
+ * statically allocated strings in the main program, but not with
+ * statically allocated memory in dynamically loaded modules, if you
+ * expect to ever unload the module again (e.g. do not use this
+ * function in GTK+ theme engines).
+ **/
+GQuark
+g_quark_from_static_string (const gchar *string)
+{
+  GQuark quark;
+  
+  if (!string)
+    return 0;
+  
+  G_LOCK (g_quark_global);
+  quark = g_quark_from_string_internal (string, FALSE);
+  G_UNLOCK (g_quark_global);
+
+  return quark;
+}
+
+/**
+ * g_quark_to_string:
+ * @quark: a #GQuark.
+ * @Returns: the string associated with the #GQuark.
+ *
+ * Gets the string associated with the given #GQuark.
+ **/
+G_CONST_RETURN gchar*
+g_quark_to_string (GQuark quark)
+{
+  gchar* result = NULL;
+
+  G_LOCK (g_quark_global);
+  if (quark < g_quark_seq_id)
+    result = g_quarks[quark];
+  G_UNLOCK (g_quark_global);
+
+  return result;
+}
+
+/* HOLDS: g_quark_global_lock */
+static inline GQuark
+g_quark_new (gchar *string)
+{
+  GQuark quark;
+  
+  if (g_quark_seq_id % G_QUARK_BLOCK_SIZE == 0)
+    g_quarks = g_renew (gchar*, g_quarks, g_quark_seq_id + G_QUARK_BLOCK_SIZE);
+  if (!g_quark_ht)
+    {
+      g_assert (g_quark_seq_id == 0);
+      g_quark_ht = g_hash_table_new (g_str_hash, g_str_equal);
+      g_quarks[g_quark_seq_id++] = NULL;
+    }
+
+  quark = g_quark_seq_id++;
+  g_quarks[quark] = string;
+  g_hash_table_insert (g_quark_ht, string, GUINT_TO_POINTER (quark));
+  
+  return quark;
+}
+
+/**
+ * g_intern_string:
+ * @string: a string
+ * 
+ * Returns a canonical representation for @string. Interned strings can
+ * be compared for equality by comparing the pointers, instead of using strcmp().
+ * 
+ * Returns: a canonical representation for the string
+ *
+ * Since: 2.10
+ */
+G_CONST_RETURN gchar*
+g_intern_string (const gchar *string)
+{
+  const gchar *result;
+  GQuark quark;
+
+  if (!string)
+    return NULL;
+
+  G_LOCK (g_quark_global);
+  quark = g_quark_from_string_internal (string, TRUE);
+  result = g_quarks[quark];
+  G_UNLOCK (g_quark_global);
+
+  return result;
+}
+
+/**
+ * g_intern_static_string:
+ * @string: a static string
+ * 
+ * Returns a canonical representation for @string. Interned strings can
+ * be compared for equality by comparing the pointers, instead of using strcmp().
+ * g_intern_static_string() does not copy the string, therefore @string must
+ * not be freed or modified. 
+ * 
+ * Returns: a canonical representation for the string
+ *
+ * Since: 2.10
+ */
+G_CONST_RETURN gchar*
+g_intern_static_string (const gchar *string)
+{
+  GQuark quark;
+  const gchar *result;
+
+  if (!string)
+    return NULL;
+
+  G_LOCK (g_quark_global);
+  quark = g_quark_from_string_internal (string, FALSE);
+  result = g_quarks[quark];
+  G_UNLOCK (g_quark_global);
+
+  return result;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gdataset.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gdataset.h
new file mode 100644 (file)
index 0000000..2733ffb
--- /dev/null
@@ -0,0 +1,122 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_DATASET_H__
+#define __G_DATASET_H__
+
+#include <glib/gquark.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GData           GData;
+
+typedef void            (*GDataForeachFunc)     (GQuark         key_id,
+                                                 gpointer       data,
+                                                 gpointer       user_data);
+
+/* Keyed Data List
+ */
+void     g_datalist_init                (GData            **datalist);
+void     g_datalist_clear               (GData            **datalist);
+gpointer g_datalist_id_get_data         (GData            **datalist,
+                                        GQuark             key_id);
+void     g_datalist_id_set_data_full    (GData            **datalist,
+                                        GQuark             key_id,
+                                        gpointer           data,
+                                        GDestroyNotify     destroy_func);
+gpointer g_datalist_id_remove_no_notify (GData            **datalist,
+                                        GQuark             key_id);
+void     g_datalist_foreach             (GData            **datalist,
+                                        GDataForeachFunc   func,
+                                        gpointer           user_data);
+
+/**
+ * G_DATALIST_FLAGS_MASK:
+ *
+ * A bitmask that restricts the possible flags passed to
+ * g_datalist_set_flags(). Passing a flags value where
+ * flags & ~G_DATALIST_FLAGS_MASK != 0 is an error.
+ */
+#define G_DATALIST_FLAGS_MASK 0x3
+
+void     g_datalist_set_flags           (GData            **datalist,
+                                        guint              flags);
+void     g_datalist_unset_flags         (GData            **datalist,
+                                        guint              flags);
+guint    g_datalist_get_flags           (GData            **datalist);
+
+#define   g_datalist_id_set_data(dl, q, d)      \
+     g_datalist_id_set_data_full ((dl), (q), (d), NULL)
+#define   g_datalist_id_remove_data(dl, q)      \
+     g_datalist_id_set_data ((dl), (q), NULL)
+#define   g_datalist_get_data(dl, k)            \
+     (g_datalist_id_get_data ((dl), g_quark_try_string (k)))
+#define   g_datalist_set_data_full(dl, k, d, f) \
+     g_datalist_id_set_data_full ((dl), g_quark_from_string (k), (d), (f))
+#define   g_datalist_remove_no_notify(dl, k)    \
+     g_datalist_id_remove_no_notify ((dl), g_quark_try_string (k))
+#define   g_datalist_set_data(dl, k, d)         \
+     g_datalist_set_data_full ((dl), (k), (d), NULL)
+#define   g_datalist_remove_data(dl, k)         \
+     g_datalist_id_set_data ((dl), g_quark_try_string (k), NULL)
+
+
+/* Location Associated Keyed Data
+ */
+void      g_dataset_destroy             (gconstpointer    dataset_location);
+gpointer  g_dataset_id_get_data         (gconstpointer    dataset_location,
+                                         GQuark           key_id);
+void      g_dataset_id_set_data_full    (gconstpointer    dataset_location,
+                                         GQuark           key_id,
+                                         gpointer         data,
+                                         GDestroyNotify   destroy_func);
+gpointer  g_dataset_id_remove_no_notify (gconstpointer    dataset_location,
+                                         GQuark           key_id);
+void      g_dataset_foreach             (gconstpointer    dataset_location,
+                                         GDataForeachFunc func,
+                                         gpointer         user_data);
+#define   g_dataset_id_set_data(l, k, d)        \
+     g_dataset_id_set_data_full ((l), (k), (d), NULL)
+#define   g_dataset_id_remove_data(l, k)        \
+     g_dataset_id_set_data ((l), (k), NULL)
+#define   g_dataset_get_data(l, k)              \
+     (g_dataset_id_get_data ((l), g_quark_try_string (k)))
+#define   g_dataset_set_data_full(l, k, d, f)   \
+     g_dataset_id_set_data_full ((l), g_quark_from_string (k), (d), (f))
+#define   g_dataset_remove_no_notify(l, k)      \
+     g_dataset_id_remove_no_notify ((l), g_quark_try_string (k))
+#define   g_dataset_set_data(l, k, d)           \
+     g_dataset_set_data_full ((l), (k), (d), NULL)
+#define   g_dataset_remove_data(l, k)           \
+     g_dataset_id_set_data ((l), g_quark_try_string (k), NULL)
+
+G_END_DECLS
+
+#endif /* __G_DATASET_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gdatasetprivate.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gdatasetprivate.h
new file mode 100644 (file)
index 0000000..80d0ccf
--- /dev/null
@@ -0,0 +1,44 @@
+/* GLIB - Library of useful routines for C programming
+ * gdataset-private.h: Internal macros for accessing dataset values
+ * Copyright (C) 2005  Red Hat
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#ifndef __G_DATASETPRIVATE_H__
+#define __G_DATASETPRIVATE_H__
+
+#include <gatomic.h>
+
+G_BEGIN_DECLS
+
+/* GET_FLAGS is implemented via atomic pointer access, to allow memory
+ * barriers to take effect without acquiring the global dataset mutex.
+ */
+#define G_DATALIST_GET_FLAGS(datalist)                         \
+  ((gsize) g_atomic_pointer_get (datalist) & G_DATALIST_FLAGS_MASK)
+
+
+G_END_DECLS
+
+#endif /* __G_DATASETPRIVATE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gdate.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gdate.c
new file mode 100644 (file)
index 0000000..2fab2f2
--- /dev/null
@@ -0,0 +1,1913 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/* 
+ * MT safe
+ */
+
+#include "config.h"
+#include "glibconfig.h"
+
+#define DEBUG_MSG(x)   /* */
+#ifdef G_ENABLE_DEBUG
+/* #define DEBUG_MSG(args)     g_message args ; */
+#endif
+
+#include <time.h>
+#include <string.h>
+#include <stdlib.h>
+#include <locale.h>
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#endif
+
+#include "gdate.h"
+
+#include "gconvert.h"
+#include "gmem.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "gthread.h"
+#include "gunicode.h"
+
+#ifdef G_OS_WIN32
+#include "garray.h"
+#endif
+
+GDate*
+g_date_new (void)
+{
+  GDate *d = g_new0 (GDate, 1); /* happily, 0 is the invalid flag for everything. */
+  
+  return d;
+}
+
+GDate*
+g_date_new_dmy (GDateDay   day, 
+                GDateMonth m, 
+                GDateYear  y)
+{
+  GDate *d;
+  g_return_val_if_fail (g_date_valid_dmy (day, m, y), NULL);
+  
+  d = g_new (GDate, 1);
+  
+  d->julian = FALSE;
+  d->dmy    = TRUE;
+  
+  d->month = m;
+  d->day   = day;
+  d->year  = y;
+  
+  g_assert (g_date_valid (d));
+  
+  return d;
+}
+
+GDate*
+g_date_new_julian (guint32 j)
+{
+  GDate *d;
+  g_return_val_if_fail (g_date_valid_julian (j), NULL);
+  
+  d = g_new (GDate, 1);
+  
+  d->julian = TRUE;
+  d->dmy    = FALSE;
+  
+  d->julian_days = j;
+  
+  g_assert (g_date_valid (d));
+  
+  return d;
+}
+
+void
+g_date_free (GDate *d)
+{
+  g_return_if_fail (d != NULL);
+  
+  g_free (d);
+}
+
+gboolean     
+g_date_valid (const GDate *d)
+{
+  g_return_val_if_fail (d != NULL, FALSE);
+  
+  return (d->julian || d->dmy);
+}
+
+static const guint8 days_in_months[2][13] = 
+{  /* error, jan feb mar apr may jun jul aug sep oct nov dec */
+  {  0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }, 
+  {  0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 } /* leap year */
+};
+
+static const guint16 days_in_year[2][14] = 
+{  /* 0, jan feb mar apr may  jun  jul  aug  sep  oct  nov  dec */
+  {  0, 0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 }, 
+  {  0, 0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+};
+
+gboolean     
+g_date_valid_month (GDateMonth m)
+{ 
+  return ( (m > G_DATE_BAD_MONTH) && (m < 13) );
+}
+
+gboolean     
+g_date_valid_year (GDateYear y)
+{
+  return ( y > G_DATE_BAD_YEAR );
+}
+
+gboolean     
+g_date_valid_day (GDateDay d)
+{
+  return ( (d > G_DATE_BAD_DAY) && (d < 32) );
+}
+
+gboolean     
+g_date_valid_weekday (GDateWeekday w)
+{
+  return ( (w > G_DATE_BAD_WEEKDAY) && (w < 8) );
+}
+
+gboolean     
+g_date_valid_julian (guint32 j)
+{
+  return (j > G_DATE_BAD_JULIAN);
+}
+
+gboolean     
+g_date_valid_dmy (GDateDay   d, 
+                  GDateMonth m, 
+                 GDateYear  y)
+{
+  return ( (m > G_DATE_BAD_MONTH) &&
+           (m < 13)               && 
+           (d > G_DATE_BAD_DAY)   && 
+           (y > G_DATE_BAD_YEAR)  &&   /* must check before using g_date_is_leap_year */
+           (d <=  (g_date_is_leap_year (y) ? 
+                  days_in_months[1][m] : days_in_months[0][m])) );
+}
+
+
+/* "Julian days" just means an absolute number of days, where Day 1 ==
+ *   Jan 1, Year 1
+ */
+static void
+g_date_update_julian (const GDate *const_d)
+{
+  GDate *d = (GDate *) const_d;
+  GDateYear year;
+  gint idx;
+  
+  g_return_if_fail (d != NULL);
+  g_return_if_fail (d->dmy);
+  g_return_if_fail (!d->julian);
+  g_return_if_fail (g_date_valid_dmy (d->day, d->month, d->year));
+  
+  /* What we actually do is: multiply years * 365 days in the year,
+   * add the number of years divided by 4, subtract the number of
+   * years divided by 100 and add the number of years divided by 400,
+   * which accounts for leap year stuff. Code from Steffen Beyer's
+   * DateCalc. 
+   */
+  
+  year = d->year - 1; /* we know d->year > 0 since it's valid */
+  
+  d->julian_days = year * 365U;
+  d->julian_days += (year >>= 2); /* divide by 4 and add */
+  d->julian_days -= (year /= 25); /* divides original # years by 100 */
+  d->julian_days += year >> 2;    /* divides by 4, which divides original by 400 */
+  
+  idx = g_date_is_leap_year (d->year) ? 1 : 0;
+  
+  d->julian_days += days_in_year[idx][d->month] + d->day;
+  
+  g_return_if_fail (g_date_valid_julian (d->julian_days));
+  
+  d->julian = TRUE;
+}
+
+static void 
+g_date_update_dmy (const GDate *const_d)
+{
+  GDate *d = (GDate *) const_d;
+  GDateYear y;
+  GDateMonth m;
+  GDateDay day;
+  
+  guint32 A, B, C, D, E, M;
+  
+  g_return_if_fail (d != NULL);
+  g_return_if_fail (d->julian);
+  g_return_if_fail (!d->dmy);
+  g_return_if_fail (g_date_valid_julian (d->julian_days));
+  
+  /* Formula taken from the Calendar FAQ; the formula was for the
+   *  Julian Period which starts on 1 January 4713 BC, so we add
+   *  1,721,425 to the number of days before doing the formula.
+   *
+   * I'm sure this can be simplified for our 1 January 1 AD period
+   * start, but I can't figure out how to unpack the formula.  
+   */
+  
+  A = d->julian_days + 1721425 + 32045;
+  B = ( 4 *(A + 36524) )/ 146097 - 1;
+  C = A - (146097 * B)/4;
+  D = ( 4 * (C + 365) ) / 1461 - 1;
+  E = C - ((1461*D) / 4);
+  M = (5 * (E - 1) + 2)/153;
+  
+  m = M + 3 - (12*(M/10));
+  day = E - (153*M + 2)/5;
+  y = 100 * B + D - 4800 + (M/10);
+  
+#ifdef G_ENABLE_DEBUG
+  if (!g_date_valid_dmy (day, m, y)) 
+    g_warning ("\nOOPS julian: %u  computed dmy: %u %u %u\n", 
+              d->julian_days, day, m, y);
+#endif
+  
+  d->month = m;
+  d->day   = day;
+  d->year  = y;
+  
+  d->dmy = TRUE;
+}
+
+GDateWeekday 
+g_date_get_weekday (const GDate *d)
+{
+  g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_WEEKDAY);
+  
+  if (!d->julian) 
+    g_date_update_julian (d);
+
+  g_return_val_if_fail (d->julian, G_DATE_BAD_WEEKDAY);
+  
+  return ((d->julian_days - 1) % 7) + 1;
+}
+
+GDateMonth   
+g_date_get_month (const GDate *d)
+{
+  g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_MONTH);
+  
+  if (!d->dmy) 
+    g_date_update_dmy (d);
+
+  g_return_val_if_fail (d->dmy, G_DATE_BAD_MONTH);
+  
+  return d->month;
+}
+
+GDateYear    
+g_date_get_year (const GDate *d)
+{
+  g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_YEAR);
+  
+  if (!d->dmy) 
+    g_date_update_dmy (d);
+
+  g_return_val_if_fail (d->dmy, G_DATE_BAD_YEAR);  
+  
+  return d->year;
+}
+
+GDateDay     
+g_date_get_day (const GDate *d)
+{
+  g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_DAY);
+  
+  if (!d->dmy) 
+    g_date_update_dmy (d);
+
+  g_return_val_if_fail (d->dmy, G_DATE_BAD_DAY);  
+  
+  return d->day;
+}
+
+guint32      
+g_date_get_julian (const GDate *d)
+{
+  g_return_val_if_fail (g_date_valid (d), G_DATE_BAD_JULIAN);
+  
+  if (!d->julian) 
+    g_date_update_julian (d);
+
+  g_return_val_if_fail (d->julian, G_DATE_BAD_JULIAN);  
+  
+  return d->julian_days;
+}
+
+guint        
+g_date_get_day_of_year (const GDate *d)
+{
+  gint idx;
+  
+  g_return_val_if_fail (g_date_valid (d), 0);
+  
+  if (!d->dmy) 
+    g_date_update_dmy (d);
+
+  g_return_val_if_fail (d->dmy, 0);  
+  
+  idx = g_date_is_leap_year (d->year) ? 1 : 0;
+  
+  return (days_in_year[idx][d->month] + d->day);
+}
+
+guint        
+g_date_get_monday_week_of_year (const GDate *d)
+{
+  GDateWeekday wd;
+  guint day;
+  GDate first;
+  
+  g_return_val_if_fail (g_date_valid (d), 0);
+  
+  if (!d->dmy) 
+    g_date_update_dmy (d);
+
+  g_return_val_if_fail (d->dmy, 0);  
+  
+  g_date_clear (&first, 1);
+  
+  g_date_set_dmy (&first, 1, 1, d->year);
+  
+  wd = g_date_get_weekday (&first) - 1; /* make Monday day 0 */
+  day = g_date_get_day_of_year (d) - 1;
+  
+  return ((day + wd)/7U + (wd == 0 ? 1 : 0));
+}
+
+guint        
+g_date_get_sunday_week_of_year (const GDate *d)
+{
+  GDateWeekday wd;
+  guint day;
+  GDate first;
+  
+  g_return_val_if_fail (g_date_valid (d), 0);
+  
+  if (!d->dmy) 
+    g_date_update_dmy (d);
+
+  g_return_val_if_fail (d->dmy, 0);  
+  
+  g_date_clear (&first, 1);
+  
+  g_date_set_dmy (&first, 1, 1, d->year);
+  
+  wd = g_date_get_weekday (&first);
+  if (wd == 7) wd = 0; /* make Sunday day 0 */
+  day = g_date_get_day_of_year (d) - 1;
+  
+  return ((day + wd)/7U + (wd == 0 ? 1 : 0));
+}
+
+/**
+ * g_date_get_iso8601_week_of_year:
+ * @date: a valid #GDate
+ *
+ * Returns the week of the year, where weeks are interpreted according
+ * to ISO 8601. 
+ * 
+ * Returns: ISO 8601 week number of the year.
+ *
+ * Since: 2.6
+ **/
+guint
+g_date_get_iso8601_week_of_year (const GDate *d)
+{
+  guint j, d4, L, d1, w;
+
+  g_return_val_if_fail (g_date_valid (d), 0);
+  
+  if (!d->julian)
+    g_date_update_julian (d);
+
+  g_return_val_if_fail (d->julian, 0);
+
+  /* Formula taken from the Calendar FAQ; the formula was for the
+   * Julian Period which starts on 1 January 4713 BC, so we add
+   * 1,721,425 to the number of days before doing the formula. 
+   */
+  j  = d->julian_days + 1721425;
+  d4 = (j + 31741 - (j % 7)) % 146097 % 36524 % 1461;
+  L  = d4 / 1460;
+  d1 = ((d4 - L) % 365) + L;
+  w  = d1 / 7 + 1;
+
+  return w;
+}
+
+gint
+g_date_days_between (const GDate *d1,
+                    const GDate *d2)
+{
+  g_return_val_if_fail (g_date_valid (d1), 0);
+  g_return_val_if_fail (g_date_valid (d2), 0);
+
+  return (gint)g_date_get_julian (d2) - (gint)g_date_get_julian (d1);
+}
+
+void         
+g_date_clear (GDate *d, guint ndates)
+{
+  g_return_if_fail (d != NULL);
+  g_return_if_fail (ndates != 0);
+  
+  memset (d, 0x0, ndates*sizeof (GDate)); 
+}
+
+G_LOCK_DEFINE_STATIC (g_date_global);
+
+/* These are for the parser, output to the user should use *
+ * g_date_strftime () - this creates more never-freed memory to annoy
+ * all those memory debugger users. :-) 
+ */
+
+static gchar *long_month_names[13] = 
+{ 
+  NULL,
+};
+
+static gchar *short_month_names[13] = 
+{
+  NULL, 
+};
+
+/* This tells us if we need to update the parse info */
+static gchar *current_locale = NULL;
+
+/* order of these in the current locale */
+static GDateDMY dmy_order[3] = 
+{
+   G_DATE_DAY, G_DATE_MONTH, G_DATE_YEAR
+};
+
+/* Where to chop two-digit years: i.e., for the 1930 default, numbers
+ * 29 and below are counted as in the year 2000, numbers 30 and above
+ * are counted as in the year 1900.  
+ */
+
+static const GDateYear twodigit_start_year = 1930;
+
+/* It is impossible to enter a year between 1 AD and 99 AD with this
+ * in effect.  
+ */
+static gboolean using_twodigit_years = FALSE;
+
+/* Adjustment of locale era to AD, non-zero means using locale era
+ */
+static gint locale_era_adjust = 0;
+
+struct _GDateParseTokens {
+  gint num_ints;
+  gint n[3];
+  guint month;
+};
+
+typedef struct _GDateParseTokens GDateParseTokens;
+
+#define NUM_LEN 10
+
+/* HOLDS: g_date_global_lock */
+static void
+g_date_fill_parse_tokens (const gchar *str, GDateParseTokens *pt)
+{
+  gchar num[4][NUM_LEN+1];
+  gint i;
+  const guchar *s;
+  
+  /* We count 4, but store 3; so we can give an error
+   * if there are 4.
+   */
+  num[0][0] = num[1][0] = num[2][0] = num[3][0] = '\0';
+  
+  s = (const guchar *) str;
+  pt->num_ints = 0;
+  while (*s && pt->num_ints < 4) 
+    {
+      
+      i = 0;
+      while (*s && g_ascii_isdigit (*s) && i < NUM_LEN)
+        {
+          num[pt->num_ints][i] = *s;
+          ++s; 
+          ++i;
+        }
+      
+      if (i > 0) 
+        {
+          num[pt->num_ints][i] = '\0';
+          ++(pt->num_ints);
+        }
+      
+      if (*s == '\0') break;
+      
+      ++s;
+    }
+  
+  pt->n[0] = pt->num_ints > 0 ? atoi (num[0]) : 0;
+  pt->n[1] = pt->num_ints > 1 ? atoi (num[1]) : 0;
+  pt->n[2] = pt->num_ints > 2 ? atoi (num[2]) : 0;
+  
+  pt->month = G_DATE_BAD_MONTH;
+  
+  if (pt->num_ints < 3)
+    {
+      gchar *casefold;
+      gchar *normalized;
+      
+      casefold = g_utf8_casefold (str, -1);
+      normalized = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL);
+      g_free (casefold);
+
+      i = 1;
+      while (i < 13)
+        {
+          if (long_month_names[i] != NULL) 
+            {
+              const gchar *found = strstr (normalized, long_month_names[i]);
+             
+              if (found != NULL)
+                {
+                  pt->month = i;
+                 break;
+                }
+            }
+         
+          if (short_month_names[i] != NULL) 
+            {
+              const gchar *found = strstr (normalized, short_month_names[i]);
+             
+              if (found != NULL)
+                {
+                  pt->month = i;
+                 break;
+                }
+            }
+
+          ++i;
+        }
+
+      g_free (normalized);
+    }
+}
+
+/* HOLDS: g_date_global_lock */
+static void
+g_date_prepare_to_parse (const gchar      *str, 
+                         GDateParseTokens *pt)
+{
+  const gchar *locale = setlocale (LC_TIME, NULL);
+  gboolean recompute_localeinfo = FALSE;
+  GDate d;
+  
+  g_return_if_fail (locale != NULL); /* should not happen */
+  
+  g_date_clear (&d, 1);              /* clear for scratch use */
+  
+  if ( (current_locale == NULL) || (strcmp (locale, current_locale) != 0) ) 
+    recompute_localeinfo = TRUE;  /* Uh, there used to be a reason for the temporary */
+  
+  if (recompute_localeinfo)
+    {
+      int i = 1;
+      GDateParseTokens testpt;
+      gchar buf[128];
+      
+      g_free (current_locale); /* still works if current_locale == NULL */
+      
+      current_locale = g_strdup (locale);
+      
+      short_month_names[0] = "Error";
+      long_month_names[0] = "Error";
+
+      while (i < 13) 
+        {
+         gchar *casefold;
+         
+          g_date_set_dmy (&d, 1, i, 1);
+         
+          g_return_if_fail (g_date_valid (&d));
+         
+          g_date_strftime (buf, 127, "%b", &d);
+
+         casefold = g_utf8_casefold (buf, -1);
+          g_free (short_month_names[i]);
+          short_month_names[i] = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL);
+         g_free (casefold);
+         
+          g_date_strftime (buf, 127, "%B", &d);
+         casefold = g_utf8_casefold (buf, -1);
+          g_free (long_month_names[i]);
+          long_month_names[i] = g_utf8_normalize (casefold, -1, G_NORMALIZE_ALL);
+         g_free (casefold);
+          
+          ++i;
+        }
+      
+      /* Determine DMY order */
+      
+      /* had to pick a random day - don't change this, some strftimes
+       * are broken on some days, and this one is good so far. */
+      g_date_set_dmy (&d, 4, 7, 1976);
+      
+      g_date_strftime (buf, 127, "%x", &d);
+      
+      g_date_fill_parse_tokens (buf, &testpt);
+      
+      i = 0;
+      while (i < testpt.num_ints)
+        {
+          switch (testpt.n[i])
+            {
+            case 7:
+              dmy_order[i] = G_DATE_MONTH;
+              break;
+            case 4:
+              dmy_order[i] = G_DATE_DAY;
+              break;
+            case 76:
+              using_twodigit_years = TRUE; /* FALL THRU */
+            case 1976:
+              dmy_order[i] = G_DATE_YEAR;
+              break;
+            default:
+              /* assume locale era */
+              locale_era_adjust = 1976 - testpt.n[i];
+              dmy_order[i] = G_DATE_YEAR;
+              break;
+            }
+          ++i;
+        }
+      
+#ifdef G_ENABLE_DEBUG
+      DEBUG_MSG (("**GDate prepared a new set of locale-specific parse rules."));
+      i = 1;
+      while (i < 13) 
+        {
+          DEBUG_MSG (("  %s   %s", long_month_names[i], short_month_names[i]));
+          ++i;
+        }
+      if (using_twodigit_years)
+        {
+         DEBUG_MSG (("**Using twodigit years with cutoff year: %u", twodigit_start_year));
+        }
+      { 
+        gchar *strings[3];
+        i = 0;
+        while (i < 3)
+          {
+            switch (dmy_order[i])
+              {
+              case G_DATE_MONTH:
+                strings[i] = "Month";
+                break;
+              case G_DATE_YEAR:
+                strings[i] = "Year";
+                break;
+              case G_DATE_DAY:
+                strings[i] = "Day";
+                break;
+              default:
+                strings[i] = NULL;
+                break;
+              }
+            ++i;
+          }
+        DEBUG_MSG (("**Order: %s, %s, %s", strings[0], strings[1], strings[2]));
+        DEBUG_MSG (("**Sample date in this locale: `%s'", buf));
+      }
+#endif
+    }
+  
+  g_date_fill_parse_tokens (str, pt);
+}
+
+void         
+g_date_set_parse (GDate       *d, 
+                  const gchar *str)
+{
+  GDateParseTokens pt;
+  guint m = G_DATE_BAD_MONTH, day = G_DATE_BAD_DAY, y = G_DATE_BAD_YEAR;
+  
+  g_return_if_fail (d != NULL);
+  
+  /* set invalid */
+  g_date_clear (d, 1);
+  
+  G_LOCK (g_date_global);
+
+  g_date_prepare_to_parse (str, &pt);
+  
+  DEBUG_MSG (("Found %d ints, `%d' `%d' `%d' and written out month %d", 
+             pt.num_ints, pt.n[0], pt.n[1], pt.n[2], pt.month));
+  
+  
+  if (pt.num_ints == 4) 
+    {
+      G_UNLOCK (g_date_global);
+      return; /* presumably a typo; bail out. */
+    }
+  
+  if (pt.num_ints > 1)
+    {
+      int i = 0;
+      int j = 0;
+      
+      g_assert (pt.num_ints < 4); /* i.e., it is 2 or 3 */
+      
+      while (i < pt.num_ints && j < 3) 
+        {
+          switch (dmy_order[j])
+            {
+            case G_DATE_MONTH:
+           {
+             if (pt.num_ints == 2 && pt.month != G_DATE_BAD_MONTH)
+               {
+                 m = pt.month;
+                 ++j;      /* skip months, but don't skip this number */
+                 continue;
+               }
+             else 
+               m = pt.n[i];
+           }
+           break;
+            case G_DATE_DAY:
+           {
+             if (pt.num_ints == 2 && pt.month == G_DATE_BAD_MONTH)
+               {
+                 day = 1;
+                 ++j;      /* skip days, since we may have month/year */
+                 continue;
+               }
+             day = pt.n[i];
+           }
+           break;
+            case G_DATE_YEAR:
+           {
+             y  = pt.n[i];
+             
+             if (locale_era_adjust != 0)
+               {
+                 y += locale_era_adjust;
+               }
+             else if (using_twodigit_years && y < 100)
+               {
+                 guint two     =  twodigit_start_year % 100;
+                 guint century = (twodigit_start_year / 100) * 100;
+                 
+                 if (y < two)
+                   century += 100;
+                 
+                 y += century;
+               }
+           }
+           break;
+            default:
+              break;
+            }
+         
+          ++i;
+          ++j;
+        }
+      
+      
+      if (pt.num_ints == 3 && !g_date_valid_dmy (day, m, y))
+        {
+          /* Try YYYY MM DD */
+          y   = pt.n[0];
+          m   = pt.n[1];
+          day = pt.n[2];
+          
+          if (using_twodigit_years && y < 100) 
+            y = G_DATE_BAD_YEAR; /* avoids ambiguity */
+        }
+      else if (pt.num_ints == 2)
+       {
+         if (m == G_DATE_BAD_MONTH && pt.month != G_DATE_BAD_MONTH)
+           m = pt.month;
+       }
+    }
+  else if (pt.num_ints == 1) 
+    {
+      if (pt.month != G_DATE_BAD_MONTH)
+        {
+          /* Month name and year? */
+          m    = pt.month;
+          day  = 1;
+          y = pt.n[0];
+        }
+      else
+        {
+          /* Try yyyymmdd and yymmdd */
+         
+          m   = (pt.n[0]/100) % 100;
+          day = pt.n[0] % 100;
+          y   = pt.n[0]/10000;
+         
+          /* FIXME move this into a separate function */
+          if (using_twodigit_years && y < 100)
+            {
+              guint two     =  twodigit_start_year % 100;
+              guint century = (twodigit_start_year / 100) * 100;
+              
+              if (y < two)
+                century += 100;
+              
+              y += century;
+            }
+        }
+    }
+  
+  /* See if we got anything valid out of all this. */
+  /* y < 8000 is to catch 19998 style typos; the library is OK up to 65535 or so */
+  if (y < 8000 && g_date_valid_dmy (day, m, y)) 
+    {
+      d->month = m;
+      d->day   = day;
+      d->year  = y;
+      d->dmy   = TRUE;
+    }
+#ifdef G_ENABLE_DEBUG
+  else 
+    {
+      DEBUG_MSG (("Rejected DMY %u %u %u", day, m, y));
+    }
+#endif
+  G_UNLOCK (g_date_global);
+}
+
+/**
+ * g_date_set_time_t:
+ * @date: a #GDate 
+ * @timet: <type>time_t</type> value to set
+ *
+ * Sets the value of a date to the date corresponding to a time 
+ * specified as a time_t. The time to date conversion is done using 
+ * the user's current timezone.
+ *
+ * To set the value of a date to the current day, you could write:
+ * |[
+ *  g_date_set_time_t (date, time (NULL)); 
+ * ]|
+ *
+ * Since: 2.10
+ */
+void         
+g_date_set_time_t (GDate *date,
+                  time_t timet)
+{
+  struct tm tm;
+  
+  g_return_if_fail (date != NULL);
+  
+#ifdef HAVE_LOCALTIME_R
+  localtime_r (&timet, &tm);
+#else
+  {
+    struct tm *ptm = localtime (&timet);
+
+    if (ptm == NULL)
+      {
+       /* Happens at least in Microsoft's C library if you pass a
+        * negative time_t. Use 2000-01-01 as default date.
+        */
+#ifndef G_DISABLE_CHECKS
+       g_return_if_fail_warning (G_LOG_DOMAIN, "g_date_set_time", "ptm != NULL");
+#endif
+
+       tm.tm_mon = 0;
+       tm.tm_mday = 1;
+       tm.tm_year = 100;
+      }
+    else
+      memcpy ((void *) &tm, (void *) ptm, sizeof(struct tm));
+  }
+#endif
+  
+  date->julian = FALSE;
+  
+  date->month = tm.tm_mon + 1;
+  date->day   = tm.tm_mday;
+  date->year  = tm.tm_year + 1900;
+  
+  g_return_if_fail (g_date_valid_dmy (date->day, date->month, date->year));
+  
+  date->dmy    = TRUE;
+}
+
+
+/**
+ * g_date_set_time:
+ * @date: a #GDate.
+ * @time_: #GTime value to set.
+ *
+ * Sets the value of a date from a #GTime value.
+ * The time to date conversion is done using the user's current timezone.
+ *
+ * Deprecated: 2.10: Use g_date_set_time_t() instead.
+ */
+void
+g_date_set_time (GDate *date,
+                GTime  time_)
+{
+  g_date_set_time_t (date, (time_t) time_);
+}
+
+/**
+ * g_date_set_time_val:
+ * @date: a #GDate 
+ * @timeval: #GTimeVal value to set
+ *
+ * Sets the value of a date from a #GTimeVal value.  Note that the
+ * @tv_usec member is ignored, because #GDate can't make use of the
+ * additional precision.
+ *
+ * The time to date conversion is done using the user's current timezone.
+ *
+ * Since: 2.10
+ */
+void
+g_date_set_time_val (GDate    *date,
+                    GTimeVal *timeval)
+{
+  g_date_set_time_t (date, (time_t) timeval->tv_sec);
+}
+
+void         
+g_date_set_month (GDate     *d, 
+                  GDateMonth m)
+{
+  g_return_if_fail (d != NULL);
+  g_return_if_fail (g_date_valid_month (m));
+
+  if (d->julian && !d->dmy) g_date_update_dmy(d);
+  d->julian = FALSE;
+  
+  d->month = m;
+  
+  if (g_date_valid_dmy (d->day, d->month, d->year))
+    d->dmy = TRUE;
+  else 
+    d->dmy = FALSE;
+}
+
+void         
+g_date_set_day (GDate    *d, 
+                GDateDay  day)
+{
+  g_return_if_fail (d != NULL);
+  g_return_if_fail (g_date_valid_day (day));
+  
+  if (d->julian && !d->dmy) g_date_update_dmy(d);
+  d->julian = FALSE;
+  
+  d->day = day;
+  
+  if (g_date_valid_dmy (d->day, d->month, d->year))
+    d->dmy = TRUE;
+  else 
+    d->dmy = FALSE;
+}
+
+void         
+g_date_set_year (GDate     *d, 
+                 GDateYear  y)
+{
+  g_return_if_fail (d != NULL);
+  g_return_if_fail (g_date_valid_year (y));
+  
+  if (d->julian && !d->dmy) g_date_update_dmy(d);
+  d->julian = FALSE;
+  
+  d->year = y;
+  
+  if (g_date_valid_dmy (d->day, d->month, d->year))
+    d->dmy = TRUE;
+  else 
+    d->dmy = FALSE;
+}
+
+void         
+g_date_set_dmy (GDate      *d, 
+                GDateDay    day, 
+                GDateMonth  m, 
+                GDateYear   y)
+{
+  g_return_if_fail (d != NULL);
+  g_return_if_fail (g_date_valid_dmy (day, m, y));
+  
+  d->julian = FALSE;
+  
+  d->month = m;
+  d->day   = day;
+  d->year  = y;
+  
+  d->dmy = TRUE;
+}
+
+void         
+g_date_set_julian (GDate   *d, 
+                   guint32  j)
+{
+  g_return_if_fail (d != NULL);
+  g_return_if_fail (g_date_valid_julian (j));
+  
+  d->julian_days = j;
+  d->julian = TRUE;
+  d->dmy = FALSE;
+}
+
+
+gboolean     
+g_date_is_first_of_month (const GDate *d)
+{
+  g_return_val_if_fail (g_date_valid (d), FALSE);
+  
+  if (!d->dmy) 
+    g_date_update_dmy (d);
+
+  g_return_val_if_fail (d->dmy, FALSE);  
+  
+  if (d->day == 1) return TRUE;
+  else return FALSE;
+}
+
+gboolean     
+g_date_is_last_of_month (const GDate *d)
+{
+  gint idx;
+  
+  g_return_val_if_fail (g_date_valid (d), FALSE);
+  
+  if (!d->dmy) 
+    g_date_update_dmy (d);
+
+  g_return_val_if_fail (d->dmy, FALSE);  
+  
+  idx = g_date_is_leap_year (d->year) ? 1 : 0;
+  
+  if (d->day == days_in_months[idx][d->month]) return TRUE;
+  else return FALSE;
+}
+
+void         
+g_date_add_days (GDate *d, 
+                 guint  ndays)
+{
+  g_return_if_fail (g_date_valid (d));
+  
+  if (!d->julian)
+    g_date_update_julian (d);
+
+  g_return_if_fail (d->julian);
+  
+  d->julian_days += ndays;
+  d->dmy = FALSE;
+}
+
+void         
+g_date_subtract_days (GDate *d, 
+                      guint  ndays)
+{
+  g_return_if_fail (g_date_valid (d));
+  
+  if (!d->julian)
+    g_date_update_julian (d);
+
+  g_return_if_fail (d->julian);
+  g_return_if_fail (d->julian_days > ndays);
+  
+  d->julian_days -= ndays;
+  d->dmy = FALSE;
+}
+
+void         
+g_date_add_months (GDate *d, 
+                   guint  nmonths)
+{
+  guint years, months;
+  gint idx;
+  
+  g_return_if_fail (g_date_valid (d));
+  
+  if (!d->dmy) 
+    g_date_update_dmy (d);
+
+  g_return_if_fail (d->dmy);  
+  
+  nmonths += d->month - 1;
+  
+  years  = nmonths/12;
+  months = nmonths%12;
+  
+  d->month = months + 1;
+  d->year  += years;
+  
+  idx = g_date_is_leap_year (d->year) ? 1 : 0;
+  
+  if (d->day > days_in_months[idx][d->month])
+    d->day = days_in_months[idx][d->month];
+  
+  d->julian = FALSE;
+  
+  g_return_if_fail (g_date_valid (d));
+}
+
+void         
+g_date_subtract_months (GDate *d, 
+                        guint  nmonths)
+{
+  guint years, months;
+  gint idx;
+  
+  g_return_if_fail (g_date_valid (d));
+  
+  if (!d->dmy) 
+    g_date_update_dmy (d);
+
+  g_return_if_fail (d->dmy);  
+  
+  years  = nmonths/12;
+  months = nmonths%12;
+  
+  g_return_if_fail (d->year > years);
+  
+  d->year  -= years;
+  
+  if (d->month > months) d->month -= months;
+  else 
+    {
+      months -= d->month;
+      d->month = 12 - months;
+      d->year -= 1;
+    }
+  
+  idx = g_date_is_leap_year (d->year) ? 1 : 0;
+  
+  if (d->day > days_in_months[idx][d->month])
+    d->day = days_in_months[idx][d->month];
+  
+  d->julian = FALSE;
+  
+  g_return_if_fail (g_date_valid (d));
+}
+
+void         
+g_date_add_years (GDate *d, 
+                  guint  nyears)
+{
+  g_return_if_fail (g_date_valid (d));
+  
+  if (!d->dmy) 
+    g_date_update_dmy (d);
+
+  g_return_if_fail (d->dmy);  
+  
+  d->year += nyears;
+  
+  if (d->month == 2 && d->day == 29)
+    {
+      if (!g_date_is_leap_year (d->year))
+        d->day = 28;
+    }
+  
+  d->julian = FALSE;
+}
+
+void         
+g_date_subtract_years (GDate *d, 
+                       guint  nyears)
+{
+  g_return_if_fail (g_date_valid (d));
+  
+  if (!d->dmy) 
+    g_date_update_dmy (d);
+
+  g_return_if_fail (d->dmy);  
+  g_return_if_fail (d->year > nyears);
+  
+  d->year -= nyears;
+  
+  if (d->month == 2 && d->day == 29)
+    {
+      if (!g_date_is_leap_year (d->year))
+        d->day = 28;
+    }
+  
+  d->julian = FALSE;
+}
+
+gboolean     
+g_date_is_leap_year (GDateYear year)
+{
+  g_return_val_if_fail (g_date_valid_year (year), FALSE);
+  
+  return ( (((year % 4) == 0) && ((year % 100) != 0)) ||
+           (year % 400) == 0 );
+}
+
+guint8         
+g_date_get_days_in_month (GDateMonth month, 
+                          GDateYear  year)
+{
+  gint idx;
+  
+  g_return_val_if_fail (g_date_valid_year (year), 0);
+  g_return_val_if_fail (g_date_valid_month (month), 0);
+  
+  idx = g_date_is_leap_year (year) ? 1 : 0;
+  
+  return days_in_months[idx][month];
+}
+
+guint8       
+g_date_get_monday_weeks_in_year (GDateYear year)
+{
+  GDate d;
+  
+  g_return_val_if_fail (g_date_valid_year (year), 0);
+  
+  g_date_clear (&d, 1);
+  g_date_set_dmy (&d, 1, 1, year);
+  if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53;
+  g_date_set_dmy (&d, 31, 12, year);
+  if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53;
+  if (g_date_is_leap_year (year)) 
+    {
+      g_date_set_dmy (&d, 2, 1, year);
+      if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53;
+      g_date_set_dmy (&d, 30, 12, year);
+      if (g_date_get_weekday (&d) == G_DATE_MONDAY) return 53;
+    }
+  return 52;
+}
+
+guint8       
+g_date_get_sunday_weeks_in_year (GDateYear year)
+{
+  GDate d;
+  
+  g_return_val_if_fail (g_date_valid_year (year), 0);
+  
+  g_date_clear (&d, 1);
+  g_date_set_dmy (&d, 1, 1, year);
+  if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53;
+  g_date_set_dmy (&d, 31, 12, year);
+  if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53;
+  if (g_date_is_leap_year (year)) 
+    {
+      g_date_set_dmy (&d, 2, 1, year);
+      if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53;
+      g_date_set_dmy (&d, 30, 12, year);
+      if (g_date_get_weekday (&d) == G_DATE_SUNDAY) return 53;
+    }
+  return 52;
+}
+
+gint         
+g_date_compare (const GDate *lhs, 
+                const GDate *rhs)
+{
+  g_return_val_if_fail (lhs != NULL, 0);
+  g_return_val_if_fail (rhs != NULL, 0);
+  g_return_val_if_fail (g_date_valid (lhs), 0);
+  g_return_val_if_fail (g_date_valid (rhs), 0);
+  
+  /* Remember the self-comparison case! I think it works right now. */
+  
+  while (TRUE)
+    {
+      if (lhs->julian && rhs->julian) 
+        {
+          if (lhs->julian_days < rhs->julian_days) return -1;
+          else if (lhs->julian_days > rhs->julian_days) return 1;
+          else                                          return 0;
+        }
+      else if (lhs->dmy && rhs->dmy) 
+        {
+          if (lhs->year < rhs->year)               return -1;
+          else if (lhs->year > rhs->year)               return 1;
+          else 
+            {
+              if (lhs->month < rhs->month)         return -1;
+              else if (lhs->month > rhs->month)         return 1;
+              else 
+                {
+                  if (lhs->day < rhs->day)              return -1;
+                  else if (lhs->day > rhs->day)              return 1;
+                  else                                       return 0;
+                }
+              
+            }
+          
+        }
+      else
+        {
+          if (!lhs->julian) g_date_update_julian (lhs);
+          if (!rhs->julian) g_date_update_julian (rhs);
+          g_return_val_if_fail (lhs->julian, 0);
+          g_return_val_if_fail (rhs->julian, 0);
+        }
+      
+    }
+  return 0; /* warnings */
+}
+
+
+void        
+g_date_to_struct_tm (const GDate *d, 
+                     struct tm   *tm)
+{
+  GDateWeekday day;
+     
+  g_return_if_fail (g_date_valid (d));
+  g_return_if_fail (tm != NULL);
+  
+  if (!d->dmy) 
+    g_date_update_dmy (d);
+
+  g_return_if_fail (d->dmy);
+  
+  /* zero all the irrelevant fields to be sure they're valid */
+  
+  /* On Linux and maybe other systems, there are weird non-POSIX
+   * fields on the end of struct tm that choke strftime if they
+   * contain garbage.  So we need to 0 the entire struct, not just the
+   * fields we know to exist. 
+   */
+  
+  memset (tm, 0x0, sizeof (struct tm));
+  
+  tm->tm_mday = d->day;
+  tm->tm_mon  = d->month - 1; /* 0-11 goes in tm */
+  tm->tm_year = ((int)d->year) - 1900; /* X/Open says tm_year can be negative */
+  
+  day = g_date_get_weekday (d);
+  if (day == 7) day = 0; /* struct tm wants days since Sunday, so Sunday is 0 */
+  
+  tm->tm_wday = (int)day;
+  
+  tm->tm_yday = g_date_get_day_of_year (d) - 1; /* 0 to 365 */
+  tm->tm_isdst = -1; /* -1 means "information not available" */
+}
+
+void
+g_date_clamp (GDate       *date,
+             const GDate *min_date,
+             const GDate *max_date)
+{
+  g_return_if_fail (g_date_valid (date));
+
+  if (min_date != NULL)
+    g_return_if_fail (g_date_valid (min_date));
+
+  if (max_date != NULL)
+    g_return_if_fail (g_date_valid (max_date));
+
+  if (min_date != NULL && max_date != NULL)
+    g_return_if_fail (g_date_compare (min_date, max_date) <= 0);
+
+  if (min_date && g_date_compare (date, min_date) < 0)
+    *date = *min_date;
+
+  if (max_date && g_date_compare (max_date, date) < 0)
+    *date = *max_date;
+}
+
+void
+g_date_order (GDate *date1,
+              GDate *date2)
+{
+  g_return_if_fail (g_date_valid (date1));
+  g_return_if_fail (g_date_valid (date2));
+
+  if (g_date_compare (date1, date2) > 0)
+    {
+      GDate tmp = *date1;
+      *date1 = *date2;
+      *date2 = tmp;
+    }
+}
+
+#ifdef G_OS_WIN32
+static gsize
+win32_strftime_helper (const GDate     *d,
+                      const gchar     *format,
+                      const struct tm *tm,
+                      gchar           *s,
+                      gsize            slen)
+{
+  SYSTEMTIME systemtime;
+  TIME_ZONE_INFORMATION tzinfo;
+  LCID lcid;
+  int n, k;
+  GArray *result;
+  const gchar *p;
+  gunichar c;
+  const wchar_t digits[] = L"0123456789";
+  gchar *convbuf;
+  glong convlen = 0;
+  gsize retval;
+
+  systemtime.wYear = tm->tm_year + 1900;
+  systemtime.wMonth = tm->tm_mon + 1;
+  systemtime.wDayOfWeek = tm->tm_wday;
+  systemtime.wDay = tm->tm_mday;
+  systemtime.wHour = tm->tm_hour;
+  systemtime.wMinute = tm->tm_min;
+  systemtime.wSecond = tm->tm_sec;
+  systemtime.wMilliseconds = 0;
+  
+  lcid = GetThreadLocale ();
+  result = g_array_sized_new (FALSE, FALSE, sizeof (wchar_t), MAX (128, strlen (format) * 2));
+
+  p = format;
+  while (*p)
+    {
+      c = g_utf8_get_char (p);
+      if (c == '%')
+       {
+         p = g_utf8_next_char (p);
+         if (!*p)
+           {
+             s[0] = '\0';
+             g_array_free (result, TRUE);
+
+             return 0;
+           }
+         
+         c = g_utf8_get_char (p);
+         if (c == 'E' || c == 'O')
+           {
+             /* Ignore modified conversion specifiers for now. */
+             p = g_utf8_next_char (p);
+             if (!*p)
+               {
+                 s[0] = '\0';
+                 g_array_free (result, TRUE);
+                 
+                 return 0;
+               }
+
+             c = g_utf8_get_char (p);
+           }
+
+         switch (c)
+           {
+           case 'a':
+             if (systemtime.wDayOfWeek == 0)
+               k = 6;
+             else
+               k = systemtime.wDayOfWeek - 1;
+             n = GetLocaleInfoW (lcid, LOCALE_SABBREVDAYNAME1+k, NULL, 0);
+             g_array_set_size (result, result->len + n);
+             GetLocaleInfoW (lcid, LOCALE_SABBREVDAYNAME1+k, ((wchar_t *) result->data) + result->len - n, n);
+             g_array_set_size (result, result->len - 1);
+             break;
+           case 'A':
+             if (systemtime.wDayOfWeek == 0)
+               k = 6;
+             else
+               k = systemtime.wDayOfWeek - 1;
+             n = GetLocaleInfoW (lcid, LOCALE_SDAYNAME1+k, NULL, 0);
+             g_array_set_size (result, result->len + n);
+             GetLocaleInfoW (lcid, LOCALE_SDAYNAME1+k, ((wchar_t *) result->data) + result->len - n, n);
+             g_array_set_size (result, result->len - 1);
+             break;
+           case 'b':
+           case 'h':
+             n = GetLocaleInfoW (lcid, LOCALE_SABBREVMONTHNAME1+systemtime.wMonth-1, NULL, 0);
+             g_array_set_size (result, result->len + n);
+             GetLocaleInfoW (lcid, LOCALE_SABBREVMONTHNAME1+systemtime.wMonth-1, ((wchar_t *) result->data) + result->len - n, n);
+             g_array_set_size (result, result->len - 1);
+             break;
+           case 'B':
+             n = GetLocaleInfoW (lcid, LOCALE_SMONTHNAME1+systemtime.wMonth-1, NULL, 0);
+             g_array_set_size (result, result->len + n);
+             GetLocaleInfoW (lcid, LOCALE_SMONTHNAME1+systemtime.wMonth-1, ((wchar_t *) result->data) + result->len - n, n);
+             g_array_set_size (result, result->len - 1);
+             break;
+           case 'c':
+             n = GetDateFormatW (lcid, 0, &systemtime, NULL, NULL, 0);
+             if (n > 0)
+               {
+                 g_array_set_size (result, result->len + n);
+                 GetDateFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n);
+                 g_array_set_size (result, result->len - 1);
+               }
+             g_array_append_vals (result, L" ", 1);
+             n = GetTimeFormatW (lcid, 0, &systemtime, NULL, NULL, 0);
+             if (n > 0)
+               {
+                 g_array_set_size (result, result->len + n);
+                 GetTimeFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n);
+                 g_array_set_size (result, result->len - 1);
+               }
+             break;
+           case 'C':
+             g_array_append_vals (result, digits + systemtime.wYear/1000, 1);
+             g_array_append_vals (result, digits + (systemtime.wYear/1000)%10, 1);
+             break;
+           case 'd':
+             g_array_append_vals (result, digits + systemtime.wDay/10, 1);
+             g_array_append_vals (result, digits + systemtime.wDay%10, 1);
+             break;
+           case 'D':
+             g_array_append_vals (result, digits + systemtime.wMonth/10, 1);
+             g_array_append_vals (result, digits + systemtime.wMonth%10, 1);
+             g_array_append_vals (result, L"/", 1);
+             g_array_append_vals (result, digits + systemtime.wDay/10, 1);
+             g_array_append_vals (result, digits + systemtime.wDay%10, 1);
+             g_array_append_vals (result, L"/", 1);
+             g_array_append_vals (result, digits + (systemtime.wYear/10)%10, 1);
+             g_array_append_vals (result, digits + systemtime.wYear%10, 1);
+             break;
+           case 'e':
+             if (systemtime.wDay >= 10)
+               g_array_append_vals (result, digits + systemtime.wDay/10, 1);
+             else
+               g_array_append_vals (result, L" ", 1);
+             g_array_append_vals (result, digits + systemtime.wDay%10, 1);
+             break;
+
+             /* A GDate has no time fields, so for now we can
+              * hardcode all time conversions into zeros (or 12 for
+              * %I). The alternative code snippets in the #else
+              * branches are here ready to be taken into use when
+              * needed by a g_strftime() or g_date_and_time_format()
+              * or whatever.
+              */
+           case 'H':
+#if 1
+             g_array_append_vals (result, L"00", 2);
+#else
+             g_array_append_vals (result, digits + systemtime.wHour/10, 1);
+             g_array_append_vals (result, digits + systemtime.wHour%10, 1);
+#endif
+             break;
+           case 'I':
+#if 1
+             g_array_append_vals (result, L"12", 2);
+#else
+             if (systemtime.wHour == 0)
+               g_array_append_vals (result, L"12", 2);
+             else
+               {
+                 g_array_append_vals (result, digits + (systemtime.wHour%12)/10, 1);
+                 g_array_append_vals (result, digits + (systemtime.wHour%12)%10, 1);
+               }
+#endif
+             break;
+           case  'j':
+             g_array_append_vals (result, digits + (tm->tm_yday+1)/100, 1);
+             g_array_append_vals (result, digits + ((tm->tm_yday+1)/10)%10, 1);
+             g_array_append_vals (result, digits + (tm->tm_yday+1)%10, 1);
+             break;
+           case 'm':
+             g_array_append_vals (result, digits + systemtime.wMonth/10, 1);
+             g_array_append_vals (result, digits + systemtime.wMonth%10, 1);
+             break;
+           case 'M':
+#if 1
+             g_array_append_vals (result, L"00", 2);
+#else
+             g_array_append_vals (result, digits + systemtime.wMinute/10, 1);
+             g_array_append_vals (result, digits + systemtime.wMinute%10, 1);
+#endif
+             break;
+           case 'n':
+             g_array_append_vals (result, L"\n", 1);
+             break;
+           case 'p':
+             n = GetTimeFormatW (lcid, 0, &systemtime, L"tt", NULL, 0);
+             if (n > 0)
+               {
+                 g_array_set_size (result, result->len + n);
+                 GetTimeFormatW (lcid, 0, &systemtime, L"tt", ((wchar_t *) result->data) + result->len - n, n);
+                 g_array_set_size (result, result->len - 1);
+               }
+             break;
+           case 'r':
+             /* This is a rather odd format. Hard to say what to do.
+              * Let's always use the POSIX %I:%M:%S %p
+              */
+#if 1
+             g_array_append_vals (result, L"12:00:00", 8);
+#else
+             if (systemtime.wHour == 0)
+               g_array_append_vals (result, L"12", 2);
+             else
+               {
+                 g_array_append_vals (result, digits + (systemtime.wHour%12)/10, 1);
+                 g_array_append_vals (result, digits + (systemtime.wHour%12)%10, 1);
+               }
+             g_array_append_vals (result, L":", 1);
+             g_array_append_vals (result, digits + systemtime.wMinute/10, 1);
+             g_array_append_vals (result, digits + systemtime.wMinute%10, 1);
+             g_array_append_vals (result, L":", 1);
+             g_array_append_vals (result, digits + systemtime.wSecond/10, 1);
+             g_array_append_vals (result, digits + systemtime.wSecond%10, 1);
+             g_array_append_vals (result, L" ", 1);
+#endif
+             n = GetTimeFormatW (lcid, 0, &systemtime, L"tt", NULL, 0);
+             if (n > 0)
+               {
+                 g_array_set_size (result, result->len + n);
+                 GetTimeFormatW (lcid, 0, &systemtime, L"tt", ((wchar_t *) result->data) + result->len - n, n);
+                 g_array_set_size (result, result->len - 1);
+               }
+             break;
+           case 'R':
+#if 1
+             g_array_append_vals (result, L"00:00", 5);
+#else
+             g_array_append_vals (result, digits + systemtime.wHour/10, 1);
+             g_array_append_vals (result, digits + systemtime.wHour%10, 1);
+             g_array_append_vals (result, L":", 1);
+             g_array_append_vals (result, digits + systemtime.wMinute/10, 1);
+             g_array_append_vals (result, digits + systemtime.wMinute%10, 1);
+#endif
+             break;
+           case 'S':
+#if 1
+             g_array_append_vals (result, L"00", 2);
+#else
+             g_array_append_vals (result, digits + systemtime.wSecond/10, 1);
+             g_array_append_vals (result, digits + systemtime.wSecond%10, 1);
+#endif
+             break;
+           case 't':
+             g_array_append_vals (result, L"\t", 1);
+             break;
+           case 'T':
+#if 1
+             g_array_append_vals (result, L"00:00:00", 8);
+#else
+             g_array_append_vals (result, digits + systemtime.wHour/10, 1);
+             g_array_append_vals (result, digits + systemtime.wHour%10, 1);
+             g_array_append_vals (result, L":", 1);
+             g_array_append_vals (result, digits + systemtime.wMinute/10, 1);
+             g_array_append_vals (result, digits + systemtime.wMinute%10, 1);
+             g_array_append_vals (result, L":", 1);
+             g_array_append_vals (result, digits + systemtime.wSecond/10, 1);
+             g_array_append_vals (result, digits + systemtime.wSecond%10, 1);
+#endif
+             break;
+           case 'u':
+             if (systemtime.wDayOfWeek == 0)
+               g_array_append_vals (result, L"7", 1);
+             else
+               g_array_append_vals (result, digits + systemtime.wDayOfWeek, 1);
+             break;
+           case 'U':
+             n = g_date_get_sunday_week_of_year (d);
+             g_array_append_vals (result, digits + n/10, 1);
+             g_array_append_vals (result, digits + n%10, 1);
+             break;
+           case 'V':
+             n = g_date_get_iso8601_week_of_year (d);
+             g_array_append_vals (result, digits + n/10, 1);
+             g_array_append_vals (result, digits + n%10, 1);
+             break;
+           case 'w':
+             g_array_append_vals (result, digits + systemtime.wDayOfWeek, 1);
+             break;
+           case 'W':
+             n = g_date_get_monday_week_of_year (d);
+             g_array_append_vals (result, digits + n/10, 1);
+             g_array_append_vals (result, digits + n%10, 1);
+             break;
+           case 'x':
+             n = GetDateFormatW (lcid, 0, &systemtime, NULL, NULL, 0);
+             if (n > 0)
+               {
+                 g_array_set_size (result, result->len + n);
+                 GetDateFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n);
+                 g_array_set_size (result, result->len - 1);
+               }
+             break;
+           case 'X':
+             n = GetTimeFormatW (lcid, 0, &systemtime, NULL, NULL, 0);
+             if (n > 0)
+               {
+                 g_array_set_size (result, result->len + n);
+                 GetTimeFormatW (lcid, 0, &systemtime, NULL, ((wchar_t *) result->data) + result->len - n, n);
+                 g_array_set_size (result, result->len - 1);
+               }
+             break;
+           case 'y':
+             g_array_append_vals (result, digits + (systemtime.wYear/10)%10, 1);
+             g_array_append_vals (result, digits + systemtime.wYear%10, 1);
+             break;
+           case 'Y':
+             g_array_append_vals (result, digits + systemtime.wYear/1000, 1);
+             g_array_append_vals (result, digits + (systemtime.wYear/100)%10, 1);
+             g_array_append_vals (result, digits + (systemtime.wYear/10)%10, 1);
+             g_array_append_vals (result, digits + systemtime.wYear%10, 1);
+             break;
+           case 'Z':
+             n = GetTimeZoneInformation (&tzinfo);
+             if (n == TIME_ZONE_ID_UNKNOWN)
+               ;
+             else if (n == TIME_ZONE_ID_STANDARD)
+               g_array_append_vals (result, tzinfo.StandardName, wcslen (tzinfo.StandardName));
+             else if (n == TIME_ZONE_ID_DAYLIGHT)
+               g_array_append_vals (result, tzinfo.DaylightName, wcslen (tzinfo.DaylightName));
+             break;
+           case '%':
+             g_array_append_vals (result, L"%", 1);
+             break;
+           }      
+       } 
+      else if (c <= 0xFFFF)
+       {
+         wchar_t wc = c;
+         g_array_append_vals (result, &wc, 1);
+       }
+      else
+       {
+         glong nwc;
+         wchar_t *ws;
+
+         ws = g_ucs4_to_utf16 (&c, 1, NULL, &nwc, NULL);
+         g_array_append_vals (result, ws, nwc);
+         g_free (ws);
+       }
+      p = g_utf8_next_char (p);
+    }
+  
+  convbuf = g_utf16_to_utf8 ((wchar_t *) result->data, result->len, NULL, &convlen, NULL);
+  g_array_free (result, TRUE);
+
+  if (!convbuf)
+    {
+      s[0] = '\0';
+      return 0;
+    }
+  
+  if (slen <= convlen)
+    {
+      /* Ensure only whole characters are copied into the buffer. */
+      gchar *end = g_utf8_find_prev_char (convbuf, convbuf + slen);
+      g_assert (end != NULL);
+      convlen = end - convbuf;
+
+      /* Return 0 because the buffer isn't large enough. */
+      retval = 0;
+    }
+  else
+    retval = convlen;
+
+  memcpy (s, convbuf, convlen);
+  s[convlen] = '\0';
+  g_free (convbuf);
+
+  return retval;
+}
+
+#endif
+
+gsize     
+g_date_strftime (gchar       *s, 
+                 gsize        slen, 
+                 const gchar *format, 
+                 const GDate *d)
+{
+  struct tm tm;
+#ifndef G_OS_WIN32
+  gsize locale_format_len = 0;
+  gchar *locale_format;
+  gsize tmplen;
+  gchar *tmpbuf;
+  gsize tmpbufsize;
+  gsize convlen = 0;
+  gchar *convbuf;
+  GError *error = NULL;
+  gsize retval;
+#endif
+
+  g_return_val_if_fail (g_date_valid (d), 0);
+  g_return_val_if_fail (slen > 0, 0); 
+  g_return_val_if_fail (format != NULL, 0);
+  g_return_val_if_fail (s != NULL, 0);
+
+  g_date_to_struct_tm (d, &tm);
+
+#ifdef G_OS_WIN32
+  if (!g_utf8_validate (format, -1, NULL))
+    {
+      s[0] = '\0';
+      return 0;
+    }
+  return win32_strftime_helper (d, format, &tm, s, slen);
+#else
+
+  locale_format = g_locale_from_utf8 (format, -1, NULL, &locale_format_len, &error);
+
+  if (error)
+    {
+      g_warning (G_STRLOC "Error converting format to locale encoding: %s\n", error->message);
+      g_error_free (error);
+
+      s[0] = '\0';
+      return 0;
+    }
+
+  tmpbufsize = MAX (128, locale_format_len * 2);
+  while (TRUE)
+    {
+      tmpbuf = g_malloc (tmpbufsize);
+
+      /* Set the first byte to something other than '\0', to be able to
+       * recognize whether strftime actually failed or just returned "".
+       */
+      tmpbuf[0] = '\1';
+      tmplen = strftime (tmpbuf, tmpbufsize, locale_format, &tm);
+
+      if (tmplen == 0 && tmpbuf[0] != '\0')
+        {
+          g_free (tmpbuf);
+          tmpbufsize *= 2;
+
+          if (tmpbufsize > 65536)
+            {
+              g_warning (G_STRLOC "Maximum buffer size for g_date_strftime exceeded: giving up\n");
+              g_free (locale_format);
+
+              s[0] = '\0';
+              return 0;
+            }
+        }
+      else
+        break;
+    }
+  g_free (locale_format);
+
+  convbuf = g_locale_to_utf8 (tmpbuf, tmplen, NULL, &convlen, &error);
+  g_free (tmpbuf);
+
+  if (error)
+    {
+      g_warning (G_STRLOC "Error converting results of strftime to UTF-8: %s\n", error->message);
+      g_error_free (error);
+
+      s[0] = '\0';
+      return 0;
+    }
+
+  if (slen <= convlen)
+    {
+      /* Ensure only whole characters are copied into the buffer.
+       */
+      gchar *end = g_utf8_find_prev_char (convbuf, convbuf + slen);
+      g_assert (end != NULL);
+      convlen = end - convbuf;
+
+      /* Return 0 because the buffer isn't large enough.
+       */
+      retval = 0;
+    }
+  else
+    retval = convlen;
+
+  memcpy (s, convbuf, convlen);
+  s[convlen] = '\0';
+  g_free (convbuf);
+
+  return retval;
+#endif
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gdate.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gdate.h
new file mode 100644 (file)
index 0000000..cb1f566
--- /dev/null
@@ -0,0 +1,263 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_DATE_H__
+#define __G_DATE_H__
+
+#include <time.h>
+
+#include <glib/gtypes.h>
+#include <glib/gquark.h>
+
+G_BEGIN_DECLS
+
+/* GDate
+ *
+ * Date calculations (not time for now, to be resolved). These are a
+ * mutant combination of Steffen Beyer's DateCalc routines
+ * (http://www.perl.com/CPAN/authors/id/STBEY/) and Jon Trowbridge's
+ * date routines (written for in-house software).  Written by Havoc
+ * Pennington <hp@pobox.com>
+ */
+
+typedef gint32  GTime;
+typedef guint16 GDateYear;
+typedef guint8  GDateDay;   /* day of the month */
+typedef struct _GDate GDate;
+
+/* enum used to specify order of appearance in parsed date strings */
+typedef enum
+{
+  G_DATE_DAY   = 0,
+  G_DATE_MONTH = 1,
+  G_DATE_YEAR  = 2
+} GDateDMY;
+
+/* actual week and month values */
+typedef enum
+{
+  G_DATE_BAD_WEEKDAY  = 0,
+  G_DATE_MONDAY       = 1,
+  G_DATE_TUESDAY      = 2,
+  G_DATE_WEDNESDAY    = 3,
+  G_DATE_THURSDAY     = 4,
+  G_DATE_FRIDAY       = 5,
+  G_DATE_SATURDAY     = 6,
+  G_DATE_SUNDAY       = 7
+} GDateWeekday;
+typedef enum
+{
+  G_DATE_BAD_MONTH = 0,
+  G_DATE_JANUARY   = 1,
+  G_DATE_FEBRUARY  = 2,
+  G_DATE_MARCH     = 3,
+  G_DATE_APRIL     = 4,
+  G_DATE_MAY       = 5,
+  G_DATE_JUNE      = 6,
+  G_DATE_JULY      = 7,
+  G_DATE_AUGUST    = 8,
+  G_DATE_SEPTEMBER = 9,
+  G_DATE_OCTOBER   = 10,
+  G_DATE_NOVEMBER  = 11,
+  G_DATE_DECEMBER  = 12
+} GDateMonth;
+
+#define G_DATE_BAD_JULIAN 0U
+#define G_DATE_BAD_DAY    0U
+#define G_DATE_BAD_YEAR   0U
+
+/* Note: directly manipulating structs is generally a bad idea, but
+ * in this case it's an *incredibly* bad idea, because all or part
+ * of this struct can be invalid at any given time. Use the functions,
+ * or you will get hosed, I promise.
+ */
+struct _GDate
+{
+  guint julian_days : 32; /* julian days representation - we use a
+                           *  bitfield hoping that 64 bit platforms
+                           *  will pack this whole struct in one big
+                           *  int
+                           */
+
+  guint julian : 1;    /* julian is valid */
+  guint dmy    : 1;    /* dmy is valid */
+
+  /* DMY representation */
+  guint day    : 6;
+  guint month  : 4;
+  guint year   : 16;
+};
+
+/* g_date_new() returns an invalid date, you then have to _set() stuff
+ * to get a usable object. You can also allocate a GDate statically,
+ * then call g_date_clear() to initialize.
+ */
+GDate*       g_date_new                   (void);
+GDate*       g_date_new_dmy               (GDateDay     day,
+                                           GDateMonth   month,
+                                           GDateYear    year);
+GDate*       g_date_new_julian            (guint32      julian_day);
+void         g_date_free                  (GDate       *date);
+
+/* check g_date_valid() after doing an operation that might fail, like
+ * _parse.  Almost all g_date operations are undefined on invalid
+ * dates (the exceptions are the mutators, since you need those to
+ * return to validity).
+ */
+gboolean     g_date_valid                 (const GDate *date);
+gboolean     g_date_valid_day             (GDateDay     day) G_GNUC_CONST;
+gboolean     g_date_valid_month           (GDateMonth month) G_GNUC_CONST;
+gboolean     g_date_valid_year            (GDateYear  year) G_GNUC_CONST;
+gboolean     g_date_valid_weekday         (GDateWeekday weekday) G_GNUC_CONST;
+gboolean     g_date_valid_julian          (guint32 julian_date) G_GNUC_CONST;
+gboolean     g_date_valid_dmy             (GDateDay     day,
+                                           GDateMonth   month,
+                                           GDateYear    year) G_GNUC_CONST;
+
+GDateWeekday g_date_get_weekday           (const GDate *date);
+GDateMonth   g_date_get_month             (const GDate *date);
+GDateYear    g_date_get_year              (const GDate *date);
+GDateDay     g_date_get_day               (const GDate *date);
+guint32      g_date_get_julian            (const GDate *date);
+guint        g_date_get_day_of_year       (const GDate *date);
+/* First monday/sunday is the start of week 1; if we haven't reached
+ * that day, return 0. These are not ISO weeks of the year; that
+ * routine needs to be added.
+ * these functions return the number of weeks, starting on the
+ * corrsponding day
+ */
+guint        g_date_get_monday_week_of_year (const GDate *date);
+guint        g_date_get_sunday_week_of_year (const GDate *date);
+guint        g_date_get_iso8601_week_of_year (const GDate *date);
+
+/* If you create a static date struct you need to clear it to get it
+ * in a sane state before use. You can clear a whole array at
+ * once with the ndates argument.
+ */
+void         g_date_clear                 (GDate       *date,
+                                           guint        n_dates);
+
+/* The parse routine is meant for dates typed in by a user, so it
+ * permits many formats but tries to catch common typos. If your data
+ * needs to be strictly validated, it is not an appropriate function.
+ */
+void         g_date_set_parse             (GDate       *date,
+                                           const gchar *str);
+void         g_date_set_time_t            (GDate       *date,
+                                          time_t       timet);
+void         g_date_set_time_val          (GDate       *date,
+                                          GTimeVal    *timeval);
+#ifndef G_DISABLE_DEPRECATED
+void         g_date_set_time              (GDate       *date,
+                                           GTime        time_);
+#endif
+void         g_date_set_month             (GDate       *date,
+                                           GDateMonth   month);
+void         g_date_set_day               (GDate       *date,
+                                           GDateDay     day);
+void         g_date_set_year              (GDate       *date,
+                                           GDateYear    year);
+void         g_date_set_dmy               (GDate       *date,
+                                           GDateDay     day,
+                                           GDateMonth   month,
+                                           GDateYear    y);
+void         g_date_set_julian            (GDate       *date,
+                                           guint32      julian_date);
+gboolean     g_date_is_first_of_month     (const GDate *date);
+gboolean     g_date_is_last_of_month      (const GDate *date);
+
+/* To go forward by some number of weeks just go forward weeks*7 days */
+void         g_date_add_days              (GDate       *date,
+                                           guint        n_days);
+void         g_date_subtract_days         (GDate       *date,
+                                           guint        n_days);
+
+/* If you add/sub months while day > 28, the day might change */
+void         g_date_add_months            (GDate       *date,
+                                           guint        n_months);
+void         g_date_subtract_months       (GDate       *date,
+                                           guint        n_months);
+
+/* If it's feb 29, changing years can move you to the 28th */
+void         g_date_add_years             (GDate       *date,
+                                           guint        n_years);
+void         g_date_subtract_years        (GDate       *date,
+                                           guint        n_years);
+gboolean     g_date_is_leap_year          (GDateYear    year) G_GNUC_CONST;
+guint8       g_date_get_days_in_month     (GDateMonth   month,
+                                           GDateYear    year) G_GNUC_CONST;
+guint8       g_date_get_monday_weeks_in_year  (GDateYear    year) G_GNUC_CONST;
+guint8       g_date_get_sunday_weeks_in_year  (GDateYear    year) G_GNUC_CONST;
+
+/* Returns the number of days between the two dates.  If date2 comes
+   before date1, a negative value is return. */
+gint         g_date_days_between          (const GDate *date1,
+                                          const GDate *date2);
+
+/* qsort-friendly (with a cast...) */
+gint         g_date_compare               (const GDate *lhs,
+                                           const GDate *rhs);
+void         g_date_to_struct_tm          (const GDate *date,
+                                           struct tm   *tm);
+
+void         g_date_clamp                 (GDate *date,
+                                          const GDate *min_date,
+                                          const GDate *max_date);
+
+/* Swap date1 and date2's values if date1 > date2. */
+void         g_date_order                 (GDate *date1, GDate *date2);
+
+/* Just like strftime() except you can only use date-related formats.
+ *   Using a time format is undefined.
+ */
+gsize        g_date_strftime              (gchar       *s,
+                                           gsize        slen,
+                                           const gchar *format,
+                                           const GDate *date);
+
+#ifndef G_DISABLE_DEPRECATED
+
+#define g_date_weekday                         g_date_get_weekday
+#define g_date_month                   g_date_get_month
+#define g_date_year                    g_date_get_year
+#define g_date_day                     g_date_get_day
+#define g_date_julian                  g_date_get_julian
+#define g_date_day_of_year             g_date_get_day_of_year
+#define g_date_monday_week_of_year     g_date_get_monday_week_of_year
+#define g_date_sunday_week_of_year     g_date_get_sunday_week_of_year
+#define g_date_days_in_month           g_date_get_days_in_month
+#define g_date_monday_weeks_in_year    g_date_get_monday_weeks_in_year
+#define g_date_sunday_weeks_in_year    g_date_get_sunday_weeks_in_year
+
+#endif /* G_DISABLE_DEPRECATED */
+
+G_END_DECLS
+
+#endif /* __G_DATE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gdatetime.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gdatetime.c
new file mode 100644 (file)
index 0000000..3509cec
--- /dev/null
@@ -0,0 +1,2426 @@
+/* gdatetime.c
+ *
+ * Copyright (C) 2009-2010 Christian Hergert <chris@dronelabs.com>
+ * Copyright (C) 2010 Thiago Santos <thiago.sousa.santos@collabora.co.uk>
+ * Copyright (C) 2010 Emmanuele Bassi <ebassi@linux.intel.com>
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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
+ * licence, or (at your option) any later version.
+ *
+ * This 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 St, Fifth Floor, Boston, MA  02110-1301
+ * USA.
+ *
+ * Authors: Christian Hergert <chris@dronelabs.com>
+ *          Thiago Santos <thiago.sousa.santos@collabora.co.uk>
+ *          Emmanuele Bassi <ebassi@linux.intel.com>
+ *          Ryan Lortie <desrt@desrt.ca>
+ */
+
+/* Algorithms within this file are based on the Calendar FAQ by
+ * Claus Tondering.  It can be found at
+ * http://www.tondering.dk/claus/cal/calendar29.txt
+ *
+ * Copyright and disclaimer
+ * ------------------------
+ *   This document is Copyright (C) 2008 by Claus Tondering.
+ *   E-mail: claus@tondering.dk. (Please include the word
+ *   "calendar" in the subject line.)
+ *   The document may be freely distributed, provided this
+ *   copyright notice is included and no money is charged for
+ *   the document.
+ *
+ *   This document is provided "as is". No warranties are made as
+ *   to its correctness.
+ */
+
+/* Prologue {{{1 */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef G_OS_WIN32
+#include <sys/time.h>
+#include <time.h>
+#endif /* !G_OS_WIN32 */
+
+#include "gdatetime.h"
+
+#include "gatomic.h"
+#include "gfileutils.h"
+#include "ghash.h"
+#include "gmain.h"
+#include "gmappedfile.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "gthread.h"
+#include "gtimezoneprivate.h"
+
+#include "glibintl.h"
+
+/**
+ * SECTION:date-time
+ * @title: GDateTime
+ * @short_description: A structure representing Date and Time
+ * @see_also: #GTimeZone
+ *
+ * #GDateTime is a structure that combines a Gregorian date and time
+ * into a single structure.  It provides many conversion and methods to
+ * manipulate dates and times.  Time precision is provided down to
+ * microseconds and the time can range (proleptically) from 0001-01-01
+ * 00:00:00 to 9999-12-31 23:59:59.999999.  #GDateTime follows POSIX
+ * time in the sense that it is oblivious to leap seconds.
+ *
+ * #GDateTime is an immutable object; once it has been created it cannot
+ * be modified further.  All modifiers will create a new #GDateTime.
+ * Nearly all such functions can fail due to the date or time going out
+ * of range, in which case %NULL will be returned.
+ *
+ * #GDateTime is reference counted: the reference count is increased by calling
+ * g_date_time_ref() and decreased by calling g_date_time_unref(). When the
+ * reference count drops to 0, the resources allocated by the #GDateTime
+ * structure are released.
+ *
+ * Many parts of the API may produce non-obvious results.  As an
+ * example, adding two months to January 31st will yield March 31st
+ * whereas adding one month and then one month again will yield either
+ * March 28th or March 29th.  Also note that adding 24 hours is not
+ * always the same as adding one day (since days containing daylight
+ * savings time transitions are either 23 or 25 hours in length).
+ *
+ * #GDateTime is available since GLib 2.26.
+ */
+
+struct _GDateTime
+{
+  /* 1 is 0001-01-01 in Proleptic Gregorian */
+  gint32 days;
+
+  /* Microsecond timekeeping within Day */
+  guint64 usec;
+
+  /* TimeZone information */
+  GTimeZone *tz;
+  gint interval;
+
+  volatile gint ref_count;
+};
+
+/* Time conversion {{{1 */
+
+#define UNIX_EPOCH_START     719163
+#define INSTANT_TO_UNIX(instant) \
+  ((instant)/USEC_PER_SECOND - UNIX_EPOCH_START * SEC_PER_DAY)
+#define UNIX_TO_INSTANT(unix) \
+  (((unix) + UNIX_EPOCH_START * SEC_PER_DAY) * USEC_PER_SECOND)
+
+#define DAYS_IN_4YEARS    1461    /* days in 4 years */
+#define DAYS_IN_100YEARS  36524   /* days in 100 years */
+#define DAYS_IN_400YEARS  146097  /* days in 400 years  */
+
+#define USEC_PER_SECOND      (G_GINT64_CONSTANT (1000000))
+#define USEC_PER_MINUTE      (G_GINT64_CONSTANT (60000000))
+#define USEC_PER_HOUR        (G_GINT64_CONSTANT (3600000000))
+#define USEC_PER_MILLISECOND (G_GINT64_CONSTANT (1000))
+#define USEC_PER_DAY         (G_GINT64_CONSTANT (86400000000))
+#define SEC_PER_DAY          (G_GINT64_CONSTANT (86400))
+
+#define GREGORIAN_LEAP(y)    ((((y) % 4) == 0) && (!((((y) % 100) == 0) && (((y) % 400) != 0))))
+#define JULIAN_YEAR(d)       ((d)->julian / 365.25)
+#define DAYS_PER_PERIOD      (G_GINT64_CONSTANT (2914695))
+
+#define GET_AMPM(d,l)         ((g_date_time_get_hour (d) < 12)  \
+                                       /* Translators: 'before midday' indicator */ \
+                                ? (l ? C_("GDateTime", "am") \
+                                       /* Translators: 'before midday' indicator */ \
+                                     : C_("GDateTime", "AM")) \
+                                  /* Translators: 'after midday' indicator */ \
+                                : (l ? C_("GDateTime", "pm") \
+                                  /* Translators: 'after midday' indicator */ \
+                                     : C_("GDateTime", "PM")))
+
+#define WEEKDAY_ABBR(d)       (get_weekday_name_abbr (g_date_time_get_day_of_week (datetime)))
+#define WEEKDAY_FULL(d)       (get_weekday_name (g_date_time_get_day_of_week (datetime)))
+
+#define MONTH_ABBR(d)         (get_month_name_abbr (g_date_time_get_month (datetime)))
+#define MONTH_FULL(d)         (get_month_name (g_date_time_get_month (datetime)))
+
+/* Translators: this is the preferred format for expressing the date */
+#define GET_PREFERRED_DATE(d) (g_date_time_format ((d), C_("GDateTime", "%m/%d/%y")))
+
+/* Translators: this is the preferred format for expressing the time */
+#define GET_PREFERRED_TIME(d) (g_date_time_format ((d), C_("GDateTime", "%H:%M:%S")))
+
+#define SECS_PER_MINUTE (60)
+#define SECS_PER_HOUR   (60 * SECS_PER_MINUTE)
+#define SECS_PER_DAY    (24 * SECS_PER_HOUR)
+#define SECS_PER_YEAR   (365 * SECS_PER_DAY)
+#define SECS_PER_JULIAN (DAYS_PER_PERIOD * SECS_PER_DAY)
+
+static const guint16 days_in_months[2][13] =
+{
+  { 0, 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 },
+  { 0, 31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }
+};
+
+static const guint16 days_in_year[2][13] =
+{
+  {  0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334, 365 },
+  {  0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335, 366 }
+};
+
+static const gchar *
+get_month_name (gint month)
+{
+  switch (month)
+    {
+    case 1:
+      return C_("full month name", "January");
+    case 2:
+      return C_("full month name", "February");
+    case 3:
+      return C_("full month name", "March");
+    case 4:
+      return C_("full month name", "April");
+    case 5:
+      return C_("full month name", "May");
+    case 6:
+      return C_("full month name", "June");
+    case 7:
+      return C_("full month name", "July");
+    case 8:
+      return C_("full month name", "August");
+    case 9:
+      return C_("full month name", "September");
+    case 10:
+      return C_("full month name", "October");
+    case 11:
+      return C_("full month name", "November");
+    case 12:
+      return C_("full month name", "December");
+
+    default:
+      g_warning ("Invalid month number %d", month);
+    }
+
+  return NULL;
+}
+
+static const gchar *
+get_month_name_abbr (gint month)
+{
+  switch (month)
+    {
+    case 1:
+      return C_("abbreviated month name", "Jan");
+    case 2:
+      return C_("abbreviated month name", "Feb");
+    case 3:
+      return C_("abbreviated month name", "Mar");
+    case 4:
+      return C_("abbreviated month name", "Apr");
+    case 5:
+      return C_("abbreviated month name", "May");
+    case 6:
+      return C_("abbreviated month name", "Jun");
+    case 7:
+      return C_("abbreviated month name", "Jul");
+    case 8:
+      return C_("abbreviated month name", "Aug");
+    case 9:
+      return C_("abbreviated month name", "Sep");
+    case 10:
+      return C_("abbreviated month name", "Oct");
+    case 11:
+      return C_("abbreviated month name", "Nov");
+    case 12:
+      return C_("abbreviated month name", "Dec");
+
+    default:
+      g_warning ("Invalid month number %d", month);
+    }
+
+  return NULL;
+}
+
+static const gchar *
+get_weekday_name (gint day)
+{
+  switch (day)
+    {
+    case 1:
+      return C_("full weekday name", "Monday");
+    case 2:
+      return C_("full weekday name", "Tuesday");
+    case 3:
+      return C_("full weekday name", "Wednesday");
+    case 4:
+      return C_("full weekday name", "Thursday");
+    case 5:
+      return C_("full weekday name", "Friday");
+    case 6:
+      return C_("full weekday name", "Saturday");
+    case 7:
+      return C_("full weekday name", "Sunday");
+
+    default:
+      g_warning ("Invalid week day number %d", day);
+    }
+
+  return NULL;
+}
+
+static const gchar *
+get_weekday_name_abbr (gint day)
+{
+  switch (day)
+    {
+    case 1:
+      return C_("abbreviated weekday name", "Mon");
+    case 2:
+      return C_("abbreviated weekday name", "Tue");
+    case 3:
+      return C_("abbreviated weekday name", "Wed");
+    case 4:
+      return C_("abbreviated weekday name", "Thu");
+    case 5:
+      return C_("abbreviated weekday name", "Fri");
+    case 6:
+      return C_("abbreviated weekday name", "Sat");
+    case 7:
+      return C_("abbreviated weekday name", "Sun");
+
+    default:
+      g_warning ("Invalid week day number %d", day);
+    }
+
+  return NULL;
+}
+
+static inline gint
+ymd_to_days (gint year,
+             gint month,
+             gint day)
+{
+  gint64 days;
+
+  days = (year - 1) * 365 + ((year - 1) / 4) - ((year - 1) / 100)
+      + ((year - 1) / 400);
+
+  days += days_in_year[0][month - 1];
+  if (GREGORIAN_LEAP (year) && month > 2)
+    day++;
+
+  days += day;
+
+  return days;
+}
+
+static void
+g_date_time_get_week_number (GDateTime *datetime,
+                             gint      *week_number,
+                             gint      *day_of_week,
+                             gint      *day_of_year)
+{
+  gint a, b, c, d, e, f, g, n, s, month, day, year;
+
+  g_date_time_get_ymd (datetime, &year, &month, &day);
+
+  if (month <= 2)
+    {
+      a = g_date_time_get_year (datetime) - 1;
+      b = (a / 4) - (a / 100) + (a / 400);
+      c = ((a - 1) / 4) - ((a - 1) / 100) + ((a - 1) / 400);
+      s = b - c;
+      e = 0;
+      f = day - 1 + (31 * (month - 1));
+    }
+  else
+    {
+      a = year;
+      b = (a / 4) - (a / 100) + (a / 400);
+      c = ((a - 1) / 4) - ((a - 1) / 100) + ((a - 1) / 400);
+      s = b - c;
+      e = s + 1;
+      f = day + (((153 * (month - 3)) + 2) / 5) + 58 + s;
+    }
+
+  g = (a + b) % 7;
+  d = (f + g - e) % 7;
+  n = f + 3 - d;
+
+  if (week_number)
+    {
+      if (n < 0)
+        *week_number = 53 - ((g - s) / 5);
+      else if (n > 364 + s)
+        *week_number = 1;
+      else
+        *week_number = (n / 7) + 1;
+    }
+
+  if (day_of_week)
+    *day_of_week = d + 1;
+
+  if (day_of_year)
+    *day_of_year = f + 1;
+}
+
+/* Lifecycle {{{1 */
+
+static GDateTime *
+g_date_time_alloc (GTimeZone *tz)
+{
+  GDateTime *datetime;
+
+  datetime = g_slice_new0 (GDateTime);
+  datetime->tz = g_time_zone_ref (tz);
+  datetime->ref_count = 1;
+
+  return datetime;
+}
+
+/**
+ * g_date_time_ref:
+ * @datetime: a #GDateTime
+ *
+ * Atomically increments the reference count of @datetime by one.
+ *
+ * Return value: the #GDateTime with the reference count increased
+ *
+ * Since: 2.26
+ */
+GDateTime *
+g_date_time_ref (GDateTime *datetime)
+{
+  g_return_val_if_fail (datetime != NULL, NULL);
+  g_return_val_if_fail (datetime->ref_count > 0, NULL);
+
+  g_atomic_int_inc (&datetime->ref_count);
+
+  return datetime;
+}
+
+/**
+ * g_date_time_unref:
+ * @datetime: a #GDateTime
+ *
+ * Atomically decrements the reference count of @datetime by one.
+ *
+ * When the reference count reaches zero, the resources allocated by
+ * @datetime are freed
+ *
+ * Since: 2.26
+ */
+void
+g_date_time_unref (GDateTime *datetime)
+{
+  g_return_if_fail (datetime != NULL);
+  g_return_if_fail (datetime->ref_count > 0);
+
+  if (g_atomic_int_dec_and_test (&datetime->ref_count))
+    {
+      g_time_zone_unref (datetime->tz);
+      g_slice_free (GDateTime, datetime);
+    }
+}
+
+/* Internal state transformers {{{1 */
+/*< internal >
+ * g_date_time_to_instant:
+ * @datetime: a #GDateTime
+ *
+ * Convert a @datetime into an instant.
+ *
+ * An instant is a number that uniquely describes a particular
+ * microsecond in time, taking time zone considerations into account.
+ * (ie: "03:00 -0400" is the same instant as "02:00 -0500").
+ *
+ * An instant is always positive but we use a signed return value to
+ * avoid troubles with C.
+ */
+static gint64
+g_date_time_to_instant (GDateTime *datetime)
+{
+  gint64 offset;
+
+  offset = g_time_zone_get_offset (datetime->tz, datetime->interval);
+  offset *= USEC_PER_SECOND;
+
+  return datetime->days * USEC_PER_DAY + datetime->usec - offset;
+}
+
+/*< internal >
+ * g_date_time_from_instant:
+ * @tz: a #GTimeZone
+ * @instant: a instant in time
+ *
+ * Creates a #GDateTime from a time zone and an instant.
+ *
+ * This might fail if the time ends up being out of range.
+ */
+static GDateTime *
+g_date_time_from_instant (GTimeZone *tz,
+                          gint64     instant)
+{
+  GDateTime *datetime;
+  gint64 offset;
+
+  if (instant < 0 || instant > 1000000000000000000)
+    return NULL;
+
+  datetime = g_date_time_alloc (tz);
+  datetime->interval = g_time_zone_find_interval (tz,
+                                                  G_TIME_TYPE_UNIVERSAL,
+                                                  INSTANT_TO_UNIX (instant));
+  offset = g_time_zone_get_offset (datetime->tz, datetime->interval);
+  offset *= USEC_PER_SECOND;
+
+  instant += offset;
+
+  datetime->days = instant / USEC_PER_DAY;
+  datetime->usec = instant % USEC_PER_DAY;
+
+  if (datetime->days < 1 || 3652059 < datetime->days)
+    {
+      g_date_time_unref (datetime);
+      datetime = NULL;
+    }
+
+  return datetime;
+}
+
+
+/*< internal >
+ * g_date_time_deal_with_date_change:
+ * @datetime: a #GDateTime
+ *
+ * This function should be called whenever the date changes by adding
+ * days, months or years.  It does three things.
+ *
+ * First, we ensure that the date falls between 0001-01-01 and
+ * 9999-12-31 and return %FALSE if it does not.
+ *
+ * Next we update the ->interval field.
+ *
+ * Finally, we ensure that the resulting date and time pair exists (by
+ * ensuring that our time zone has an interval containing it) and
+ * adjusting as required.  For example, if we have the time 02:30:00 on
+ * March 13 2010 in Toronto and we add 1 day to it, we would end up with
+ * 2:30am on March 14th, which doesn't exist.  In that case, we bump the
+ * time up to 3:00am.
+ */
+static gboolean
+g_date_time_deal_with_date_change (GDateTime *datetime)
+{
+  GTimeType was_dst;
+  gint64 full_time;
+  gint64 usec;
+
+  if (datetime->days < 1 || datetime->days > 3652059)
+    return FALSE;
+
+  was_dst = g_time_zone_is_dst (datetime->tz, datetime->interval);
+
+  full_time = datetime->days * USEC_PER_DAY + datetime->usec;
+
+
+  usec = full_time % USEC_PER_SECOND;
+  full_time /= USEC_PER_SECOND;
+  full_time -= UNIX_EPOCH_START * SEC_PER_DAY;
+
+  datetime->interval = g_time_zone_adjust_time (datetime->tz,
+                                                was_dst,
+                                                &full_time);
+  full_time += UNIX_EPOCH_START * SEC_PER_DAY;
+  full_time *= USEC_PER_SECOND;
+  full_time += usec;
+
+  datetime->days = full_time / USEC_PER_DAY;
+  datetime->usec = full_time % USEC_PER_DAY;
+
+  /* maybe daylight time caused us to shift to a different day,
+   * but it definitely didn't push us into a different year */
+  return TRUE;
+}
+
+static GDateTime *
+g_date_time_replace_days (GDateTime *datetime,
+                          gint       days)
+{
+  GDateTime *new;
+
+  new = g_date_time_alloc (datetime->tz);
+  new->interval = datetime->interval;
+  new->usec = datetime->usec;
+  new->days = days;
+
+  if (!g_date_time_deal_with_date_change (new))
+    {
+      g_date_time_unref (new);
+      new = NULL;
+    }
+
+  return new;
+}
+
+/* now/unix/timeval Constructors {{{1 */
+
+/*< internal >
+ * g_date_time_new_from_timeval:
+ * @tz: a #GTimeZone
+ * @tv: a #GTimeVal
+ *
+ * Creates a #GDateTime corresponding to the given #GTimeVal @tv in the
+ * given time zone @tz.
+ *
+ * The time contained in a #GTimeVal is always stored in the form of
+ * seconds elapsed since 1970-01-01 00:00:00 UTC, regardless of the
+ * given time zone.
+ *
+ * This call can fail (returning %NULL) if @tv represents a time outside
+ * of the supported range of #GDateTime.
+ *
+ * You should release the return value by calling g_date_time_unref()
+ * when you are done with it.
+ *
+ * Returns: a new #GDateTime, or %NULL
+ *
+ * Since: 2.26
+ **/
+static GDateTime *
+g_date_time_new_from_timeval (GTimeZone      *tz,
+                              const GTimeVal *tv)
+{
+  return g_date_time_from_instant (tz, tv->tv_usec +
+                                   UNIX_TO_INSTANT (tv->tv_sec));
+}
+
+/*< internal >
+ * g_date_time_new_from_unix:
+ * @tz: a #GTimeZone
+ * @t: the Unix time
+ *
+ * Creates a #GDateTime corresponding to the given Unix time @t in the
+ * given time zone @tz.
+ *
+ * Unix time is the number of seconds that have elapsed since 1970-01-01
+ * 00:00:00 UTC, regardless of the time zone given.
+ *
+ * This call can fail (returning %NULL) if @t represents a time outside
+ * of the supported range of #GDateTime.
+ *
+ * You should release the return value by calling g_date_time_unref()
+ * when you are done with it.
+ *
+ * Returns: a new #GDateTime, or %NULL
+ *
+ * Since: 2.26
+ **/
+static GDateTime *
+g_date_time_new_from_unix (GTimeZone *tz,
+                           gint64     secs)
+{
+  return g_date_time_from_instant (tz, UNIX_TO_INSTANT (secs));
+}
+
+/**
+ * g_date_time_new_now:
+ * @tz: a #GTimeZone
+ *
+ * Creates a #GDateTime corresponding to this exact instant in the given
+ * time zone @tz.  The time is as accurate as the system allows, to a
+ * maximum accuracy of 1 microsecond.
+ *
+ * This function will always succeed unless the system clock is set to
+ * truly insane values (or unless GLib is still being used after the
+ * year 9999).
+ *
+ * You should release the return value by calling g_date_time_unref()
+ * when you are done with it.
+ *
+ * Returns: a new #GDateTime, or %NULL
+ *
+ * Since: 2.26
+ **/
+GDateTime *
+g_date_time_new_now (GTimeZone *tz)
+{
+  GTimeVal tv;
+
+  g_get_current_time (&tv);
+
+  return g_date_time_new_from_timeval (tz, &tv);
+}
+
+/**
+ * g_date_time_new_now_local:
+ *
+ * Creates a #GDateTime corresponding to this exact instant in the local
+ * time zone.
+ *
+ * This is equivalent to calling g_date_time_new_now() with the time
+ * zone returned by g_time_zone_new_local().
+ *
+ * Returns: a new #GDateTime, or %NULL
+ *
+ * Since: 2.26
+ **/
+GDateTime *
+g_date_time_new_now_local (void)
+{
+  GDateTime *datetime;
+  GTimeZone *local;
+
+  local = g_time_zone_new_local ();
+  datetime = g_date_time_new_now (local);
+  g_time_zone_unref (local);
+
+  return datetime;
+}
+
+/**
+ * g_date_time_new_now_utc:
+ *
+ * Creates a #GDateTime corresponding to this exact instant in UTC.
+ *
+ * This is equivalent to calling g_date_time_new_now() with the time
+ * zone returned by g_time_zone_new_utc().
+ *
+ * Returns: a new #GDateTime, or %NULL
+ *
+ * Since: 2.26
+ **/
+GDateTime *
+g_date_time_new_now_utc (void)
+{
+  GDateTime *datetime;
+  GTimeZone *utc;
+
+  utc = g_time_zone_new_utc ();
+  datetime = g_date_time_new_now (utc);
+  g_time_zone_unref (utc);
+
+  return datetime;
+}
+
+/**
+ * g_date_time_new_from_unix_local:
+ * @t: the Unix time
+ *
+ * Creates a #GDateTime corresponding to the given Unix time @t in the
+ * local time zone.
+ *
+ * Unix time is the number of seconds that have elapsed since 1970-01-01
+ * 00:00:00 UTC, regardless of the local time offset.
+ *
+ * This call can fail (returning %NULL) if @t represents a time outside
+ * of the supported range of #GDateTime.
+ *
+ * You should release the return value by calling g_date_time_unref()
+ * when you are done with it.
+ *
+ * Returns: a new #GDateTime, or %NULL
+ *
+ * Since: 2.26
+ **/
+GDateTime *
+g_date_time_new_from_unix_local (gint64 t)
+{
+  GDateTime *datetime;
+  GTimeZone *local;
+
+  local = g_time_zone_new_local ();
+  datetime = g_date_time_new_from_unix (local, t);
+  g_time_zone_unref (local);
+
+  return datetime;
+}
+
+/**
+ * g_date_time_new_from_unix_utc:
+ * @t: the Unix time
+ *
+ * Creates a #GDateTime corresponding to the given Unix time @t in UTC.
+ *
+ * Unix time is the number of seconds that have elapsed since 1970-01-01
+ * 00:00:00 UTC.
+ *
+ * This call can fail (returning %NULL) if @t represents a time outside
+ * of the supported range of #GDateTime.
+ *
+ * You should release the return value by calling g_date_time_unref()
+ * when you are done with it.
+ *
+ * Returns: a new #GDateTime, or %NULL
+ *
+ * Since: 2.26
+ **/
+GDateTime *
+g_date_time_new_from_unix_utc (gint64 t)
+{
+  GDateTime *datetime;
+  GTimeZone *utc;
+
+  utc = g_time_zone_new_utc ();
+  datetime = g_date_time_new_from_unix (utc, t);
+  g_time_zone_unref (utc);
+
+  return datetime;
+}
+
+/**
+ * g_date_time_new_from_timeval_local:
+ * @tv: a #GTimeVal
+ *
+ * Creates a #GDateTime corresponding to the given #GTimeVal @tv in the
+ * local time zone.
+ *
+ * The time contained in a #GTimeVal is always stored in the form of
+ * seconds elapsed since 1970-01-01 00:00:00 UTC, regardless of the
+ * local time offset.
+ *
+ * This call can fail (returning %NULL) if @tv represents a time outside
+ * of the supported range of #GDateTime.
+ *
+ * You should release the return value by calling g_date_time_unref()
+ * when you are done with it.
+ *
+ * Returns: a new #GDateTime, or %NULL
+ *
+ * Since: 2.26
+ **/
+GDateTime *
+g_date_time_new_from_timeval_local (const GTimeVal *tv)
+{
+  GDateTime *datetime;
+  GTimeZone *local;
+
+  local = g_time_zone_new_local ();
+  datetime = g_date_time_new_from_timeval (local, tv);
+  g_time_zone_unref (local);
+
+  return datetime;
+}
+
+/**
+ * g_date_time_new_from_timeval_utc:
+ * @tv: a #GTimeVal
+ *
+ * Creates a #GDateTime corresponding to the given #GTimeVal @tv in UTC.
+ *
+ * The time contained in a #GTimeVal is always stored in the form of
+ * seconds elapsed since 1970-01-01 00:00:00 UTC.
+ *
+ * This call can fail (returning %NULL) if @tv represents a time outside
+ * of the supported range of #GDateTime.
+ *
+ * You should release the return value by calling g_date_time_unref()
+ * when you are done with it.
+ *
+ * Returns: a new #GDateTime, or %NULL
+ *
+ * Since: 2.26
+ **/
+GDateTime *
+g_date_time_new_from_timeval_utc (const GTimeVal *tv)
+{
+  GDateTime *datetime;
+  GTimeZone *utc;
+
+  utc = g_time_zone_new_utc ();
+  datetime = g_date_time_new_from_timeval (utc, tv);
+  g_time_zone_unref (utc);
+
+  return datetime;
+}
+
+/* full new functions {{{1 */
+
+/**
+ * g_date_time_new:
+ * @tz: a #GTimeZone
+ * @year: the year component of the date
+ * @month: the month component of the date
+ * @day: the day component of the date
+ * @hour: the hour component of the date
+ * @minute: the minute component of the date
+ * @seconds: the number of seconds past the minute
+ *
+ * Creates a new #GDateTime corresponding to the given date and time in
+ * the time zone @tz.
+ *
+ * The @year must be between 1 and 9999, @month between 1 and 12 and @day
+ * between 1 and 28, 29, 30 or 31 depending on the month and the year.
+ *
+ * @hour must be between 0 and 23 and @minute must be between 0 and 59.
+ *
+ * @seconds must be at least 0.0 and must be strictly less than 60.0.
+ * It will be rounded down to the nearest microsecond.
+ *
+ * If the given time is not representable in the given time zone (for
+ * example, 02:30 on March 14th 2010 in Toronto, due to daylight savings
+ * time) then the time will be rounded up to the nearest existing time
+ * (in this case, 03:00).  If this matters to you then you should verify
+ * the return value for containing the same as the numbers you gave.
+ *
+ * In the case that the given time is ambiguous in the given time zone
+ * (for example, 01:30 on November 7th 2010 in Toronto, due to daylight
+ * savings time) then the time falling within standard (ie:
+ * non-daylight) time is taken.
+ *
+ * It not considered a programmer error for the values to this function
+ * to be out of range, but in the case that they are, the function will
+ * return %NULL.
+ *
+ * You should release the return value by calling g_date_time_unref()
+ * when you are done with it.
+ *
+ * Returns: a new #GDateTime, or %NULL
+ *
+ * Since: 2.26
+ **/
+GDateTime *
+g_date_time_new (GTimeZone *tz,
+                 gint       year,
+                 gint       month,
+                 gint       day,
+                 gint       hour,
+                 gint       minute,
+                 gdouble    seconds)
+{
+  GDateTime *datetime;
+  gint64 full_time;
+
+  datetime = g_date_time_alloc (tz);
+  datetime->days = ymd_to_days (year, month, day);
+  datetime->usec = (hour   * USEC_PER_HOUR)
+                 + (minute * USEC_PER_MINUTE)
+                 + (gint64) (seconds * USEC_PER_SECOND);
+
+  full_time = SEC_PER_DAY *
+                (ymd_to_days (year, month, day) - UNIX_EPOCH_START) +
+              SECS_PER_HOUR * hour +
+              SECS_PER_MINUTE * minute +
+              (int) seconds;
+
+  datetime->interval = g_time_zone_adjust_time (datetime->tz,
+                                                G_TIME_TYPE_STANDARD,
+                                                &full_time);
+
+  full_time += UNIX_EPOCH_START * SEC_PER_DAY;
+  datetime->days = full_time / SEC_PER_DAY;
+  datetime->usec = (full_time % SEC_PER_DAY) * USEC_PER_SECOND;
+  datetime->usec += ((int) (seconds * USEC_PER_SECOND)) % USEC_PER_SECOND;
+
+  return datetime;
+}
+
+/**
+ * g_date_time_new_local:
+ * @year: the year component of the date
+ * @month: the month component of the date
+ * @day: the day component of the date
+ * @hour: the hour component of the date
+ * @minute: the minute component of the date
+ * @seconds: the number of seconds past the minute
+ *
+ * Creates a new #GDateTime corresponding to the given date and time in
+ * the local time zone.
+ *
+ * This call is equivalent to calling g_date_time_new() with the time
+ * zone returned by g_time_zone_new_local().
+ *
+ * Returns: a #GDateTime, or %NULL
+ *
+ * Since: 2.26.
+ **/
+GDateTime *
+g_date_time_new_local (gint    year,
+                       gint    month,
+                       gint    day,
+                       gint    hour,
+                       gint    minute,
+                       gdouble seconds)
+{
+  GDateTime *datetime;
+  GTimeZone *local;
+
+  local = g_time_zone_new_local ();
+  datetime = g_date_time_new (local, year, month, day, hour, minute, seconds);
+  g_time_zone_unref (local);
+
+  return datetime;
+}
+
+/**
+ * g_date_time_new_utc:
+ * @year: the year component of the date
+ * @month: the month component of the date
+ * @day: the day component of the date
+ * @hour: the hour component of the date
+ * @minute: the minute component of the date
+ * @seconds: the number of seconds past the minute
+ *
+ * Creates a new #GDateTime corresponding to the given date and time in
+ * UTC.
+ *
+ * This call is equivalent to calling g_date_time_new() with the time
+ * zone returned by g_time_zone_new_utc().
+ *
+ * Returns: a #GDateTime, or %NULL
+ *
+ * Since: 2.26.
+ **/
+GDateTime *
+g_date_time_new_utc (gint    year,
+                     gint    month,
+                     gint    day,
+                     gint    hour,
+                     gint    minute,
+                     gdouble seconds)
+{
+  GDateTime *datetime;
+  GTimeZone *utc;
+
+  utc = g_time_zone_new_utc ();
+  datetime = g_date_time_new (utc, year, month, day, hour, minute, seconds);
+  g_time_zone_unref (utc);
+
+  return datetime;
+}
+
+/* Adders {{{1 */
+
+/**
+ * g_date_time_add:
+ * @datetime: a #GDateTime
+ * @timespan: a #GTimeSpan
+ *
+ * Creates a copy of @datetime and adds the specified timespan to the copy.
+ *
+ * Return value: the newly created #GDateTime which should be freed with
+ *   g_date_time_unref().
+ *
+ * Since: 2.26
+ */
+GDateTime*
+g_date_time_add (GDateTime *datetime,
+                 GTimeSpan  timespan)
+{
+  return g_date_time_from_instant (datetime->tz, timespan +
+                                   g_date_time_to_instant (datetime));
+}
+
+/**
+ * g_date_time_add_years:
+ * @datetime: a #GDateTime
+ * @years: the number of years
+ *
+ * Creates a copy of @datetime and adds the specified number of years to the
+ * copy.
+ *
+ * Return value: the newly created #GDateTime which should be freed with
+ *   g_date_time_unref().
+ *
+ * Since: 2.26
+ */
+GDateTime *
+g_date_time_add_years (GDateTime *datetime,
+                       gint       years)
+{
+  gint year, month, day;
+
+  g_return_val_if_fail (datetime != NULL, NULL);
+
+  if (years < -10000 || years > 10000)
+    return NULL;
+
+  g_date_time_get_ymd (datetime, &year, &month, &day);
+  year += years;
+
+  /* only possible issue is if we've entered a year with no February 29
+   */
+  if (month == 2 && day == 29 && !GREGORIAN_LEAP (year))
+    day = 28;
+
+  return g_date_time_replace_days (datetime, ymd_to_days (year, month, day));
+}
+
+/**
+ * g_date_time_add_months:
+ * @datetime: a #GDateTime
+ * @months: the number of months
+ *
+ * Creates a copy of @datetime and adds the specified number of months to the
+ * copy.
+ *
+ * Return value: the newly created #GDateTime which should be freed with
+ *   g_date_time_unref().
+ *
+ * Since: 2.26
+ */
+GDateTime*
+g_date_time_add_months (GDateTime *datetime,
+                        gint       months)
+{
+  gint year, month, day;
+
+  g_return_val_if_fail (datetime != NULL, NULL);
+  g_date_time_get_ymd (datetime, &year, &month, &day);
+
+  if (months < -120000 || months > 120000)
+    return NULL;
+
+  year += months / 12;
+  month += months % 12;
+  if (month < 1)
+    {
+      month += 12;
+      year--;
+    }
+  else if (month > 12)
+    {
+      month -= 12;
+      year++;
+    }
+
+  day = MIN (day, days_in_months[GREGORIAN_LEAP (year)][month]);
+
+  return g_date_time_replace_days (datetime, ymd_to_days (year, month, day));
+}
+
+/**
+ * g_date_time_add_weeks:
+ * @datetime: a #GDateTime
+ * @weeks: the number of weeks
+ *
+ * Creates a copy of @datetime and adds the specified number of weeks to the
+ * copy.
+ *
+ * Return value: the newly created #GDateTime which should be freed with
+ *   g_date_time_unref().
+ *
+ * Since: 2.26
+ */
+GDateTime*
+g_date_time_add_weeks (GDateTime *datetime,
+                       gint             weeks)
+{
+  g_return_val_if_fail (datetime != NULL, NULL);
+
+  return g_date_time_add_days (datetime, weeks * 7);
+}
+
+/**
+ * g_date_time_add_days:
+ * @datetime: a #GDateTime
+ * @days: the number of days
+ *
+ * Creates a copy of @datetime and adds the specified number of days to the
+ * copy.
+ *
+ * Return value: the newly created #GDateTime which should be freed with
+ *   g_date_time_unref().
+ *
+ * Since: 2.26
+ */
+GDateTime*
+g_date_time_add_days (GDateTime *datetime,
+                      gint       days)
+{
+  g_return_val_if_fail (datetime != NULL, NULL);
+
+  if (days < -3660000 || days > 3660000)
+    return NULL;
+
+  return g_date_time_replace_days (datetime, datetime->days + days);
+}
+
+/**
+ * g_date_time_add_hours:
+ * @datetime: a #GDateTime
+ * @hours: the number of hours to add
+ *
+ * Creates a copy of @datetime and adds the specified number of hours
+ *
+ * Return value: the newly created #GDateTime which should be freed with
+ *   g_date_time_unref().
+ *
+ * Since: 2.26
+ */
+GDateTime*
+g_date_time_add_hours (GDateTime *datetime,
+                       gint       hours)
+{
+  return g_date_time_add (datetime, hours * USEC_PER_HOUR);
+}
+
+/**
+ * g_date_time_add_minutes:
+ * @datetime: a #GDateTime
+ * @minutes: the number of minutes to add
+ *
+ * Creates a copy of @datetime adding the specified number of minutes.
+ *
+ * Return value: the newly created #GDateTime which should be freed with
+ *   g_date_time_unref().
+ *
+ * Since: 2.26
+ */
+GDateTime*
+g_date_time_add_minutes (GDateTime *datetime,
+                         gint             minutes)
+{
+  return g_date_time_add (datetime, minutes * USEC_PER_MINUTE);
+}
+
+
+/**
+ * g_date_time_add_seconds:
+ * @datetime: a #GDateTime
+ * @seconds: the number of seconds to add
+ *
+ * Creates a copy of @datetime and adds the specified number of seconds.
+ *
+ * Return value: the newly created #GDateTime which should be freed with
+ *   g_date_time_unref().
+ *
+ * Since: 2.26
+ */
+GDateTime*
+g_date_time_add_seconds (GDateTime *datetime,
+                         gdouble    seconds)
+{
+  return g_date_time_add (datetime, seconds * USEC_PER_SECOND);
+}
+
+/**
+ * g_date_time_add_full:
+ * @datetime: a #GDateTime
+ * @years: the number of years to add
+ * @months: the number of months to add
+ * @days: the number of days to add
+ * @hours: the number of hours to add
+ * @minutes: the number of minutes to add
+ * @seconds: the number of seconds to add
+ *
+ * Creates a new #GDateTime adding the specified values to the current date and
+ * time in @datetime.
+ *
+ * Return value: the newly created #GDateTime that should be freed with
+ *   g_date_time_unref().
+ *
+ * Since: 2.26
+ */
+GDateTime *
+g_date_time_add_full (GDateTime *datetime,
+                      gint       years,
+                      gint       months,
+                      gint       days,
+                      gint       hours,
+                      gint       minutes,
+                      gdouble    seconds)
+{
+  gint year, month, day;
+  gint64 full_time;
+  GDateTime *new;
+  gint interval;
+
+  g_return_val_if_fail (datetime != NULL, NULL);
+  g_date_time_get_ymd (datetime, &year, &month, &day);
+
+  months += years * 12;
+
+  if (months < -120000 || months > 120000)
+    return NULL;
+
+  if (days < -3660000 || days > 3660000)
+    return NULL;
+
+  year += months / 12;
+  month += months % 12;
+  if (month < 1)
+    {
+      month += 12;
+      year--;
+    }
+  else if (month > 12)
+    {
+      month -= 12;
+      year++;
+    }
+
+  day = MIN (day, days_in_months[GREGORIAN_LEAP (year)][month]);
+
+  /* full_time is now in unix (local) time */
+  full_time = datetime->usec / USEC_PER_SECOND + SEC_PER_DAY *
+    (ymd_to_days (year, month, day) + days - UNIX_EPOCH_START);
+
+  interval = g_time_zone_adjust_time (datetime->tz,
+                                      g_time_zone_is_dst (datetime->tz,
+                                                          datetime->interval),
+                                      &full_time);
+
+  /* move to UTC unix time */
+  full_time -= g_time_zone_get_offset (datetime->tz, interval);
+
+  /* convert back to an instant, add back fractional seconds */
+  full_time += UNIX_EPOCH_START * SEC_PER_DAY;
+  full_time = full_time * USEC_PER_SECOND +
+              datetime->usec % USEC_PER_SECOND;
+
+  /* do the actual addition now */
+  full_time += (hours * USEC_PER_HOUR) +
+               (minutes * USEC_PER_MINUTE) +
+               (gint64) (seconds * USEC_PER_SECOND);
+
+  /* find the new interval */
+  interval = g_time_zone_find_interval (datetime->tz,
+                                        G_TIME_TYPE_UNIVERSAL,
+                                        INSTANT_TO_UNIX (full_time));
+
+  /* convert back into local time */
+  full_time += USEC_PER_SECOND *
+               g_time_zone_get_offset (datetime->tz, interval);
+
+  /* split into days and usec of a new datetime */
+  new = g_date_time_alloc (datetime->tz);
+  new->interval = interval;
+  new->days = full_time / USEC_PER_DAY;
+  new->usec = full_time % USEC_PER_DAY;
+
+  /* XXX validate */
+
+  return new;
+}
+
+/* Compare, difference, hash, equal {{{1 */
+/**
+ * g_date_time_compare:
+ * @dt1: first #GDateTime to compare
+ * @dt2: second #GDateTime to compare
+ *
+ * #GCompareFunc-compatible comparison for #GDateTime<!-- -->'s. Both
+ * #GDateTime<-- -->'s must be non-%NULL.
+ *
+ * Return value: 0 for equal, less than zero if dt1 is less than dt2, greater
+ *   than zero if dt2 is greator than dt1.
+ *
+ * Since: 2.26
+ */
+gint
+g_date_time_compare (gconstpointer dt1,
+                     gconstpointer dt2)
+{
+  gint64 difference;
+
+  difference = g_date_time_difference ((GDateTime *) dt1, (GDateTime *) dt2);
+
+  if (difference < 0)
+    return -1;
+
+  else if (difference > 0)
+    return 1;
+
+  else
+    return 0;
+}
+
+/**
+ * g_date_time_difference:
+ * @end: a #GDateTime
+ * @begin: a #GDateTime
+ *
+ * Calculates the difference in time between @end and @begin.  The
+ * #GTimeSpan that is returned is effectively @end - @begin (ie:
+ * positive if the first simparameter is larger).
+ *
+ * Return value: the difference between the two #GDateTime, as a time
+ *   span expressed in microseconds.
+ *
+ * Since: 2.26
+ */
+GTimeSpan
+g_date_time_difference (GDateTime *end,
+                        GDateTime *begin)
+{
+  g_return_val_if_fail (begin != NULL, 0);
+  g_return_val_if_fail (end != NULL, 0);
+
+  return g_date_time_to_instant (end) -
+         g_date_time_to_instant (begin);
+}
+
+/**
+ * g_date_time_hash:
+ * @datetime: a #GDateTime
+ *
+ * Hashes @datetime into a #guint, suitable for use within #GHashTable.
+ *
+ * Return value: a #guint containing the hash
+ *
+ * Since: 2.26
+ */
+guint
+g_date_time_hash (gconstpointer datetime)
+{
+  return g_date_time_to_instant ((GDateTime *) datetime);
+}
+
+/**
+ * g_date_time_equal:
+ * @dt1: a #GDateTime
+ * @dt2: a #GDateTime
+ *
+ * Checks to see if @dt1 and @dt2 are equal.
+ *
+ * Equal here means that they represent the same moment after converting
+ * them to the same time zone.
+ *
+ * Return value: %TRUE if @dt1 and @dt2 are equal
+ *
+ * Since: 2.26
+ */
+gboolean
+g_date_time_equal (gconstpointer dt1,
+                   gconstpointer dt2)
+{
+  return g_date_time_difference ((GDateTime *) dt1, (GDateTime *) dt2) == 0;
+}
+
+/* Year, Month, Day Getters {{{1 */
+/**
+ * g_date_time_get_ymd:
+ * @datetime: a #GDateTime.
+ * @year: (out): the return location for the gregorian year, or %NULL.
+ * @month: (out): the return location for the monty of the year, or %NULL.
+ * @day: (out): the return location for the day of the month, or %NULL.
+ *
+ * Retrieves the Gregorian day, month, and year of a given #GDateTime.
+ *
+ * Since: 2.26
+ **/
+void
+g_date_time_get_ymd (GDateTime *datetime,
+                     gint      *year,
+                     gint      *month,
+                     gint      *day)
+{
+  gint the_year;
+  gint the_month;
+  gint the_day;
+  gint remaining_days;
+  gint y100_cycles;
+  gint y4_cycles;
+  gint y1_cycles;
+  gint preceding;
+  gboolean leap;
+
+  g_return_if_fail (datetime != NULL);
+
+  remaining_days = datetime->days;
+
+  /*
+   * We need to convert an offset in days to its year/month/day representation.
+   * Leap years makes this a little trickier than it should be, so we use
+   * 400, 100 and 4 years cycles here to get to the correct year.
+   */
+
+  /* Our days offset starts sets 0001-01-01 as day 1, if it was day 0 our
+   * math would be simpler, so let's do it */
+  remaining_days--;
+
+  the_year = (remaining_days / DAYS_IN_400YEARS) * 400 + 1;
+  remaining_days = remaining_days % DAYS_IN_400YEARS;
+
+  y100_cycles = remaining_days / DAYS_IN_100YEARS;
+  remaining_days = remaining_days % DAYS_IN_100YEARS;
+  the_year += y100_cycles * 100;
+
+  y4_cycles = remaining_days / DAYS_IN_4YEARS;
+  remaining_days = remaining_days % DAYS_IN_4YEARS;
+  the_year += y4_cycles * 4;
+
+  y1_cycles = remaining_days / 365;
+  the_year += y1_cycles;
+  remaining_days = remaining_days % 365;
+
+  if (y1_cycles == 4 || y100_cycles == 4) {
+    g_assert (remaining_days == 0);
+
+    /* special case that indicates that the date is actually one year before,
+     * in the 31th of December */
+    the_year--;
+    the_month = 12;
+    the_day = 31;
+    goto end;
+  }
+
+  /* now get the month and the day */
+  leap = y1_cycles == 3 && (y4_cycles != 24 || y100_cycles == 3);
+
+  g_assert (leap == GREGORIAN_LEAP(the_year));
+
+  the_month = (remaining_days + 50) >> 5;
+  preceding = (days_in_year[0][the_month - 1] + (the_month > 2 && leap));
+  if (preceding > remaining_days)
+    {
+      /* estimate is too large */
+      the_month -= 1;
+      preceding -= leap ? days_in_months[1][the_month]
+                        : days_in_months[0][the_month];
+    }
+
+  remaining_days -= preceding;
+  g_assert(0 <= remaining_days);
+
+  the_day = remaining_days + 1;
+
+end:
+  if (year)
+    *year = the_year;
+  if (month)
+    *month = the_month;
+  if (day)
+    *day = the_day;
+}
+
+/**
+ * g_date_time_get_year:
+ * @datetime: A #GDateTime
+ *
+ * Retrieves the year represented by @datetime in the Gregorian calendar.
+ *
+ * Return value: the year represented by @datetime
+ *
+ * Since: 2.26
+ */
+gint
+g_date_time_get_year (GDateTime *datetime)
+{
+  gint year;
+
+  g_return_val_if_fail (datetime != NULL, 0);
+
+  g_date_time_get_ymd (datetime, &year, NULL, NULL);
+
+  return year;
+}
+
+/**
+ * g_date_time_get_month:
+ * @datetime: a #GDateTime
+ *
+ * Retrieves the month of the year represented by @datetime in the Gregorian
+ * calendar.
+ *
+ * Return value: the month represented by @datetime
+ *
+ * Since: 2.26
+ */
+gint
+g_date_time_get_month (GDateTime *datetime)
+{
+  gint month;
+
+  g_return_val_if_fail (datetime != NULL, 0);
+
+  g_date_time_get_ymd (datetime, NULL, &month, NULL);
+
+  return month;
+}
+
+/**
+ * g_date_time_get_day_of_month:
+ * @datetime: a #GDateTime
+ *
+ * Retrieves the day of the month represented by @datetime in the gregorian
+ * calendar.
+ *
+ * Return value: the day of the month
+ *
+ * Since: 2.26
+ */
+gint
+g_date_time_get_day_of_month (GDateTime *datetime)
+{
+  gint           day_of_year,
+                 i;
+  const guint16 *days;
+  guint16        last = 0;
+
+  g_return_val_if_fail (datetime != NULL, 0);
+
+  days = days_in_year[GREGORIAN_LEAP (g_date_time_get_year (datetime)) ? 1 : 0];
+  g_date_time_get_week_number (datetime, NULL, NULL, &day_of_year);
+
+  for (i = 1; i <= 12; i++)
+    {
+      if (days [i] >= day_of_year)
+        return day_of_year - last;
+      last = days [i];
+    }
+
+  g_warn_if_reached ();
+  return 0;
+}
+
+/* Week of year / day of week getters {{{1 */
+/**
+ * g_date_time_get_week_numbering_year:
+ * @date: a #GDateTime
+ *
+ * Returns the ISO 8601 week-numbering year in which the week containing
+ * @datetime falls.
+ *
+ * This function, taken together with g_date_time_get_week_of_year() and
+ * g_date_time_get_day_of_week() can be used to determine the full ISO
+ * week date on which @datetime falls.
+ *
+ * This is usually equal to the normal Gregorian year (as returned by
+ * g_date_time_get_year()), except as detailed below:
+ *
+ * For Thursday, the week-numbering year is always equal to the usual
+ * calendar year.  For other days, the number is such that every day
+ * within a complete week (Monday to Sunday) is contained within the
+ * same week-numbering year.
+ *
+ * For Monday, Tuesday and Wednesday occuring near the end of the year,
+ * this may mean that the week-numbering year is one greater than the
+ * calendar year (so that these days have the same week-numbering year
+ * as the Thursday occuring early in the next year).
+ *
+ * For Friday, Saturaday and Sunday occuring near the start of the year,
+ * this may mean that the week-numbering year is one less than the
+ * calendar year (so that these days have the same week-numbering year
+ * as the Thursday occuring late in the previous year).
+ *
+ * An equivalent description is that the week-numbering year is equal to
+ * the calendar year containing the majority of the days in the current
+ * week (Monday to Sunday).
+ *
+ * Note that January 1 0001 in the proleptic Gregorian calendar is a
+ * Monday, so this function never returns 0.
+ *
+ * Returns: the ISO 8601 week-numbering year for @datetime
+ *
+ * Since: 2.26
+ **/
+gint
+g_date_time_get_week_numbering_year (GDateTime *datetime)
+{
+  gint year, month, day, weekday;
+
+  g_date_time_get_ymd (datetime, &year, &month, &day);
+  weekday = g_date_time_get_day_of_week (datetime);
+
+  /* January 1, 2, 3 might be in the previous year if they occur after
+   * Thursday.
+   *
+   *   Jan 1:  Friday, Saturday, Sunday    =>  day 1:  weekday 5, 6, 7
+   *   Jan 2:  Saturday, Sunday            =>  day 2:  weekday 6, 7
+   *   Jan 3:  Sunday                      =>  day 3:  weekday 7
+   *
+   * So we have a special case if (day - weekday) <= -4
+   */
+  if (month == 1 && (day - weekday) <= -4)
+    return year - 1;
+
+  /* December 29, 30, 31 might be in the next year if they occur before
+   * Thursday.
+   *
+   *   Dec 31: Monday, Tuesday, Wednesday  =>  day 31: weekday 1, 2, 3
+   *   Dec 30: Monday, Tuesday             =>  day 30: weekday 1, 2
+   *   Dec 29: Monday                      =>  day 29: weekday 1
+   *
+   * So we have a special case if (day - weekday) >= 28
+   */
+  else if (month == 12 && (day - weekday) >= 28)
+    return year + 1;
+
+  else
+    return year;
+}
+
+/**
+ * g_date_time_get_week_of_year:
+ * @datetime: a #GDateTime
+ *
+ * Returns the ISO 8601 week number for the week containing @datetime.
+ * The ISO 8601 week number is the same for every day of the week (from
+ * Moday through Sunday).  That can produce some unusual results
+ * (described below).
+ *
+ * The first week of the year is week 1.  This is the week that contains
+ * the first Thursday of the year.  Equivalently, this is the first week
+ * that has more than 4 of its days falling within the calendar year.
+ *
+ * The value 0 is never returned by this function.  Days contained
+ * within a year but occuring before the first ISO 8601 week of that
+ * year are considered as being contained in the last week of the
+ * previous year.  Similarly, the final days of a calendar year may be
+ * considered as being part of the first ISO 8601 week of the next year
+ * if 4 or more days of that week are contained within the new year.
+ *
+ * Returns: the ISO 8601 week number for @datetime.
+ *
+ * Since: 2.26
+ */
+gint
+g_date_time_get_week_of_year (GDateTime *datetime)
+{
+  gint weeknum;
+
+  g_return_val_if_fail (datetime != NULL, 0);
+
+  g_date_time_get_week_number (datetime, &weeknum, NULL, NULL);
+
+  return weeknum;
+}
+
+/**
+ * g_date_time_get_day_of_week:
+ * @datetime: a #GDateTime
+ *
+ * Retrieves the ISO 8601 day of the week on which @datetime falls (1 is
+ * Monday, 2 is Tuesday... 7 is Sunday).
+ *
+ * Return value: the day of the week
+ *
+ * Since: 2.26
+ */
+gint
+g_date_time_get_day_of_week (GDateTime *datetime)
+{
+  g_return_val_if_fail (datetime != NULL, 0);
+
+  return (datetime->days - 1) % 7 + 1;
+}
+
+/* Day of year getter {{{1 */
+/**
+ * g_date_time_get_day_of_year:
+ * @datetime: a #GDateTime
+ *
+ * Retrieves the day of the year represented by @datetime in the Gregorian
+ * calendar.
+ *
+ * Return value: the day of the year
+ *
+ * Since: 2.26
+ */
+gint
+g_date_time_get_day_of_year (GDateTime *datetime)
+{
+  gint doy = 0;
+
+  g_return_val_if_fail (datetime != NULL, 0);
+
+  g_date_time_get_week_number (datetime, NULL, NULL, &doy);
+  return doy;
+}
+
+/* Time component getters {{{1 */
+
+/**
+ * g_date_time_get_hour:
+ * @datetime: a #GDateTime
+ *
+ * Retrieves the hour of the day represented by @datetime
+ *
+ * Return value: the hour of the day
+ *
+ * Since: 2.26
+ */
+gint
+g_date_time_get_hour (GDateTime *datetime)
+{
+  g_return_val_if_fail (datetime != NULL, 0);
+
+  return (datetime->usec / USEC_PER_HOUR);
+}
+
+/**
+ * g_date_time_get_minute:
+ * @datetime: a #GDateTime
+ *
+ * Retrieves the minute of the hour represented by @datetime
+ *
+ * Return value: the minute of the hour
+ *
+ * Since: 2.26
+ */
+gint
+g_date_time_get_minute (GDateTime *datetime)
+{
+  g_return_val_if_fail (datetime != NULL, 0);
+
+  return (datetime->usec % USEC_PER_HOUR) / USEC_PER_MINUTE;
+}
+
+/**
+ * g_date_time_get_second:
+ * @datetime: a #GDateTime
+ *
+ * Retrieves the second of the minute represented by @datetime
+ *
+ * Return value: the second represented by @datetime
+ *
+ * Since: 2.26
+ */
+gint
+g_date_time_get_second (GDateTime *datetime)
+{
+  g_return_val_if_fail (datetime != NULL, 0);
+
+  return (datetime->usec % USEC_PER_MINUTE) / USEC_PER_SECOND;
+}
+
+/**
+ * g_date_time_get_microsecond:
+ * @datetime: a #GDateTime
+ *
+ * Retrieves the microsecond of the date represented by @datetime
+ *
+ * Return value: the microsecond of the second
+ *
+ * Since: 2.26
+ */
+gint
+g_date_time_get_microsecond (GDateTime *datetime)
+{
+  g_return_val_if_fail (datetime != NULL, 0);
+
+  return (datetime->usec % USEC_PER_SECOND);
+}
+
+/**
+ * g_date_time_get_seconds:
+ * @datetime: a #GDateTime
+ *
+ * Retrieves the number of seconds since the start of the last minute,
+ * including the fractional part.
+ *
+ * Returns: the number of seconds
+ *
+ * Since: 2.26
+ **/
+gdouble
+g_date_time_get_seconds (GDateTime *datetime)
+{
+  g_return_val_if_fail (datetime != NULL, 0);
+
+  return (datetime->usec % USEC_PER_MINUTE) / 1000000.0;
+}
+
+/* Exporters {{{1 */
+/**
+ * g_date_time_to_unix:
+ * @datetime: a #GDateTime
+ *
+ * Gives the Unix time corresponding to @datetime, rounding down to the
+ * nearest second.
+ *
+ * Unix time is the number of seconds that have elapsed since 1970-01-01
+ * 00:00:00 UTC, regardless of the time zone associated with @datetime.
+ *
+ * Returns: the Unix time corresponding to @datetime
+ *
+ * Since: 2.26
+ **/
+gint64
+g_date_time_to_unix (GDateTime *datetime)
+{
+  return INSTANT_TO_UNIX (g_date_time_to_instant (datetime));
+}
+
+/**
+ * g_date_time_to_timeval:
+ * @datetime: a #GDateTime
+ * @tv: a #GTimeVal to modify
+ *
+ * Stores the instant in time that @datetime represents into @tv.
+ *
+ * The time contained in a #GTimeVal is always stored in the form of
+ * seconds elapsed since 1970-01-01 00:00:00 UTC, regardless of the time
+ * zone associated with @datetime.
+ *
+ * On systems where 'long' is 32bit (ie: all 32bit systems and all
+ * Windows systems), a #GTimeVal is incapable of storing the entire
+ * range of values that #GDateTime is capable of expressing.  On those
+ * systems, this function returns %FALSE to indicate that the time is
+ * out of range.
+ *
+ * On systems where 'long' is 64bit, this function never fails.
+ *
+ * Returns: %TRUE if successful, else %FALSE
+ *
+ * Since: 2.26
+ **/
+gboolean
+g_date_time_to_timeval (GDateTime *datetime,
+                        GTimeVal  *tv)
+{
+  tv->tv_sec = INSTANT_TO_UNIX (g_date_time_to_instant (datetime));
+  tv->tv_usec = datetime->usec % USEC_PER_SECOND;
+
+  return TRUE;
+}
+
+/* Timezone queries {{{1 */
+/**
+ * g_date_time_get_utc_offset:
+ * @datetime: a #GDateTime
+ *
+ * Determines the offset to UTC in effect at the time and in the time
+ * zone of @datetime.
+ *
+ * The offset is the number of microseconds that you add to UTC time to
+ * arrive at local time for the time zone (ie: negative numbers for time
+ * zones west of GMT, positive numbers for east).
+ *
+ * If @datetime represents UTC time, then the offset is always zero.
+ *
+ * Returns: the number of microseconds that should be added to UTC to
+ *          get the local time
+ *
+ * Since: 2.26
+ **/
+GTimeSpan
+g_date_time_get_utc_offset (GDateTime *datetime)
+{
+  gint offset;
+
+  g_return_val_if_fail (datetime != NULL, 0);
+
+  offset = g_time_zone_get_offset (datetime->tz, datetime->interval);
+
+  return (gint64) offset * USEC_PER_SECOND;
+}
+
+/**
+ * g_date_time_get_timezone_abbreviation:
+ * @datetime: a #GDateTime
+ *
+ * Determines the time zone abbreviation to be used at the time and in
+ * the time zone of @datetime.
+ *
+ * For example, in Toronto this is currently "EST" during the winter
+ * months and "EDT" during the summer months when daylight savings
+ * time is in effect.
+ *
+ * Returns: (transfer none): the time zone abbreviation. The returned
+ *          string is owned by the #GDateTime and it should not be
+ *          modified or freed
+ *
+ * Since: 2.26
+ **/
+const gchar *
+g_date_time_get_timezone_abbreviation (GDateTime *datetime)
+{
+  g_return_val_if_fail (datetime != NULL, NULL);
+
+  return g_time_zone_get_abbreviation (datetime->tz, datetime->interval);
+}
+
+/**
+ * g_date_time_is_daylight_savings:
+ * @datetime: a #GDateTime
+ *
+ * Determines if daylight savings time is in effect at the time and in
+ * the time zone of @datetime.
+ *
+ * Returns: %TRUE if daylight savings time is in effect
+ *
+ * Since: 2.26
+ **/
+gboolean
+g_date_time_is_daylight_savings (GDateTime *datetime)
+{
+  g_return_val_if_fail (datetime != NULL, FALSE);
+
+  return g_time_zone_is_dst (datetime->tz, datetime->interval);
+}
+
+/* Timezone convert {{{1 */
+/**
+ * g_date_time_to_timezone:
+ * @datetime: a #GDateTime
+ * @tz: the new #GTimeZone
+ *
+ * Create a new #GDateTime corresponding to the same instant in time as
+ * @datetime, but in the time zone @tz.
+ *
+ * This call can fail in the case that the time goes out of bounds.  For
+ * example, converting 0001-01-01 00:00:00 UTC to a time zone west of
+ * Greenwich will fail (due to the year 0 being out of range).
+ *
+ * You should release the return value by calling g_date_time_unref()
+ * when you are done with it.
+ *
+ * Returns: a new #GDateTime, or %NULL
+ *
+ * Since: 2.26
+ **/
+GDateTime *
+g_date_time_to_timezone (GDateTime *datetime,
+                         GTimeZone *tz)
+{
+  return g_date_time_from_instant (tz, g_date_time_to_instant (datetime));
+}
+
+/**
+ * g_date_time_to_local:
+ * @datetime: a #GDateTime
+ *
+ * Creates a new #GDateTime corresponding to the same instant in time as
+ * @datetime, but in the local time zone.
+ *
+ * This call is equivalent to calling g_date_time_to_timezone() with the
+ * time zone returned by g_time_zone_new_local().
+ *
+ * Returns: the newly created #GDateTime
+ *
+ * Since: 2.26
+ **/
+GDateTime *
+g_date_time_to_local (GDateTime *datetime)
+{
+  GDateTime *new;
+  GTimeZone *local;
+
+  local = g_time_zone_new_local ();
+  new = g_date_time_to_timezone (datetime, local);
+  g_time_zone_unref (local);
+
+  return new;
+}
+
+/**
+ * g_date_time_to_utc:
+ * @datetime: a #GDateTime
+ *
+ * Creates a new #GDateTime corresponding to the same instant in time as
+ * @datetime, but in UTC.
+ *
+ * This call is equivalent to calling g_date_time_to_timezone() with the
+ * time zone returned by g_time_zone_new_utc().
+ *
+ * Returns: the newly created #GDateTime
+ *
+ * Since: 2.26
+ **/
+GDateTime *
+g_date_time_to_utc (GDateTime *datetime)
+{
+  GDateTime *new;
+  GTimeZone *utc;
+
+  utc = g_time_zone_new_utc ();
+  new = g_date_time_to_timezone (datetime, utc);
+  g_time_zone_unref (utc);
+
+  return new;
+}
+
+/* Format {{{1 */
+/**
+ * g_date_time_format:
+ * @datetime: A #GDateTime
+ * @format: a valid UTF-8 string, containing the format for the
+ *          #GDateTime
+ *
+ * Creates a newly allocated string representing the requested @format.
+ *
+ * The following format specifiers are supported:
+ *
+ * <variablelist>
+ *  <varlistentry><term>
+ *    <literal>%%a</literal>:
+ *   </term><listitem><simpara>
+ *    the abbreviated weekday name according to the current locale
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%A</literal>:
+ *   </term><listitem><simpara>
+ *    the full weekday name according to the current locale
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%b</literal>:
+ *   </term><listitem><simpara>
+ *    the abbreviated month name according to the current locale
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%B</literal>:
+ *   </term><listitem><simpara>
+ *    the full month name according to the current locale
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%d</literal>:
+ *   </term><listitem><simpara>
+ *    the day of the month as a decimal number (range 01 to 31)
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%e</literal>:
+ *   </term><listitem><simpara>
+ *    the day of the month as a decimal number (range  1 to 31)
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%F</literal>:
+ *   </term><listitem><simpara>
+ *    equivalent to <literal>%%Y-%%m-%%d</literal> (the ISO 8601 date
+ *    format)
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%h</literal>:
+ *   </term><listitem><simpara>
+ *    equivalent to <literal>%%b</literal>
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%H</literal>:
+ *   </term><listitem><simpara>
+ *    the hour as a decimal number using a 24-hour clock (range 00 to
+ *    23)
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%I</literal>:
+ *   </term><listitem><simpara>
+ *    the hour as a decimal number using a 12-hour clock (range 01 to
+ *    12)
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%j</literal>:
+ *   </term><listitem><simpara>
+ *    the day of the year as a decimal number (range 001 to 366)
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%k</literal>:
+ *   </term><listitem><simpara>
+ *    the hour (24-hour clock) as a decimal number (range 0 to 23);
+ *    single digits are preceded by a blank
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%l</literal>:
+ *   </term><listitem><simpara>
+ *    the hour (12-hour clock) as a decimal number (range 1 to 12);
+ *    single digits are preceded by a blank
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%m</literal>:
+ *   </term><listitem><simpara>
+ *    the month as a decimal number (range 01 to 12)
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%M</literal>:
+ *   </term><listitem><simpara>
+ *    the minute as a decimal number (range 00 to 59)
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%N</literal>:
+ *   </term><listitem><simpara>
+ *    the micro-seconds as a decimal number
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%p</literal>:
+ *   </term><listitem><simpara>
+ *    either "AM" or "PM" according to the given time value, or the
+ *    corresponding  strings for the current locale.  Noon is treated as
+ *    "PM" and midnight as "AM".
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%P</literal>:
+ *   </term><listitem><simpara>
+ *    like %%p but lowercase: "am" or "pm" or a corresponding string for
+ *    the current locale
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%r</literal>:
+ *   </term><listitem><simpara>
+ *    the time in a.m. or p.m. notation
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%R</literal>:
+ *   </term><listitem><simpara>
+ *    the time in 24-hour notation (<literal>%%H:%%M</literal>)
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%s</literal>:
+ *   </term><listitem><simpara>
+ *    the number of seconds since the Epoch, that is, since 1970-01-01
+ *    00:00:00 UTC
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%S</literal>:
+ *   </term><listitem><simpara>
+ *    the second as a decimal number (range 00 to 60)
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%t</literal>:
+ *   </term><listitem><simpara>
+ *    a tab character
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%u</literal>:
+ *   </term><listitem><simpara>
+ *    the day of the week as a decimal, range 1 to 7, Monday being 1
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%W</literal>:
+ *   </term><listitem><simpara>
+ *    the week number of the current year as a decimal number
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%x</literal>:
+ *   </term><listitem><simpara>
+ *    the preferred date representation for the current locale without
+ *    the time
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%X</literal>:
+ *   </term><listitem><simpara>
+ *    the preferred time representation for the current locale without
+ *    the date
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%y</literal>:
+ *   </term><listitem><simpara>
+ *    the year as a decimal number without the century
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%Y</literal>:
+ *   </term><listitem><simpara>
+ *    the year as a decimal number including the century
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%z</literal>:
+ *   </term><listitem><simpara>
+ *    the time-zone as hour offset from UTC
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%Z</literal>:
+ *   </term><listitem><simpara>
+ *    the time zone or name or abbreviation
+ *  </simpara></listitem></varlistentry>
+ *  <varlistentry><term>
+ *    <literal>%%%</literal>:
+ *   </term><listitem><simpara>
+ *    a literal <literal>%%</literal> character
+ *  </simpara></listitem></varlistentry>
+ * </variablelist>
+ *
+ * Returns: a newly allocated string formatted to the requested format
+ *          or %NULL in the case that there was an error.  The string
+ *          should be freed with g_free().
+ *
+ * Since: 2.26
+ */
+gchar *
+g_date_time_format (GDateTime *datetime,
+                    const gchar     *format)
+{
+  GString  *outstr;
+  gchar    *tmp;
+  gunichar  c;
+  glong     utf8len;
+  gboolean  in_mod;
+
+  g_return_val_if_fail (datetime != NULL, NULL);
+  g_return_val_if_fail (format != NULL, NULL);
+  g_return_val_if_fail (g_utf8_validate (format, -1, NULL), NULL);
+
+  outstr = g_string_sized_new (strlen (format) * 2);
+  utf8len = g_utf8_strlen (format, -1);
+  in_mod = FALSE;
+
+  for (; *format; format = g_utf8_next_char(format))
+    {
+      c = g_utf8_get_char (format);
+
+      switch (c)
+        {
+        case '%':
+          if (!in_mod)
+            {
+              in_mod = TRUE;
+              break;
+            }
+            /* Fall through */
+        default:
+          if (in_mod)
+            {
+              switch (c)
+                {
+                case 'a':
+                  g_string_append (outstr, WEEKDAY_ABBR (datetime));
+                  break;
+                case 'A':
+                  g_string_append (outstr, WEEKDAY_FULL (datetime));
+                  break;
+                case 'b':
+                  g_string_append (outstr, MONTH_ABBR (datetime));
+                  break;
+                case 'B':
+                  g_string_append (outstr, MONTH_FULL (datetime));
+                  break;
+                case 'd':
+                  g_string_append_printf (outstr, "%02d", g_date_time_get_day_of_month (datetime));
+                  break;
+                case 'e':
+                  g_string_append_printf (outstr, "%2d", g_date_time_get_day_of_month (datetime));
+                  break;
+                case 'F':
+                  g_string_append_printf (outstr, "%d-%02d-%02d",
+                                          g_date_time_get_year (datetime),
+                                          g_date_time_get_month (datetime),
+                                          g_date_time_get_day_of_month (datetime));
+                  break;
+                case 'h':
+                  g_string_append (outstr, MONTH_ABBR (datetime));
+                  break;
+                case 'H':
+                  g_string_append_printf (outstr, "%02d", g_date_time_get_hour (datetime));
+                  break;
+                case 'I':
+                  if (g_date_time_get_hour (datetime) == 0)
+                    g_string_append (outstr, "12");
+                  else
+                    g_string_append_printf (outstr, "%02d", g_date_time_get_hour (datetime) % 12);
+                  break;
+                case 'j':
+                  g_string_append_printf (outstr, "%03d", g_date_time_get_day_of_year (datetime));
+                  break;
+                case 'k':
+                  g_string_append_printf (outstr, "%2d", g_date_time_get_hour (datetime));
+                  break;
+                case 'l':
+                  if (g_date_time_get_hour (datetime) == 0)
+                    g_string_append (outstr, "12");
+                  else
+                    g_string_append_printf (outstr, "%2d", g_date_time_get_hour (datetime) % 12);
+                  break;
+                case 'm':
+                  g_string_append_printf (outstr, "%02d", g_date_time_get_month (datetime));
+                  break;
+                case 'M':
+                  g_string_append_printf (outstr, "%02d", g_date_time_get_minute (datetime));
+                  break;
+                case 'N':
+                  g_string_append_printf (outstr, "%"G_GUINT64_FORMAT, datetime->usec % USEC_PER_SECOND);
+                  break;
+                case 'p':
+                  g_string_append (outstr, GET_AMPM (datetime, FALSE));
+                  break;
+                case 'P':
+                  g_string_append (outstr, GET_AMPM (datetime, TRUE));
+                  break;
+                case 'r':
+                  {
+                    gint hour = g_date_time_get_hour (datetime) % 12;
+                    if (hour == 0)
+                      hour = 12;
+                    g_string_append_printf (outstr, "%02d:%02d:%02d %s",
+                                            hour,
+                                            g_date_time_get_minute (datetime),
+                                            g_date_time_get_second (datetime),
+                                            GET_AMPM (datetime, FALSE));
+                  }
+                  break;
+                case 'R':
+                  g_string_append_printf (outstr, "%02d:%02d",
+                                          g_date_time_get_hour (datetime),
+                                          g_date_time_get_minute (datetime));
+                  break;
+                case 's':
+                  g_string_append_printf (outstr, "%" G_GINT64_FORMAT, g_date_time_to_unix (datetime));
+                  break;
+                case 'S':
+                  g_string_append_printf (outstr, "%02d", g_date_time_get_second (datetime));
+                  break;
+                case 't':
+                  g_string_append_c (outstr, '\t');
+                  break;
+                case 'u':
+                  g_string_append_printf (outstr, "%d", g_date_time_get_day_of_week (datetime));
+                  break;
+                case 'W':
+                  g_string_append_printf (outstr, "%d", g_date_time_get_day_of_year (datetime) / 7);
+                  break;
+                case 'x':
+                  {
+                    tmp = GET_PREFERRED_DATE (datetime);
+                    g_string_append (outstr, tmp);
+                    g_free (tmp);
+                  }
+                  break;
+                case 'X':
+                  {
+                    tmp = GET_PREFERRED_TIME (datetime);
+                    g_string_append (outstr, tmp);
+                    g_free (tmp);
+                  }
+                  break;
+                case 'y':
+                  g_string_append_printf (outstr, "%02d", g_date_time_get_year (datetime) % 100);
+                  break;
+                case 'Y':
+                  g_string_append_printf (outstr, "%d", g_date_time_get_year (datetime));
+                  break;
+                case 'z':
+                  if (datetime->tz != NULL)
+                    {
+                      gint64 offset = g_date_time_get_utc_offset (datetime)
+                                    / USEC_PER_SECOND;
+
+                      g_string_append_printf (outstr, "%c%02d%02d",
+                                              offset >= 0 ? '+' : '-',
+                                              (int) offset / 3600,
+                                              (int) offset / 60 % 60);
+                    }
+                  else
+                    g_string_append (outstr, "+0000");
+                  break;
+                case 'Z':
+                  g_string_append (outstr, g_date_time_get_timezone_abbreviation (datetime));
+                  break;
+                case '%':
+                  g_string_append_c (outstr, '%');
+                  break;
+                case 'n':
+                  g_string_append_c (outstr, '\n');
+                  break;
+                default:
+                  goto bad_format;
+                }
+              in_mod = FALSE;
+            }
+          else
+            g_string_append_unichar (outstr, c);
+        }
+    }
+
+  return g_string_free (outstr, FALSE);
+
+bad_format:
+  g_string_free (outstr, TRUE);
+  return NULL;
+}
+
+
+/* Epilogue {{{1 */
+/* vim:set foldmethod=marker: */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gdatetime.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gdatetime.h
new file mode 100644 (file)
index 0000000..b76df89
--- /dev/null
@@ -0,0 +1,217 @@
+/*
+ * Copyright (C) 2009-2010 Christian Hergert <chris@dronelabs.com>
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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
+ * licence, or (at your option) any later version.
+ *
+ * This 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 St, Fifth Floor, Boston, MA  02110-1301
+ * USA.
+ *
+ * Authors: Christian Hergert <chris@dronelabs.com>
+ *          Thiago Santos <thiago.sousa.santos@collabora.co.uk>
+ *          Emmanuele Bassi <ebassi@linux.intel.com>
+ *          Ryan Lortie <desrt@desrt.ca>
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_DATE_TIME_H__
+#define __G_DATE_TIME_H__
+
+#include <glib/gtimezone.h>
+
+G_BEGIN_DECLS
+
+/**
+ * G_TIME_SPAN_DAY:
+ *
+ * Evaluates to a time span of one day.
+ *
+ * Since: 2.26
+ */
+#define G_TIME_SPAN_DAY                 (G_GINT64_CONSTANT (86400000000))
+
+/**
+ * G_TIME_SPAN_HOUR:
+ *
+ * Evaluates to a time span of one hour.
+ *
+ * Since: 2.26
+ */
+#define G_TIME_SPAN_HOUR                (G_GINT64_CONSTANT (3600000000))
+
+/**
+ * G_TIME_SPAN_MINUTE:
+ *
+ * Evaluates to a time span of one minute.
+ *
+ * Since: 2.26
+ */
+#define G_TIME_SPAN_MINUTE              (G_GINT64_CONSTANT (60000000))
+
+/**
+ * G_TIME_SPAN_SECOND:
+ *
+ * Evaluates to a time span of one second.
+ *
+ * Since: 2.26
+ */
+#define G_TIME_SPAN_SECOND              (G_GINT64_CONSTANT (1000000))
+
+/**
+ * G_TIME_SPAN_MILLISECOND:
+ *
+ * Evaluates to a time span of one millisecond.
+ *
+ * Since: 2.26
+ */
+#define G_TIME_SPAN_MILLISECOND         (G_GINT64_CONSTANT (1000))
+
+/**
+ * GTimeSpan:
+ *
+ * A value representing an interval of time, in microseconds.
+ *
+ * Since: 2.26
+ */
+typedef gint64 GTimeSpan;
+
+/**
+ * GDateTime:
+ *
+ * <structname>GDateTime</structname> is an opaque structure whose members
+ * cannot be accessed directly.
+ *
+ * Since: 2.26
+ */
+typedef struct _GDateTime GDateTime;
+
+void                    g_date_time_unref                               (GDateTime      *datetime);
+GDateTime *             g_date_time_ref                                 (GDateTime      *datetime);
+
+GDateTime *             g_date_time_new_now                             (GTimeZone      *tz);
+GDateTime *             g_date_time_new_now_local                       (void);
+GDateTime *             g_date_time_new_now_utc                         (void);
+
+GDateTime *             g_date_time_new_from_unix_local                 (gint64          t);
+GDateTime *             g_date_time_new_from_unix_utc                   (gint64          t);
+
+GDateTime *             g_date_time_new_from_timeval_local              (const GTimeVal *tv);
+GDateTime *             g_date_time_new_from_timeval_utc                (const GTimeVal *tv);
+
+GDateTime *             g_date_time_new                                 (GTimeZone      *tz,
+                                                                         gint            year,
+                                                                         gint            month,
+                                                                         gint            day,
+                                                                         gint            hour,
+                                                                         gint            minute,
+                                                                         gdouble         seconds);
+GDateTime *             g_date_time_new_local                           (gint            year,
+                                                                         gint            month,
+                                                                         gint            day,
+                                                                         gint            hour,
+                                                                         gint            minute,
+                                                                         gdouble         seconds);
+GDateTime *             g_date_time_new_utc                             (gint            year,
+                                                                         gint            month,
+                                                                         gint            day,
+                                                                         gint            hour,
+                                                                         gint            minute,
+                                                                         gdouble         seconds);
+
+G_GNUC_WARN_UNUSED_RESULT
+GDateTime *             g_date_time_add                                 (GDateTime      *datetime,
+                                                                         GTimeSpan       timespan);
+
+G_GNUC_WARN_UNUSED_RESULT
+GDateTime *             g_date_time_add_years                           (GDateTime      *datetime,
+                                                                         gint            years);
+G_GNUC_WARN_UNUSED_RESULT
+GDateTime *             g_date_time_add_months                          (GDateTime      *datetime,
+                                                                         gint            months);
+G_GNUC_WARN_UNUSED_RESULT
+GDateTime *             g_date_time_add_weeks                           (GDateTime      *datetime,
+                                                                         gint            weeks);
+G_GNUC_WARN_UNUSED_RESULT
+GDateTime *             g_date_time_add_days                            (GDateTime      *datetime,
+                                                                         gint            days);
+
+G_GNUC_WARN_UNUSED_RESULT
+GDateTime *             g_date_time_add_hours                           (GDateTime      *datetime,
+                                                                         gint            hours);
+G_GNUC_WARN_UNUSED_RESULT
+GDateTime *             g_date_time_add_minutes                         (GDateTime      *datetime,
+                                                                         gint            minutes);
+G_GNUC_WARN_UNUSED_RESULT
+GDateTime *             g_date_time_add_seconds                         (GDateTime      *datetime,
+                                                                         gdouble         seconds);
+
+G_GNUC_WARN_UNUSED_RESULT
+GDateTime *             g_date_time_add_full                            (GDateTime      *datetime,
+                                                                         gint            years,
+                                                                         gint            months,
+                                                                         gint            days,
+                                                                         gint            hours,
+                                                                         gint            minutes,
+                                                                         gdouble         seconds);
+
+gint                    g_date_time_compare                             (gconstpointer   dt1,
+                                                                         gconstpointer   dt2);
+GTimeSpan               g_date_time_difference                          (GDateTime      *end,
+                                                                         GDateTime      *begin);
+guint                   g_date_time_hash                                (gconstpointer   datetime);
+gboolean                g_date_time_equal                               (gconstpointer   dt1,
+                                                                         gconstpointer   dt2);
+
+void                    g_date_time_get_ymd                             (GDateTime      *datetime,
+                                                                         gint           *year,
+                                                                         gint           *month,
+                                                                         gint           *day);
+
+gint                    g_date_time_get_year                            (GDateTime      *datetime);
+gint                    g_date_time_get_month                           (GDateTime      *datetime);
+gint                    g_date_time_get_day_of_month                    (GDateTime      *datetime);
+
+gint                    g_date_time_get_week_numbering_year             (GDateTime      *datetime);
+gint                    g_date_time_get_week_of_year                    (GDateTime      *datetime);
+gint                    g_date_time_get_day_of_week                     (GDateTime      *datetime);
+
+gint                    g_date_time_get_day_of_year                     (GDateTime      *datetime);
+
+gint                    g_date_time_get_hour                            (GDateTime      *datetime);
+gint                    g_date_time_get_minute                          (GDateTime      *datetime);
+gint                    g_date_time_get_second                          (GDateTime      *datetime);
+gint                    g_date_time_get_microsecond                     (GDateTime      *datetime);
+gdouble                 g_date_time_get_seconds                         (GDateTime      *datetime);
+
+gint64                  g_date_time_to_unix                             (GDateTime      *datetime);
+gboolean                g_date_time_to_timeval                          (GDateTime      *datetime,
+                                                                         GTimeVal       *tv);
+
+GTimeSpan               g_date_time_get_utc_offset                      (GDateTime      *datetime);
+const gchar *           g_date_time_get_timezone_abbreviation           (GDateTime      *datetime);
+gboolean                g_date_time_is_daylight_savings                 (GDateTime      *datetime);
+
+GDateTime *             g_date_time_to_timezone                         (GDateTime      *datetime,
+                                                                         GTimeZone      *tz);
+GDateTime *             g_date_time_to_local                            (GDateTime      *datetime);
+GDateTime *             g_date_time_to_utc                              (GDateTime      *datetime);
+
+gchar *                 g_date_time_format                              (GDateTime      *datetime,
+                                                                         const gchar    *format) G_GNUC_MALLOC;
+
+G_END_DECLS
+
+#endif /* __G_DATE_TIME_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gdebug.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gdebug.h
new file mode 100644 (file)
index 0000000..dea3dde
--- /dev/null
@@ -0,0 +1,59 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#ifndef __G_DEBUG_H__
+#define __G_DEBUG_H__
+
+G_BEGIN_DECLS 
+
+typedef enum {
+  G_DEBUG_FATAL_WARNINGS  = 1 << 0,
+  G_DEBUG_FATAL_CRITICALS = 1 << 1
+} GDebugFlag;
+
+
+#ifdef G_ENABLE_DEBUG
+
+#define G_NOTE(type, action)            G_STMT_START { \
+    if (!_g_debug_initialized)                         \
+       { _g_debug_init (); }                           \
+    if (_g_debug_flags & G_DEBUG_##type)               \
+       { action; };                         } G_STMT_END
+
+#else /* !G_ENABLE_DEBUG */
+
+#define G_NOTE(type, action)
+      
+#endif /* G_ENABLE_DEBUG */
+
+GLIB_VAR gboolean _g_debug_initialized;
+GLIB_VAR guint _g_debug_flags;
+
+G_GNUC_INTERNAL void _g_debug_init (void);
+
+G_END_DECLS
+
+#endif /* __G_DEBUG_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gdir.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gdir.c
new file mode 100644 (file)
index 0000000..0f0a17f
--- /dev/null
@@ -0,0 +1,314 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gdir.c: Simplified wrapper around the DIRENT functions.
+ *
+ * Copyright 2001 Hans Breuer
+ * Copyright 2004 Tor Lillqvist
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <string.h>
+#include <stdio.h>
+#include <sys/stat.h>
+
+#ifdef HAVE_DIRENT_H
+#include <sys/types.h>
+#include <dirent.h>
+#endif
+
+#include "gdir.h"
+
+#include "gconvert.h"
+#include "gfileutils.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "glibintl.h"
+
+
+#if defined (_MSC_VER) && !defined (HAVE_DIRENT_H)
+#include "../build/win32/dirent/dirent.h"
+#include "../build/win32/dirent/wdirent.c"
+#endif
+
+struct _GDir
+{
+#ifdef G_OS_WIN32
+  _WDIR *wdirp;
+#else
+  DIR *dirp;
+#endif
+#ifdef G_OS_WIN32
+  gchar utf8_buf[FILENAME_MAX*4];
+#endif
+};
+
+/**
+ * g_dir_open:
+ * @path: the path to the directory you are interested in. On Unix
+ *         in the on-disk encoding. On Windows in UTF-8
+ * @flags: Currently must be set to 0. Reserved for future use.
+ * @error: return location for a #GError, or %NULL.
+ *         If non-%NULL, an error will be set if and only if
+ *         g_dir_open() fails.
+ *
+ * Opens a directory for reading. The names of the files in the
+ * directory can then be retrieved using g_dir_read_name().  Note
+ * that the ordering is not defined.
+ *
+ * Return value: a newly allocated #GDir on success, %NULL on failure.
+ *   If non-%NULL, you must free the result with g_dir_close()
+ *   when you are finished with it.
+ **/
+GDir *
+g_dir_open (const gchar  *path,
+            guint         flags,
+            GError      **error)
+{
+  GDir *dir;
+  int errsv;
+#ifdef G_OS_WIN32
+  wchar_t *wpath;
+#else
+  gchar *utf8_path;
+#endif
+
+  g_return_val_if_fail (path != NULL, NULL);
+
+#ifdef G_OS_WIN32
+  wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, error);
+
+  if (wpath == NULL)
+    return NULL;
+
+  dir = g_new (GDir, 1);
+
+  dir->wdirp = _wopendir (wpath);
+  g_free (wpath);
+
+  if (dir->wdirp)
+    return dir;
+
+  /* error case */
+  errsv = errno;
+
+  g_set_error (error,
+              G_FILE_ERROR,
+              g_file_error_from_errno (errsv),
+              _("Error opening directory '%s': %s"),
+              path, g_strerror (errsv));
+  
+  g_free (dir);
+      
+  return NULL;
+#else
+  dir = g_new (GDir, 1);
+
+  dir->dirp = opendir (path);
+
+  if (dir->dirp)
+    return dir;
+
+  /* error case */
+  errsv = errno;
+
+  utf8_path = g_filename_to_utf8 (path, -1,
+                                 NULL, NULL, NULL);
+
+  g_set_error (error,
+               G_FILE_ERROR,
+               g_file_error_from_errno (errsv),
+               _("Error opening directory '%s': %s"),
+              utf8_path, g_strerror (errsv));
+
+  g_free (utf8_path);
+  g_free (dir);
+
+  return NULL;
+#endif
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+/* The above function actually is called g_dir_open_utf8, and it's
+ * that what applications compiled with this GLib version will
+ * use.
+ */
+
+#undef g_dir_open
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+GDir *
+g_dir_open (const gchar  *path,
+            guint         flags,
+            GError      **error)
+{
+  gchar *utf8_path = g_locale_to_utf8 (path, -1, NULL, NULL, error);
+  GDir *retval;
+
+  if (utf8_path == NULL)
+    return NULL;
+
+  retval = g_dir_open_utf8 (utf8_path, flags, error);
+
+  g_free (utf8_path);
+
+  return retval;
+}
+#endif
+
+/**
+ * g_dir_read_name:
+ * @dir: a #GDir* created by g_dir_open()
+ *
+ * Retrieves the name of another entry in the directory, or %NULL.
+ * The order of entries returned from this function is not defined,
+ * and may vary by file system or other operating-system dependent
+ * factors. 
+ *
+ * On Unix, the '.' and '..' entries are omitted, and the returned
+ * name is in the on-disk encoding.
+ *
+ * On Windows, as is true of all GLib functions which operate on
+ * filenames, the returned name is in UTF-8.
+ *
+ * Return value: The entry's name or %NULL if there are no 
+ *   more entries. The return value is owned by GLib and
+ *   must not be modified or freed.
+ **/
+G_CONST_RETURN gchar*
+g_dir_read_name (GDir *dir)
+{
+#ifdef G_OS_WIN32
+  gchar *utf8_name;
+  struct _wdirent *wentry;
+#else
+  struct dirent *entry;
+#endif
+
+  g_return_val_if_fail (dir != NULL, NULL);
+
+#ifdef G_OS_WIN32
+  while (1)
+    {
+      wentry = _wreaddir (dir->wdirp);
+      while (wentry 
+            && (0 == wcscmp (wentry->d_name, L".") ||
+                0 == wcscmp (wentry->d_name, L"..")))
+       wentry = _wreaddir (dir->wdirp);
+
+      if (wentry == NULL)
+       return NULL;
+
+      utf8_name = g_utf16_to_utf8 (wentry->d_name, -1, NULL, NULL, NULL);
+
+      if (utf8_name == NULL)
+       continue;               /* Huh, impossible? Skip it anyway */
+
+      strcpy (dir->utf8_buf, utf8_name);
+      g_free (utf8_name);
+
+      return dir->utf8_buf;
+    }
+#else
+  entry = readdir (dir->dirp);
+  while (entry 
+         && (0 == strcmp (entry->d_name, ".") ||
+             0 == strcmp (entry->d_name, "..")))
+    entry = readdir (dir->dirp);
+
+  if (entry)
+    return entry->d_name;
+  else
+    return NULL;
+#endif
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+/* Ditto for g_dir_read_name */
+
+#undef g_dir_read_name
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+G_CONST_RETURN gchar*
+g_dir_read_name (GDir *dir)
+{
+  while (1)
+    {
+      const gchar *utf8_name = g_dir_read_name_utf8 (dir);
+      gchar *retval;
+      
+      if (utf8_name == NULL)
+       return NULL;
+
+      retval = g_locale_from_utf8 (utf8_name, -1, NULL, NULL, NULL);
+
+      if (retval != NULL)
+       {
+         strcpy (dir->utf8_buf, retval);
+         g_free (retval);
+
+         return dir->utf8_buf;
+       }
+    }
+}
+
+#endif
+
+/**
+ * g_dir_rewind:
+ * @dir: a #GDir* created by g_dir_open()
+ *
+ * Resets the given directory. The next call to g_dir_read_name()
+ * will return the first entry again.
+ **/
+void
+g_dir_rewind (GDir *dir)
+{
+  g_return_if_fail (dir != NULL);
+  
+#ifdef G_OS_WIN32
+  _wrewinddir (dir->wdirp);
+#else
+  rewinddir (dir->dirp);
+#endif
+}
+
+/**
+ * g_dir_close:
+ * @dir: a #GDir* created by g_dir_open()
+ *
+ * Closes the directory and deallocates all related resources.
+ **/
+void
+g_dir_close (GDir *dir)
+{
+  g_return_if_fail (dir != NULL);
+
+#ifdef G_OS_WIN32
+  _wclosedir (dir->wdirp);
+#else
+  closedir (dir->dirp);
+#endif
+  g_free (dir);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gdir.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gdir.h
new file mode 100644 (file)
index 0000000..85e9896
--- /dev/null
@@ -0,0 +1,52 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gdir.c: Simplified wrapper around the DIRENT functions.
+ *
+ * Copyright 2001 Hans Breuer
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_DIR_H__
+#define __G_DIR_H__
+
+#include <glib/gerror.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GDir GDir;
+
+#ifdef G_OS_WIN32
+/* For DLL ABI stability, keep old names for old (non-UTF-8) functionality. */
+#define g_dir_open g_dir_open_utf8
+#define g_dir_read_name g_dir_read_name_utf8
+#endif
+
+GDir    *                g_dir_open           (const gchar  *path,
+                                              guint         flags,
+                                              GError      **error);
+G_CONST_RETURN gchar    *g_dir_read_name      (GDir         *dir);
+void                     g_dir_rewind         (GDir         *dir);
+void                     g_dir_close          (GDir         *dir);
+
+G_END_DECLS
+
+#endif /* __G_DIR_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gen-script-table.pl b/resource/csdk/connectivity/lib/android/glib-master/glib/gen-script-table.pl
new file mode 100644 (file)
index 0000000..27268ab
--- /dev/null
@@ -0,0 +1,119 @@
+#!/usr/bin/perl -w 
+#
+# Script to convert http://www.unicode.org/Public/UNIDATA/Scripts.txt
+# into a machine-readable table.
+#
+######################################################################
+
+if (@ARGV != 1) {
+    die "Usage: gen-script-table.pl Scripts.txt > gscripttable.h\n";
+}
+
+open IN, $ARGV[0] || die "Cannot open $ARGV[0]: $!\n";
+
+my @ranges;
+my $file;
+my $easy_range;
+my $i;
+my $start;
+my $end;
+my $script;
+
+
+while (<IN>) {
+    if (/^\#\s+(Scripts-.*.txt)/) {
+       $file = $1;
+    }
+    
+    s/#.*//;
+    next if /^\s*$/;
+    if (!/^([0-9A-F]+)(?:\.\.([0-9A-F]+))?\s*;\s*([A-Za-z_]+)\s*$/) {
+       die "Cannot parse line: '$_'\n";
+    }
+
+    if (defined $2) {
+       push @ranges, [ hex $1, hex $2, uc $3 ];
+    } else {
+       push @ranges, [ hex $1, hex $1, uc $3 ];
+    }
+}
+
+@ranges = sort { $a->[0] <=> $b->[0] } @ranges;
+$date = gmtime;
+
+print <<"EOT";
+/* gscripttable.h: Generated by gen-script-table.pl
+ *
+ *  Date: $date
+ *  Source: $file
+ *
+ * Do not edit.
+ */
+
+EOT
+
+$easy_range = 0x2000;
+
+print <<"EOT";
+#define G_EASY_SCRIPTS_RANGE $easy_range
+
+static const guchar g_script_easy_table[$easy_range] = {
+EOT
+
+$i = 0;
+$end = -1;
+
+for (my $c = 0; $c < $easy_range; $c++) {
+
+    if ($c % 3 == 0) {
+      printf "\n ";
+    }
+
+    if ($c > $end) {
+        $start = $ranges[$i]->[0];
+        $end = $ranges[$i]->[1];
+        $script = $ranges[$i]->[2];
+        $i++;
+    }
+    
+    if ($c < $start) {
+        printf " G_UNICODE_SCRIPT_UNKNOWN,";
+    } else {
+        printf " G_UNICODE_SCRIPT_%s,", $script;
+    }
+}
+
+if ($end >= $easy_range) {
+    $i--;
+    $ranges[$i]->[0] = $easy_range;
+}
+
+
+print <<"EOT";
+
+};
+
+static const struct {
+    gunichar    start;
+    guint16     chars;
+    guint16     script;
+} g_script_table[] = { 
+EOT
+
+for (; $i <= $#ranges; $i++) {
+    $start = $ranges[$i]->[0];
+    $end = $ranges[$i]->[1];
+    $script = $ranges[$i]->[2];
+
+    while ($i <= $#ranges - 1 &&
+          $ranges[$i + 1]->[0] == $end + 1 &&
+          $ranges[$i + 1]->[2] eq $script) {
+       $i++;
+       $end = $ranges[$i]->[1];
+    }
+
+    printf " { %#06x, %5d, G_UNICODE_SCRIPT_%s },\n", $start, $end - $start + 1, $script;
+}
+
+printf "};\n";
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gen-unicode-tables.pl b/resource/csdk/connectivity/lib/android/glib-master/glib/gen-unicode-tables.pl
new file mode 100644 (file)
index 0000000..5368adf
--- /dev/null
@@ -0,0 +1,1303 @@
+#! /usr/bin/perl -w
+
+#    Copyright (C) 1998, 1999 Tom Tromey
+#    Copyright (C) 2001 Red Hat Software
+
+#    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, 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.
+
+# Contributer(s):
+#   Andrew Taylor <andrew.taylor@montage.ca>
+
+# gen-unicode-tables.pl - Generate tables for libunicode from Unicode data.
+# See http://www.unicode.org/Public/UNIDATA/UnicodeCharacterDatabase.html
+# I consider the output of this program to be unrestricted.  Use it as
+# you will.
+
+# FIXME:
+# * For decomp table it might make sense to use a shift count other
+#   than 8.  We could easily compute the perfect shift count.
+
+# we use some perl unicode features
+require 5.006;
+
+use vars qw($CODE $NAME $CATEGORY $COMBINING_CLASSES $BIDI_CATEGORY $DECOMPOSITION $DECIMAL_VALUE $DIGIT_VALUE $NUMERIC_VALUE $MIRRORED $OLD_NAME $COMMENT $UPPER $LOWER $TITLE $BREAK_CODE $BREAK_CATEGORY $BREAK_NAME $CASE_CODE $CASE_LOWER $CASE_TITLE $CASE_UPPER $CASE_CONDITION);
+
+
+# Names of fields in Unicode data table.
+$CODE = 0;
+$NAME = 1;
+$CATEGORY = 2;
+$COMBINING_CLASSES = 3;
+$BIDI_CATEGORY = 4;
+$DECOMPOSITION = 5;
+$DECIMAL_VALUE = 6;
+$DIGIT_VALUE = 7;
+$NUMERIC_VALUE = 8;
+$MIRRORED = 9;
+$OLD_NAME = 10;
+$COMMENT = 11;
+$UPPER = 12;
+$LOWER = 13;
+$TITLE = 14;
+
+# Names of fields in the line break table
+$BREAK_CODE = 0;
+$BREAK_PROPERTY = 1;
+
+# Names of fields in the SpecialCasing table
+$CASE_CODE = 0;
+$CASE_LOWER = 1;
+$CASE_TITLE = 2;
+$CASE_UPPER = 3;
+$CASE_CONDITION = 4;
+
+# Names of fields in the CaseFolding table
+$FOLDING_CODE = 0;
+$FOLDING_STATUS = 1;
+$FOLDING_MAPPING = 2;
+
+# Map general category code onto symbolic name.
+%mappings =
+    (
+     # Normative.
+     'Lu' => "G_UNICODE_UPPERCASE_LETTER",
+     'Ll' => "G_UNICODE_LOWERCASE_LETTER",
+     'Lt' => "G_UNICODE_TITLECASE_LETTER",
+     'Mn' => "G_UNICODE_NON_SPACING_MARK",
+     'Mc' => "G_UNICODE_COMBINING_MARK",
+     'Me' => "G_UNICODE_ENCLOSING_MARK",
+     'Nd' => "G_UNICODE_DECIMAL_NUMBER",
+     'Nl' => "G_UNICODE_LETTER_NUMBER",
+     'No' => "G_UNICODE_OTHER_NUMBER",
+     'Zs' => "G_UNICODE_SPACE_SEPARATOR",
+     'Zl' => "G_UNICODE_LINE_SEPARATOR",
+     'Zp' => "G_UNICODE_PARAGRAPH_SEPARATOR",
+     'Cc' => "G_UNICODE_CONTROL",
+     'Cf' => "G_UNICODE_FORMAT",
+     'Cs' => "G_UNICODE_SURROGATE",
+     'Co' => "G_UNICODE_PRIVATE_USE",
+     'Cn' => "G_UNICODE_UNASSIGNED",
+
+     # Informative.
+     'Lm' => "G_UNICODE_MODIFIER_LETTER",
+     'Lo' => "G_UNICODE_OTHER_LETTER",
+     'Pc' => "G_UNICODE_CONNECT_PUNCTUATION",
+     'Pd' => "G_UNICODE_DASH_PUNCTUATION",
+     'Ps' => "G_UNICODE_OPEN_PUNCTUATION",
+     'Pe' => "G_UNICODE_CLOSE_PUNCTUATION",
+     'Pi' => "G_UNICODE_INITIAL_PUNCTUATION",
+     'Pf' => "G_UNICODE_FINAL_PUNCTUATION",
+     'Po' => "G_UNICODE_OTHER_PUNCTUATION",
+     'Sm' => "G_UNICODE_MATH_SYMBOL",
+     'Sc' => "G_UNICODE_CURRENCY_SYMBOL",
+     'Sk' => "G_UNICODE_MODIFIER_SYMBOL",
+     'So' => "G_UNICODE_OTHER_SYMBOL"
+     );
+
+%break_mappings =
+    (
+     'BK' => "G_UNICODE_BREAK_MANDATORY",
+     'CR' => "G_UNICODE_BREAK_CARRIAGE_RETURN",
+     'LF' => "G_UNICODE_BREAK_LINE_FEED",
+     'CM' => "G_UNICODE_BREAK_COMBINING_MARK",
+     'SG' => "G_UNICODE_BREAK_SURROGATE",
+     'ZW' => "G_UNICODE_BREAK_ZERO_WIDTH_SPACE",
+     'IN' => "G_UNICODE_BREAK_INSEPARABLE",
+     'GL' => "G_UNICODE_BREAK_NON_BREAKING_GLUE",
+     'CB' => "G_UNICODE_BREAK_CONTINGENT",
+     'SP' => "G_UNICODE_BREAK_SPACE",
+     'BA' => "G_UNICODE_BREAK_AFTER",
+     'BB' => "G_UNICODE_BREAK_BEFORE",
+     'B2' => "G_UNICODE_BREAK_BEFORE_AND_AFTER",
+     'HY' => "G_UNICODE_BREAK_HYPHEN",
+     'NS' => "G_UNICODE_BREAK_NON_STARTER",
+     'OP' => "G_UNICODE_BREAK_OPEN_PUNCTUATION",
+     'CL' => "G_UNICODE_BREAK_CLOSE_PUNCTUATION",
+     'QU' => "G_UNICODE_BREAK_QUOTATION",
+     'EX' => "G_UNICODE_BREAK_EXCLAMATION",
+     'ID' => "G_UNICODE_BREAK_IDEOGRAPHIC",
+     'NU' => "G_UNICODE_BREAK_NUMERIC",
+     'IS' => "G_UNICODE_BREAK_INFIX_SEPARATOR",
+     'SY' => "G_UNICODE_BREAK_SYMBOL",
+     'AL' => "G_UNICODE_BREAK_ALPHABETIC",
+     'PR' => "G_UNICODE_BREAK_PREFIX",
+     'PO' => "G_UNICODE_BREAK_POSTFIX",
+     'SA' => "G_UNICODE_BREAK_COMPLEX_CONTEXT",
+     'AI' => "G_UNICODE_BREAK_AMBIGUOUS",
+     'NL' => "G_UNICODE_BREAK_NEXT_LINE",
+     'WJ' => "G_UNICODE_BREAK_WORD_JOINER",
+     'XX' => "G_UNICODE_BREAK_UNKNOWN",
+     'JL' => "G_UNICODE_BREAK_HANGUL_L_JAMO",
+     'JV' => "G_UNICODE_BREAK_HANGUL_V_JAMO",
+     'JT' => "G_UNICODE_BREAK_HANGUL_T_JAMO",
+     'H2' => "G_UNICODE_BREAK_HANGUL_LV_SYLLABLE",
+     'H3' => "G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE"
+     );
+
+# Title case mappings.
+%title_to_lower = ();
+%title_to_upper = ();
+
+# Maximum length of special-case strings
+
+my @special_cases;
+my @special_case_offsets;
+my $special_case_offset = 0;
+
+$do_decomp = 0;
+$do_props = 1;
+if (@ARGV && $ARGV[0] eq '-decomp')
+{
+    $do_decomp = 1;
+    $do_props = 0;
+    shift @ARGV;
+}
+elsif (@ARGV && $ARGV[0] eq '-both')
+{
+    $do_decomp = 1;
+    shift @ARGV;
+}
+
+if (@ARGV != 2) {
+    $0 =~ s@.*/@@;
+    die "\nUsage: $0 [-decomp | -both] UNICODE-VERSION DIRECTORY\n\n       DIRECTORY should contain the following Unicode data files:\n       UnicodeData.txt, LineBreak.txt, SpecialCasing.txt, CaseFolding.txt,\n       CompositionExclusions.txt, BidiMirroring.txt\n\n";
+}
+
+my ($unicodedatatxt, $linebreaktxt, $specialcasingtxt, $casefoldingtxt, $compositionexclusionstxt);
+
+my $d = $ARGV[1];
+opendir (my $dir, $d) or die "Cannot open Unicode data dir $d: $!\n";
+for my $f (readdir ($dir))
+{
+    $unicodedatatxt = "$d/$f" if ($f =~ /UnicodeData.*\.txt/);
+    $linebreaktxt = "$d/$f" if ($f =~ /LineBreak.*\.txt/);
+    $specialcasingtxt = "$d/$f" if ($f =~ /SpecialCasing.*\.txt/);
+    $casefoldingtxt = "$d/$f" if ($f =~ /CaseFolding.*\.txt/);
+    $compositionexclusionstxt = "$d/$f" if ($f =~ /CompositionExclusions.*\.txt/);
+}
+
+defined $unicodedatatxt or die "Did not find UnicodeData file";
+defined $linebreaktxt or die "Did not find LineBreak file";
+defined $specialcasingtxt or die "Did not find SpecialCasing file";
+defined $casefoldingtxt or die "Did not find CaseFolding file";
+defined $compositionexclusionstxt or die "Did not find CompositionExclusions file";
+
+print "Creating decomp table\n" if ($do_decomp);
+print "Creating property table\n" if ($do_props);
+
+print "Composition exlusions from $compositionexclusionstxt\n";
+
+open (INPUT, "< $compositionexclusionstxt") || exit 1;
+
+while (<INPUT>) {
+
+    chop;
+
+    next if /^#/;
+    next if /^\s*$/;
+
+    s/\s*#.*//;
+
+    s/^\s*//;
+    s/\s*$//;
+
+    $composition_exclusions{hex($_)} = 1;
+}
+
+close INPUT;
+
+print "Unicode data from $unicodedatatxt\n";
+
+open (INPUT, "< $unicodedatatxt") || exit 1;
+
+# we save memory by skipping the huge empty area before U+E0000
+my $pages_before_e0000;
+
+$last_code = -1;
+while (<INPUT>)
+{
+    chop;
+    @fields = split (';', $_, 30);
+    if ($#fields != 14)
+    {
+       printf STDERR ("Entry for $fields[$CODE] has wrong number of fields (%d)\n", $#fields);
+    }
+
+    $code = hex ($fields[$CODE]);
+
+    if ($code >= 0xE0000 and $last_code < 0xE0000)
+    {
+        $pages_before_e0000 = ($last_code >> 8) + 1;
+    }
+
+    if ($code > $last_code + 1)
+    {
+       # Found a gap.
+       if ($fields[$NAME] =~ /Last>/)
+       {
+           # Fill the gap with the last character read,
+            # since this was a range specified in the char database
+           @gfields = @fields;
+       }
+       else
+       {
+           # The gap represents undefined characters.  Only the type
+           # matters.
+           @gfields = ('', '', 'Cn', '0', '', '', '', '', '', '', '',
+                       '', '', '', '');
+       }
+       for (++$last_code; $last_code < $code; ++$last_code)
+       {
+           $gfields{$CODE} = sprintf ("%04x", $last_code);
+           &process_one ($last_code, @gfields);
+       }
+    }
+    &process_one ($code, @fields);
+    $last_code = $code;
+}
+
+close INPUT;
+
+@gfields = ('', '', 'Cn', '0', '', '', '', '', '', '', '',
+           '', '', '', '');
+for (++$last_code; $last_code <= 0x10FFFF; ++$last_code)
+{
+    $gfields{$CODE} = sprintf ("%04x", $last_code);
+    &process_one ($last_code, @gfields);
+}
+--$last_code;                  # Want last to be 0x10FFFF.
+
+print "Creating line break table\n";
+
+print "Line break data from $linebreaktxt\n";
+
+open (INPUT, "< $linebreaktxt") || exit 1;
+
+$last_code = -1;
+while (<INPUT>)
+{
+    my ($start_code, $end_code);
+    
+    chop;
+
+    next if /^#/;
+
+    s/\s*#.*//;
+    
+    @fields = split (';', $_, 30);
+    if ($#fields != 1)
+    {
+       printf STDERR ("Entry for $fields[$CODE] has wrong number of fields (%d)\n", $#fields);
+       next;
+    }
+
+    if ($fields[$CODE] =~ /([A-F0-9]{4,6})\.\.([A-F0-9]{4,6})/) 
+    {
+       $start_code = hex ($1);
+       $end_code = hex ($2);
+    } else {
+       $start_code = $end_code = hex ($fields[$CODE]);
+       
+    }
+
+    if ($start_code > $last_code + 1)
+    {
+       # The gap represents undefined characters. If assigned,
+       # they are AL, if not assigned, XX
+       for (++$last_code; $last_code < $start_code; ++$last_code)
+       {
+           if ($type[$last_code] eq 'Cn')
+           {
+               $break_props[$last_code] = 'XX';
+           }
+           else
+           {
+               $break_props[$last_code] = 'AL';
+           }
+       }
+    }
+
+    for ($last_code = $start_code; $last_code <= $end_code; $last_code++)
+    {
+       $break_props[$last_code] = $fields[$BREAK_PROPERTY];
+    }
+    
+    $last_code = $end_code;
+}
+
+close INPUT;
+
+for (++$last_code; $last_code <= 0x10FFFF; ++$last_code)
+{
+  if ($type[$last_code] eq 'Cn')
+    {
+      $break_props[$last_code] = 'XX';
+    }
+  else
+    {
+      $break_props[$last_code] = 'AL';
+    }
+}
+--$last_code;                  # Want last to be 0x10FFFF.
+
+print STDERR "Last code is not 0x10FFFF" if ($last_code != 0x10FFFF);
+
+print "Reading special-casing table for case conversion\n";
+
+open (INPUT, "< $specialcasingtxt") || exit 1;
+
+while (<INPUT>)
+{
+    my $code;
+    
+    chop;
+
+    next if /^#/;
+    next if /^\s*$/;
+
+    s/\s*#.*//;
+
+    @fields = split ('\s*;\s*', $_, 30);
+
+    $raw_code = $fields[$CASE_CODE];
+    $code = hex ($raw_code);
+
+    if ($#fields != 4 && $#fields != 5)
+    {
+       printf STDERR ("Entry for $raw_code has wrong number of fields (%d)\n", $#fields);
+       next;
+    }
+
+    if (!defined $type[$code])
+    {
+       printf STDERR "Special case for code point: $code, which has no defined type\n";
+       next;
+    }
+
+    if (defined $fields[5]) {
+       # Ignore conditional special cases - we'll handle them in code
+       next;
+    }
+    
+    if ($type[$code] eq 'Lu') 
+    {
+       (hex $fields[$CASE_UPPER] == $code) || die "$raw_code is Lu and UCD_Upper($raw_code) != $raw_code";
+
+       &add_special_case ($code, $value[$code], $fields[$CASE_LOWER], $fields[$CASE_TITLE]);
+       
+    } elsif ($type[$code] eq 'Lt') 
+    {
+       (hex $fields[$CASE_TITLE] == $code) || die "$raw_code is Lt and UCD_Title($raw_code) != $raw_code";
+       
+       &add_special_case ($code, undef, $fields[$CASE_LOWER], $fields[$CASE_UPPER]);
+    } elsif ($type[$code] eq 'Ll') 
+    {
+       (hex $fields[$CASE_LOWER] == $code) || die "$raw_code is Ll and UCD_Lower($raw_code) != $raw_code";
+       
+       &add_special_case ($code, $value[$code], $fields[$CASE_UPPER], $fields[$CASE_TITLE]);
+    } else {
+       printf STDERR "Special case for non-alphabetic code point: $raw_code\n";
+       next;
+    }
+}
+
+close INPUT;
+
+open (INPUT, "< $casefoldingtxt") || exit 1;
+
+my $casefoldlen = 0;
+my @casefold;
+while (<INPUT>)
+{
+    my $code;
+    
+    chop;
+
+    next if /^#/;
+    next if /^\s*$/;
+
+    s/\s*#.*//;
+
+    @fields = split ('\s*;\s*', $_, 30);
+
+    $raw_code = $fields[$FOLDING_CODE];
+    $code = hex ($raw_code);
+
+    if ($#fields != 3)
+    {
+       printf STDERR ("Entry for $raw_code has wrong number of fields (%d)\n", $#fields);
+       next;
+    }
+
+    # we don't use Simple or Turkic rules here
+    next if ($fields[$FOLDING_STATUS] =~ /^[ST]$/);
+
+    @values = map { hex ($_) } split /\s+/, $fields[$FOLDING_MAPPING];
+
+    # Check simple case
+
+    if (@values == 1 && 
+       !(defined $value[$code] && $value[$code] >= 0x1000000) &&
+       defined $type[$code]) {
+
+       my $lower;
+       if ($type[$code] eq 'Ll') 
+       {
+           $lower = $code;
+       } elsif ($type[$code] eq 'Lt') 
+       {
+           $lower = $title_to_lower{$code};
+       } elsif ($type[$code] eq 'Lu') 
+       {
+           $lower = $value[$code];
+       } else {
+           $lower = $code;
+       }
+       
+       if ($lower == $values[0]) {
+           next;
+       }
+    }
+
+    my $string = pack ("U*", @values);
+
+    if (1 + &length_in_bytes ($string) > $casefoldlen) {
+       $casefoldlen = 1 + &length_in_bytes ($string);
+    }
+
+    push @casefold, [ $code, &escape ($string) ];
+}
+
+close INPUT;
+
+if ($do_props) {
+    &print_tables ($last_code)
+}
+if ($do_decomp) {
+    &print_decomp ($last_code);
+    &output_composition_table;
+}
+
+&print_line_break ($last_code);
+
+exit 0;
+
+
+# perl "length" returns the length in characters
+sub length_in_bytes
+{
+    my ($string) = @_;
+
+    use bytes;
+    return length $string;
+}
+
+# Process a single character.
+sub process_one
+{
+    my ($code, @fields) = @_;
+
+    $type[$code] = $fields[$CATEGORY];
+    if ($type[$code] eq 'Nd')
+    {
+       $value[$code] = int ($fields[$DECIMAL_VALUE]);
+    }
+    elsif ($type[$code] eq 'Ll')
+    {
+       $value[$code] = hex ($fields[$UPPER]);
+    }
+    elsif ($type[$code] eq 'Lu')
+    {
+       $value[$code] = hex ($fields[$LOWER]);
+    }
+
+    if ($type[$code] eq 'Lt')
+    {
+       $title_to_lower{$code} = hex ($fields[$LOWER]);
+       $title_to_upper{$code} = hex ($fields[$UPPER]);
+    }
+
+    $cclass[$code] = $fields[$COMBINING_CLASSES];
+
+    # Handle decompositions.
+    if ($fields[$DECOMPOSITION] ne '')
+    {
+       if ($fields[$DECOMPOSITION] =~ s/\<.*\>\s*//) {
+           $decompose_compat[$code] = 1;
+       } else {
+           $decompose_compat[$code] = 0;
+
+          if (!exists $composition_exclusions{$code}) {
+              $compositions{$code} = $fields[$DECOMPOSITION];
+          }
+        }
+       $decompositions[$code] = $fields[$DECOMPOSITION];
+    }
+}
+
+sub print_tables
+{
+    my ($last) = @_;
+    my ($outfile) = "gunichartables.h";
+
+    local ($bytes_out) = 0;
+
+    print "Writing $outfile...\n";
+
+    open (OUT, "> $outfile");
+
+    print OUT "/* This file is automatically generated.  DO NOT EDIT!\n";
+    print OUT "   Instead, edit gen-unicode-tables.pl and re-run.  */\n\n";
+
+    print OUT "#ifndef CHARTABLES_H\n";
+    print OUT "#define CHARTABLES_H\n\n";
+
+    print OUT "#define G_UNICODE_DATA_VERSION \"$ARGV[0]\"\n\n";
+
+    printf OUT "#define G_UNICODE_LAST_CHAR 0x%04x\n\n", $last;
+
+    printf OUT "#define G_UNICODE_MAX_TABLE_INDEX 10000\n\n";
+
+    my $last_part1 = ($pages_before_e0000 * 256) - 1;
+    printf OUT "#define G_UNICODE_LAST_CHAR_PART1 0x%04X\n\n", $last_part1;
+    printf OUT "#define G_UNICODE_LAST_PAGE_PART1 %d\n\n", $pages_before_e0000 - 1;
+
+    $table_index = 0;
+    printf OUT "static const char type_data[][256] = {\n";
+    for ($count = 0; $count <= $last; $count += 256)
+    {
+       $row[$count / 256] = &print_row ($count, 1, \&fetch_type);
+    }
+    printf OUT "\n};\n\n";
+
+    printf OUT "/* U+0000 through U+%04X */\n", $last_part1;
+    print OUT "static const gint16 type_table_part1[$pages_before_e0000] = {\n";
+    for ($count = 0; $count <= $last_part1; $count += 256)
+    {
+       print OUT ",\n" if $count > 0;
+       print OUT "  ", $row[$count / 256];
+       $bytes_out += 2;
+    }
+    print OUT "\n};\n\n";
+
+    printf OUT "/* U+E0000 through U+%04X */\n", $last;
+    print OUT "static const gint16 type_table_part2[768] = {\n";
+    for ($count = 0xE0000; $count <= $last; $count += 256)
+    {
+       print OUT ",\n" if $count > 0xE0000;
+       print OUT "  ", $row[$count / 256];
+       $bytes_out += 2;
+    }
+    print OUT "\n};\n\n";
+
+
+    #
+    # Now print attribute table.
+    #
+
+    $table_index = 0;
+    printf OUT "static const gunichar attr_data[][256] = {\n";
+    for ($count = 0; $count <= $last; $count += 256)
+    {
+       $row[$count / 256] = &print_row ($count, 4, \&fetch_attr);
+    }
+    printf OUT "\n};\n\n";
+
+    printf OUT "/* U+0000 through U+%04X */\n", $last_part1;
+    print OUT "static const gint16 attr_table_part1[$pages_before_e0000] = {\n";
+    for ($count = 0; $count <= $last_part1; $count += 256)
+    {
+       print OUT ",\n" if $count > 0;
+       print OUT "  ", $row[$count / 256];
+       $bytes_out += 2;
+    }
+    print OUT "\n};\n\n";
+
+    printf OUT "/* U+E0000 through U+%04X */\n", $last;
+    print OUT "static const gint16 attr_table_part2[768] = {\n";
+    for ($count = 0xE0000; $count <= $last; $count += 256)
+    {
+       print OUT ",\n" if $count > 0xE0000;
+       print OUT "  ", $row[$count / 256];
+       $bytes_out += 2;
+    }
+    print OUT "\n};\n\n";
+
+    #
+    # print title case table
+    #
+
+    print OUT "static const gunichar title_table[][3] = {\n";
+    my ($item);
+    my ($first) = 1;
+    foreach $item (sort keys %title_to_lower)
+    {
+       print OUT ",\n"
+           unless $first;
+       $first = 0;
+       printf OUT "  { 0x%04x, 0x%04x, 0x%04x }", $item, $title_to_upper{$item}, $title_to_lower{$item};
+       $bytes_out += 12;
+    }
+    print OUT "\n};\n\n";
+
+    #
+    # And special case conversion table -- conversions that change length
+    #
+    &output_special_case_table (\*OUT);
+    &output_casefold_table (\*OUT);
+
+    print OUT "#endif /* CHARTABLES_H */\n";
+
+    close (OUT);
+
+    printf STDERR "Generated %d bytes in tables\n", $bytes_out;
+}
+
+# A fetch function for the type table.
+sub fetch_type
+{
+    my ($index) = @_;
+    return $mappings{$type[$index]};
+}
+
+# A fetch function for the attribute table.
+sub fetch_attr
+{
+    my ($index) = @_;
+    if (defined $value[$index])
+      {
+        return sprintf ("0x%04x", $value[$index]);
+      }
+    else
+      {
+        return "0x0000";
+      }
+}
+
+sub print_row
+{
+    my ($start, $typsize, $fetcher) = @_;
+
+    my ($i);
+    my (@values);
+    my ($flag) = 1;
+    my ($off);
+
+    for ($off = 0; $off < 256; ++$off)
+    {
+       $values[$off] = $fetcher->($off + $start);
+       if ($values[$off] ne $values[0])
+       {
+           $flag = 0;
+       }
+    }
+    if ($flag)
+    {
+       return $values[0] . " + G_UNICODE_MAX_TABLE_INDEX";
+    }
+
+    printf OUT ",\n" if ($table_index != 0);
+    printf OUT "  { /* page %d, index %d */\n    ", $start / 256, $table_index;
+    my ($column) = 4;
+    for ($i = $start; $i < $start + 256; ++$i)
+    {
+       print OUT ", "
+           if $i > $start;
+       my ($text) = $values[$i - $start];
+       if (length ($text) + $column + 2 > 78)
+       {
+           print OUT "\n    ";
+           $column = 4;
+       }
+       print OUT $text;
+       $column += length ($text) + 2;
+    }
+    print OUT "\n  }";
+
+    $bytes_out += 256 * $typsize;
+
+    return sprintf "%d /* page %d */", $table_index++, $start / 256;
+}
+
+sub escape
+{
+    my ($string) = @_;
+
+    my $escaped = unpack("H*", $string);
+    $escaped =~ s/(.{2})/\\x$1/g;
+
+    return $escaped;
+}
+
+# Returns the offset of $decomp in the offset string. Updates the
+# referenced variables as appropriate.
+sub handle_decomp ($$$$)
+{
+    my ($decomp, $decomp_offsets_ref, $decomp_string_ref, $decomp_string_offset_ref) = @_;
+    my $offset = "G_UNICODE_NOT_PRESENT_OFFSET";
+
+    if (defined $decomp)
+    {
+        if (defined $decomp_offsets_ref->{$decomp})
+        {
+            $offset = $decomp_offsets_ref->{$decomp};
+        }
+        else
+        {
+            $offset = ${$decomp_string_offset_ref};
+            $decomp_offsets_ref->{$decomp} = $offset;
+            ${$decomp_string_ref} .= "\n  \"" . &escape ($decomp) . "\\0\" /* offset ${$decomp_string_offset_ref} */";
+            ${$decomp_string_offset_ref} += &length_in_bytes ($decomp) + 1;
+        }
+    }
+
+    return $offset;
+}
+
+# Generate the character decomposition header.
+sub print_decomp
+{
+    my ($last) = @_;
+    my ($outfile) = "gunidecomp.h";
+
+    local ($bytes_out) = 0;
+
+    print "Writing $outfile...\n";
+
+    open (OUT, "> $outfile") || exit 1;
+
+    print OUT "/* This file is automatically generated.  DO NOT EDIT! */\n\n";
+    print OUT "#ifndef DECOMP_H\n";
+    print OUT "#define DECOMP_H\n\n";
+
+    printf OUT "#define G_UNICODE_LAST_CHAR 0x%04x\n\n", $last;
+
+    printf OUT "#define G_UNICODE_MAX_TABLE_INDEX (0x110000 / 256)\n\n";
+
+    my $last_part1 = ($pages_before_e0000 * 256) - 1;
+    printf OUT "#define G_UNICODE_LAST_CHAR_PART1 0x%04X\n\n", $last_part1;
+    printf OUT "#define G_UNICODE_LAST_PAGE_PART1 %d\n\n", $pages_before_e0000 - 1;
+
+    $NOT_PRESENT_OFFSET = 65535;
+    print OUT "#define G_UNICODE_NOT_PRESENT_OFFSET $NOT_PRESENT_OFFSET\n\n";
+
+    my ($count, @row);
+    $table_index = 0;
+    printf OUT "static const guchar cclass_data[][256] = {\n";
+    for ($count = 0; $count <= $last; $count += 256)
+    {
+       $row[$count / 256] = &print_row ($count, 1, \&fetch_cclass);
+    }
+    printf OUT "\n};\n\n";
+
+    print OUT "static const gint16 combining_class_table_part1[$pages_before_e0000] = {\n";
+    for ($count = 0; $count <= $last_part1; $count += 256)
+    {
+       print OUT ",\n" if $count > 0;
+       print OUT "  ", $row[$count / 256];
+       $bytes_out += 2;
+    }
+    print OUT "\n};\n\n";
+
+    print OUT "static const gint16 combining_class_table_part2[768] = {\n";
+    for ($count = 0xE0000; $count <= $last; $count += 256)
+    {
+       print OUT ",\n" if $count > 0xE0000;
+       print OUT "  ", $row[$count / 256];
+       $bytes_out += 2;
+    }
+    print OUT "\n};\n\n";
+
+    print OUT "typedef struct\n{\n";
+    print OUT "  gunichar ch;\n";
+    print OUT "  guint16 canon_offset;\n";
+    print OUT "  guint16 compat_offset;\n";
+    print OUT "} decomposition;\n\n";
+
+    print OUT "static const decomposition decomp_table[] =\n{\n";
+    my ($iter);
+    my ($first) = 1;
+    my ($decomp_string) = "";
+    my ($decomp_string_offset) = 0;
+    for ($count = 0; $count <= $last; ++$count)
+    {
+       if (defined $decompositions[$count])
+       {
+           print OUT ",\n"
+               if ! $first;
+           $first = 0;
+
+           my $canon_decomp;
+           my $compat_decomp;
+
+           if (!$decompose_compat[$count]) {
+               $canon_decomp = make_decomp ($count, 0);
+           }
+           $compat_decomp = make_decomp ($count, 1);
+
+           if (defined $canon_decomp && $compat_decomp eq $canon_decomp) {
+               undef $compat_decomp; 
+           }
+
+           my $canon_offset = handle_decomp ($canon_decomp, \%decomp_offsets, \$decomp_string, \$decomp_string_offset);
+           my $compat_offset = handle_decomp ($compat_decomp, \%decomp_offsets, \$decomp_string, \$decomp_string_offset);
+
+            die if $decomp_string_offset > $NOT_PRESENT_OFFSET;
+
+            printf OUT qq(  { 0x%04x, $canon_offset, $compat_offset }), $count;
+           $bytes_out += 8;
+       }
+    }
+    print OUT "\n};\n\n";
+    $bytes_out += $decomp_string_offset + 1;
+
+    printf OUT "static const gchar decomp_expansion_string[] = %s;\n\n", $decomp_string;
+
+    print OUT "#endif /* DECOMP_H */\n";
+
+    printf STDERR "Generated %d bytes in decomp tables\n", $bytes_out;
+}
+
+sub print_line_break
+{
+    my ($last) = @_;
+    my ($outfile) = "gunibreak.h";
+
+    local ($bytes_out) = 0;
+
+    print "Writing $outfile...\n";
+
+    open (OUT, "> $outfile");
+
+    print OUT "/* This file is automatically generated.  DO NOT EDIT!\n";
+    print OUT "   Instead, edit gen-unicode-tables.pl and re-run.  */\n\n";
+
+    print OUT "#ifndef BREAKTABLES_H\n";
+    print OUT "#define BREAKTABLES_H\n\n";
+
+    print OUT "#define G_UNICODE_DATA_VERSION \"$ARGV[0]\"\n\n";
+
+    printf OUT "#define G_UNICODE_LAST_CHAR 0x%04X\n\n", $last;
+
+    printf OUT "#define G_UNICODE_MAX_TABLE_INDEX 10000\n\n";
+
+    my $last_part1 = ($pages_before_e0000 * 256) - 1;
+    printf OUT "/* the last code point that should be looked up in break_property_table_part1 */\n";
+    printf OUT "#define G_UNICODE_LAST_CHAR_PART1 0x%04X\n\n", $last_part1;
+
+    $table_index = 0;
+    printf OUT "static const gint8 break_property_data[][256] = {\n";
+    for ($count = 0; $count <= $last; $count += 256)
+    {
+       $row[$count / 256] = &print_row ($count, 1, \&fetch_break_type);
+    }
+    printf OUT "\n};\n\n";
+
+    printf OUT "/* U+0000 through U+%04X */\n", $last_part1;
+    print OUT "static const gint16 break_property_table_part1[$pages_before_e0000] = {\n";
+    for ($count = 0; $count <= $last_part1; $count += 256)
+    {
+       print OUT ",\n" if $count > 0;
+       print OUT "  ", $row[$count / 256];
+       $bytes_out += 2;
+    }
+    print OUT "\n};\n\n";
+
+    printf OUT "/* U+E0000 through U+%04X */\n", $last;
+    print OUT "static const gint16 break_property_table_part2[768] = {\n";
+    for ($count = 0xE0000; $count <= $last; $count += 256)
+    {
+       print OUT ",\n" if $count > 0xE0000;
+       print OUT "  ", $row[$count / 256];
+       $bytes_out += 2;
+    }
+    print OUT "\n};\n\n";
+
+
+    print OUT "#endif /* BREAKTABLES_H */\n";
+
+    close (OUT);
+
+    printf STDERR "Generated %d bytes in break tables\n", $bytes_out;
+}
+
+
+# A fetch function for the break properties table.
+sub fetch_break_type
+{
+    my ($index) = @_;
+    return $break_mappings{$break_props[$index]};
+}
+
+# Fetcher for combining class.
+sub fetch_cclass
+{
+    my ($i) = @_;
+    return $cclass[$i];
+}
+
+# Expand a character decomposition recursively.
+sub expand_decomp
+{
+    my ($code, $compat) = @_;
+
+    my ($iter, $val);
+    my (@result) = ();
+    foreach $iter (split (' ', $decompositions[$code]))
+    {
+       $val = hex ($iter);
+       if (defined $decompositions[$val] && 
+           ($compat || !$decompose_compat[$val]))
+       {
+           push (@result, &expand_decomp ($val, $compat));
+       }
+       else
+       {
+           push (@result, $val);
+       }
+    }
+
+    return @result;
+}
+
+sub make_decomp
+{
+    my ($code, $compat) = @_;
+
+    my $result = "";
+    foreach $iter (&expand_decomp ($code, $compat))
+    {
+       $result .= pack ("U", $iter);  # to utf-8
+    }
+
+    $result;
+}
+# Generate special case data string from two fields
+sub add_special_case
+{
+    my ($code, $single, $field1, $field2) = @_;
+
+    @values = (defined $single ? $single : (),
+              (map { hex ($_) } split /\s+/, $field1),
+               0,
+               (map { hex ($_) } split /\s+/, $field2));
+    $result = "";
+
+
+    for $value (@values) {
+       $result .= pack ("U", $value);  # to utf-8
+    }
+    
+    push @special_case_offsets, $special_case_offset;
+
+    # We encode special cases up in the 0x1000000 space
+    $value[$code] = 0x1000000 + $special_case_offset;
+
+    $special_case_offset += 1 + &length_in_bytes ($result);
+
+    push @special_cases, &escape ($result);
+}
+
+sub output_special_case_table
+{
+    my $out = shift;
+
+    print $out <<EOT;
+
+/* Table of special cases for case conversion; each record contains
+ * First, the best single character mapping to lowercase if Lu, 
+ * and to uppercase if Ll, followed by the output mapping for the two cases 
+ * other than the case of the codepoint, in the order [Ll],[Lu],[Lt],
+ * encoded in UTF-8, separated and terminated by a null character.
+ */
+static const gchar special_case_table[] = {
+EOT
+
+    my $i = 0;
+    for $case (@special_cases) {
+       print $out qq( "$case\\0" /* offset ${special_case_offsets[$i]} */\n);
+        $i++;
+    }
+
+    print $out <<EOT;
+};
+
+EOT
+
+    print STDERR "Generated " . ($special_case_offset + 1) . " bytes in special case table\n";
+}
+
+sub enumerate_ordered
+{
+    my ($array) = @_;
+
+    my $n = 0;
+    for my $code (sort { $a <=> $b } keys %$array) {
+       if ($array->{$code} == 1) {
+           delete $array->{$code};
+           next;
+       }
+       $array->{$code} = $n++;
+    }
+
+    return $n;
+}
+
+sub output_composition_table
+{
+    print STDERR "Generating composition table\n";
+    
+    local ($bytes_out) = 0;
+
+    my %first;
+    my %second;
+
+    # First we need to go through and remove decompositions
+    # starting with a non-starter, and single-character 
+    # decompositions. At the same time, record
+    # the first and second character of each decomposition
+    
+    for $code (keys %compositions) 
+    {
+       @values = map { hex ($_) } split /\s+/, $compositions{$code};
+
+        # non-starters
+       if ($cclass[$values[0]]) {
+           delete $compositions{$code};
+           next;
+       }
+
+        # single-character decompositions
+       if (@values == 1) {
+           delete $compositions{$code};
+           next;
+       }
+
+       if (@values != 2) {
+           die "$code has more than two elements in its decomposition!\n";
+       }
+
+       if (exists $first{$values[0]}) {
+           $first{$values[0]}++;
+       } else {
+           $first{$values[0]} = 1;
+       }
+    }
+
+    # Assign integer indices, removing singletons
+    my $n_first = enumerate_ordered (\%first);
+
+    # Now record the second character of each (non-singleton) decomposition
+    for $code (keys %compositions) {
+       @values = map { hex ($_) } split /\s+/, $compositions{$code};
+
+       if (exists $first{$values[0]}) {
+           if (exists $second{$values[1]}) {
+               $second{$values[1]}++;
+           } else {
+               $second{$values[1]} = 1;
+           }
+       }
+    }
+
+    # Assign integer indices, removing duplicate
+    my $n_second = enumerate_ordered (\%second);
+
+    # Build reverse table
+
+    my @first_singletons;
+    my @second_singletons;
+    my %reverse;
+    for $code (keys %compositions) {
+       @values = map { hex ($_) } split /\s+/, $compositions{$code};
+
+       my $first = $first{$values[0]};
+       my $second = $second{$values[1]};
+
+       if (defined $first && defined $second) {
+           $reverse{"$first|$second"} = $code;
+       } elsif (!defined $first) {
+           push @first_singletons, [ $values[0], $values[1], $code ];
+       } else {
+           push @second_singletons, [ $values[1], $values[0], $code ];
+       }
+    }
+
+    @first_singletons = sort { $a->[0] <=> $b->[0] } @first_singletons;
+    @second_singletons = sort { $a->[0] <=> $b->[0] } @second_singletons;
+
+    my %vals;
+    
+    open OUT, ">gunicomp.h" or die "Cannot open gunicomp.h: $!\n";
+    
+    # Assign values in lookup table for all code points involved
+    
+    my $total = 1;
+    my $last = 0;
+    printf OUT "#define COMPOSE_FIRST_START %d\n", $total;
+    for $code (keys %first) {
+       $vals{$code} = $first{$code} + $total;
+       $last = $code if $code > $last;
+    }
+    $total += $n_first;
+    $i = 0;
+    printf OUT "#define COMPOSE_FIRST_SINGLE_START %d\n", $total;
+    for $record (@first_singletons) {
+       my $code = $record->[0];
+       $vals{$code} = $i++ + $total;
+       $last = $code if $code > $last;
+    }
+    $total += @first_singletons;
+    printf OUT "#define COMPOSE_SECOND_START %d\n", $total;
+    for $code (keys %second) {
+       $vals{$code} = $second{$code} + $total;
+       $last = $code if $code > $last;
+    }
+    $total += $n_second;
+    $i = 0;
+    printf OUT "#define COMPOSE_SECOND_SINGLE_START %d\n\n", $total;
+    for $record (@second_singletons) {
+       my $code = $record->[0];
+       $vals{$code} = $i++ + $total;
+       $last = $code if $code > $last;
+    }
+
+    printf OUT "#define COMPOSE_TABLE_LAST %d\n\n", $last / 256;
+
+    # Output lookup table
+
+    my @row;                                             
+    $table_index = 0;
+    printf OUT "static const guint16 compose_data[][256] = {\n";
+    for (my $count = 0; $count <= $last; $count += 256)
+    {
+       $row[$count / 256] = &print_row ($count, 2, sub { exists $vals{$_[0]} ? $vals{$_[0]} : 0; });
+    }
+    printf OUT "\n};\n\n";
+
+    print OUT "static const gint16 compose_table[COMPOSE_TABLE_LAST + 1] = {\n";
+    for (my $count = 0; $count <= $last; $count += 256)
+    {
+       print OUT ",\n" if $count > 0;
+       print OUT "  ", $row[$count / 256];
+        $bytes_out += 2;
+    }
+    print OUT "\n};\n\n";
+
+    # Output first singletons
+
+    print OUT "static const guint16 compose_first_single[][2] = {\n";
+    $i = 0;                                 
+    for $record (@first_singletons) {
+        if ($record->[1] > 0xFFFF or $record->[2] > 0xFFFF) {
+            die "time to switch compose_first_single to gunichar" ;
+        }
+       print OUT ",\n" if $i++ > 0;
+       printf OUT " { %#06x, %#06x }", $record->[1], $record->[2];
+    }
+    print OUT "\n};\n";
+                                    
+    $bytes_out += @first_singletons * 4;
+                 
+    # Output second singletons
+
+    print OUT "static const guint16 compose_second_single[][2] = {\n";
+    $i = 0;                                 
+    for $record (@second_singletons) {
+        if ($record->[1] > 0xFFFF or $record->[2] > 0xFFFF) {
+            die "time to switch compose_second_single to gunichar";
+        }
+       print OUT ",\n" if $i++ > 0;
+       printf OUT " { %#06x, %#06x }", $record->[1], $record->[2];
+    }
+    print OUT "\n};\n";
+                                    
+    $bytes_out += @second_singletons * 4;                                   
+                 
+    # Output array of composition pairs
+
+    print OUT <<EOT;
+static const guint16 compose_array[$n_first][$n_second] = {
+EOT
+                       
+    for (my $i = 0; $i < $n_first; $i++) {
+       print OUT ",\n" if $i;
+       print OUT " { ";
+       for (my $j = 0; $j < $n_second; $j++) {
+           print OUT ", " if $j;
+           if (exists $reverse{"$i|$j"}) {
+                if ($reverse{"$i|$j"} > 0xFFFF) {
+                    die "time to switch compose_array to gunichar" ;
+                }
+               printf OUT "0x%04x", $reverse{"$i|$j"};
+           } else {
+               print OUT "     0";
+            }
+       }
+       print OUT " }";
+    }
+    print OUT "\n";
+
+    print OUT <<EOT;
+};
+EOT
+
+    $bytes_out += $n_first * $n_second * 2;
+    
+    printf STDERR "Generated %d bytes in compose tables\n", $bytes_out;
+}
+
+sub output_casefold_table
+{
+    my $out = shift;
+
+    print $out <<EOT;
+
+/* Table of casefolding cases that can't be derived by lowercasing
+ */
+static const struct {
+  guint16 ch;
+  gchar data[$casefoldlen];
+} casefold_table[] = {
+EOT
+
+   @casefold = sort { $a->[0] <=> $b->[0] } @casefold; 
+    
+   for $case (@casefold) 
+   {
+       $code = $case->[0];
+       $string = $case->[1];
+
+       if ($code > 0xFFFF) {
+           die "time to switch casefold_table to gunichar" ;
+       }
+
+       print $out sprintf(qq(  { 0x%04x, "$string" },\n), $code);
+    
+   }
+
+    print $out <<EOT;
+};
+
+EOT
+
+   my $recordlen = (2+$casefoldlen+1) & ~1;
+   printf "Generated %d bytes for casefold table\n", $recordlen * @casefold;
+}
+
+                            
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gerror.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gerror.c
new file mode 100644 (file)
index 0000000..1f39739
--- /dev/null
@@ -0,0 +1,387 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+
+#include "gerror.h"
+
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+
+/**
+ * g_error_new_valist:
+ * @domain: error domain
+ * @code: error code
+ * @format: printf()-style format for error message
+ * @args: #va_list of parameters for the message format
+ *
+ * Creates a new #GError with the given @domain and @code,
+ * and a message formatted with @format.
+ *
+ * Returns: a new #GError
+ *
+ * Since: 2.22
+ */
+GError*
+g_error_new_valist (GQuark       domain,
+                    gint         code,
+                    const gchar *format,
+                    va_list      args)
+{
+  GError *error;
+
+  error = g_slice_new (GError);
+
+  error->domain = domain;
+  error->code = code;
+  error->message = g_strdup_vprintf (format, args);
+
+  return error;
+}
+
+/**
+ * g_error_new:
+ * @domain: error domain
+ * @code: error code
+ * @format: printf()-style format for error message
+ * @Varargs: parameters for message format
+ *
+ * Creates a new #GError with the given @domain and @code,
+ * and a message formatted with @format.
+ *
+ * Return value: a new #GError
+ */
+GError*
+g_error_new (GQuark       domain,
+             gint         code,
+             const gchar *format,
+             ...)
+{
+  GError* error;
+  va_list args;
+
+  g_return_val_if_fail (format != NULL, NULL);
+  g_return_val_if_fail (domain != 0, NULL);
+
+  va_start (args, format);
+  error = g_error_new_valist (domain, code, format, args);
+  va_end (args);
+
+  return error;
+}
+
+/**
+ * g_error_new_literal:
+ * @domain: error domain
+ * @code: error code
+ * @message: error message
+ *
+ * Creates a new #GError; unlike g_error_new(), @message is
+ * not a printf()-style format string. Use this function if
+ * @message contains text you don't have control over,
+ * that could include printf() escape sequences.
+ *
+ * Return value: a new #GError
+ **/
+GError*
+g_error_new_literal (GQuark         domain,
+                     gint           code,
+                     const gchar   *message)
+{
+  GError* err;
+
+  g_return_val_if_fail (message != NULL, NULL);
+  g_return_val_if_fail (domain != 0, NULL);
+
+  err = g_slice_new (GError);
+
+  err->domain = domain;
+  err->code = code;
+  err->message = g_strdup (message);
+
+  return err;
+}
+
+/**
+ * g_error_free:
+ * @error: a #GError
+ *
+ * Frees a #GError and associated resources.
+ */
+void
+g_error_free (GError *error)
+{
+  g_return_if_fail (error != NULL);
+
+  g_free (error->message);
+
+  g_slice_free (GError, error);
+}
+
+/**
+ * g_error_copy:
+ * @error: a #GError
+ *
+ * Makes a copy of @error.
+ *
+ * Return value: a new #GError
+ */
+GError*
+g_error_copy (const GError *error)
+{
+  GError *copy;
+  g_return_val_if_fail (error != NULL, NULL);
+
+  copy = g_slice_new (GError);
+
+  *copy = *error;
+
+  copy->message = g_strdup (error->message);
+
+  return copy;
+}
+
+/**
+ * g_error_matches:
+ * @error: a #GError or %NULL
+ * @domain: an error domain
+ * @code: an error code
+ *
+ * Returns %TRUE if @error matches @domain and @code, %FALSE
+ * otherwise. In particular, when @error is %NULL, %FALSE will
+ * be returned.
+ *
+ * Return value: whether @error has @domain and @code
+ */
+gboolean
+g_error_matches (const GError *error,
+                 GQuark        domain,
+                 gint          code)
+{
+  return error &&
+    error->domain == domain &&
+    error->code == code;
+}
+
+#define ERROR_OVERWRITTEN_WARNING "GError set over the top of a previous GError or uninitialized memory.\n" \
+               "This indicates a bug in someone's code. You must ensure an error is NULL before it's set.\n" \
+               "The overwriting error message was: %s"
+
+/**
+ * g_set_error:
+ * @err: a return location for a #GError, or %NULL
+ * @domain: error domain
+ * @code: error code
+ * @format: printf()-style format
+ * @Varargs: args for @format
+ *
+ * Does nothing if @err is %NULL; if @err is non-%NULL, then *@err
+ * must be %NULL. A new #GError is created and assigned to *@err.
+ */
+void
+g_set_error (GError      **err,
+             GQuark        domain,
+             gint          code,
+             const gchar  *format,
+             ...)
+{
+  GError *new;
+
+  va_list args;
+
+  if (err == NULL)
+    return;
+
+  va_start (args, format);
+  new = g_error_new_valist (domain, code, format, args);
+  va_end (args);
+
+  if (*err == NULL)
+    *err = new;
+  else
+    g_warning (ERROR_OVERWRITTEN_WARNING, new->message); 
+}
+
+/**
+ * g_set_error_literal:
+ * @err: a return location for a #GError, or %NULL
+ * @domain: error domain
+ * @code: error code
+ * @message: error message
+ *
+ * Does nothing if @err is %NULL; if @err is non-%NULL, then *@err
+ * must be %NULL. A new #GError is created and assigned to *@err.
+ * Unlike g_set_error(), @message is not a printf()-style format string.
+ * Use this function if @message contains text you don't have control over,
+ * that could include printf() escape sequences.
+ *
+ * Since: 2.18
+ */
+void
+g_set_error_literal (GError      **err,
+                     GQuark        domain,
+                     gint          code,
+                     const gchar  *message)
+{
+  GError *new;
+
+  if (err == NULL)
+    return;
+
+  new = g_error_new_literal (domain, code, message);
+  if (*err == NULL)
+    *err = new;
+  else
+    g_warning (ERROR_OVERWRITTEN_WARNING, new->message); 
+}
+
+/**
+ * g_propagate_error:
+ * @dest: error return location
+ * @src: error to move into the return location
+ *
+ * If @dest is %NULL, free @src; otherwise, moves @src into *@dest.
+ * The error variable @dest points to must be %NULL.
+ */
+void
+g_propagate_error (GError **dest,
+                  GError  *src)
+{
+  g_return_if_fail (src != NULL);
+  if (dest == NULL)
+    {
+      if (src)
+        g_error_free (src);
+      return;
+    }
+  else
+    {
+      if (*dest != NULL)
+        g_warning (ERROR_OVERWRITTEN_WARNING, src->message);
+      else
+        *dest = src;
+    }
+}
+
+/**
+ * g_clear_error:
+ * @err: a #GError return location
+ *
+ * If @err is %NULL, does nothing. If @err is non-%NULL,
+ * calls g_error_free() on *@err and sets *@err to %NULL.
+ */
+void
+g_clear_error (GError **err)
+{
+  if (err && *err)
+    {
+      g_error_free (*err);
+      *err = NULL;
+    }
+}
+
+static void
+g_error_add_prefix (gchar       **string,
+                    const gchar  *format,
+                    va_list       ap)
+{
+  gchar *oldstring;
+  gchar *prefix;
+
+  prefix = g_strdup_vprintf (format, ap);
+  oldstring = *string;
+  *string = g_strconcat (prefix, oldstring, NULL);
+  g_free (oldstring);
+  g_free (prefix);
+}
+
+/**
+ * g_prefix_error:
+ * @err: a return location for a #GError, or %NULL
+ * @format: printf()-style format string
+ * @...: arguments to @format
+ *
+ * Formats a string according to @format and
+ * prefix it to an existing error message.  If
+ * @err is %NULL (ie: no error variable) then do
+ * nothing.
+ *
+ * If *@err is %NULL (ie: an error variable is
+ * present but there is no error condition) then
+ * also do nothing.  Whether or not it makes
+ * sense to take advantage of this feature is up
+ * to you.
+ *
+ * Since: 2.16
+ */
+void
+g_prefix_error (GError      **err,
+                const gchar  *format,
+                ...)
+{
+  if (err && *err)
+    {
+      va_list ap;
+
+      va_start (ap, format);
+      g_error_add_prefix (&(*err)->message, format, ap);
+      va_end (ap);
+    }
+}
+
+/**
+ * g_propagate_prefixed_error:
+ * @dest: error return location
+ * @src: error to move into the return location
+ * @format: printf()-style format string
+ * @...: arguments to @format
+ *
+ * If @dest is %NULL, free @src; otherwise,
+ * moves @src into *@dest. *@dest must be %NULL.
+ * After the move, add a prefix as with
+ * g_prefix_error().
+ *
+ * Since: 2.16
+ **/
+void
+g_propagate_prefixed_error (GError      **dest,
+                            GError       *src,
+                            const gchar  *format,
+                            ...)
+{
+  g_propagate_error (dest, src);
+
+  if (dest && *dest)
+    {
+      va_list ap;
+
+      va_start (ap, format);
+      g_error_add_prefix (&(*dest)->message, format, ap);
+      va_end (ap);
+    }
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gerror.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gerror.h
new file mode 100644 (file)
index 0000000..b303487
--- /dev/null
@@ -0,0 +1,98 @@
+/* gerror.h - Error reporting system
+ *
+ *  Copyright 2000 Red Hat, Inc.
+ *
+ * The Gnome 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 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *   Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_ERROR_H__
+#define __G_ERROR_H__
+
+#include <stdarg.h>
+
+#include <glib/gquark.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GError GError;
+
+struct _GError
+{
+  GQuark       domain;
+  gint         code;
+  gchar       *message;
+};
+
+GError*  g_error_new           (GQuark         domain,
+                                gint           code,
+                                const gchar   *format,
+                                ...) G_GNUC_PRINTF (3, 4);
+
+GError*  g_error_new_literal   (GQuark         domain,
+                                gint           code,
+                                const gchar   *message);
+GError*  g_error_new_valist    (GQuark         domain,
+                                gint           code,
+                                const gchar   *format,
+                                va_list        args);
+
+void     g_error_free          (GError        *error);
+GError*  g_error_copy          (const GError  *error);
+
+gboolean g_error_matches       (const GError  *error,
+                                GQuark         domain,
+                                gint           code);
+
+/* if (err) *err = g_error_new(domain, code, format, ...), also has
+ * some sanity checks.
+ */
+void     g_set_error           (GError       **err,
+                                GQuark         domain,
+                                gint           code,
+                                const gchar   *format,
+                                ...) G_GNUC_PRINTF (4, 5);
+
+void     g_set_error_literal   (GError       **err,
+                                GQuark         domain,
+                                gint           code,
+                                const gchar   *message);
+
+/* if (dest) *dest = src; also has some sanity checks.
+ */
+void     g_propagate_error     (GError       **dest,
+                               GError        *src);
+
+/* if (err && *err) { g_error_free(*err); *err = NULL; } */
+void     g_clear_error         (GError       **err);
+
+/* if (err) prefix the formatted string to the ->message */
+void     g_prefix_error               (GError       **err,
+                                       const gchar   *format,
+                                       ...) G_GNUC_PRINTF (2, 3);
+
+/* g_propagate_error then g_error_prefix on dest */
+void     g_propagate_prefixed_error   (GError       **dest,
+                                       GError        *src,
+                                       const gchar   *format,
+                                       ...) G_GNUC_PRINTF (3, 4);
+
+G_END_DECLS
+
+#endif /* __G_ERROR_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gfileutils.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gfileutils.c
new file mode 100644 (file)
index 0000000..185a756
--- /dev/null
@@ -0,0 +1,2020 @@
+/* gfileutils.c - File utility functions
+ *
+ *  Copyright 2000 Red Hat, Inc.
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *   Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "glibconfig.h"
+
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <stdlib.h>
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include <io.h>
+#endif /* G_OS_WIN32 */
+
+#ifndef S_ISLNK
+#define S_ISLNK(x) 0
+#endif
+
+#ifndef O_BINARY
+#define O_BINARY 0
+#endif
+
+#include "gfileutils.h"
+
+#include "gstdio.h"
+#include "glibintl.h"
+
+
+/**
+ * g_mkdir_with_parents:
+ * @pathname: a pathname in the GLib file name encoding
+ * @mode: permissions to use for newly created directories
+ *
+ * Create a directory if it doesn't already exist. Create intermediate
+ * parent directories as needed, too.
+ *
+ * Returns: 0 if the directory already exists, or was successfully
+ * created. Returns -1 if an error occurred, with errno set.
+ *
+ * Since: 2.8
+ */
+int
+g_mkdir_with_parents (const gchar *pathname,
+                     int          mode)
+{
+  gchar *fn, *p;
+
+  if (pathname == NULL || *pathname == '\0')
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  fn = g_strdup (pathname);
+
+  if (g_path_is_absolute (fn))
+    p = (gchar *) g_path_skip_root (fn);
+  else
+    p = fn;
+
+  do
+    {
+      while (*p && !G_IS_DIR_SEPARATOR (*p))
+       p++;
+      
+      if (!*p)
+       p = NULL;
+      else
+       *p = '\0';
+      
+      if (!g_file_test (fn, G_FILE_TEST_EXISTS))
+       {
+         if (g_mkdir (fn, mode) == -1)
+           {
+             int errno_save = errno;
+             g_free (fn);
+             errno = errno_save;
+             return -1;
+           }
+       }
+      else if (!g_file_test (fn, G_FILE_TEST_IS_DIR))
+       {
+         g_free (fn);
+         errno = ENOTDIR;
+         return -1;
+       }
+      if (p)
+       {
+         *p++ = G_DIR_SEPARATOR;
+         while (*p && G_IS_DIR_SEPARATOR (*p))
+           p++;
+       }
+    }
+  while (p);
+
+  g_free (fn);
+
+  return 0;
+}
+
+/**
+ * g_file_test:
+ * @filename: a filename to test in the GLib file name encoding
+ * @test: bitfield of #GFileTest flags
+ * 
+ * Returns %TRUE if any of the tests in the bitfield @test are
+ * %TRUE. For example, <literal>(G_FILE_TEST_EXISTS | 
+ * G_FILE_TEST_IS_DIR)</literal> will return %TRUE if the file exists; 
+ * the check whether it's a directory doesn't matter since the existence 
+ * test is %TRUE. With the current set of available tests, there's no point
+ * passing in more than one test at a time.
+ * 
+ * Apart from %G_FILE_TEST_IS_SYMLINK all tests follow symbolic links,
+ * so for a symbolic link to a regular file g_file_test() will return
+ * %TRUE for both %G_FILE_TEST_IS_SYMLINK and %G_FILE_TEST_IS_REGULAR.
+ *
+ * Note, that for a dangling symbolic link g_file_test() will return
+ * %TRUE for %G_FILE_TEST_IS_SYMLINK and %FALSE for all other flags.
+ *
+ * You should never use g_file_test() to test whether it is safe
+ * to perform an operation, because there is always the possibility
+ * of the condition changing before you actually perform the operation.
+ * For example, you might think you could use %G_FILE_TEST_IS_SYMLINK
+ * to know whether it is safe to write to a file without being
+ * tricked into writing into a different location. It doesn't work!
+ * |[
+ * /&ast; DON'T DO THIS &ast;/
+ *  if (!g_file_test (filename, G_FILE_TEST_IS_SYMLINK)) 
+ *    {
+ *      fd = g_open (filename, O_WRONLY);
+ *      /&ast; write to fd &ast;/
+ *    }
+ * ]|
+ *
+ * Another thing to note is that %G_FILE_TEST_EXISTS and
+ * %G_FILE_TEST_IS_EXECUTABLE are implemented using the access()
+ * system call. This usually doesn't matter, but if your program
+ * is setuid or setgid it means that these tests will give you
+ * the answer for the real user ID and group ID, rather than the
+ * effective user ID and group ID.
+ *
+ * On Windows, there are no symlinks, so testing for
+ * %G_FILE_TEST_IS_SYMLINK will always return %FALSE. Testing for
+ * %G_FILE_TEST_IS_EXECUTABLE will just check that the file exists and
+ * its name indicates that it is executable, checking for well-known
+ * extensions and those listed in the %PATHEXT environment variable.
+ *
+ * Return value: whether a test was %TRUE
+ **/
+gboolean
+g_file_test (const gchar *filename,
+             GFileTest    test)
+{
+#ifdef G_OS_WIN32
+/* stuff missing in std vc6 api */
+#  ifndef INVALID_FILE_ATTRIBUTES
+#    define INVALID_FILE_ATTRIBUTES -1
+#  endif
+#  ifndef FILE_ATTRIBUTE_DEVICE
+#    define FILE_ATTRIBUTE_DEVICE 64
+#  endif
+  int attributes;
+  wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+
+  if (wfilename == NULL)
+    return FALSE;
+
+  attributes = GetFileAttributesW (wfilename);
+
+  g_free (wfilename);
+
+  if (attributes == INVALID_FILE_ATTRIBUTES)
+    return FALSE;
+
+  if (test & G_FILE_TEST_EXISTS)
+    return TRUE;
+      
+  if (test & G_FILE_TEST_IS_REGULAR)
+    {
+      if ((attributes & (FILE_ATTRIBUTE_DIRECTORY | FILE_ATTRIBUTE_DEVICE)) == 0)
+       return TRUE;
+    }
+
+  if (test & G_FILE_TEST_IS_DIR)
+    {
+      if ((attributes & FILE_ATTRIBUTE_DIRECTORY) != 0)
+       return TRUE;
+    }
+
+  /* "while" so that we can exit this "loop" with a simple "break" */
+  while (test & G_FILE_TEST_IS_EXECUTABLE)
+    {
+      const gchar *lastdot = strrchr (filename, '.');
+      const gchar *pathext = NULL, *p;
+      int extlen;
+
+      if (lastdot == NULL)
+        break;
+
+      if (_stricmp (lastdot, ".exe") == 0 ||
+         _stricmp (lastdot, ".cmd") == 0 ||
+         _stricmp (lastdot, ".bat") == 0 ||
+         _stricmp (lastdot, ".com") == 0)
+       return TRUE;
+
+      /* Check if it is one of the types listed in %PATHEXT% */
+
+      pathext = g_getenv ("PATHEXT");
+      if (pathext == NULL)
+        break;
+
+      pathext = g_utf8_casefold (pathext, -1);
+
+      lastdot = g_utf8_casefold (lastdot, -1);
+      extlen = strlen (lastdot);
+
+      p = pathext;
+      while (TRUE)
+       {
+         const gchar *q = strchr (p, ';');
+         if (q == NULL)
+           q = p + strlen (p);
+         if (extlen == q - p &&
+             memcmp (lastdot, p, extlen) == 0)
+           {
+             g_free ((gchar *) pathext);
+             g_free ((gchar *) lastdot);
+             return TRUE;
+           }
+         if (*q)
+           p = q + 1;
+         else
+           break;
+       }
+
+      g_free ((gchar *) pathext);
+      g_free ((gchar *) lastdot);
+      break;
+    }
+
+  return FALSE;
+#else
+  if ((test & G_FILE_TEST_EXISTS) && (access (filename, F_OK) == 0))
+    return TRUE;
+  
+  if ((test & G_FILE_TEST_IS_EXECUTABLE) && (access (filename, X_OK) == 0))
+    {
+      if (getuid () != 0)
+       return TRUE;
+
+      /* For root, on some POSIX systems, access (filename, X_OK)
+       * will succeed even if no executable bits are set on the
+       * file. We fall through to a stat test to avoid that.
+       */
+    }
+  else
+    test &= ~G_FILE_TEST_IS_EXECUTABLE;
+
+  if (test & G_FILE_TEST_IS_SYMLINK)
+    {
+      struct stat s;
+
+      if ((lstat (filename, &s) == 0) && S_ISLNK (s.st_mode))
+        return TRUE;
+    }
+  
+  if (test & (G_FILE_TEST_IS_REGULAR |
+             G_FILE_TEST_IS_DIR |
+             G_FILE_TEST_IS_EXECUTABLE))
+    {
+      struct stat s;
+      
+      if (stat (filename, &s) == 0)
+       {
+         if ((test & G_FILE_TEST_IS_REGULAR) && S_ISREG (s.st_mode))
+           return TRUE;
+         
+         if ((test & G_FILE_TEST_IS_DIR) && S_ISDIR (s.st_mode))
+           return TRUE;
+
+         /* The extra test for root when access (file, X_OK) succeeds.
+          */
+         if ((test & G_FILE_TEST_IS_EXECUTABLE) &&
+             ((s.st_mode & S_IXOTH) ||
+              (s.st_mode & S_IXUSR) ||
+              (s.st_mode & S_IXGRP)))
+           return TRUE;
+       }
+    }
+
+  return FALSE;
+#endif
+}
+
+GQuark
+g_file_error_quark (void)
+{
+  return g_quark_from_static_string ("g-file-error-quark");
+}
+
+/**
+ * g_file_error_from_errno:
+ * @err_no: an "errno" value
+ * 
+ * Gets a #GFileError constant based on the passed-in @errno.
+ * For example, if you pass in %EEXIST this function returns
+ * #G_FILE_ERROR_EXIST. Unlike @errno values, you can portably
+ * assume that all #GFileError values will exist.
+ *
+ * Normally a #GFileError value goes into a #GError returned
+ * from a function that manipulates files. So you would use
+ * g_file_error_from_errno() when constructing a #GError.
+ * 
+ * Return value: #GFileError corresponding to the given @errno
+ **/
+GFileError
+g_file_error_from_errno (gint err_no)
+{
+  switch (err_no)
+    {
+#ifdef EEXIST
+    case EEXIST:
+      return G_FILE_ERROR_EXIST;
+      break;
+#endif
+
+#ifdef EISDIR
+    case EISDIR:
+      return G_FILE_ERROR_ISDIR;
+      break;
+#endif
+
+#ifdef EACCES
+    case EACCES:
+      return G_FILE_ERROR_ACCES;
+      break;
+#endif
+
+#ifdef ENAMETOOLONG
+    case ENAMETOOLONG:
+      return G_FILE_ERROR_NAMETOOLONG;
+      break;
+#endif
+
+#ifdef ENOENT
+    case ENOENT:
+      return G_FILE_ERROR_NOENT;
+      break;
+#endif
+
+#ifdef ENOTDIR
+    case ENOTDIR:
+      return G_FILE_ERROR_NOTDIR;
+      break;
+#endif
+
+#ifdef ENXIO
+    case ENXIO:
+      return G_FILE_ERROR_NXIO;
+      break;
+#endif
+
+#ifdef ENODEV
+    case ENODEV:
+      return G_FILE_ERROR_NODEV;
+      break;
+#endif
+
+#ifdef EROFS
+    case EROFS:
+      return G_FILE_ERROR_ROFS;
+      break;
+#endif
+
+#ifdef ETXTBSY
+    case ETXTBSY:
+      return G_FILE_ERROR_TXTBSY;
+      break;
+#endif
+
+#ifdef EFAULT
+    case EFAULT:
+      return G_FILE_ERROR_FAULT;
+      break;
+#endif
+
+#ifdef ELOOP
+    case ELOOP:
+      return G_FILE_ERROR_LOOP;
+      break;
+#endif
+
+#ifdef ENOSPC
+    case ENOSPC:
+      return G_FILE_ERROR_NOSPC;
+      break;
+#endif
+
+#ifdef ENOMEM
+    case ENOMEM:
+      return G_FILE_ERROR_NOMEM;
+      break;
+#endif
+
+#ifdef EMFILE
+    case EMFILE:
+      return G_FILE_ERROR_MFILE;
+      break;
+#endif
+
+#ifdef ENFILE
+    case ENFILE:
+      return G_FILE_ERROR_NFILE;
+      break;
+#endif
+
+#ifdef EBADF
+    case EBADF:
+      return G_FILE_ERROR_BADF;
+      break;
+#endif
+
+#ifdef EINVAL
+    case EINVAL:
+      return G_FILE_ERROR_INVAL;
+      break;
+#endif
+
+#ifdef EPIPE
+    case EPIPE:
+      return G_FILE_ERROR_PIPE;
+      break;
+#endif
+
+#ifdef EAGAIN
+    case EAGAIN:
+      return G_FILE_ERROR_AGAIN;
+      break;
+#endif
+
+#ifdef EINTR
+    case EINTR:
+      return G_FILE_ERROR_INTR;
+      break;
+#endif
+
+#ifdef EIO
+    case EIO:
+      return G_FILE_ERROR_IO;
+      break;
+#endif
+
+#ifdef EPERM
+    case EPERM:
+      return G_FILE_ERROR_PERM;
+      break;
+#endif
+
+#ifdef ENOSYS
+    case ENOSYS:
+      return G_FILE_ERROR_NOSYS;
+      break;
+#endif
+
+    default:
+      return G_FILE_ERROR_FAILED;
+      break;
+    }
+}
+
+static gboolean
+get_contents_stdio (const gchar  *display_filename,
+                    FILE         *f,
+                    gchar       **contents,
+                    gsize        *length,
+                    GError      **error)
+{
+  gchar buf[4096];
+  gsize bytes;
+  gchar *str = NULL;
+  gsize total_bytes = 0;
+  gsize total_allocated = 0;
+  gchar *tmp;
+
+  g_assert (f != NULL);
+
+  while (!feof (f))
+    {
+      gint save_errno;
+
+      bytes = fread (buf, 1, sizeof (buf), f);
+      save_errno = errno;
+
+      while ((total_bytes + bytes + 1) > total_allocated)
+        {
+          if (str)
+            total_allocated *= 2;
+          else
+            total_allocated = MIN (bytes + 1, sizeof (buf));
+
+          tmp = g_try_realloc (str, total_allocated);
+
+          if (tmp == NULL)
+            {
+              g_set_error (error,
+                           G_FILE_ERROR,
+                           G_FILE_ERROR_NOMEM,
+                           _("Could not allocate %lu bytes to read file \"%s\""),
+                           (gulong) total_allocated,
+                          display_filename);
+
+              goto error;
+            }
+
+         str = tmp;
+        }
+
+      if (ferror (f))
+        {
+          g_set_error (error,
+                       G_FILE_ERROR,
+                       g_file_error_from_errno (save_errno),
+                       _("Error reading file '%s': %s"),
+                       display_filename,
+                      g_strerror (save_errno));
+
+          goto error;
+        }
+
+      memcpy (str + total_bytes, buf, bytes);
+
+      if (total_bytes + bytes < total_bytes) 
+        {
+          g_set_error (error,
+                       G_FILE_ERROR,
+                       G_FILE_ERROR_FAILED,
+                       _("File \"%s\" is too large"),
+                       display_filename);
+
+          goto error;
+        }
+
+      total_bytes += bytes;
+    }
+
+  fclose (f);
+
+  if (total_allocated == 0)
+    {
+      str = g_new (gchar, 1);
+      total_bytes = 0;
+    }
+
+  str[total_bytes] = '\0';
+
+  if (length)
+    *length = total_bytes;
+
+  *contents = str;
+
+  return TRUE;
+
+ error:
+
+  g_free (str);
+  fclose (f);
+
+  return FALSE;
+}
+
+#ifndef G_OS_WIN32
+
+static gboolean
+get_contents_regfile (const gchar  *display_filename,
+                      struct stat  *stat_buf,
+                      gint          fd,
+                      gchar       **contents,
+                      gsize        *length,
+                      GError      **error)
+{
+  gchar *buf;
+  gsize bytes_read;
+  gsize size;
+  gsize alloc_size;
+  
+  size = stat_buf->st_size;
+
+  alloc_size = size + 1;
+  buf = g_try_malloc (alloc_size);
+
+  if (buf == NULL)
+    {
+      g_set_error (error,
+                   G_FILE_ERROR,
+                   G_FILE_ERROR_NOMEM,
+                   _("Could not allocate %lu bytes to read file \"%s\""),
+                   (gulong) alloc_size, 
+                  display_filename);
+
+      goto error;
+    }
+  
+  bytes_read = 0;
+  while (bytes_read < size)
+    {
+      gssize rc;
+          
+      rc = read (fd, buf + bytes_read, size - bytes_read);
+
+      if (rc < 0)
+        {
+          if (errno != EINTR) 
+            {
+             int save_errno = errno;
+
+              g_free (buf);
+              g_set_error (error,
+                           G_FILE_ERROR,
+                           g_file_error_from_errno (save_errno),
+                           _("Failed to read from file '%s': %s"),
+                           display_filename, 
+                          g_strerror (save_errno));
+
+             goto error;
+            }
+        }
+      else if (rc == 0)
+        break;
+      else
+        bytes_read += rc;
+    }
+      
+  buf[bytes_read] = '\0';
+
+  if (length)
+    *length = bytes_read;
+  
+  *contents = buf;
+
+  close (fd);
+
+  return TRUE;
+
+ error:
+
+  close (fd);
+  
+  return FALSE;
+}
+
+static gboolean
+get_contents_posix (const gchar  *filename,
+                    gchar       **contents,
+                    gsize        *length,
+                    GError      **error)
+{
+  struct stat stat_buf;
+  gint fd;
+  gchar *display_filename = g_filename_display_name (filename);
+
+  /* O_BINARY useful on Cygwin */
+  fd = open (filename, O_RDONLY|O_BINARY);
+
+  if (fd < 0)
+    {
+      int save_errno = errno;
+
+      g_set_error (error,
+                   G_FILE_ERROR,
+                   g_file_error_from_errno (save_errno),
+                   _("Failed to open file '%s': %s"),
+                   display_filename, 
+                  g_strerror (save_errno));
+      g_free (display_filename);
+
+      return FALSE;
+    }
+
+  /* I don't think this will ever fail, aside from ENOMEM, but. */
+  if (fstat (fd, &stat_buf) < 0)
+    {
+      int save_errno = errno;
+
+      close (fd);
+      g_set_error (error,
+                   G_FILE_ERROR,
+                   g_file_error_from_errno (save_errno),
+                   _("Failed to get attributes of file '%s': fstat() failed: %s"),
+                   display_filename, 
+                  g_strerror (save_errno));
+      g_free (display_filename);
+
+      return FALSE;
+    }
+
+  if (stat_buf.st_size > 0 && S_ISREG (stat_buf.st_mode))
+    {
+      gboolean retval = get_contents_regfile (display_filename,
+                                             &stat_buf,
+                                             fd,
+                                             contents,
+                                             length,
+                                             error);
+      g_free (display_filename);
+
+      return retval;
+    }
+  else
+    {
+      FILE *f;
+      gboolean retval;
+
+      f = fdopen (fd, "r");
+      
+      if (f == NULL)
+        {
+         int save_errno = errno;
+
+          g_set_error (error,
+                       G_FILE_ERROR,
+                       g_file_error_from_errno (save_errno),
+                       _("Failed to open file '%s': fdopen() failed: %s"),
+                       display_filename, 
+                      g_strerror (save_errno));
+          g_free (display_filename);
+
+          return FALSE;
+        }
+  
+      retval = get_contents_stdio (display_filename, f, contents, length, error);
+      g_free (display_filename);
+
+      return retval;
+    }
+}
+
+#else  /* G_OS_WIN32 */
+
+static gboolean
+get_contents_win32 (const gchar  *filename,
+                   gchar       **contents,
+                   gsize        *length,
+                   GError      **error)
+{
+  FILE *f;
+  gboolean retval;
+  gchar *display_filename = g_filename_display_name (filename);
+  int save_errno;
+  
+  f = g_fopen (filename, "rb");
+  save_errno = errno;
+
+  if (f == NULL)
+    {
+      g_set_error (error,
+                   G_FILE_ERROR,
+                   g_file_error_from_errno (save_errno),
+                   _("Failed to open file '%s': %s"),
+                   display_filename,
+                  g_strerror (save_errno));
+      g_free (display_filename);
+
+      return FALSE;
+    }
+  
+  retval = get_contents_stdio (display_filename, f, contents, length, error);
+  g_free (display_filename);
+
+  return retval;
+}
+
+#endif
+
+/**
+ * g_file_get_contents:
+ * @filename: name of a file to read contents from, in the GLib file name encoding
+ * @contents: location to store an allocated string, use g_free() to free
+ *     the returned string
+ * @length: location to store length in bytes of the contents, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Reads an entire file into allocated memory, with good error
+ * checking.
+ *
+ * If the call was successful, it returns %TRUE and sets @contents to the file
+ * contents and @length to the length of the file contents in bytes. The string
+ * stored in @contents will be nul-terminated, so for text files you can pass
+ * %NULL for the @length argument. If the call was not successful, it returns
+ * %FALSE and sets @error. The error domain is #G_FILE_ERROR. Possible error
+ * codes are those in the #GFileError enumeration. In the error case,
+ * @contents is set to %NULL and @length is set to zero.
+ *
+ * Return value: %TRUE on success, %FALSE if an error occurred
+ **/
+gboolean
+g_file_get_contents (const gchar  *filename,
+                     gchar       **contents,
+                     gsize        *length,
+                     GError      **error)
+{  
+  g_return_val_if_fail (filename != NULL, FALSE);
+  g_return_val_if_fail (contents != NULL, FALSE);
+
+  *contents = NULL;
+  if (length)
+    *length = 0;
+
+#ifdef G_OS_WIN32
+  return get_contents_win32 (filename, contents, length, error);
+#else
+  return get_contents_posix (filename, contents, length, error);
+#endif
+}
+
+static gboolean
+rename_file (const char  *old_name,
+            const char  *new_name,
+            GError     **err)
+{
+  errno = 0;
+  if (g_rename (old_name, new_name) == -1)
+    {
+      int save_errno = errno;
+      gchar *display_old_name = g_filename_display_name (old_name);
+      gchar *display_new_name = g_filename_display_name (new_name);
+
+      g_set_error (err,
+                  G_FILE_ERROR,
+                  g_file_error_from_errno (save_errno),
+                  _("Failed to rename file '%s' to '%s': g_rename() failed: %s"),
+                  display_old_name,
+                  display_new_name,
+                  g_strerror (save_errno));
+
+      g_free (display_old_name);
+      g_free (display_new_name);
+      
+      return FALSE;
+    }
+  
+  return TRUE;
+}
+
+static gchar *
+write_to_temp_file (const gchar  *contents,
+                   gssize        length,
+                   const gchar  *dest_file,
+                   GError      **err)
+{
+  gchar *tmp_name;
+  gchar *display_name;
+  gchar *retval;
+  FILE *file;
+  gint fd;
+  int save_errno;
+
+  retval = NULL;
+  
+  tmp_name = g_strdup_printf ("%s.XXXXXX", dest_file);
+
+  errno = 0;
+  fd = g_mkstemp_full (tmp_name, O_RDWR | O_BINARY, 0666);
+  save_errno = errno;
+
+  display_name = g_filename_display_name (tmp_name);
+      
+  if (fd == -1)
+    {
+      g_set_error (err,
+                  G_FILE_ERROR,
+                  g_file_error_from_errno (save_errno),
+                  _("Failed to create file '%s': %s"),
+                  display_name, g_strerror (save_errno));
+      
+      goto out;
+    }
+
+  errno = 0;
+  file = fdopen (fd, "wb");
+  if (!file)
+    {
+      save_errno = errno;
+      g_set_error (err,
+                  G_FILE_ERROR,
+                  g_file_error_from_errno (save_errno),
+                  _("Failed to open file '%s' for writing: fdopen() failed: %s"),
+                  display_name,
+                  g_strerror (save_errno));
+
+      close (fd);
+      g_unlink (tmp_name);
+      
+      goto out;
+    }
+
+  if (length > 0)
+    {
+      gsize n_written;
+      
+      errno = 0;
+
+      n_written = fwrite (contents, 1, length, file);
+
+      if (n_written < length)
+       {
+         save_errno = errno;
+      
+         g_set_error (err,
+                      G_FILE_ERROR,
+                      g_file_error_from_errno (save_errno),
+                      _("Failed to write file '%s': fwrite() failed: %s"),
+                      display_name,
+                      g_strerror (save_errno));
+
+         fclose (file);
+         g_unlink (tmp_name);
+         
+         goto out;
+       }
+    }
+
+  errno = 0;
+  if (fflush (file) != 0)
+    { 
+      save_errno = errno;
+      
+      g_set_error (err,
+                  G_FILE_ERROR,
+                  g_file_error_from_errno (save_errno),
+                  _("Failed to write file '%s': fflush() failed: %s"),
+                  display_name, 
+                  g_strerror (save_errno));
+
+      g_unlink (tmp_name);
+      
+      goto out;
+    }
+  
+#ifdef HAVE_FSYNC
+  {
+    struct stat statbuf;
+
+    errno = 0;
+    /* If the final destination exists and is > 0 bytes, we want to sync the
+     * newly written file to ensure the data is on disk when we rename over
+     * the destination. Otherwise if we get a system crash we can lose both
+     * the new and the old file on some filesystems. (I.E. those that don't
+     * guarantee the data is written to the disk before the metadata.)
+     */
+    if (g_lstat (dest_file, &statbuf) == 0 &&
+       statbuf.st_size > 0 &&
+       fsync (fileno (file)) != 0)
+      {
+       save_errno = errno;
+
+       g_set_error (err,
+                    G_FILE_ERROR,
+                    g_file_error_from_errno (save_errno),
+                    _("Failed to write file '%s': fsync() failed: %s"),
+                    display_name,
+                    g_strerror (save_errno));
+
+       g_unlink (tmp_name);
+
+       goto out;
+      }
+  }
+#endif
+  
+  errno = 0;
+  if (fclose (file) == EOF)
+    { 
+      save_errno = errno;
+      
+      g_set_error (err,
+                  G_FILE_ERROR,
+                  g_file_error_from_errno (save_errno),
+                  _("Failed to close file '%s': fclose() failed: %s"),
+                  display_name, 
+                  g_strerror (save_errno));
+
+      g_unlink (tmp_name);
+      
+      goto out;
+    }
+
+  retval = g_strdup (tmp_name);
+  
+ out:
+  g_free (tmp_name);
+  g_free (display_name);
+  
+  return retval;
+}
+
+/**
+ * g_file_set_contents:
+ * @filename: name of a file to write @contents to, in the GLib file name
+ *   encoding
+ * @contents: string to write to the file
+ * @length: length of @contents, or -1 if @contents is a nul-terminated string
+ * @error: return location for a #GError, or %NULL
+ *
+ * Writes all of @contents to a file named @filename, with good error checking.
+ * If a file called @filename already exists it will be overwritten.
+ *
+ * This write is atomic in the sense that it is first written to a temporary
+ * file which is then renamed to the final name. Notes:
+ * <itemizedlist>
+ * <listitem>
+ *    On Unix, if @filename already exists hard links to @filename will break.
+ *    Also since the file is recreated, existing permissions, access control
+ *    lists, metadata etc. may be lost. If @filename is a symbolic link,
+ *    the link itself will be replaced, not the linked file.
+ * </listitem>
+ * <listitem>
+ *   On Windows renaming a file will not remove an existing file with the
+ *   new name, so on Windows there is a race condition between the existing
+ *   file being removed and the temporary file being renamed.
+ * </listitem>
+ * <listitem>
+ *   On Windows there is no way to remove a file that is open to some
+ *   process, or mapped into memory. Thus, this function will fail if
+ *   @filename already exists and is open.
+ * </listitem>
+ * </itemizedlist>
+ *
+ * If the call was sucessful, it returns %TRUE. If the call was not successful,
+ * it returns %FALSE and sets @error. The error domain is #G_FILE_ERROR.
+ * Possible error codes are those in the #GFileError enumeration.
+ *
+ * Note that the name for the temporary file is constructed by appending up
+ * to 7 characters to @filename.
+ *
+ * Return value: %TRUE on success, %FALSE if an error occurred
+ *
+ * Since: 2.8
+ **/
+gboolean
+g_file_set_contents (const gchar  *filename,
+                    const gchar  *contents,
+                    gssize        length,
+                    GError      **error)
+{
+  gchar *tmp_filename;
+  gboolean retval;
+  GError *rename_error = NULL;
+  
+  g_return_val_if_fail (filename != NULL, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  g_return_val_if_fail (contents != NULL || length == 0, FALSE);
+  g_return_val_if_fail (length >= -1, FALSE);
+  
+  if (length == -1)
+    length = strlen (contents);
+
+  tmp_filename = write_to_temp_file (contents, length, filename, error);
+  
+  if (!tmp_filename)
+    {
+      retval = FALSE;
+      goto out;
+    }
+
+  if (!rename_file (tmp_filename, filename, &rename_error))
+    {
+#ifndef G_OS_WIN32
+
+      g_unlink (tmp_filename);
+      g_propagate_error (error, rename_error);
+      retval = FALSE;
+      goto out;
+
+#else /* G_OS_WIN32 */
+      
+      /* Renaming failed, but on Windows this may just mean
+       * the file already exists. So if the target file
+       * exists, try deleting it and do the rename again.
+       */
+      if (!g_file_test (filename, G_FILE_TEST_EXISTS))
+       {
+         g_unlink (tmp_filename);
+         g_propagate_error (error, rename_error);
+         retval = FALSE;
+         goto out;
+       }
+
+      g_error_free (rename_error);
+      
+      if (g_unlink (filename) == -1)
+       {
+          gchar *display_filename = g_filename_display_name (filename);
+
+         int save_errno = errno;
+         
+         g_set_error (error,
+                      G_FILE_ERROR,
+                      g_file_error_from_errno (save_errno),
+                      _("Existing file '%s' could not be removed: g_unlink() failed: %s"),
+                      display_filename,
+                      g_strerror (save_errno));
+
+         g_free (display_filename);
+         g_unlink (tmp_filename);
+         retval = FALSE;
+         goto out;
+       }
+      
+      if (!rename_file (tmp_filename, filename, error))
+       {
+         g_unlink (tmp_filename);
+         retval = FALSE;
+         goto out;
+       }
+
+#endif
+    }
+
+  retval = TRUE;
+  
+ out:
+  g_free (tmp_filename);
+  return retval;
+}
+
+/**
+ * g_mkstemp_full:
+ * @tmpl: template filename
+ * @flags: flags to pass to an open() call in addition to O_EXCL and
+ *         O_CREAT, which are passed automatically
+ * @mode: permissios to create the temporary file with
+ *
+ * Opens a temporary file. See the mkstemp() documentation
+ * on most UNIX-like systems.
+ *
+ * The parameter is a string that should follow the rules for
+ * mkstemp() templates, i.e. contain the string "XXXXXX".
+ * g_mkstemp_full() is slightly more flexible than mkstemp()
+ * in that the sequence does not have to occur at the very end of the
+ * template and you can pass a @mode and additional @flags. The X
+ * string will be modified to form the name of a file that didn't exist.
+ * The string should be in the GLib file name encoding. Most importantly,
+ * on Windows it should be in UTF-8.
+ *
+ * Return value: A file handle (as from open()) to the file
+ *     opened for reading and writing. The file handle should be
+ *     closed with close(). In case of errors, -1 is returned.
+ *
+ * Since: 2.22
+ */
+/*
+ * g_mkstemp_full based on the mkstemp implementation from the GNU C library.
+ * Copyright (C) 1991,92,93,94,95,96,97,98,99 Free Software Foundation, Inc.
+ */
+gint
+g_mkstemp_full (gchar *tmpl, 
+                int    flags,
+               int    mode)
+{
+  char *XXXXXX;
+  int count, fd;
+  static const char letters[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+  static const int NLETTERS = sizeof (letters) - 1;
+  glong value;
+  GTimeVal tv;
+  static int counter = 0;
+
+  g_return_val_if_fail (tmpl != NULL, -1);
+
+
+  /* find the last occurrence of "XXXXXX" */
+  XXXXXX = g_strrstr (tmpl, "XXXXXX");
+
+  if (!XXXXXX || strncmp (XXXXXX, "XXXXXX", 6))
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  /* Get some more or less random data.  */
+  g_get_current_time (&tv);
+  value = (tv.tv_usec ^ tv.tv_sec) + counter++;
+
+  for (count = 0; count < 100; value += 7777, ++count)
+    {
+      glong v = value;
+
+      /* Fill in the random bits.  */
+      XXXXXX[0] = letters[v % NLETTERS];
+      v /= NLETTERS;
+      XXXXXX[1] = letters[v % NLETTERS];
+      v /= NLETTERS;
+      XXXXXX[2] = letters[v % NLETTERS];
+      v /= NLETTERS;
+      XXXXXX[3] = letters[v % NLETTERS];
+      v /= NLETTERS;
+      XXXXXX[4] = letters[v % NLETTERS];
+      v /= NLETTERS;
+      XXXXXX[5] = letters[v % NLETTERS];
+
+      /* tmpl is in UTF-8 on Windows, thus use g_open() */
+      fd = g_open (tmpl, flags | O_CREAT | O_EXCL, mode);
+
+      if (fd >= 0)
+       return fd;
+      else if (errno != EEXIST)
+       /* Any other error will apply also to other names we might
+        *  try, and there are 2^32 or so of them, so give up now.
+        */
+       return -1;
+    }
+
+  /* We got out of the loop because we ran out of combinations to try.  */
+  errno = EEXIST;
+  return -1;
+}
+
+/**
+ * g_mkstemp:
+ * @tmpl: template filename
+ *
+ * Opens a temporary file. See the mkstemp() documentation
+ * on most UNIX-like systems. 
+ *
+ * The parameter is a string that should follow the rules for
+ * mkstemp() templates, i.e. contain the string "XXXXXX". 
+ * g_mkstemp() is slightly more flexible than mkstemp()
+ * in that the sequence does not have to occur at the very end of the 
+ * template. The X string will 
+ * be modified to form the name of a file that didn't exist.
+ * The string should be in the GLib file name encoding. Most importantly, 
+ * on Windows it should be in UTF-8.
+ *
+ * Return value: A file handle (as from open()) to the file
+ * opened for reading and writing. The file is opened in binary mode
+ * on platforms where there is a difference. The file handle should be
+ * closed with close(). In case of errors, -1 is returned.  
+ */ 
+gint
+g_mkstemp (gchar *tmpl)
+{
+  return g_mkstemp_full (tmpl, O_RDWR | O_BINARY, 0600);
+}
+
+/**
+ * g_file_open_tmp:
+ * @tmpl: Template for file name, as in g_mkstemp(), basename only,
+ *        or %NULL, to a default template
+ * @name_used: location to store actual name used, or %NULL
+ * @error: return location for a #GError
+ *
+ * Opens a file for writing in the preferred directory for temporary
+ * files (as returned by g_get_tmp_dir()). 
+ *
+ * @tmpl should be a string in the GLib file name encoding containing 
+ * a sequence of six 'X' characters, as the parameter to g_mkstemp().
+ * However, unlike these functions, the template should only be a
+ * basename, no directory components are allowed. If template is
+ * %NULL, a default template is used.
+ *
+ * Note that in contrast to g_mkstemp() (and mkstemp()) 
+ * @tmpl is not modified, and might thus be a read-only literal string.
+ *
+ * The actual name used is returned in @name_used if non-%NULL. This
+ * string should be freed with g_free() when not needed any longer.
+ * The returned name is in the GLib file name encoding.
+ *
+ * Return value: A file handle (as from open()) to 
+ * the file opened for reading and writing. The file is opened in binary 
+ * mode on platforms where there is a difference. The file handle should be
+ * closed with close(). In case of errors, -1 is returned 
+ * and @error will be set.
+ **/
+gint
+g_file_open_tmp (const gchar  *tmpl,
+                gchar       **name_used,
+                GError      **error)
+{
+  int retval;
+  const char *tmpdir;
+  const char *sep;
+  char *fulltemplate;
+  const char *slash;
+
+  if (tmpl == NULL)
+    tmpl = ".XXXXXX";
+
+  if ((slash = strchr (tmpl, G_DIR_SEPARATOR)) != NULL
+#ifdef G_OS_WIN32
+      || (strchr (tmpl, '/') != NULL && (slash = "/"))
+#endif
+      )
+    {
+      gchar *display_tmpl = g_filename_display_name (tmpl);
+      char c[2];
+      c[0] = *slash;
+      c[1] = '\0';
+
+      g_set_error (error,
+                  G_FILE_ERROR,
+                  G_FILE_ERROR_FAILED,
+                  _("Template '%s' invalid, should not contain a '%s'"),
+                  display_tmpl, c);
+      g_free (display_tmpl);
+
+      return -1;
+    }
+  
+  if (strstr (tmpl, "XXXXXX") == NULL)
+    {
+      gchar *display_tmpl = g_filename_display_name (tmpl);
+      g_set_error (error,
+                  G_FILE_ERROR,
+                  G_FILE_ERROR_FAILED,
+                  _("Template '%s' doesn't contain XXXXXX"),
+                  display_tmpl);
+      g_free (display_tmpl);
+      return -1;
+    }
+
+  tmpdir = g_get_tmp_dir ();
+
+  if (G_IS_DIR_SEPARATOR (tmpdir [strlen (tmpdir) - 1]))
+    sep = "";
+  else
+    sep = G_DIR_SEPARATOR_S;
+
+  fulltemplate = g_strconcat (tmpdir, sep, tmpl, NULL);
+
+  retval = g_mkstemp (fulltemplate);
+
+  if (retval == -1)
+    {
+      int save_errno = errno;
+      gchar *display_fulltemplate = g_filename_display_name (fulltemplate);
+
+      g_set_error (error,
+                  G_FILE_ERROR,
+                  g_file_error_from_errno (save_errno),
+                  _("Failed to create file '%s': %s"),
+                  display_fulltemplate, g_strerror (save_errno));
+      g_free (display_fulltemplate);
+      g_free (fulltemplate);
+      return -1;
+    }
+
+  if (name_used)
+    *name_used = fulltemplate;
+  else
+    g_free (fulltemplate);
+
+  return retval;
+}
+
+static gchar *
+g_build_path_va (const gchar  *separator,
+                const gchar  *first_element,
+                va_list      *args,
+                gchar       **str_array)
+{
+  GString *result;
+  gint separator_len = strlen (separator);
+  gboolean is_first = TRUE;
+  gboolean have_leading = FALSE;
+  const gchar *single_element = NULL;
+  const gchar *next_element;
+  const gchar *last_trailing = NULL;
+  gint i = 0;
+
+  result = g_string_new (NULL);
+
+  if (str_array)
+    next_element = str_array[i++];
+  else
+    next_element = first_element;
+
+  while (TRUE)
+    {
+      const gchar *element;
+      const gchar *start;
+      const gchar *end;
+
+      if (next_element)
+       {
+         element = next_element;
+         if (str_array)
+           next_element = str_array[i++];
+         else
+           next_element = va_arg (*args, gchar *);
+       }
+      else
+       break;
+
+      /* Ignore empty elements */
+      if (!*element)
+       continue;
+      
+      start = element;
+
+      if (separator_len)
+       {
+         while (strncmp (start, separator, separator_len) == 0)
+           start += separator_len;
+       }
+
+      end = start + strlen (start);
+      
+      if (separator_len)
+       {
+         while (end >= start + separator_len &&
+                strncmp (end - separator_len, separator, separator_len) == 0)
+           end -= separator_len;
+         
+         last_trailing = end;
+         while (last_trailing >= element + separator_len &&
+                strncmp (last_trailing - separator_len, separator, separator_len) == 0)
+           last_trailing -= separator_len;
+
+         if (!have_leading)
+           {
+             /* If the leading and trailing separator strings are in the
+              * same element and overlap, the result is exactly that element
+              */
+             if (last_trailing <= start)
+               single_element = element;
+                 
+             g_string_append_len (result, element, start - element);
+             have_leading = TRUE;
+           }
+         else
+           single_element = NULL;
+       }
+
+      if (end == start)
+       continue;
+
+      if (!is_first)
+       g_string_append (result, separator);
+      
+      g_string_append_len (result, start, end - start);
+      is_first = FALSE;
+    }
+
+  if (single_element)
+    {
+      g_string_free (result, TRUE);
+      return g_strdup (single_element);
+    }
+  else
+    {
+      if (last_trailing)
+       g_string_append (result, last_trailing);
+  
+      return g_string_free (result, FALSE);
+    }
+}
+
+/**
+ * g_build_pathv:
+ * @separator: a string used to separator the elements of the path.
+ * @args: %NULL-terminated array of strings containing the path elements.
+ * 
+ * Behaves exactly like g_build_path(), but takes the path elements 
+ * as a string array, instead of varargs. This function is mainly
+ * meant for language bindings.
+ *
+ * Return value: a newly-allocated string that must be freed with g_free().
+ *
+ * Since: 2.8
+ */
+gchar *
+g_build_pathv (const gchar  *separator,
+              gchar       **args)
+{
+  if (!args)
+    return NULL;
+
+  return g_build_path_va (separator, NULL, NULL, args);
+}
+
+
+/**
+ * g_build_path:
+ * @separator: a string used to separator the elements of the path.
+ * @first_element: the first element in the path
+ * @Varargs: remaining elements in path, terminated by %NULL
+ * 
+ * Creates a path from a series of elements using @separator as the
+ * separator between elements. At the boundary between two elements,
+ * any trailing occurrences of separator in the first element, or
+ * leading occurrences of separator in the second element are removed
+ * and exactly one copy of the separator is inserted.
+ *
+ * Empty elements are ignored.
+ *
+ * The number of leading copies of the separator on the result is
+ * the same as the number of leading copies of the separator on
+ * the first non-empty element.
+ *
+ * The number of trailing copies of the separator on the result is
+ * the same as the number of trailing copies of the separator on
+ * the last non-empty element. (Determination of the number of
+ * trailing copies is done without stripping leading copies, so
+ * if the separator is <literal>ABA</literal>, <literal>ABABA</literal>
+ * has 1 trailing copy.)
+ *
+ * However, if there is only a single non-empty element, and there
+ * are no characters in that element not part of the leading or
+ * trailing separators, then the result is exactly the original value
+ * of that element.
+ *
+ * Other than for determination of the number of leading and trailing
+ * copies of the separator, elements consisting only of copies
+ * of the separator are ignored.
+ * 
+ * Return value: a newly-allocated string that must be freed with g_free().
+ **/
+gchar *
+g_build_path (const gchar *separator,
+             const gchar *first_element,
+             ...)
+{
+  gchar *str;
+  va_list args;
+
+  g_return_val_if_fail (separator != NULL, NULL);
+
+  va_start (args, first_element);
+  str = g_build_path_va (separator, first_element, &args, NULL);
+  va_end (args);
+
+  return str;
+}
+
+#ifdef G_OS_WIN32
+
+static gchar *
+g_build_pathname_va (const gchar  *first_element,
+                    va_list      *args,
+                    gchar       **str_array)
+{
+  /* Code copied from g_build_pathv(), and modified to use two
+   * alternative single-character separators.
+   */
+  GString *result;
+  gboolean is_first = TRUE;
+  gboolean have_leading = FALSE;
+  const gchar *single_element = NULL;
+  const gchar *next_element;
+  const gchar *last_trailing = NULL;
+  gchar current_separator = '\\';
+  gint i = 0;
+
+  result = g_string_new (NULL);
+
+  if (str_array)
+    next_element = str_array[i++];
+  else
+    next_element = first_element;
+  
+  while (TRUE)
+    {
+      const gchar *element;
+      const gchar *start;
+      const gchar *end;
+
+      if (next_element)
+       {
+         element = next_element;
+         if (str_array)
+           next_element = str_array[i++];
+         else
+           next_element = va_arg (*args, gchar *);
+       }
+      else
+       break;
+
+      /* Ignore empty elements */
+      if (!*element)
+       continue;
+      
+      start = element;
+
+      if (TRUE)
+       {
+         while (start &&
+                (*start == '\\' || *start == '/'))
+           {
+             current_separator = *start;
+             start++;
+           }
+       }
+
+      end = start + strlen (start);
+      
+      if (TRUE)
+       {
+         while (end >= start + 1 &&
+                (end[-1] == '\\' || end[-1] == '/'))
+           {
+             current_separator = end[-1];
+             end--;
+           }
+         
+         last_trailing = end;
+         while (last_trailing >= element + 1 &&
+                (last_trailing[-1] == '\\' || last_trailing[-1] == '/'))
+           last_trailing--;
+
+         if (!have_leading)
+           {
+             /* If the leading and trailing separator strings are in the
+              * same element and overlap, the result is exactly that element
+              */
+             if (last_trailing <= start)
+               single_element = element;
+                 
+             g_string_append_len (result, element, start - element);
+             have_leading = TRUE;
+           }
+         else
+           single_element = NULL;
+       }
+
+      if (end == start)
+       continue;
+
+      if (!is_first)
+       g_string_append_len (result, &current_separator, 1);
+      
+      g_string_append_len (result, start, end - start);
+      is_first = FALSE;
+    }
+
+  if (single_element)
+    {
+      g_string_free (result, TRUE);
+      return g_strdup (single_element);
+    }
+  else
+    {
+      if (last_trailing)
+       g_string_append (result, last_trailing);
+  
+      return g_string_free (result, FALSE);
+    }
+}
+
+#endif
+
+/**
+ * g_build_filenamev:
+ * @args: %NULL-terminated array of strings containing the path elements.
+ * 
+ * Behaves exactly like g_build_filename(), but takes the path elements 
+ * as a string array, instead of varargs. This function is mainly
+ * meant for language bindings.
+ *
+ * Return value: a newly-allocated string that must be freed with g_free().
+ * 
+ * Since: 2.8
+ */
+gchar *
+g_build_filenamev (gchar **args)
+{
+  gchar *str;
+
+#ifndef G_OS_WIN32
+  str = g_build_path_va (G_DIR_SEPARATOR_S, NULL, NULL, args);
+#else
+  str = g_build_pathname_va (NULL, NULL, args);
+#endif
+
+  return str;
+}
+
+/**
+ * g_build_filename:
+ * @first_element: the first element in the path
+ * @Varargs: remaining elements in path, terminated by %NULL
+ * 
+ * Creates a filename from a series of elements using the correct
+ * separator for filenames.
+ *
+ * On Unix, this function behaves identically to <literal>g_build_path
+ * (G_DIR_SEPARATOR_S, first_element, ....)</literal>.
+ *
+ * On Windows, it takes into account that either the backslash
+ * (<literal>\</literal> or slash (<literal>/</literal>) can be used
+ * as separator in filenames, but otherwise behaves as on Unix. When
+ * file pathname separators need to be inserted, the one that last
+ * previously occurred in the parameters (reading from left to right)
+ * is used.
+ *
+ * No attempt is made to force the resulting filename to be an absolute
+ * path. If the first element is a relative path, the result will
+ * be a relative path. 
+ * 
+ * Return value: a newly-allocated string that must be freed with g_free().
+ **/
+gchar *
+g_build_filename (const gchar *first_element, 
+                 ...)
+{
+  gchar *str;
+  va_list args;
+
+  va_start (args, first_element);
+#ifndef G_OS_WIN32
+  str = g_build_path_va (G_DIR_SEPARATOR_S, first_element, &args, NULL);
+#else
+  str = g_build_pathname_va (first_element, &args, NULL);
+#endif
+  va_end (args);
+
+  return str;
+}
+
+#define KILOBYTE_FACTOR (G_GOFFSET_CONSTANT (1024))
+#define MEGABYTE_FACTOR (KILOBYTE_FACTOR * KILOBYTE_FACTOR)
+#define GIGABYTE_FACTOR (MEGABYTE_FACTOR * KILOBYTE_FACTOR)
+#define TERABYTE_FACTOR (GIGABYTE_FACTOR * KILOBYTE_FACTOR)
+#define PETABYTE_FACTOR (TERABYTE_FACTOR * KILOBYTE_FACTOR)
+#define EXABYTE_FACTOR  (PETABYTE_FACTOR * KILOBYTE_FACTOR)
+
+/**
+ * g_format_size_for_display:
+ * @size: a size in bytes.
+ * 
+ * Formats a size (for example the size of a file) into a human readable string.
+ * Sizes are rounded to the nearest size prefix (KB, MB, GB) and are displayed 
+ * rounded to the nearest  tenth. E.g. the file size 3292528 bytes will be
+ * converted into the string "3.1 MB".
+ *
+ * The prefix units base is 1024 (i.e. 1 KB is 1024 bytes).
+ *
+ * This string should be freed with g_free() when not needed any longer.
+ *
+ * Returns: a newly-allocated formatted string containing a human readable
+ *          file size.
+ *
+ * Since: 2.16
+ **/
+char *
+g_format_size_for_display (goffset size)
+{
+  if (size < (goffset) KILOBYTE_FACTOR)
+    return g_strdup_printf (g_dngettext(GETTEXT_PACKAGE, "%u byte", "%u bytes",(guint) size), (guint) size);
+  else
+    {
+      gdouble displayed_size;
+      
+      if (size < (goffset) MEGABYTE_FACTOR)
+       {
+         displayed_size = (gdouble) size / (gdouble) KILOBYTE_FACTOR;
+         return g_strdup_printf (_("%.1f KB"), displayed_size);
+       }
+      else if (size < (goffset) GIGABYTE_FACTOR)
+       {
+         displayed_size = (gdouble) size / (gdouble) MEGABYTE_FACTOR;
+         return g_strdup_printf (_("%.1f MB"), displayed_size);
+       }
+      else if (size < (goffset) TERABYTE_FACTOR)
+       {
+         displayed_size = (gdouble) size / (gdouble) GIGABYTE_FACTOR;
+         return g_strdup_printf (_("%.1f GB"), displayed_size);
+       }
+      else if (size < (goffset) PETABYTE_FACTOR)
+       {
+         displayed_size = (gdouble) size / (gdouble) TERABYTE_FACTOR;
+         return g_strdup_printf (_("%.1f TB"), displayed_size);
+       }
+      else if (size < (goffset) EXABYTE_FACTOR)
+       {
+         displayed_size = (gdouble) size / (gdouble) PETABYTE_FACTOR;
+         return g_strdup_printf (_("%.1f PB"), displayed_size);
+       }
+      else
+        {
+         displayed_size = (gdouble) size / (gdouble) EXABYTE_FACTOR;
+         return g_strdup_printf (_("%.1f EB"), displayed_size);
+        }
+    }
+}
+
+
+/**
+ * g_file_read_link:
+ * @filename: the symbolic link
+ * @error: return location for a #GError
+ *
+ * Reads the contents of the symbolic link @filename like the POSIX
+ * readlink() function.  The returned string is in the encoding used
+ * for filenames. Use g_filename_to_utf8() to convert it to UTF-8.
+ *
+ * Returns: A newly-allocated string with the contents of the symbolic link, 
+ *          or %NULL if an error occurred.
+ *
+ * Since: 2.4
+ */
+gchar *
+g_file_read_link (const gchar  *filename,
+                 GError      **error)
+{
+#ifdef HAVE_READLINK
+  gchar *buffer;
+  guint size;
+  gint read_size;    
+  
+  size = 256; 
+  buffer = g_malloc (size);
+  
+  while (TRUE) 
+    {
+      read_size = readlink (filename, buffer, size);
+      if (read_size < 0) {
+       int save_errno = errno;
+       gchar *display_filename = g_filename_display_name (filename);
+
+       g_free (buffer);
+       g_set_error (error,
+                    G_FILE_ERROR,
+                    g_file_error_from_errno (save_errno),
+                    _("Failed to read the symbolic link '%s': %s"),
+                    display_filename, 
+                    g_strerror (save_errno));
+       g_free (display_filename);
+       
+       return NULL;
+      }
+    
+      if (read_size < size) 
+       {
+         buffer[read_size] = 0;
+         return buffer;
+       }
+      
+      size *= 2;
+      buffer = g_realloc (buffer, size);
+    }
+#else
+  g_set_error_literal (error,
+                       G_FILE_ERROR,
+                       G_FILE_ERROR_INVAL,
+                       _("Symbolic links not supported"));
+       
+  return NULL;
+#endif
+}
+
+/* NOTE : Keep this part last to ensure nothing in this file uses the
+ * below binary compatibility versions.
+ */
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+/* Binary compatibility versions. Will be called by code compiled
+ * against quite old (pre-2.8, I think) headers only, not from more
+ * recently compiled code.
+ */
+
+#undef g_file_test
+
+gboolean
+g_file_test (const gchar *filename,
+             GFileTest    test)
+{
+  gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, NULL);
+  gboolean retval;
+
+  if (utf8_filename == NULL)
+    return FALSE;
+
+  retval = g_file_test_utf8 (utf8_filename, test);
+
+  g_free (utf8_filename);
+
+  return retval;
+}
+
+#undef g_file_get_contents
+
+gboolean
+g_file_get_contents (const gchar  *filename,
+                     gchar       **contents,
+                     gsize        *length,
+                     GError      **error)
+{
+  gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
+  gboolean retval;
+
+  if (utf8_filename == NULL)
+    return FALSE;
+
+  retval = g_file_get_contents_utf8 (utf8_filename, contents, length, error);
+
+  g_free (utf8_filename);
+
+  return retval;
+}
+
+#undef g_mkstemp
+
+gint
+g_mkstemp (gchar *tmpl)
+{
+  char *XXXXXX;
+  int count, fd;
+  static const char letters[] =
+    "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789";
+  static const int NLETTERS = sizeof (letters) - 1;
+  glong value;
+  GTimeVal tv;
+  static int counter = 0;
+
+  /* find the last occurrence of 'XXXXXX' */
+  XXXXXX = g_strrstr (tmpl, "XXXXXX");
+
+  if (!XXXXXX)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  /* Get some more or less random data.  */
+  g_get_current_time (&tv);
+  value = (tv.tv_usec ^ tv.tv_sec) + counter++;
+
+  for (count = 0; count < 100; value += 7777, ++count)
+    {
+      glong v = value;
+
+      /* Fill in the random bits.  */
+      XXXXXX[0] = letters[v % NLETTERS];
+      v /= NLETTERS;
+      XXXXXX[1] = letters[v % NLETTERS];
+      v /= NLETTERS;
+      XXXXXX[2] = letters[v % NLETTERS];
+      v /= NLETTERS;
+      XXXXXX[3] = letters[v % NLETTERS];
+      v /= NLETTERS;
+      XXXXXX[4] = letters[v % NLETTERS];
+      v /= NLETTERS;
+      XXXXXX[5] = letters[v % NLETTERS];
+
+      /* This is the backward compatibility system codepage version,
+       * thus use normal open().
+       */
+      fd = open (tmpl, O_RDWR | O_CREAT | O_EXCL | O_BINARY, 0600);
+
+      if (fd >= 0)
+       return fd;
+      else if (errno != EEXIST)
+       /* Any other error will apply also to other names we might
+        *  try, and there are 2^32 or so of them, so give up now.
+        */
+       return -1;
+    }
+
+  /* We got out of the loop because we ran out of combinations to try.  */
+  errno = EEXIST;
+  return -1;
+}
+
+#undef g_file_open_tmp
+
+gint
+g_file_open_tmp (const gchar  *tmpl,
+                gchar       **name_used,
+                GError      **error)
+{
+  gchar *utf8_tmpl = g_locale_to_utf8 (tmpl, -1, NULL, NULL, error);
+  gchar *utf8_name_used;
+  gint retval;
+
+  if (utf8_tmpl == NULL)
+    return -1;
+
+  retval = g_file_open_tmp_utf8 (utf8_tmpl, &utf8_name_used, error);
+  
+  if (retval == -1)
+    return -1;
+
+  if (name_used)
+    *name_used = g_locale_from_utf8 (utf8_name_used, -1, NULL, NULL, NULL);
+
+  g_free (utf8_name_used);
+
+  return retval;
+}
+
+#endif
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gfileutils.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gfileutils.h
new file mode 100644 (file)
index 0000000..d8f9d3b
--- /dev/null
@@ -0,0 +1,128 @@
+/* gfileutils.h - File utility functions
+ *
+ *  Copyright 2000 Red Hat, Inc.
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *   Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_FILEUTILS_H__
+#define __G_FILEUTILS_H__
+
+#include <glib/gerror.h>
+
+G_BEGIN_DECLS
+
+#define G_FILE_ERROR g_file_error_quark ()
+
+typedef enum
+{
+  G_FILE_ERROR_EXIST,
+  G_FILE_ERROR_ISDIR,
+  G_FILE_ERROR_ACCES,
+  G_FILE_ERROR_NAMETOOLONG,
+  G_FILE_ERROR_NOENT,
+  G_FILE_ERROR_NOTDIR,
+  G_FILE_ERROR_NXIO,
+  G_FILE_ERROR_NODEV,
+  G_FILE_ERROR_ROFS,
+  G_FILE_ERROR_TXTBSY,
+  G_FILE_ERROR_FAULT,
+  G_FILE_ERROR_LOOP,
+  G_FILE_ERROR_NOSPC,
+  G_FILE_ERROR_NOMEM,
+  G_FILE_ERROR_MFILE,
+  G_FILE_ERROR_NFILE,
+  G_FILE_ERROR_BADF,
+  G_FILE_ERROR_INVAL,
+  G_FILE_ERROR_PIPE,
+  G_FILE_ERROR_AGAIN,
+  G_FILE_ERROR_INTR,
+  G_FILE_ERROR_IO,
+  G_FILE_ERROR_PERM,
+  G_FILE_ERROR_NOSYS,
+  G_FILE_ERROR_FAILED
+} GFileError;
+
+/* For backward-compat reasons, these are synced to an old 
+ * anonymous enum in libgnome. But don't use that enum
+ * in new code.
+ */
+typedef enum
+{
+  G_FILE_TEST_IS_REGULAR    = 1 << 0,
+  G_FILE_TEST_IS_SYMLINK    = 1 << 1,
+  G_FILE_TEST_IS_DIR        = 1 << 2,
+  G_FILE_TEST_IS_EXECUTABLE = 1 << 3,
+  G_FILE_TEST_EXISTS        = 1 << 4
+} GFileTest;
+
+GQuark     g_file_error_quark      (void);
+/* So other code can generate a GFileError */
+GFileError g_file_error_from_errno (gint err_no);
+
+#ifdef G_OS_WIN32
+#define g_file_test g_file_test_utf8
+#define g_file_get_contents g_file_get_contents_utf8
+#define g_mkstemp g_mkstemp_utf8
+#define g_file_open_tmp g_file_open_tmp_utf8
+#endif
+
+gboolean g_file_test         (const gchar  *filename,
+                              GFileTest     test);
+gboolean g_file_get_contents (const gchar  *filename,
+                              gchar       **contents,
+                              gsize        *length,    
+                              GError      **error);
+gboolean g_file_set_contents (const gchar *filename,
+                             const gchar *contents,
+                             gssize         length,
+                             GError       **error);
+gchar   *g_file_read_link    (const gchar  *filename,
+                             GError      **error);
+
+/* Wrapper / workalike for mkstemp() */
+gint    g_mkstemp            (gchar        *tmpl);
+gint    g_mkstemp_full       (gchar        *tmpl,
+                              int           flags,
+                              int           mode);
+
+/* Wrapper for g_mkstemp */
+gint    g_file_open_tmp      (const gchar  *tmpl,
+                             gchar       **name_used,
+                             GError      **error);
+
+char *g_format_size_for_display (goffset size);
+
+gchar *g_build_path     (const gchar *separator,
+                        const gchar *first_element,
+                        ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
+gchar *g_build_pathv    (const gchar  *separator,
+                        gchar       **args) G_GNUC_MALLOC;
+
+gchar *g_build_filename (const gchar *first_element,
+                        ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
+gchar *g_build_filenamev (gchar      **args) G_GNUC_MALLOC;
+
+int    g_mkdir_with_parents (const gchar *pathname,
+                            int          mode);
+
+G_END_DECLS
+
+#endif /* __G_FILEUTILS_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/ghash.c b/resource/csdk/connectivity/lib/android/glib-master/glib/ghash.c
new file mode 100644 (file)
index 0000000..5f2df05
--- /dev/null
@@ -0,0 +1,1461 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include <string.h>  /* memset */
+
+#include "ghash.h"
+
+#include "gatomic.h"
+#include "gtestutils.h"
+
+
+/**
+ * SECTION: hash_tables
+ * @title: Hash Tables
+ * @short_description: associations between keys and values so that
+ *                     given a key the value can be found quickly
+ *
+ * A #GHashTable provides associations between keys and values which is
+ * optimized so that given a key, the associated value can be found
+ * very quickly.
+ *
+ * Note that neither keys nor values are copied when inserted into the
+ * #GHashTable, so they must exist for the lifetime of the #GHashTable.
+ * This means that the use of static strings is OK, but temporary
+ * strings (i.e. those created in buffers and those returned by GTK+
+ * widgets) should be copied with g_strdup() before being inserted.
+ *
+ * If keys or values are dynamically allocated, you must be careful to
+ * ensure that they are freed when they are removed from the
+ * #GHashTable, and also when they are overwritten by new insertions
+ * into the #GHashTable. It is also not advisable to mix static strings
+ * and dynamically-allocated strings in a #GHashTable, because it then
+ * becomes difficult to determine whether the string should be freed.
+ *
+ * To create a #GHashTable, use g_hash_table_new().
+ *
+ * To insert a key and value into a #GHashTable, use
+ * g_hash_table_insert().
+ *
+ * To lookup a value corresponding to a given key, use
+ * g_hash_table_lookup() and g_hash_table_lookup_extended().
+ *
+ * To remove a key and value, use g_hash_table_remove().
+ *
+ * To call a function for each key and value pair use
+ * g_hash_table_foreach() or use a iterator to iterate over the
+ * key/value pairs in the hash table, see #GHashTableIter.
+ *
+ * To destroy a #GHashTable use g_hash_table_destroy().
+ **/
+
+/**
+ * GHashTable:
+ *
+ * The #GHashTable struct is an opaque data structure to represent a
+ * <link linkend="glib-Hash-Tables">Hash Table</link>. It should only be
+ * accessed via the following functions.
+ **/
+
+/**
+ * GHashFunc:
+ * @key: a key.
+ * @Returns: the hash value corresponding to the key.
+ *
+ * Specifies the type of the hash function which is passed to
+ * g_hash_table_new() when a #GHashTable is created.
+ *
+ * The function is passed a key and should return a #guint hash value.
+ * The functions g_direct_hash(), g_int_hash() and g_str_hash() provide
+ * hash functions which can be used when the key is a #gpointer, #gint,
+ * and #gchar* respectively.
+ *
+ * <!-- FIXME: Need more here. --> The hash values should be evenly
+ * distributed over a fairly large range? The modulus is taken with the
+ * hash table size (a prime number) to find the 'bucket' to place each
+ * key into. The function should also be very fast, since it is called
+ * for each key lookup.
+ **/
+
+/**
+ * GHFunc:
+ * @key: a key.
+ * @value: the value corresponding to the key.
+ * @user_data: user data passed to g_hash_table_foreach().
+ *
+ * Specifies the type of the function passed to g_hash_table_foreach().
+ * It is called with each key/value pair, together with the @user_data
+ * parameter which is passed to g_hash_table_foreach().
+ **/
+
+/**
+ * GHRFunc:
+ * @key: a key.
+ * @value: the value associated with the key.
+ * @user_data: user data passed to g_hash_table_remove().
+ * @Returns: %TRUE if the key/value pair should be removed from the
+ *           #GHashTable.
+ *
+ * Specifies the type of the function passed to
+ * g_hash_table_foreach_remove(). It is called with each key/value
+ * pair, together with the @user_data parameter passed to
+ * g_hash_table_foreach_remove(). It should return %TRUE if the
+ * key/value pair should be removed from the #GHashTable.
+ **/
+
+/**
+ * GEqualFunc:
+ * @a: a value.
+ * @b: a value to compare with.
+ * @Returns: %TRUE if @a = @b; %FALSE otherwise.
+ *
+ * Specifies the type of a function used to test two values for
+ * equality. The function should return %TRUE if both values are equal
+ * and %FALSE otherwise.
+ **/
+
+/**
+ * GHashTableIter:
+ *
+ * A GHashTableIter structure represents an iterator that can be used
+ * to iterate over the elements of a #GHashTable. GHashTableIter
+ * structures are typically allocated on the stack and then initialized
+ * with g_hash_table_iter_init().
+ **/
+
+#define HASH_TABLE_MIN_SHIFT 3  /* 1 << 3 == 8 buckets */
+
+typedef struct _GHashNode      GHashNode;
+
+struct _GHashNode
+{
+  gpointer   key;
+  gpointer   value;
+
+  /* If key_hash == 0, node is not in use
+   * If key_hash == 1, node is a tombstone
+   * If key_hash >= 2, node contains data */
+  guint      key_hash;
+};
+
+struct _GHashTable
+{
+  gint             size;
+  gint             mod;
+  guint            mask;
+  gint             nnodes;
+  gint             noccupied;  /* nnodes + tombstones */
+  GHashNode       *nodes;
+  GHashFunc        hash_func;
+  GEqualFunc       key_equal_func;
+  volatile gint    ref_count;
+#ifndef G_DISABLE_ASSERT
+  /*
+   * Tracks the structure of the hash table, not its contents: is only
+   * incremented when a node is added or removed (is not incremented
+   * when the key or data of a node is modified).
+   */
+  int              version;
+#endif
+  GDestroyNotify   key_destroy_func;
+  GDestroyNotify   value_destroy_func;
+};
+
+typedef struct
+{
+  GHashTable  *hash_table;
+  gpointer     dummy1;
+  gpointer     dummy2;
+  int          position;
+  gboolean     dummy3;
+  int          version;
+} RealIter;
+
+/* Each table size has an associated prime modulo (the first prime
+ * lower than the table size) used to find the initial bucket. Probing
+ * then works modulo 2^n. The prime modulo is necessary to get a
+ * good distribution with poor hash functions. */
+static const gint prime_mod [] =
+{
+  1,          /* For 1 << 0 */
+  2,
+  3,
+  7,
+  13,
+  31,
+  61,
+  127,
+  251,
+  509,
+  1021,
+  2039,
+  4093,
+  8191,
+  16381,
+  32749,
+  65521,      /* For 1 << 16 */
+  131071,
+  262139,
+  524287,
+  1048573,
+  2097143,
+  4194301,
+  8388593,
+  16777213,
+  33554393,
+  67108859,
+  134217689,
+  268435399,
+  536870909,
+  1073741789,
+  2147483647  /* For 1 << 31 */
+};
+
+static void
+g_hash_table_set_shift (GHashTable *hash_table, gint shift)
+{
+  gint i;
+  guint mask = 0;
+
+  hash_table->size = 1 << shift;
+  hash_table->mod  = prime_mod [shift];
+
+  for (i = 0; i < shift; i++)
+    {
+      mask <<= 1;
+      mask |= 1;
+    }
+
+  hash_table->mask = mask;
+}
+
+static gint
+g_hash_table_find_closest_shift (gint n)
+{
+  gint i;
+
+  for (i = 0; n; i++)
+    n >>= 1;
+
+  return i;
+}
+
+static void
+g_hash_table_set_shift_from_size (GHashTable *hash_table, gint size)
+{
+  gint shift;
+
+  shift = g_hash_table_find_closest_shift (size);
+  shift = MAX (shift, HASH_TABLE_MIN_SHIFT);
+
+  g_hash_table_set_shift (hash_table, shift);
+}
+
+/*
+ * g_hash_table_lookup_node:
+ * @hash_table: our #GHashTable
+ * @key: the key to lookup against
+ * @hash_return: optional key hash return location
+ * Return value: index of the described #GHashNode
+ *
+ * Performs a lookup in the hash table.  Virtually all hash operations
+ * will use this function internally.
+ *
+ * This function first computes the hash value of the key using the
+ * user's hash function.
+ *
+ * If an entry in the table matching @key is found then this function
+ * returns the index of that entry in the table, and if not, the
+ * index of an empty node (never a tombstone).
+ */
+static inline guint
+g_hash_table_lookup_node (GHashTable    *hash_table,
+                          gconstpointer  key)
+{
+  GHashNode *node;
+  guint node_index;
+  guint hash_value;
+  guint step = 0;
+
+  /* Empty buckets have hash_value set to 0, and for tombstones, it's 1.
+   * We need to make sure our hash value is not one of these. */
+
+  hash_value = (* hash_table->hash_func) (key);
+  if (G_UNLIKELY (hash_value <= 1))
+    hash_value = 2;
+
+  node_index = hash_value % hash_table->mod;
+  node = &hash_table->nodes [node_index];
+
+  while (node->key_hash)
+    {
+      /*  We first check if our full hash values
+       *  are equal so we can avoid calling the full-blown
+       *  key equality function in most cases.
+       */
+
+      if (node->key_hash == hash_value)
+        {
+          if (hash_table->key_equal_func)
+            {
+              if (hash_table->key_equal_func (node->key, key))
+                break;
+            }
+          else if (node->key == key)
+            {
+              break;
+            }
+        }
+
+      step++;
+      node_index += step;
+      node_index &= hash_table->mask;
+      node = &hash_table->nodes [node_index];
+    }
+
+  return node_index;
+}
+
+/*
+ * g_hash_table_lookup_node_for_insertion:
+ * @hash_table: our #GHashTable
+ * @key: the key to lookup against
+ * @hash_return: key hash return location
+ * Return value: index of the described #GHashNode
+ *
+ * Performs a lookup in the hash table, preserving extra information
+ * usually needed for insertion.
+ *
+ * This function first computes the hash value of the key using the
+ * user's hash function.
+ *
+ * If an entry in the table matching @key is found then this function
+ * returns the index of that entry in the table, and if not, the
+ * index of an unused node (empty or tombstone) where the key can be
+ * inserted.
+ *
+ * The computed hash value is returned in the variable pointed to
+ * by @hash_return. This is to save insertions from having to compute
+ * the hash record again for the new record.
+ */
+static inline guint
+g_hash_table_lookup_node_for_insertion (GHashTable    *hash_table,
+                                        gconstpointer  key,
+                                        guint         *hash_return)
+{
+  GHashNode *node;
+  guint node_index;
+  guint hash_value;
+  guint first_tombstone;
+  gboolean have_tombstone = FALSE;
+  guint step = 0;
+
+  /* Empty buckets have hash_value set to 0, and for tombstones, it's 1.
+   * We need to make sure our hash value is not one of these. */
+
+  hash_value = (* hash_table->hash_func) (key);
+  if (G_UNLIKELY (hash_value <= 1))
+    hash_value = 2;
+
+  *hash_return = hash_value;
+
+  node_index = hash_value % hash_table->mod;
+  node = &hash_table->nodes [node_index];
+
+  while (node->key_hash)
+    {
+      /*  We first check if our full hash values
+       *  are equal so we can avoid calling the full-blown
+       *  key equality function in most cases.
+       */
+
+      if (node->key_hash == hash_value)
+        {
+          if (hash_table->key_equal_func)
+            {
+              if (hash_table->key_equal_func (node->key, key))
+                return node_index;
+            }
+          else if (node->key == key)
+            {
+              return node_index;
+            }
+        }
+      else if (node->key_hash == 1 && !have_tombstone)
+        {
+          first_tombstone = node_index;
+          have_tombstone = TRUE;
+        }
+
+      step++;
+      node_index += step;
+      node_index &= hash_table->mask;
+      node = &hash_table->nodes [node_index];
+    }
+
+  if (have_tombstone)
+    return first_tombstone;
+
+  return node_index;
+}
+
+/*
+ * g_hash_table_remove_node:
+ * @hash_table: our #GHashTable
+ * @node: pointer to node to remove
+ * @notify: %TRUE if the destroy notify handlers are to be called
+ *
+ * Removes a node from the hash table and updates the node count.
+ * The node is replaced by a tombstone. No table resize is performed.
+ *
+ * If @notify is %TRUE then the destroy notify functions are called
+ * for the key and value of the hash node.
+ */
+static void
+g_hash_table_remove_node (GHashTable   *hash_table,
+                          GHashNode    *node,
+                          gboolean      notify)
+{
+  if (notify && hash_table->key_destroy_func)
+    hash_table->key_destroy_func (node->key);
+
+  if (notify && hash_table->value_destroy_func)
+    hash_table->value_destroy_func (node->value);
+
+  /* Erect tombstone */
+  node->key_hash = 1;
+
+  /* Be GC friendly */
+  node->key = NULL;
+  node->value = NULL;
+
+  hash_table->nnodes--;
+}
+
+/*
+ * g_hash_table_remove_all_nodes:
+ * @hash_table: our #GHashTable
+ * @notify: %TRUE if the destroy notify handlers are to be called
+ *
+ * Removes all nodes from the table.  Since this may be a precursor to
+ * freeing the table entirely, no resize is performed.
+ *
+ * If @notify is %TRUE then the destroy notify functions are called
+ * for the key and value of the hash node.
+ */
+static void
+g_hash_table_remove_all_nodes (GHashTable *hash_table,
+                               gboolean    notify)
+{
+  int i;
+
+  for (i = 0; i < hash_table->size; i++)
+    {
+      GHashNode *node = &hash_table->nodes [i];
+
+      if (node->key_hash > 1)
+        {
+          if (notify && hash_table->key_destroy_func)
+            hash_table->key_destroy_func (node->key);
+
+          if (notify && hash_table->value_destroy_func)
+            hash_table->value_destroy_func (node->value);
+        }
+    }
+
+  /* We need to set node->key_hash = 0 for all nodes - might as well be GC
+   * friendly and clear everything */
+  memset (hash_table->nodes, 0, hash_table->size * sizeof (GHashNode));
+
+  hash_table->nnodes = 0;
+  hash_table->noccupied = 0;
+}
+
+/*
+ * g_hash_table_resize:
+ * @hash_table: our #GHashTable
+ *
+ * Resizes the hash table to the optimal size based on the number of
+ * nodes currently held.  If you call this function then a resize will
+ * occur, even if one does not need to occur.  Use
+ * g_hash_table_maybe_resize() instead.
+ *
+ * This function may "resize" the hash table to its current size, with
+ * the side effect of cleaning up tombstones and otherwise optimizing
+ * the probe sequences.
+ */
+static void
+g_hash_table_resize (GHashTable *hash_table)
+{
+  GHashNode *new_nodes;
+  gint old_size;
+  gint i;
+
+  old_size = hash_table->size;
+  g_hash_table_set_shift_from_size (hash_table, hash_table->nnodes * 2);
+
+  new_nodes = g_new0 (GHashNode, hash_table->size);
+
+  for (i = 0; i < old_size; i++)
+    {
+      GHashNode *node = &hash_table->nodes [i];
+      GHashNode *new_node;
+      guint hash_val;
+      guint step = 0;
+
+      if (node->key_hash <= 1)
+        continue;
+
+      hash_val = node->key_hash % hash_table->mod;
+      new_node = &new_nodes [hash_val];
+
+      while (new_node->key_hash)
+        {
+          step++;
+          hash_val += step;
+          hash_val &= hash_table->mask;
+          new_node = &new_nodes [hash_val];
+        }
+
+      *new_node = *node;
+    }
+
+  g_free (hash_table->nodes);
+  hash_table->nodes = new_nodes;
+  hash_table->noccupied = hash_table->nnodes;
+}
+
+/*
+ * g_hash_table_maybe_resize:
+ * @hash_table: our #GHashTable
+ *
+ * Resizes the hash table, if needed.
+ *
+ * Essentially, calls g_hash_table_resize() if the table has strayed
+ * too far from its ideal size for its number of nodes.
+ */
+static inline void
+g_hash_table_maybe_resize (GHashTable *hash_table)
+{
+  gint noccupied = hash_table->noccupied;
+  gint size = hash_table->size;
+
+  if ((size > hash_table->nnodes * 4 && size > 1 << HASH_TABLE_MIN_SHIFT) ||
+      (size <= noccupied + (noccupied / 16)))
+    g_hash_table_resize (hash_table);
+}
+
+/**
+ * g_hash_table_new:
+ * @hash_func: a function to create a hash value from a key.
+ *   Hash values are used to determine where keys are stored within the
+ *   #GHashTable data structure. The g_direct_hash(), g_int_hash(),
+ *   g_int64_hash(), g_double_hash() and g_str_hash() functions are provided
+ *   for some common types of keys.
+ *   If hash_func is %NULL, g_direct_hash() is used.
+ * @key_equal_func: a function to check two keys for equality.  This is
+ *   used when looking up keys in the #GHashTable.  The g_direct_equal(),
+ *   g_int_equal(), g_int64_equal(), g_double_equal() and g_str_equal()
+ *   functions are provided for the most common types of keys.
+ *   If @key_equal_func is %NULL, keys are compared directly in a similar
+ *   fashion to g_direct_equal(), but without the overhead of a function call.
+ *
+ * Creates a new #GHashTable with a reference count of 1.
+ *
+ * Return value: a new #GHashTable.
+ **/
+GHashTable*
+g_hash_table_new (GHashFunc    hash_func,
+                  GEqualFunc   key_equal_func)
+{
+  return g_hash_table_new_full (hash_func, key_equal_func, NULL, NULL);
+}
+
+
+/**
+ * g_hash_table_new_full:
+ * @hash_func: a function to create a hash value from a key.
+ * @key_equal_func: a function to check two keys for equality.
+ * @key_destroy_func: a function to free the memory allocated for the key
+ *   used when removing the entry from the #GHashTable or %NULL if you
+ *   don't want to supply such a function.
+ * @value_destroy_func: a function to free the memory allocated for the
+ *   value used when removing the entry from the #GHashTable or %NULL if
+ *   you don't want to supply such a function.
+ *
+ * Creates a new #GHashTable like g_hash_table_new() with a reference count
+ * of 1 and allows to specify functions to free the memory allocated for the
+ * key and value that get called when removing the entry from the #GHashTable.
+ *
+ * Return value: a new #GHashTable.
+ **/
+GHashTable*
+g_hash_table_new_full (GHashFunc       hash_func,
+                       GEqualFunc      key_equal_func,
+                       GDestroyNotify  key_destroy_func,
+                       GDestroyNotify  value_destroy_func)
+{
+  GHashTable *hash_table;
+
+  hash_table = g_slice_new (GHashTable);
+  g_hash_table_set_shift (hash_table, HASH_TABLE_MIN_SHIFT);
+  hash_table->nnodes             = 0;
+  hash_table->noccupied          = 0;
+  hash_table->hash_func          = hash_func ? hash_func : g_direct_hash;
+  hash_table->key_equal_func     = key_equal_func;
+  hash_table->ref_count          = 1;
+#ifndef G_DISABLE_ASSERT
+  hash_table->version            = 0;
+#endif
+  hash_table->key_destroy_func   = key_destroy_func;
+  hash_table->value_destroy_func = value_destroy_func;
+  hash_table->nodes              = g_new0 (GHashNode, hash_table->size);
+
+  return hash_table;
+}
+
+/**
+ * g_hash_table_iter_init:
+ * @iter: an uninitialized #GHashTableIter.
+ * @hash_table: a #GHashTable.
+ *
+ * Initializes a key/value pair iterator and associates it with
+ * @hash_table. Modifying the hash table after calling this function
+ * invalidates the returned iterator.
+ * |[
+ * GHashTableIter iter;
+ * gpointer key, value;
+ *
+ * g_hash_table_iter_init (&iter, hash_table);
+ * while (g_hash_table_iter_next (&iter, &key, &value)) 
+ *   {
+ *     /&ast; do something with key and value &ast;/
+ *   }
+ * ]|
+ *
+ * Since: 2.16
+ **/
+void
+g_hash_table_iter_init (GHashTableIter *iter,
+                       GHashTable     *hash_table)
+{
+  RealIter *ri = (RealIter *) iter;
+
+  g_return_if_fail (iter != NULL);
+  g_return_if_fail (hash_table != NULL);
+
+  ri->hash_table = hash_table;
+  ri->position = -1;
+#ifndef G_DISABLE_ASSERT
+  ri->version = hash_table->version;
+#endif
+}
+
+/**
+ * g_hash_table_iter_next:
+ * @iter: an initialized #GHashTableIter.
+ * @key: a location to store the key, or %NULL.
+ * @value: a location to store the value, or %NULL.
+ *
+ * Advances @iter and retrieves the key and/or value that are now
+ * pointed to as a result of this advancement. If %FALSE is returned,
+ * @key and @value are not set, and the iterator becomes invalid.
+ *
+ * Return value: %FALSE if the end of the #GHashTable has been reached.
+ *
+ * Since: 2.16
+ **/
+gboolean
+g_hash_table_iter_next (GHashTableIter *iter,
+                       gpointer       *key,
+                       gpointer       *value)
+{
+  RealIter *ri = (RealIter *) iter;
+  GHashNode *node;
+  gint position;
+
+  g_return_val_if_fail (iter != NULL, FALSE);
+#ifndef G_DISABLE_ASSERT
+  g_return_val_if_fail (ri->version == ri->hash_table->version, FALSE);
+#endif
+  g_return_val_if_fail (ri->position < ri->hash_table->size, FALSE);
+
+  position = ri->position;
+
+  do
+    {
+      position++;
+      if (position >= ri->hash_table->size)
+        {
+          ri->position = position;
+          return FALSE;
+        }
+
+      node = &ri->hash_table->nodes [position];
+    }
+  while (node->key_hash <= 1);
+
+  if (key != NULL)
+    *key = node->key;
+  if (value != NULL)
+    *value = node->value;
+
+  ri->position = position;
+  return TRUE;
+}
+
+/**
+ * g_hash_table_iter_get_hash_table:
+ * @iter: an initialized #GHashTableIter.
+ *
+ * Returns the #GHashTable associated with @iter.
+ *
+ * Return value: the #GHashTable associated with @iter.
+ *
+ * Since: 2.16
+ **/
+GHashTable *
+g_hash_table_iter_get_hash_table (GHashTableIter *iter)
+{
+  g_return_val_if_fail (iter != NULL, NULL);
+
+  return ((RealIter *) iter)->hash_table;
+}
+
+static void
+iter_remove_or_steal (RealIter *ri, gboolean notify)
+{
+  g_return_if_fail (ri != NULL);
+#ifndef G_DISABLE_ASSERT
+  g_return_if_fail (ri->version == ri->hash_table->version);
+#endif
+  g_return_if_fail (ri->position >= 0);
+  g_return_if_fail (ri->position < ri->hash_table->size);
+
+  g_hash_table_remove_node (ri->hash_table, &ri->hash_table->nodes [ri->position], notify);
+
+#ifndef G_DISABLE_ASSERT
+  ri->version++;
+  ri->hash_table->version++;
+#endif
+}
+
+/**
+ * g_hash_table_iter_remove:
+ * @iter: an initialized #GHashTableIter.
+ *
+ * Removes the key/value pair currently pointed to by the iterator
+ * from its associated #GHashTable. Can only be called after
+ * g_hash_table_iter_next() returned %TRUE, and cannot be called more
+ * than once for the same key/value pair.
+ *
+ * If the #GHashTable was created using g_hash_table_new_full(), the
+ * key and value are freed using the supplied destroy functions, otherwise
+ * you have to make sure that any dynamically allocated values are freed 
+ * yourself.
+ *
+ * Since: 2.16
+ **/
+void
+g_hash_table_iter_remove (GHashTableIter *iter)
+{
+  iter_remove_or_steal ((RealIter *) iter, TRUE);
+}
+
+/**
+ * g_hash_table_iter_steal:
+ * @iter: an initialized #GHashTableIter.
+ *
+ * Removes the key/value pair currently pointed to by the iterator
+ * from its associated #GHashTable, without calling the key and value
+ * destroy functions. Can only be called after
+ * g_hash_table_iter_next() returned %TRUE, and cannot be called more
+ * than once for the same key/value pair.
+ *
+ * Since: 2.16
+ **/
+void
+g_hash_table_iter_steal (GHashTableIter *iter)
+{
+  iter_remove_or_steal ((RealIter *) iter, FALSE);
+}
+
+
+/**
+ * g_hash_table_ref:
+ * @hash_table: a valid #GHashTable.
+ *
+ * Atomically increments the reference count of @hash_table by one.
+ * This function is MT-safe and may be called from any thread.
+ *
+ * Return value: the passed in #GHashTable.
+ *
+ * Since: 2.10
+ **/
+GHashTable*
+g_hash_table_ref (GHashTable *hash_table)
+{
+  g_return_val_if_fail (hash_table != NULL, NULL);
+  g_return_val_if_fail (hash_table->ref_count > 0, hash_table);
+
+  g_atomic_int_add (&hash_table->ref_count, 1);
+  return hash_table;
+}
+
+/**
+ * g_hash_table_unref:
+ * @hash_table: a valid #GHashTable.
+ *
+ * Atomically decrements the reference count of @hash_table by one.
+ * If the reference count drops to 0, all keys and values will be
+ * destroyed, and all memory allocated by the hash table is released.
+ * This function is MT-safe and may be called from any thread.
+ *
+ * Since: 2.10
+ **/
+void
+g_hash_table_unref (GHashTable *hash_table)
+{
+  g_return_if_fail (hash_table != NULL);
+  g_return_if_fail (hash_table->ref_count > 0);
+
+  if (g_atomic_int_exchange_and_add (&hash_table->ref_count, -1) - 1 == 0)
+    {
+      g_hash_table_remove_all_nodes (hash_table, TRUE);
+      g_free (hash_table->nodes);
+      g_slice_free (GHashTable, hash_table);
+    }
+}
+
+/**
+ * g_hash_table_destroy:
+ * @hash_table: a #GHashTable.
+ *
+ * Destroys all keys and values in the #GHashTable and decrements its
+ * reference count by 1. If keys and/or values are dynamically allocated,
+ * you should either free them first or create the #GHashTable with destroy
+ * notifiers using g_hash_table_new_full(). In the latter case the destroy
+ * functions you supplied will be called on all keys and values during the
+ * destruction phase.
+ **/
+void
+g_hash_table_destroy (GHashTable *hash_table)
+{
+  g_return_if_fail (hash_table != NULL);
+  g_return_if_fail (hash_table->ref_count > 0);
+
+  g_hash_table_remove_all (hash_table);
+  g_hash_table_unref (hash_table);
+}
+
+/**
+ * g_hash_table_lookup:
+ * @hash_table: a #GHashTable.
+ * @key: the key to look up.
+ *
+ * Looks up a key in a #GHashTable. Note that this function cannot
+ * distinguish between a key that is not present and one which is present
+ * and has the value %NULL. If you need this distinction, use
+ * g_hash_table_lookup_extended().
+ *
+ * Return value: the associated value, or %NULL if the key is not found.
+ **/
+gpointer
+g_hash_table_lookup (GHashTable   *hash_table,
+                     gconstpointer key)
+{
+  GHashNode *node;
+  guint      node_index;
+
+  g_return_val_if_fail (hash_table != NULL, NULL);
+
+  node_index = g_hash_table_lookup_node (hash_table, key);
+  node = &hash_table->nodes [node_index];
+
+  return node->key_hash ? node->value : NULL;
+}
+
+/**
+ * g_hash_table_lookup_extended:
+ * @hash_table: a #GHashTable
+ * @lookup_key: the key to look up
+ * @orig_key: return location for the original key, or %NULL
+ * @value: return location for the value associated with the key, or %NULL
+ *
+ * Looks up a key in the #GHashTable, returning the original key and the
+ * associated value and a #gboolean which is %TRUE if the key was found. This
+ * is useful if you need to free the memory allocated for the original key,
+ * for example before calling g_hash_table_remove().
+ *
+ * You can actually pass %NULL for @lookup_key to test
+ * whether the %NULL key exists.
+ *
+ * Return value: %TRUE if the key was found in the #GHashTable.
+ **/
+gboolean
+g_hash_table_lookup_extended (GHashTable    *hash_table,
+                              gconstpointer  lookup_key,
+                              gpointer      *orig_key,
+                              gpointer      *value)
+{
+  GHashNode *node;
+  guint      node_index;
+
+  g_return_val_if_fail (hash_table != NULL, FALSE);
+
+  node_index = g_hash_table_lookup_node (hash_table, lookup_key);
+  node = &hash_table->nodes [node_index];
+
+  if (!node->key_hash)
+    return FALSE;
+
+  if (orig_key)
+    *orig_key = node->key;
+
+  if (value)
+    *value = node->value;
+
+  return TRUE;
+}
+
+/*
+ * g_hash_table_insert_internal:
+ * @hash_table: our #GHashTable
+ * @key: the key to insert
+ * @value: the value to insert
+ * @keep_new_key: if %TRUE and this key already exists in the table
+ *   then call the destroy notify function on the old key.  If %FALSE
+ *   then call the destroy notify function on the new key.
+ *
+ * Implements the common logic for the g_hash_table_insert() and
+ * g_hash_table_replace() functions.
+ *
+ * Do a lookup of @key.  If it is found, replace it with the new
+ * @value (and perhaps the new @key).  If it is not found, create a
+ * new node.
+ */
+static void
+g_hash_table_insert_internal (GHashTable *hash_table,
+                              gpointer    key,
+                              gpointer    value,
+                              gboolean    keep_new_key)
+{
+  GHashNode *node;
+  guint node_index;
+  guint key_hash;
+  guint old_hash;
+
+  g_return_if_fail (hash_table != NULL);
+  g_return_if_fail (hash_table->ref_count > 0);
+
+  node_index = g_hash_table_lookup_node_for_insertion (hash_table, key, &key_hash);
+  node = &hash_table->nodes [node_index];
+
+  old_hash = node->key_hash;
+
+  if (old_hash > 1)
+    {
+      if (keep_new_key)
+        {
+          if (hash_table->key_destroy_func)
+            hash_table->key_destroy_func (node->key);
+          node->key = key;
+        }
+      else
+        {
+          if (hash_table->key_destroy_func)
+            hash_table->key_destroy_func (key);
+        }
+
+      if (hash_table->value_destroy_func)
+        hash_table->value_destroy_func (node->value);
+
+      node->value = value;
+    }
+  else
+    {
+      node->key = key;
+      node->value = value;
+      node->key_hash = key_hash;
+
+      hash_table->nnodes++;
+
+      if (old_hash == 0)
+        {
+          /* We replaced an empty node, and not a tombstone */
+          hash_table->noccupied++;
+          g_hash_table_maybe_resize (hash_table);
+        }
+
+#ifndef G_DISABLE_ASSERT
+      hash_table->version++;
+#endif
+    }
+}
+
+/**
+ * g_hash_table_insert:
+ * @hash_table: a #GHashTable.
+ * @key: a key to insert.
+ * @value: the value to associate with the key.
+ *
+ * Inserts a new key and value into a #GHashTable.
+ *
+ * If the key already exists in the #GHashTable its current value is replaced
+ * with the new value. If you supplied a @value_destroy_func when creating the
+ * #GHashTable, the old value is freed using that function. If you supplied
+ * a @key_destroy_func when creating the #GHashTable, the passed key is freed
+ * using that function.
+ **/
+void
+g_hash_table_insert (GHashTable *hash_table,
+                     gpointer    key,
+                     gpointer    value)
+{
+  g_hash_table_insert_internal (hash_table, key, value, FALSE);
+}
+
+/**
+ * g_hash_table_replace:
+ * @hash_table: a #GHashTable.
+ * @key: a key to insert.
+ * @value: the value to associate with the key.
+ *
+ * Inserts a new key and value into a #GHashTable similar to
+ * g_hash_table_insert(). The difference is that if the key already exists
+ * in the #GHashTable, it gets replaced by the new key. If you supplied a
+ * @value_destroy_func when creating the #GHashTable, the old value is freed
+ * using that function. If you supplied a @key_destroy_func when creating the
+ * #GHashTable, the old key is freed using that function.
+ **/
+void
+g_hash_table_replace (GHashTable *hash_table,
+                      gpointer    key,
+                      gpointer    value)
+{
+  g_hash_table_insert_internal (hash_table, key, value, TRUE);
+}
+
+/*
+ * g_hash_table_remove_internal:
+ * @hash_table: our #GHashTable
+ * @key: the key to remove
+ * @notify: %TRUE if the destroy notify handlers are to be called
+ * Return value: %TRUE if a node was found and removed, else %FALSE
+ *
+ * Implements the common logic for the g_hash_table_remove() and
+ * g_hash_table_steal() functions.
+ *
+ * Do a lookup of @key and remove it if it is found, calling the
+ * destroy notify handlers only if @notify is %TRUE.
+ */
+static gboolean
+g_hash_table_remove_internal (GHashTable    *hash_table,
+                              gconstpointer  key,
+                              gboolean       notify)
+{
+  GHashNode *node;
+  guint node_index;
+
+  g_return_val_if_fail (hash_table != NULL, FALSE);
+
+  node_index = g_hash_table_lookup_node (hash_table, key);
+  node = &hash_table->nodes [node_index];
+
+  /* g_hash_table_lookup_node() never returns a tombstone, so this is safe */
+  if (!node->key_hash)
+    return FALSE;
+
+  g_hash_table_remove_node (hash_table, node, notify);
+  g_hash_table_maybe_resize (hash_table);
+
+#ifndef G_DISABLE_ASSERT
+  hash_table->version++;
+#endif
+
+  return TRUE;
+}
+
+/**
+ * g_hash_table_remove:
+ * @hash_table: a #GHashTable.
+ * @key: the key to remove.
+ *
+ * Removes a key and its associated value from a #GHashTable.
+ *
+ * If the #GHashTable was created using g_hash_table_new_full(), the
+ * key and value are freed using the supplied destroy functions, otherwise
+ * you have to make sure that any dynamically allocated values are freed
+ * yourself.
+ *
+ * Return value: %TRUE if the key was found and removed from the #GHashTable.
+ **/
+gboolean
+g_hash_table_remove (GHashTable    *hash_table,
+                     gconstpointer  key)
+{
+  return g_hash_table_remove_internal (hash_table, key, TRUE);
+}
+
+/**
+ * g_hash_table_steal:
+ * @hash_table: a #GHashTable.
+ * @key: the key to remove.
+ *
+ * Removes a key and its associated value from a #GHashTable without
+ * calling the key and value destroy functions.
+ *
+ * Return value: %TRUE if the key was found and removed from the #GHashTable.
+ **/
+gboolean
+g_hash_table_steal (GHashTable    *hash_table,
+                    gconstpointer  key)
+{
+  return g_hash_table_remove_internal (hash_table, key, FALSE);
+}
+
+/**
+ * g_hash_table_remove_all:
+ * @hash_table: a #GHashTable
+ *
+ * Removes all keys and their associated values from a #GHashTable.
+ *
+ * If the #GHashTable was created using g_hash_table_new_full(), the keys
+ * and values are freed using the supplied destroy functions, otherwise you
+ * have to make sure that any dynamically allocated values are freed
+ * yourself.
+ *
+ * Since: 2.12
+ **/
+void
+g_hash_table_remove_all (GHashTable *hash_table)
+{
+  g_return_if_fail (hash_table != NULL);
+
+#ifndef G_DISABLE_ASSERT
+  if (hash_table->nnodes != 0)
+    hash_table->version++;
+#endif
+
+  g_hash_table_remove_all_nodes (hash_table, TRUE);
+  g_hash_table_maybe_resize (hash_table);
+}
+
+/**
+ * g_hash_table_steal_all:
+ * @hash_table: a #GHashTable.
+ *
+ * Removes all keys and their associated values from a #GHashTable
+ * without calling the key and value destroy functions.
+ *
+ * Since: 2.12
+ **/
+void
+g_hash_table_steal_all (GHashTable *hash_table)
+{
+  g_return_if_fail (hash_table != NULL);
+
+#ifndef G_DISABLE_ASSERT
+  if (hash_table->nnodes != 0)
+    hash_table->version++;
+#endif
+
+  g_hash_table_remove_all_nodes (hash_table, FALSE);
+  g_hash_table_maybe_resize (hash_table);
+}
+
+/*
+ * g_hash_table_foreach_remove_or_steal:
+ * @hash_table: our #GHashTable
+ * @func: the user's callback function
+ * @user_data: data for @func
+ * @notify: %TRUE if the destroy notify handlers are to be called
+ *
+ * Implements the common logic for g_hash_table_foreach_remove() and
+ * g_hash_table_foreach_steal().
+ *
+ * Iterates over every node in the table, calling @func with the key
+ * and value of the node (and @user_data).  If @func returns %TRUE the
+ * node is removed from the table.
+ *
+ * If @notify is true then the destroy notify handlers will be called
+ * for each removed node.
+ */
+static guint
+g_hash_table_foreach_remove_or_steal (GHashTable *hash_table,
+                                      GHRFunc    func,
+                                      gpointer    user_data,
+                                      gboolean    notify)
+{
+  guint deleted = 0;
+  gint i;
+
+  for (i = 0; i < hash_table->size; i++)
+    {
+      GHashNode *node = &hash_table->nodes [i];
+
+      if (node->key_hash > 1 && (* func) (node->key, node->value, user_data))
+        {
+          g_hash_table_remove_node (hash_table, node, notify);
+          deleted++;
+        }
+    }
+
+  g_hash_table_maybe_resize (hash_table);
+
+#ifndef G_DISABLE_ASSERT
+  if (deleted > 0)
+    hash_table->version++;
+#endif
+
+  return deleted;
+}
+
+/**
+ * g_hash_table_foreach_remove:
+ * @hash_table: a #GHashTable.
+ * @func: the function to call for each key/value pair.
+ * @user_data: user data to pass to the function.
+ *
+ * Calls the given function for each key/value pair in the #GHashTable.
+ * If the function returns %TRUE, then the key/value pair is removed from the
+ * #GHashTable. If you supplied key or value destroy functions when creating
+ * the #GHashTable, they are used to free the memory allocated for the removed
+ * keys and values.
+ *
+ * See #GHashTableIter for an alternative way to loop over the 
+ * key/value pairs in the hash table.
+ *
+ * Return value: the number of key/value pairs removed.
+ **/
+guint
+g_hash_table_foreach_remove (GHashTable *hash_table,
+                             GHRFunc     func,
+                             gpointer    user_data)
+{
+  g_return_val_if_fail (hash_table != NULL, 0);
+  g_return_val_if_fail (func != NULL, 0);
+
+  return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, TRUE);
+}
+
+/**
+ * g_hash_table_foreach_steal:
+ * @hash_table: a #GHashTable.
+ * @func: the function to call for each key/value pair.
+ * @user_data: user data to pass to the function.
+ *
+ * Calls the given function for each key/value pair in the #GHashTable.
+ * If the function returns %TRUE, then the key/value pair is removed from the
+ * #GHashTable, but no key or value destroy functions are called.
+ *
+ * See #GHashTableIter for an alternative way to loop over the 
+ * key/value pairs in the hash table.
+ *
+ * Return value: the number of key/value pairs removed.
+ **/
+guint
+g_hash_table_foreach_steal (GHashTable *hash_table,
+                            GHRFunc     func,
+                            gpointer    user_data)
+{
+  g_return_val_if_fail (hash_table != NULL, 0);
+  g_return_val_if_fail (func != NULL, 0);
+
+  return g_hash_table_foreach_remove_or_steal (hash_table, func, user_data, FALSE);
+}
+
+/**
+ * g_hash_table_foreach:
+ * @hash_table: a #GHashTable.
+ * @func: the function to call for each key/value pair.
+ * @user_data: user data to pass to the function.
+ *
+ * Calls the given function for each of the key/value pairs in the
+ * #GHashTable.  The function is passed the key and value of each
+ * pair, and the given @user_data parameter.  The hash table may not
+ * be modified while iterating over it (you can't add/remove
+ * items). To remove all items matching a predicate, use
+ * g_hash_table_foreach_remove().
+ *
+ * See g_hash_table_find() for performance caveats for linear
+ * order searches in contrast to g_hash_table_lookup().
+ **/
+void
+g_hash_table_foreach (GHashTable *hash_table,
+                      GHFunc      func,
+                      gpointer    user_data)
+{
+  gint i;
+
+  g_return_if_fail (hash_table != NULL);
+  g_return_if_fail (func != NULL);
+
+  for (i = 0; i < hash_table->size; i++)
+    {
+      GHashNode *node = &hash_table->nodes [i];
+
+      if (node->key_hash > 1)
+        (* func) (node->key, node->value, user_data);
+    }
+}
+
+/**
+ * g_hash_table_find:
+ * @hash_table: a #GHashTable.
+ * @predicate:  function to test the key/value pairs for a certain property.
+ * @user_data:  user data to pass to the function.
+ *
+ * Calls the given function for key/value pairs in the #GHashTable until
+ * @predicate returns %TRUE.  The function is passed the key and value of
+ * each pair, and the given @user_data parameter. The hash table may not
+ * be modified while iterating over it (you can't add/remove items).
+ *
+ * Note, that hash tables are really only optimized for forward lookups,
+ * i.e. g_hash_table_lookup().
+ * So code that frequently issues g_hash_table_find() or
+ * g_hash_table_foreach() (e.g. in the order of once per every entry in a
+ * hash table) should probably be reworked to use additional or different
+ * data structures for reverse lookups (keep in mind that an O(n) find/foreach
+ * operation issued for all n values in a hash table ends up needing O(n*n)
+ * operations).
+ *
+ * Return value: The value of the first key/value pair is returned, for which
+ * func evaluates to %TRUE. If no pair with the requested property is found,
+ * %NULL is returned.
+ *
+ * Since: 2.4
+ **/
+gpointer
+g_hash_table_find (GHashTable      *hash_table,
+                   GHRFunc          predicate,
+                   gpointer         user_data)
+{
+  gint i;
+
+  g_return_val_if_fail (hash_table != NULL, NULL);
+  g_return_val_if_fail (predicate != NULL, NULL);
+
+  for (i = 0; i < hash_table->size; i++)
+    {
+      GHashNode *node = &hash_table->nodes [i];
+
+      if (node->key_hash > 1 && predicate (node->key, node->value, user_data))
+        return node->value;
+    }
+
+  return NULL;
+}
+
+/**
+ * g_hash_table_size:
+ * @hash_table: a #GHashTable.
+ *
+ * Returns the number of elements contained in the #GHashTable.
+ *
+ * Return value: the number of key/value pairs in the #GHashTable.
+ **/
+guint
+g_hash_table_size (GHashTable *hash_table)
+{
+  g_return_val_if_fail (hash_table != NULL, 0);
+
+  return hash_table->nnodes;
+}
+
+/**
+ * g_hash_table_get_keys:
+ * @hash_table: a #GHashTable
+ *
+ * Retrieves every key inside @hash_table. The returned data is valid
+ * until @hash_table is modified.
+ *
+ * Return value: a #GList containing all the keys inside the hash
+ *   table. The content of the list is owned by the hash table and
+ *   should not be modified or freed. Use g_list_free() when done
+ *   using the list.
+ *
+ * Since: 2.14
+ */
+GList *
+g_hash_table_get_keys (GHashTable *hash_table)
+{
+  gint i;
+  GList *retval;
+
+  g_return_val_if_fail (hash_table != NULL, NULL);
+
+  retval = NULL;
+  for (i = 0; i < hash_table->size; i++)
+    {
+      GHashNode *node = &hash_table->nodes [i];
+
+      if (node->key_hash > 1)
+        retval = g_list_prepend (retval, node->key);
+    }
+
+  return retval;
+}
+
+/**
+ * g_hash_table_get_values:
+ * @hash_table: a #GHashTable
+ *
+ * Retrieves every value inside @hash_table. The returned data is
+ * valid until @hash_table is modified.
+ *
+ * Return value: a #GList containing all the values inside the hash
+ *   table. The content of the list is owned by the hash table and
+ *   should not be modified or freed. Use g_list_free() when done
+ *   using the list.
+ *
+ * Since: 2.14
+ */
+GList *
+g_hash_table_get_values (GHashTable *hash_table)
+{
+  gint i;
+  GList *retval;
+
+  g_return_val_if_fail (hash_table != NULL, NULL);
+
+  retval = NULL;
+  for (i = 0; i < hash_table->size; i++)
+    {
+      GHashNode *node = &hash_table->nodes [i];
+
+      if (node->key_hash > 1)
+        retval = g_list_prepend (retval, node->value);
+    }
+
+  return retval;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/ghash.h b/resource/csdk/connectivity/lib/android/glib-master/glib/ghash.h
new file mode 100644 (file)
index 0000000..9128721
--- /dev/null
@@ -0,0 +1,166 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_HASH_H__
+#define __G_HASH_H__
+
+#include <glib/gtypes.h>
+#include <glib/glist.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GHashTable  GHashTable;
+
+typedef gboolean  (*GHRFunc)  (gpointer  key,
+                               gpointer  value,
+                               gpointer  user_data);
+
+typedef struct _GHashTableIter GHashTableIter;
+
+struct _GHashTableIter
+{
+  /*< private >*/
+  gpointer     dummy1;
+  gpointer     dummy2;
+  gpointer     dummy3;
+  int          dummy4;
+  gboolean     dummy5;
+  gpointer     dummy6;
+};
+
+/* Hash tables
+ */
+GHashTable* g_hash_table_new              (GHashFunc       hash_func,
+                                           GEqualFunc      key_equal_func);
+GHashTable* g_hash_table_new_full                 (GHashFunc       hash_func,
+                                           GEqualFunc      key_equal_func,
+                                           GDestroyNotify  key_destroy_func,
+                                           GDestroyNotify  value_destroy_func);
+void       g_hash_table_destroy           (GHashTable     *hash_table);
+void       g_hash_table_insert            (GHashTable     *hash_table,
+                                           gpointer        key,
+                                           gpointer        value);
+void        g_hash_table_replace           (GHashTable     *hash_table,
+                                           gpointer        key,
+                                           gpointer        value);
+gboolean    g_hash_table_remove                   (GHashTable     *hash_table,
+                                           gconstpointer   key);
+void        g_hash_table_remove_all        (GHashTable     *hash_table);
+gboolean    g_hash_table_steal             (GHashTable     *hash_table,
+                                           gconstpointer   key);
+void        g_hash_table_steal_all         (GHashTable     *hash_table);
+gpointer    g_hash_table_lookup                   (GHashTable     *hash_table,
+                                           gconstpointer   key);
+gboolean    g_hash_table_lookup_extended   (GHashTable    *hash_table,
+                                           gconstpointer   lookup_key,
+                                           gpointer       *orig_key,
+                                           gpointer       *value);
+void       g_hash_table_foreach           (GHashTable     *hash_table,
+                                           GHFunc          func,
+                                           gpointer        user_data);
+gpointer    g_hash_table_find             (GHashTable     *hash_table,
+                                           GHRFunc         predicate,
+                                           gpointer        user_data);
+guint      g_hash_table_foreach_remove    (GHashTable     *hash_table,
+                                           GHRFunc         func,
+                                           gpointer        user_data);
+guint      g_hash_table_foreach_steal     (GHashTable     *hash_table,
+                                           GHRFunc         func,
+                                           gpointer        user_data);
+guint      g_hash_table_size              (GHashTable     *hash_table);
+GList *     g_hash_table_get_keys          (GHashTable     *hash_table);
+GList *     g_hash_table_get_values        (GHashTable     *hash_table);
+
+void        g_hash_table_iter_init         (GHashTableIter *iter,
+                                           GHashTable     *hash_table);
+gboolean    g_hash_table_iter_next         (GHashTableIter *iter,
+                                           gpointer       *key,
+                                           gpointer       *value);
+GHashTable* g_hash_table_iter_get_hash_table (GHashTableIter *iter);
+void        g_hash_table_iter_remove       (GHashTableIter *iter);
+void        g_hash_table_iter_steal        (GHashTableIter *iter);
+
+/* keeping hash tables alive */
+GHashTable* g_hash_table_ref                      (GHashTable     *hash_table);
+void        g_hash_table_unref             (GHashTable     *hash_table);
+
+#ifndef G_DISABLE_DEPRECATED
+
+/**
+ * g_hash_table_freeze:
+ * @hash_table: a #GHashTable
+ *
+ * This function is deprecated and will be removed in the next major
+ * release of GLib. It does nothing.
+ **/
+#define g_hash_table_freeze(hash_table) ((void)0)
+
+/**
+ * g_hash_table_thaw:
+ * @hash_table: a #GHashTable
+ *
+ * This function is deprecated and will be removed in the next major
+ * release of GLib. It does nothing.
+ **/
+#define g_hash_table_thaw(hash_table) ((void)0)
+
+#endif /* G_DISABLE_DEPRECATED */
+
+/* Hash Functions
+ */
+gboolean g_str_equal (gconstpointer  v1,
+                      gconstpointer  v2);
+guint    g_str_hash  (gconstpointer  v);
+
+gboolean g_int_equal (gconstpointer  v1,
+                      gconstpointer  v2);
+guint    g_int_hash  (gconstpointer  v);
+
+gboolean g_int64_equal (gconstpointer  v1,
+                        gconstpointer  v2);
+guint    g_int64_hash  (gconstpointer  v);
+
+gboolean g_double_equal (gconstpointer  v1,
+                         gconstpointer  v2);
+guint    g_double_hash  (gconstpointer  v);
+
+/* This "hash" function will just return the key's address as an
+ * unsigned integer. Useful for hashing on plain addresses or
+ * simple integer values.
+ * Passing NULL into g_hash_table_new() as GHashFunc has the
+ * same effect as passing g_direct_hash().
+ */
+guint    g_direct_hash  (gconstpointer  v) G_GNUC_CONST;
+gboolean g_direct_equal (gconstpointer  v1,
+                         gconstpointer  v2) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __G_HASH_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/ghook.c b/resource/csdk/connectivity/lib/android/glib-master/glib/ghook.c
new file mode 100644 (file)
index 0000000..1406b58
--- /dev/null
@@ -0,0 +1,636 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * GHook: Callback maintenance functions
+ * Copyright (C) 1998 Tim Janik
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "ghook.h"
+
+#include "gtestutils.h"
+
+
+/* --- functions --- */
+static void
+default_finalize_hook (GHookList *hook_list,
+                      GHook     *hook)
+{
+  GDestroyNotify destroy = hook->destroy;
+
+  if (destroy)
+    {
+      hook->destroy = NULL;
+      destroy (hook->data);
+    }
+}
+
+void
+g_hook_list_init (GHookList *hook_list,
+                 guint      hook_size)
+{
+  g_return_if_fail (hook_list != NULL);
+  g_return_if_fail (hook_size >= sizeof (GHook));
+  
+  hook_list->seq_id = 1;
+  hook_list->hook_size = hook_size;
+  hook_list->is_setup = TRUE;
+  hook_list->hooks = NULL;
+  hook_list->dummy3 = NULL;
+  hook_list->finalize_hook = default_finalize_hook;
+  hook_list->dummy[0] = NULL;
+  hook_list->dummy[1] = NULL;
+}
+
+void
+g_hook_list_clear (GHookList *hook_list)
+{
+  g_return_if_fail (hook_list != NULL);
+  
+  if (hook_list->is_setup)
+    {
+      GHook *hook;
+      
+      hook_list->is_setup = FALSE;
+      
+      hook = hook_list->hooks;
+      if (!hook)
+       {
+         /* destroy hook_list->hook_memchunk */
+       }
+      else
+       do
+         {
+           GHook *tmp;
+           
+           g_hook_ref (hook_list, hook);
+           g_hook_destroy_link (hook_list, hook);
+           tmp = hook->next;
+           g_hook_unref (hook_list, hook);
+           hook = tmp;
+         }
+       while (hook);
+    }
+}
+
+GHook*
+g_hook_alloc (GHookList *hook_list)
+{
+  GHook *hook;
+  
+  g_return_val_if_fail (hook_list != NULL, NULL);
+  g_return_val_if_fail (hook_list->is_setup, NULL);
+  
+  hook = g_slice_alloc0 (hook_list->hook_size);
+  hook->data = NULL;
+  hook->next = NULL;
+  hook->prev = NULL;
+  hook->flags = G_HOOK_FLAG_ACTIVE;
+  hook->ref_count = 0;
+  hook->hook_id = 0;
+  hook->func = NULL;
+  hook->destroy = NULL;
+  
+  return hook;
+}
+
+void
+g_hook_free (GHookList *hook_list,
+            GHook     *hook)
+{
+  g_return_if_fail (hook_list != NULL);
+  g_return_if_fail (hook_list->is_setup);
+  g_return_if_fail (hook != NULL);
+  g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
+  g_return_if_fail (!G_HOOK_IN_CALL (hook));
+
+  if(hook_list->finalize_hook != NULL)
+      hook_list->finalize_hook (hook_list, hook);
+  g_slice_free1 (hook_list->hook_size, hook);
+}
+
+void
+g_hook_destroy_link (GHookList *hook_list,
+                    GHook     *hook)
+{
+  g_return_if_fail (hook_list != NULL);
+  g_return_if_fail (hook != NULL);
+
+  hook->flags &= ~G_HOOK_FLAG_ACTIVE;
+  if (hook->hook_id)
+    {
+      hook->hook_id = 0;
+      g_hook_unref (hook_list, hook); /* counterpart to g_hook_insert_before */
+    }
+}
+
+gboolean
+g_hook_destroy (GHookList   *hook_list,
+               gulong       hook_id)
+{
+  GHook *hook;
+  
+  g_return_val_if_fail (hook_list != NULL, FALSE);
+  g_return_val_if_fail (hook_id > 0, FALSE);
+  
+  hook = g_hook_get (hook_list, hook_id);
+  if (hook)
+    {
+      g_hook_destroy_link (hook_list, hook);
+      return TRUE;
+    }
+  
+  return FALSE;
+}
+
+void
+g_hook_unref (GHookList *hook_list,
+             GHook     *hook)
+{
+  g_return_if_fail (hook_list != NULL);
+  g_return_if_fail (hook != NULL);
+  g_return_if_fail (hook->ref_count > 0);
+  
+  hook->ref_count--;
+  if (!hook->ref_count)
+    {
+      g_return_if_fail (hook->hook_id == 0);
+      g_return_if_fail (!G_HOOK_IN_CALL (hook));
+
+      if (hook->prev)
+       hook->prev->next = hook->next;
+      else
+       hook_list->hooks = hook->next;
+      if (hook->next)
+       {
+         hook->next->prev = hook->prev;
+         hook->next = NULL;
+       }
+      hook->prev = NULL;
+
+      if (!hook_list->is_setup)
+       {
+         hook_list->is_setup = TRUE;
+         g_hook_free (hook_list, hook);
+         hook_list->is_setup = FALSE;
+      
+         if (!hook_list->hooks)
+           {
+             /* destroy hook_list->hook_memchunk */
+           }
+       }
+      else
+       g_hook_free (hook_list, hook);
+    }
+}
+
+GHook *
+g_hook_ref (GHookList *hook_list,
+           GHook     *hook)
+{
+  g_return_val_if_fail (hook_list != NULL, NULL);
+  g_return_val_if_fail (hook != NULL, NULL);
+  g_return_val_if_fail (hook->ref_count > 0, NULL);
+  
+  hook->ref_count++;
+
+  return hook;
+}
+
+void
+g_hook_prepend (GHookList *hook_list,
+               GHook     *hook)
+{
+  g_return_if_fail (hook_list != NULL);
+  
+  g_hook_insert_before (hook_list, hook_list->hooks, hook);
+}
+
+void
+g_hook_insert_before (GHookList *hook_list,
+                     GHook     *sibling,
+                     GHook     *hook)
+{
+  g_return_if_fail (hook_list != NULL);
+  g_return_if_fail (hook_list->is_setup);
+  g_return_if_fail (hook != NULL);
+  g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
+  g_return_if_fail (hook->ref_count == 0);
+  
+  hook->hook_id = hook_list->seq_id++;
+  hook->ref_count = 1; /* counterpart to g_hook_destroy_link */
+  
+  if (sibling)
+    {
+      if (sibling->prev)
+       {
+         hook->prev = sibling->prev;
+         hook->prev->next = hook;
+         hook->next = sibling;
+         sibling->prev = hook;
+       }
+      else
+       {
+         hook_list->hooks = hook;
+         hook->next = sibling;
+         sibling->prev = hook;
+       }
+    }
+  else
+    {
+      if (hook_list->hooks)
+       {
+         sibling = hook_list->hooks;
+         while (sibling->next)
+           sibling = sibling->next;
+         hook->prev = sibling;
+         sibling->next = hook;
+       }
+      else
+       hook_list->hooks = hook;
+    }
+}
+
+void
+g_hook_list_invoke (GHookList *hook_list,
+                   gboolean   may_recurse)
+{
+  GHook *hook;
+  
+  g_return_if_fail (hook_list != NULL);
+  g_return_if_fail (hook_list->is_setup);
+
+  hook = g_hook_first_valid (hook_list, may_recurse);
+  while (hook)
+    {
+      GHookFunc func;
+      gboolean was_in_call;
+      
+      func = (GHookFunc) hook->func;
+      
+      was_in_call = G_HOOK_IN_CALL (hook);
+      hook->flags |= G_HOOK_FLAG_IN_CALL;
+      func (hook->data);
+      if (!was_in_call)
+       hook->flags &= ~G_HOOK_FLAG_IN_CALL;
+      
+      hook = g_hook_next_valid (hook_list, hook, may_recurse);
+    }
+}
+
+void
+g_hook_list_invoke_check (GHookList *hook_list,
+                         gboolean   may_recurse)
+{
+  GHook *hook;
+  
+  g_return_if_fail (hook_list != NULL);
+  g_return_if_fail (hook_list->is_setup);
+  
+  hook = g_hook_first_valid (hook_list, may_recurse);
+  while (hook)
+    {
+      GHookCheckFunc func;
+      gboolean was_in_call;
+      gboolean need_destroy;
+      
+      func = (GHookCheckFunc) hook->func;
+      
+      was_in_call = G_HOOK_IN_CALL (hook);
+      hook->flags |= G_HOOK_FLAG_IN_CALL;
+      need_destroy = !func (hook->data);
+      if (!was_in_call)
+       hook->flags &= ~G_HOOK_FLAG_IN_CALL;
+      if (need_destroy)
+       g_hook_destroy_link (hook_list, hook);
+      
+      hook = g_hook_next_valid (hook_list, hook, may_recurse);
+    }
+}
+
+void
+g_hook_list_marshal_check (GHookList          *hook_list,
+                          gboolean             may_recurse,
+                          GHookCheckMarshaller marshaller,
+                          gpointer             data)
+{
+  GHook *hook;
+  
+  g_return_if_fail (hook_list != NULL);
+  g_return_if_fail (hook_list->is_setup);
+  g_return_if_fail (marshaller != NULL);
+  
+  hook = g_hook_first_valid (hook_list, may_recurse);
+  while (hook)
+    {
+      gboolean was_in_call;
+      gboolean need_destroy;
+      
+      was_in_call = G_HOOK_IN_CALL (hook);
+      hook->flags |= G_HOOK_FLAG_IN_CALL;
+      need_destroy = !marshaller (hook, data);
+      if (!was_in_call)
+       hook->flags &= ~G_HOOK_FLAG_IN_CALL;
+      if (need_destroy)
+       g_hook_destroy_link (hook_list, hook);
+      
+      hook = g_hook_next_valid (hook_list, hook, may_recurse);
+    }
+}
+
+void
+g_hook_list_marshal (GHookList              *hook_list,
+                    gboolean                 may_recurse,
+                    GHookMarshaller          marshaller,
+                    gpointer                 data)
+{
+  GHook *hook;
+  
+  g_return_if_fail (hook_list != NULL);
+  g_return_if_fail (hook_list->is_setup);
+  g_return_if_fail (marshaller != NULL);
+  
+  hook = g_hook_first_valid (hook_list, may_recurse);
+  while (hook)
+    {
+      gboolean was_in_call;
+      
+      was_in_call = G_HOOK_IN_CALL (hook);
+      hook->flags |= G_HOOK_FLAG_IN_CALL;
+      marshaller (hook, data);
+      if (!was_in_call)
+       hook->flags &= ~G_HOOK_FLAG_IN_CALL;
+      
+      hook = g_hook_next_valid (hook_list, hook, may_recurse);
+    }
+}
+
+GHook*
+g_hook_first_valid (GHookList *hook_list,
+                   gboolean   may_be_in_call)
+{
+  g_return_val_if_fail (hook_list != NULL, NULL);
+  
+  if (hook_list->is_setup)
+    {
+      GHook *hook;
+      
+      hook = hook_list->hooks;
+      if (hook)
+       {
+         g_hook_ref (hook_list, hook);
+         if (G_HOOK_IS_VALID (hook) && (may_be_in_call || !G_HOOK_IN_CALL (hook)))
+           return hook;
+         else
+           return g_hook_next_valid (hook_list, hook, may_be_in_call);
+       }
+    }
+  
+  return NULL;
+}
+
+GHook*
+g_hook_next_valid (GHookList *hook_list,
+                  GHook     *hook,
+                  gboolean   may_be_in_call)
+{
+  GHook *ohook = hook;
+
+  g_return_val_if_fail (hook_list != NULL, NULL);
+
+  if (!hook)
+    return NULL;
+  
+  hook = hook->next;
+  while (hook)
+    {
+      if (G_HOOK_IS_VALID (hook) && (may_be_in_call || !G_HOOK_IN_CALL (hook)))
+       {
+         g_hook_ref (hook_list, hook);
+         g_hook_unref (hook_list, ohook);
+         
+         return hook;
+       }
+      hook = hook->next;
+    }
+  g_hook_unref (hook_list, ohook);
+
+  return NULL;
+}
+
+GHook*
+g_hook_get (GHookList *hook_list,
+           gulong     hook_id)
+{
+  GHook *hook;
+  
+  g_return_val_if_fail (hook_list != NULL, NULL);
+  g_return_val_if_fail (hook_id > 0, NULL);
+  
+  hook = hook_list->hooks;
+  while (hook)
+    {
+      if (hook->hook_id == hook_id)
+       return hook;
+      hook = hook->next;
+    }
+  
+  return NULL;
+}
+
+GHook*
+g_hook_find (GHookList   *hook_list,
+            gboolean      need_valids,
+            GHookFindFunc func,
+            gpointer      data)
+{
+  GHook *hook;
+  
+  g_return_val_if_fail (hook_list != NULL, NULL);
+  g_return_val_if_fail (func != NULL, NULL);
+  
+  hook = hook_list->hooks;
+  while (hook)
+    {
+      GHook *tmp;
+
+      /* test only non-destroyed hooks */
+      if (!hook->hook_id)
+       {
+         hook = hook->next;
+         continue;
+       }
+      
+      g_hook_ref (hook_list, hook);
+      
+      if (func (hook, data) && hook->hook_id && (!need_valids || G_HOOK_ACTIVE (hook)))
+       {
+         g_hook_unref (hook_list, hook);
+         
+         return hook;
+       }
+
+      tmp = hook->next;
+      g_hook_unref (hook_list, hook);
+      hook = tmp;
+    }
+  
+  return NULL;
+}
+
+GHook*
+g_hook_find_data (GHookList *hook_list,
+                 gboolean   need_valids,
+                 gpointer   data)
+{
+  GHook *hook;
+  
+  g_return_val_if_fail (hook_list != NULL, NULL);
+  
+  hook = hook_list->hooks;
+  while (hook)
+    {
+      /* test only non-destroyed hooks */
+      if (hook->data == data &&
+         hook->hook_id &&
+         (!need_valids || G_HOOK_ACTIVE (hook)))
+       return hook;
+
+      hook = hook->next;
+    }
+  
+  return NULL;
+}
+
+GHook*
+g_hook_find_func (GHookList *hook_list,
+                 gboolean   need_valids,
+                 gpointer   func)
+{
+  GHook *hook;
+  
+  g_return_val_if_fail (hook_list != NULL, NULL);
+  g_return_val_if_fail (func != NULL, NULL);
+  
+  hook = hook_list->hooks;
+  while (hook)
+    {
+      /* test only non-destroyed hooks */
+      if (hook->func == func &&
+         hook->hook_id &&
+         (!need_valids || G_HOOK_ACTIVE (hook)))
+       return hook;
+
+      hook = hook->next;
+    }
+  
+  return NULL;
+}
+
+GHook*
+g_hook_find_func_data (GHookList *hook_list,
+                      gboolean   need_valids,
+                      gpointer   func,
+                      gpointer   data)
+{
+  GHook *hook;
+  
+  g_return_val_if_fail (hook_list != NULL, NULL);
+  g_return_val_if_fail (func != NULL, NULL);
+  
+  hook = hook_list->hooks;
+  while (hook)
+    {
+      /* test only non-destroyed hooks */
+      if (hook->data == data &&
+         hook->func == func &&
+         hook->hook_id &&
+         (!need_valids || G_HOOK_ACTIVE (hook)))
+       return hook;
+
+      hook = hook->next;
+    }
+  
+  return NULL;
+}
+
+void
+g_hook_insert_sorted (GHookList              *hook_list,
+                     GHook           *hook,
+                     GHookCompareFunc func)
+{
+  GHook *sibling;
+  
+  g_return_if_fail (hook_list != NULL);
+  g_return_if_fail (hook_list->is_setup);
+  g_return_if_fail (hook != NULL);
+  g_return_if_fail (G_HOOK_IS_UNLINKED (hook));
+  g_return_if_fail (hook->func != NULL);
+  g_return_if_fail (func != NULL);
+
+  /* first non-destroyed hook */
+  sibling = hook_list->hooks;
+  while (sibling && !sibling->hook_id)
+    sibling = sibling->next;
+  
+  while (sibling)
+    {
+      GHook *tmp;
+      
+      g_hook_ref (hook_list, sibling);
+      if (func (hook, sibling) <= 0 && sibling->hook_id)
+       {
+         g_hook_unref (hook_list, sibling);
+         break;
+       }
+
+      /* next non-destroyed hook */
+      tmp = sibling->next;
+      while (tmp && !tmp->hook_id)
+       tmp = tmp->next;
+
+      g_hook_unref (hook_list, sibling);
+      sibling = tmp;
+    }
+  
+  g_hook_insert_before (hook_list, sibling, hook);
+}
+
+gint
+g_hook_compare_ids (GHook *new_hook,
+                   GHook *sibling)
+{
+  if (new_hook->hook_id < sibling->hook_id)
+    return -1;
+  else if (new_hook->hook_id > sibling->hook_id)
+    return 1;
+  
+  return 0;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/ghook.h b/resource/csdk/connectivity/lib/android/glib-master/glib/ghook.h
new file mode 100644 (file)
index 0000000..5577fc3
--- /dev/null
@@ -0,0 +1,181 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_HOOK_H__
+#define __G_HOOK_H__
+
+#include <glib/gmem.h>
+
+G_BEGIN_DECLS
+
+
+/* --- typedefs --- */
+typedef struct _GHook          GHook;
+typedef struct _GHookList      GHookList;
+
+typedef gint           (*GHookCompareFunc)     (GHook          *new_hook,
+                                                GHook          *sibling);
+typedef gboolean       (*GHookFindFunc)        (GHook          *hook,
+                                                gpointer        data);
+typedef void           (*GHookMarshaller)      (GHook          *hook,
+                                                gpointer        marshal_data);
+typedef gboolean       (*GHookCheckMarshaller) (GHook          *hook,
+                                                gpointer        marshal_data);
+typedef void           (*GHookFunc)            (gpointer        data);
+typedef gboolean       (*GHookCheckFunc)       (gpointer        data);
+typedef void           (*GHookFinalizeFunc)    (GHookList      *hook_list,
+                                                GHook          *hook);
+typedef enum
+{
+  G_HOOK_FLAG_ACTIVE       = 1 << 0,
+  G_HOOK_FLAG_IN_CALL      = 1 << 1,
+  G_HOOK_FLAG_MASK         = 0x0f
+} GHookFlagMask;
+#define G_HOOK_FLAG_USER_SHIFT (4)
+
+
+/* --- structures --- */
+struct _GHookList
+{
+  gulong           seq_id;
+  guint                    hook_size : 16;
+  guint                    is_setup : 1;
+  GHook                   *hooks;
+  gpointer         dummy3;
+  GHookFinalizeFunc finalize_hook;
+  gpointer         dummy[2];
+};
+struct _GHook
+{
+  gpointer      data;
+  GHook                *next;
+  GHook                *prev;
+  guint                 ref_count;
+  gulong        hook_id;
+  guint                 flags;
+  gpointer      func;
+  GDestroyNotify destroy;
+};
+
+
+/* --- macros --- */
+#define        G_HOOK(hook)                    ((GHook*) (hook))
+#define        G_HOOK_FLAGS(hook)              (G_HOOK (hook)->flags)
+#define        G_HOOK_ACTIVE(hook)             ((G_HOOK_FLAGS (hook) & \
+                                         G_HOOK_FLAG_ACTIVE) != 0)
+#define        G_HOOK_IN_CALL(hook)            ((G_HOOK_FLAGS (hook) & \
+                                         G_HOOK_FLAG_IN_CALL) != 0)
+#define G_HOOK_IS_VALID(hook)          (G_HOOK (hook)->hook_id != 0 && \
+                                        (G_HOOK_FLAGS (hook) & \
+                                          G_HOOK_FLAG_ACTIVE))
+#define G_HOOK_IS_UNLINKED(hook)       (G_HOOK (hook)->next == NULL && \
+                                        G_HOOK (hook)->prev == NULL && \
+                                        G_HOOK (hook)->hook_id == 0 && \
+                                        G_HOOK (hook)->ref_count == 0)
+
+
+/* --- prototypes --- */
+/* callback maintenance functions */
+void    g_hook_list_init               (GHookList              *hook_list,
+                                        guint                   hook_size);
+void    g_hook_list_clear              (GHookList              *hook_list);
+GHook*  g_hook_alloc                   (GHookList              *hook_list);
+void    g_hook_free                    (GHookList              *hook_list,
+                                        GHook                  *hook);
+GHook *         g_hook_ref                     (GHookList              *hook_list,
+                                        GHook                  *hook);
+void    g_hook_unref                   (GHookList              *hook_list,
+                                        GHook                  *hook);
+gboolean g_hook_destroy                        (GHookList              *hook_list,
+                                        gulong                  hook_id);
+void    g_hook_destroy_link            (GHookList              *hook_list,
+                                        GHook                  *hook);
+void    g_hook_prepend                 (GHookList              *hook_list,
+                                        GHook                  *hook);
+void    g_hook_insert_before           (GHookList              *hook_list,
+                                        GHook                  *sibling,
+                                        GHook                  *hook);
+void    g_hook_insert_sorted           (GHookList              *hook_list,
+                                        GHook                  *hook,
+                                        GHookCompareFunc        func);
+GHook*  g_hook_get                     (GHookList              *hook_list,
+                                        gulong                  hook_id);
+GHook*  g_hook_find                    (GHookList              *hook_list,
+                                        gboolean                need_valids,
+                                        GHookFindFunc           func,
+                                        gpointer                data);
+GHook*  g_hook_find_data               (GHookList              *hook_list,
+                                        gboolean                need_valids,
+                                        gpointer                data);
+GHook*  g_hook_find_func               (GHookList              *hook_list,
+                                        gboolean                need_valids,
+                                        gpointer                func);
+GHook*  g_hook_find_func_data          (GHookList              *hook_list,
+                                        gboolean                need_valids,
+                                        gpointer                func,
+                                        gpointer                data);
+/* return the first valid hook, and increment its reference count */
+GHook*  g_hook_first_valid             (GHookList              *hook_list,
+                                        gboolean                may_be_in_call);
+/* return the next valid hook with incremented reference count, and
+ * decrement the reference count of the original hook
+ */
+GHook*  g_hook_next_valid              (GHookList              *hook_list,
+                                        GHook                  *hook,
+                                        gboolean                may_be_in_call);
+/* GHookCompareFunc implementation to insert hooks sorted by their id */
+gint    g_hook_compare_ids             (GHook                  *new_hook,
+                                        GHook                  *sibling);
+/* convenience macros */
+#define         g_hook_append( hook_list, hook )  \
+     g_hook_insert_before ((hook_list), NULL, (hook))
+/* invoke all valid hooks with the (*GHookFunc) signature.
+ */
+void    g_hook_list_invoke             (GHookList              *hook_list,
+                                        gboolean                may_recurse);
+/* invoke all valid hooks with the (*GHookCheckFunc) signature,
+ * and destroy the hook if FALSE is returned.
+ */
+void    g_hook_list_invoke_check       (GHookList              *hook_list,
+                                        gboolean                may_recurse);
+/* invoke a marshaller on all valid hooks.
+ */
+void    g_hook_list_marshal            (GHookList              *hook_list,
+                                        gboolean                may_recurse,
+                                        GHookMarshaller         marshaller,
+                                        gpointer                marshal_data);
+void    g_hook_list_marshal_check      (GHookList              *hook_list,
+                                        gboolean                may_recurse,
+                                        GHookCheckMarshaller    marshaller,
+                                        gpointer                marshal_data);
+
+G_END_DECLS
+
+#endif /* __G_HOOK_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/ghostutils.c b/resource/csdk/connectivity/lib/android/glib-master/glib/ghostutils.c
new file mode 100644 (file)
index 0000000..c036195
--- /dev/null
@@ -0,0 +1,769 @@
+/* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
+
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "ghostutils.h"
+
+#include "garray.h"
+#include "gmem.h"
+#include "gstring.h"
+#include "gstrfuncs.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION:ghostutils
+ * @short_description: Internet hostname utilities
+ *
+ * Functions for manipulating internet hostnames; in particular, for
+ * converting between Unicode and ASCII-encoded forms of
+ * Internationalized Domain Names (IDNs).
+ *
+ * The <ulink
+ * url="http://www.ietf.org/rfc/rfc3490.txt">Internationalized Domain
+ * Names for Applications (IDNA)</ulink> standards allow for the use
+ * of Unicode domain names in applications, while providing
+ * backward-compatibility with the old ASCII-only DNS, by defining an
+ * ASCII-Compatible Encoding of any given Unicode name, which can be
+ * used with non-IDN-aware applications and protocols. (For example,
+ * "Παν語.org" maps to "xn--4wa8awb4637h.org".)
+ **/
+
+#define IDNA_ACE_PREFIX     "xn--"
+#define IDNA_ACE_PREFIX_LEN 4
+
+/* Punycode constants, from RFC 3492. */
+
+#define PUNYCODE_BASE          36
+#define PUNYCODE_TMIN           1
+#define PUNYCODE_TMAX          26
+#define PUNYCODE_SKEW          38
+#define PUNYCODE_DAMP         700
+#define PUNYCODE_INITIAL_BIAS  72
+#define PUNYCODE_INITIAL_N   0x80
+
+#define PUNYCODE_IS_BASIC(cp) ((guint)(cp) < 0x80)
+
+/* Encode/decode a single base-36 digit */
+static inline gchar
+encode_digit (guint dig)
+{
+  if (dig < 26)
+    return dig + 'a';
+  else
+    return dig - 26 + '0';
+}
+
+static inline guint
+decode_digit (gchar dig)
+{
+  if (dig >= 'A' && dig <= 'Z')
+    return dig - 'A';
+  else if (dig >= 'a' && dig <= 'z')
+    return dig - 'a';
+  else if (dig >= '0' && dig <= '9')
+    return dig - '0' + 26;
+  else
+    return G_MAXUINT;
+}
+
+/* Punycode bias adaptation algorithm, RFC 3492 section 6.1 */
+static guint
+adapt (guint    delta,
+       guint    numpoints,
+       gboolean firsttime)
+{
+  guint k;
+
+  delta = firsttime ? delta / PUNYCODE_DAMP : delta / 2;
+  delta += delta / numpoints;
+
+  k = 0;
+  while (delta > ((PUNYCODE_BASE - PUNYCODE_TMIN) * PUNYCODE_TMAX) / 2)
+    {
+      delta /= PUNYCODE_BASE - PUNYCODE_TMIN;
+      k += PUNYCODE_BASE;
+    }
+
+  return k + ((PUNYCODE_BASE - PUNYCODE_TMIN + 1) * delta /
+             (delta + PUNYCODE_SKEW));
+}
+
+/* Punycode encoder, RFC 3492 section 6.3. The algorithm is
+ * sufficiently bizarre that it's not really worth trying to explain
+ * here.
+ */
+static gboolean
+punycode_encode (const gchar *input_utf8,
+                 gsize        input_utf8_length,
+                GString     *output)
+{
+  guint delta, handled_chars, num_basic_chars, bias, j, q, k, t, digit;
+  gunichar n, m, *input;
+  glong input_length;
+  gboolean success = FALSE;
+
+  /* Convert from UTF-8 to Unicode code points */
+  input = g_utf8_to_ucs4 (input_utf8, input_utf8_length, NULL,
+                         &input_length, NULL);
+  if (!input)
+    return FALSE;
+
+  /* Copy basic chars */
+  for (j = num_basic_chars = 0; j < input_length; j++)
+    {
+      if (PUNYCODE_IS_BASIC (input[j]))
+       {
+         g_string_append_c (output, g_ascii_tolower (input[j]));
+         num_basic_chars++;
+       }
+    }
+  if (num_basic_chars)
+    g_string_append_c (output, '-');
+
+  handled_chars = num_basic_chars;
+
+  /* Encode non-basic chars */
+  delta = 0;
+  bias = PUNYCODE_INITIAL_BIAS;
+  n = PUNYCODE_INITIAL_N;
+  while (handled_chars < input_length)
+    {
+      /* let m = the minimum {non-basic} code point >= n in the input */
+      for (m = G_MAXUINT, j = 0; j < input_length; j++)
+       {
+         if (input[j] >= n && input[j] < m)
+           m = input[j];
+       }
+
+      if (m - n > (G_MAXUINT - delta) / (handled_chars + 1))
+       goto fail;
+      delta += (m - n) * (handled_chars + 1);
+      n = m;
+
+      for (j = 0; j < input_length; j++)
+       {
+         if (input[j] < n)
+           {
+             if (++delta == 0)
+               goto fail;
+           }
+         else if (input[j] == n)
+           {
+             q = delta;
+             for (k = PUNYCODE_BASE; ; k += PUNYCODE_BASE)
+               {
+                 if (k <= bias)
+                   t = PUNYCODE_TMIN;
+                 else if (k >= bias + PUNYCODE_TMAX)
+                   t = PUNYCODE_TMAX;
+                 else
+                   t = k - bias;
+                 if (q < t)
+                   break;
+                 digit = t + (q - t) % (PUNYCODE_BASE - t);
+                 g_string_append_c (output, encode_digit (digit));
+                 q = (q - t) / (PUNYCODE_BASE - t);
+               }
+
+             g_string_append_c (output, encode_digit (q));
+             bias = adapt (delta, handled_chars + 1, handled_chars == num_basic_chars);
+             delta = 0;
+             handled_chars++;
+           }
+       }
+
+      delta++;
+      n++;
+    }
+
+  success = TRUE;
+
+ fail:
+  g_free (input);
+  return success;
+}
+
+/* From RFC 3454, Table B.1 */
+#define idna_is_junk(ch) ((ch) == 0x00AD || (ch) == 0x1806 || (ch) == 0x200B || (ch) == 0x2060 || (ch) == 0xFEFF || (ch) == 0x034F || (ch) == 0x180B || (ch) == 0x180C || (ch) == 0x180D || (ch) == 0x200C || (ch) == 0x200D || ((ch) >= 0xFE00 && (ch) <= 0xFE0F))
+
+/* Scan @str for "junk" and return a cleaned-up string if any junk
+ * is found. Else return %NULL.
+ */
+static gchar *
+remove_junk (const gchar *str,
+             gint         len)
+{
+  GString *cleaned = NULL;
+  const gchar *p;
+  gunichar ch;
+
+  for (p = str; len == -1 ? *p : p < str + len; p = g_utf8_next_char (p))
+    {
+      ch = g_utf8_get_char (p);
+      if (idna_is_junk (ch))
+       {
+         if (!cleaned)
+           {
+             cleaned = g_string_new (NULL);
+             g_string_append_len (cleaned, str, p - str);
+           }
+       }
+      else if (cleaned)
+       g_string_append_unichar (cleaned, ch);
+    }
+
+  if (cleaned)
+    return g_string_free (cleaned, FALSE);
+  else
+    return NULL;
+}
+
+static inline gboolean
+contains_uppercase_letters (const gchar *str,
+                            gint         len)
+{
+  const gchar *p;
+
+  for (p = str; len == -1 ? *p : p < str + len; p = g_utf8_next_char (p))
+    {
+      if (g_unichar_isupper (g_utf8_get_char (p)))
+       return TRUE;
+    }
+  return FALSE;
+}
+
+static inline gboolean
+contains_non_ascii (const gchar *str,
+                    gint         len)
+{
+  const gchar *p;
+
+  for (p = str; len == -1 ? *p : p < str + len; p++)
+    {
+      if ((guchar)*p > 0x80)
+       return TRUE;
+    }
+  return FALSE;
+}
+
+/* RFC 3454, Appendix C. ish. */
+static inline gboolean
+idna_is_prohibited (gunichar ch)
+{
+  switch (g_unichar_type (ch))
+    {
+    case G_UNICODE_CONTROL:
+    case G_UNICODE_FORMAT:
+    case G_UNICODE_UNASSIGNED:
+    case G_UNICODE_PRIVATE_USE:
+    case G_UNICODE_SURROGATE:
+    case G_UNICODE_LINE_SEPARATOR:
+    case G_UNICODE_PARAGRAPH_SEPARATOR:
+    case G_UNICODE_SPACE_SEPARATOR:
+      return TRUE;
+
+    case G_UNICODE_OTHER_SYMBOL:
+      if (ch == 0xFFFC || ch == 0xFFFD ||
+         (ch >= 0x2FF0 && ch <= 0x2FFB))
+       return TRUE;
+      return FALSE;
+
+    case G_UNICODE_NON_SPACING_MARK:
+      if (ch == 0x0340 || ch == 0x0341)
+       return TRUE;
+      return FALSE;
+
+    default:
+      return FALSE;
+    }
+}
+
+/* RFC 3491 IDN cleanup algorithm. */
+static gchar *
+nameprep (const gchar *hostname,
+          gint         len)
+{
+  gchar *name, *tmp = NULL, *p;
+
+  /* It would be nice if we could do this without repeatedly
+   * allocating strings and converting back and forth between
+   * gunichars and UTF-8... The code does at least avoid doing most of
+   * the sub-operations when they would just be equivalent to a
+   * g_strdup().
+   */
+
+  /* Remove presentation-only characters */
+  name = remove_junk (hostname, len);
+  if (name)
+    {
+      tmp = name;
+      len = -1;
+    }
+  else
+    name = (gchar *)hostname;
+
+  /* Convert to lowercase */
+  if (contains_uppercase_letters (name, len))
+    {
+      name = g_utf8_strdown (name, len);
+      g_free (tmp);
+      tmp = name;
+      len = -1;
+    }
+
+  /* If there are no UTF8 characters, we're done. */
+  if (!contains_non_ascii (name, len))
+    {
+      if (name == (gchar *)hostname)
+        return len == -1 ? g_strdup (hostname) : g_strndup (hostname, len);
+      else
+        return name;
+    }
+
+  /* Normalize */
+  name = g_utf8_normalize (name, len, G_NORMALIZE_NFKC);
+  g_free (tmp);
+  tmp = name;
+
+  if (!name)
+    return NULL;
+
+  /* KC normalization may have created more capital letters (eg,
+   * angstrom -> capital A with ring). So we have to lowercasify a
+   * second time. (This is more-or-less how the nameprep algorithm
+   * does it. If tolower(nfkc(tolower(X))) is guaranteed to be the
+   * same as tolower(nfkc(X)), then we could skip the first tolower,
+   * but I'm not sure it is.)
+   */
+  if (contains_uppercase_letters (name, -1))
+    {
+      name = g_utf8_strdown (name, -1);
+      g_free (tmp);
+      tmp = name;
+    }
+
+  /* Check for prohibited characters */
+  for (p = name; *p; p = g_utf8_next_char (p))
+    {
+      if (idna_is_prohibited (g_utf8_get_char (p)))
+       {
+         name = NULL;
+          g_free (tmp);
+         goto done;
+       }
+    }
+
+  /* FIXME: We're supposed to verify certain constraints on bidi
+   * characters, but glib does not appear to have that information.
+   */
+
+ done:
+  return name;
+}
+
+/**
+ * g_hostname_to_ascii:
+ * @hostname: a valid UTF-8 or ASCII hostname
+ *
+ * Converts @hostname to its canonical ASCII form; an ASCII-only
+ * string containing no uppercase letters and not ending with a
+ * trailing dot.
+ *
+ * Return value: an ASCII hostname, which must be freed, or %NULL if
+ * @hostname is in some way invalid.
+ *
+ * Since: 2.22
+ **/
+gchar *
+g_hostname_to_ascii (const gchar *hostname)
+{
+  gchar *name, *label, *p;
+  GString *out;
+  gssize llen, oldlen;
+  gboolean unicode;
+
+  label = name = nameprep (hostname, -1);
+  if (!name)
+    return NULL;
+
+  out = g_string_new (NULL);
+
+  do
+    {
+      unicode = FALSE;
+      for (p = label; *p && *p != '.'; p++)
+       {
+         if ((guchar)*p > 0x80)
+           unicode = TRUE;
+       }
+
+      oldlen = out->len;
+      llen = p - label;
+      if (unicode)
+       {
+          if (!strncmp (label, IDNA_ACE_PREFIX, IDNA_ACE_PREFIX_LEN))
+            goto fail;
+
+         g_string_append (out, IDNA_ACE_PREFIX);
+         if (!punycode_encode (label, llen, out))
+           goto fail;
+       }
+      else
+        g_string_append_len (out, label, llen);
+
+      if (out->len - oldlen > 63)
+       goto fail;
+
+      label += llen;
+      if (*label && *++label)
+        g_string_append_c (out, '.');
+    }
+  while (*label);
+
+  g_free (name);
+  return g_string_free (out, FALSE);
+
+ fail:
+  g_free (name);
+  g_string_free (out, TRUE);
+  return NULL;
+}
+
+/**
+ * g_hostname_is_non_ascii:
+ * @hostname: a hostname
+ *
+ * Tests if @hostname contains Unicode characters. If this returns
+ * %TRUE, you need to encode the hostname with g_hostname_to_ascii()
+ * before using it in non-IDN-aware contexts.
+ *
+ * Note that a hostname might contain a mix of encoded and unencoded
+ * segments, and so it is possible for g_hostname_is_non_ascii() and
+ * g_hostname_is_ascii_encoded() to both return %TRUE for a name.
+ *
+ * Return value: %TRUE if @hostname contains any non-ASCII characters
+ *
+ * Since: 2.22
+ **/
+gboolean
+g_hostname_is_non_ascii (const gchar *hostname)
+{
+  return contains_non_ascii (hostname, -1);
+}
+
+/* Punycode decoder, RFC 3492 section 6.2. As with punycode_encode(),
+ * read the RFC if you want to understand what this is actually doing.
+ */
+static gboolean
+punycode_decode (const gchar *input,
+                 gsize        input_length,
+                 GString     *output)
+{
+  GArray *output_chars;
+  gunichar n;
+  guint i, bias;
+  guint oldi, w, k, digit, t;
+  const gchar *split;
+
+  n = PUNYCODE_INITIAL_N;
+  i = 0;
+  bias = PUNYCODE_INITIAL_BIAS;
+
+  split = input + input_length - 1;
+  while (split > input && *split != '-')
+    split--;
+  if (split > input)
+    {
+      output_chars = g_array_sized_new (FALSE, FALSE, sizeof (gunichar),
+                                       split - input);
+      input_length -= (split - input) + 1;
+      while (input < split)
+       {
+         gunichar ch = (gunichar)*input++;
+         if (!PUNYCODE_IS_BASIC (ch))
+           goto fail;
+         g_array_append_val (output_chars, ch);
+       }
+      input++;
+    }
+  else
+    output_chars = g_array_new (FALSE, FALSE, sizeof (gunichar));
+
+  while (input_length)
+    {
+      oldi = i;
+      w = 1;
+      for (k = PUNYCODE_BASE; ; k += PUNYCODE_BASE)
+       {
+         if (!input_length--)
+           goto fail;
+         digit = decode_digit (*input++);
+         if (digit >= PUNYCODE_BASE)
+           goto fail;
+         if (digit > (G_MAXUINT - i) / w)
+           goto fail;
+         i += digit * w;
+         if (k <= bias)
+           t = PUNYCODE_TMIN;
+         else if (k >= bias + PUNYCODE_TMAX)
+           t = PUNYCODE_TMAX;
+         else
+           t = k - bias;
+         if (digit < t)
+           break;
+         if (w > G_MAXUINT / (PUNYCODE_BASE - t))
+           goto fail;
+         w *= (PUNYCODE_BASE - t);
+       }
+
+      bias = adapt (i - oldi, output_chars->len + 1, oldi == 0);
+
+      if (i / (output_chars->len + 1) > G_MAXUINT - n)
+       goto fail;
+      n += i / (output_chars->len + 1);
+      i %= (output_chars->len + 1);
+
+      g_array_insert_val (output_chars, i++, n);
+    }
+
+  for (i = 0; i < output_chars->len; i++)
+    g_string_append_unichar (output, g_array_index (output_chars, gunichar, i));
+  g_array_free (output_chars, TRUE);
+  return TRUE;
+
+ fail:
+  g_array_free (output_chars, TRUE);
+  return FALSE;
+}
+
+/**
+ * g_hostname_to_unicode:
+ * @hostname: a valid UTF-8 or ASCII hostname
+ *
+ * Converts @hostname to its canonical presentation form; a UTF-8
+ * string in Unicode normalization form C, containing no uppercase
+ * letters, no forbidden characters, and no ASCII-encoded segments,
+ * and not ending with a trailing dot.
+ *
+ * Of course if @hostname is not an internationalized hostname, then
+ * the canonical presentation form will be entirely ASCII.
+ *
+ * Return value: a UTF-8 hostname, which must be freed, or %NULL if
+ * @hostname is in some way invalid.
+ *
+ * Since: 2.22
+ **/
+gchar *
+g_hostname_to_unicode (const gchar *hostname)
+{
+  GString *out;
+  gssize llen;
+
+  out = g_string_new (NULL);
+
+  do
+    {
+      llen = strcspn (hostname, ".");
+      if (!g_ascii_strncasecmp (hostname, IDNA_ACE_PREFIX, IDNA_ACE_PREFIX_LEN))
+       {
+         hostname += IDNA_ACE_PREFIX_LEN;
+         llen -= IDNA_ACE_PREFIX_LEN;
+         if (!punycode_decode (hostname, llen, out))
+           {
+             g_string_free (out, TRUE);
+             return NULL;
+           }
+       }
+      else
+        {
+          gchar *canonicalized = nameprep (hostname, llen);
+
+          if (!canonicalized)
+            {
+              g_string_free (out, TRUE);
+              return NULL;
+            }
+          g_string_append (out, canonicalized);
+          g_free (canonicalized);
+        }
+
+      hostname += llen;
+      if (*hostname && *++hostname)
+        g_string_append_c (out, '.');
+    }
+  while (*hostname);
+
+  return g_string_free (out, FALSE);
+}
+
+/**
+ * g_hostname_is_ascii_encoded:
+ * @hostname: a hostname
+ *
+ * Tests if @hostname contains segments with an ASCII-compatible
+ * encoding of an Internationalized Domain Name. If this returns
+ * %TRUE, you should decode the hostname with g_hostname_to_unicode()
+ * before displaying it to the user.
+ *
+ * Note that a hostname might contain a mix of encoded and unencoded
+ * segments, and so it is possible for g_hostname_is_non_ascii() and
+ * g_hostname_is_ascii_encoded() to both return %TRUE for a name.
+ *
+ * Return value: %TRUE if @hostname contains any ASCII-encoded
+ * segments.
+ *
+ * Since: 2.22
+ **/
+gboolean
+g_hostname_is_ascii_encoded (const gchar *hostname)
+{
+  while (1)
+    {
+      if (!g_ascii_strncasecmp (hostname, IDNA_ACE_PREFIX, IDNA_ACE_PREFIX_LEN))
+       return TRUE;
+      hostname = strchr (hostname, '.');
+      if (!hostname++)
+       return FALSE;
+    }
+}
+
+/**
+ * g_hostname_is_ip_address:
+ * @hostname: a hostname (or IP address in string form)
+ *
+ * Tests if @hostname is the string form of an IPv4 or IPv6 address.
+ * (Eg, "192.168.0.1".)
+ *
+ * Return value: %TRUE if @hostname is an IP address
+ *
+ * Since: 2.22
+ **/
+gboolean
+g_hostname_is_ip_address (const gchar *hostname)
+{
+  gchar *p, *end;
+  gint nsegments, octet;
+
+  /* On Linux we could implement this using inet_pton, but the Windows
+   * equivalent of that requires linking against winsock, so we just
+   * figure this out ourselves. Tested by tests/hostutils.c.
+   */
+
+  p = (char *)hostname;
+
+  if (strchr (p, ':'))
+    {
+      gboolean skipped;
+
+      /* If it contains a ':', it's an IPv6 address (assuming it's an
+       * IP address at all). This consists of eight ':'-separated
+       * segments, each containing a 1-4 digit hex number, except that
+       * optionally: (a) the last two segments can be replaced by an
+       * IPv4 address, and (b) a single span of 1 to 8 "0000" segments
+       * can be replaced with just "::".
+       */
+
+      nsegments = 0;
+      skipped = FALSE;
+      while (*p && nsegments < 8)
+        {
+          /* Each segment after the first must be preceded by a ':'.
+           * (We also handle half of the "string starts with ::" case
+           * here.)
+           */
+          if (p != (char *)hostname || (p[0] == ':' && p[1] == ':'))
+            {
+              if (*p != ':')
+                return FALSE;
+              p++;
+            }
+
+          /* If there's another ':', it means we're skipping some segments */
+          if (*p == ':' && !skipped)
+            {
+              skipped = TRUE;
+              nsegments++;
+
+              /* Handle the "string ends with ::" case */
+              if (!p[1])
+                p++;
+
+              continue;
+            }
+
+          /* Read the segment, make sure it's valid. */
+          for (end = p; g_ascii_isxdigit (*end); end++)
+            ;
+          if (end == p || end > p + 4)
+            return FALSE;
+
+          if (*end == '.')
+            {
+              if ((nsegments == 6 && !skipped) || (nsegments <= 6 && skipped))
+                goto parse_ipv4;
+              else
+                return FALSE;
+            }
+
+          nsegments++;
+          p = end;
+        }
+
+      return !*p && (nsegments == 8 || skipped);
+    }
+
+ parse_ipv4:
+
+  /* Parse IPv4: N.N.N.N, where each N <= 255 and doesn't have leading 0s. */
+  for (nsegments = 0; nsegments < 4; nsegments++)
+    {
+      if (nsegments != 0)
+        {
+          if (*p != '.')
+            return FALSE;
+          p++;
+        }
+
+      /* Check the segment; a little tricker than the IPv6 case since
+       * we can't allow extra leading 0s, and we can't assume that all
+       * strings of valid length are within range.
+       */
+      octet = 0;
+      if (*p == '0')
+        end = p + 1;
+      else
+        {
+          for (end = p; g_ascii_isdigit (*end); end++)
+            octet = 10 * octet + (*end - '0');
+        }
+      if (end == p || end > p + 3 || octet > 255)
+        return FALSE;
+
+      p = end;
+    }
+
+  /* If there's nothing left to parse, then it's ok. */
+  return !*p;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/ghostutils.h b/resource/csdk/connectivity/lib/android/glib-master/glib/ghostutils.h
new file mode 100644 (file)
index 0000000..0349da3
--- /dev/null
@@ -0,0 +1,40 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_HOST_UTILS_H__
+#define __G_HOST_UTILS_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+gboolean  g_hostname_is_non_ascii     (const gchar *hostname);
+gboolean  g_hostname_is_ascii_encoded (const gchar *hostname);
+gboolean  g_hostname_is_ip_address    (const gchar *hostname);
+
+gchar    *g_hostname_to_ascii         (const gchar *hostname);
+gchar    *g_hostname_to_unicode       (const gchar *hostname);
+
+G_END_DECLS
+
+#endif /* __G_HOST_UTILS_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gi18n-lib.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gi18n-lib.h
new file mode 100644 (file)
index 0000000..ca002a7
--- /dev/null
@@ -0,0 +1,38 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997, 2002  Peter Mattis, Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_I18N_LIB_H__
+#define __G_I18N_LIB_H__
+
+#include <glib.h>
+
+#include <libintl.h>
+#include <string.h>
+
+#ifndef GETTEXT_PACKAGE
+#error You must define GETTEXT_PACKAGE before including gi18n-lib.h.  Did you forget to include config.h?
+#endif
+
+#define  _(String) ((char *) g_dgettext (GETTEXT_PACKAGE, String))
+#define Q_(String) g_dpgettext (GETTEXT_PACKAGE, String, 0)
+#define N_(String) (String)
+#define C_(Context,String) g_dpgettext (GETTEXT_PACKAGE, Context "\004" String, strlen (Context) + 1)
+#define NC_(Context, String) (String)
+
+#endif  /* __G_I18N_LIB_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gi18n.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gi18n.h
new file mode 100644 (file)
index 0000000..c710046
--- /dev/null
@@ -0,0 +1,34 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997, 2002  Peter Mattis, Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_I18N_H__
+#define __G_I18N_H__
+
+#include <glib.h>
+
+#include <libintl.h>
+#include <string.h>
+
+#define  _(String) gettext (String)
+#define Q_(String) g_dpgettext (NULL, String, 0)
+#define N_(String) (String)
+#define C_(Context,String) g_dpgettext (NULL, Context "\004" String, strlen (Context) + 1)
+#define NC_(Context, String) (String)
+
+#endif  /* __G_I18N_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/giochannel.c b/resource/csdk/connectivity/lib/android/glib-master/glib/giochannel.c
new file mode 100644 (file)
index 0000000..e70e40a
--- /dev/null
@@ -0,0 +1,2580 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * giochannel.c: IO Channel abstraction
+ * Copyright 1998 Owen Taylor
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/* 
+ * MT safe
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <errno.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#undef G_DISABLE_DEPRECATED
+
+#include "giochannel.h"
+
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "glibintl.h"
+
+
+/**
+ * SECTION: iochannels
+ * @title: IO Channels
+ * @short_description: portable support for using files, pipes and
+ *                     sockets
+ * @see_also: <para> <variablelist> <varlistentry>
+ *            <term>g_io_add_watch(), g_io_add_watch_full(),
+ *            g_source_remove()</term> <listitem><para> Convenience
+ *            functions for creating #GIOChannel instances and adding
+ *            them to the <link linkend="glib-The-Main-Event-Loop">main
+ *            event loop</link>. </para></listitem> </varlistentry>
+ *            </variablelist> </para>
+ *
+ * The #GIOChannel data type aims to provide a portable method for
+ * using file descriptors, pipes, and sockets, and integrating them
+ * into the <link linkend="glib-The-Main-Event-Loop">main event
+ * loop</link>. Currently full support is available on UNIX platforms,
+ * support for Windows is only partially complete.
+ *
+ * To create a new #GIOChannel on UNIX systems use
+ * g_io_channel_unix_new(). This works for plain file descriptors,
+ * pipes and sockets. Alternatively, a channel can be created for a
+ * file in a system independent manner using g_io_channel_new_file().
+ *
+ * Once a #GIOChannel has been created, it can be used in a generic
+ * manner with the functions g_io_channel_read_chars(),
+ * g_io_channel_write_chars(), g_io_channel_seek_position(), and
+ * g_io_channel_shutdown().
+ *
+ * To add a #GIOChannel to the <link
+ * linkend="glib-The-Main-Event-Loop">main event loop</link> use
+ * g_io_add_watch() or g_io_add_watch_full(). Here you specify which
+ * events you are interested in on the #GIOChannel, and provide a
+ * function to be called whenever these events occur.
+ *
+ * #GIOChannel instances are created with an initial reference count of
+ * 1. g_io_channel_ref() and g_io_channel_unref() can be used to
+ * increment or decrement the reference count respectively. When the
+ * reference count falls to 0, the #GIOChannel is freed. (Though it
+ * isn't closed automatically, unless it was created using
+ * g_io_channel_new_from_file().) Using g_io_add_watch() or
+ * g_io_add_watch_full() increments a channel's reference count.
+ *
+ * The new functions g_io_channel_read_chars(),
+ * g_io_channel_read_line(), g_io_channel_read_line_string(),
+ * g_io_channel_read_to_end(), g_io_channel_write_chars(),
+ * g_io_channel_seek_position(), and g_io_channel_flush() should not be
+ * mixed with the deprecated functions g_io_channel_read(),
+ * g_io_channel_write(), and g_io_channel_seek() on the same channel.
+ **/
+
+/**
+ * GIOChannel:
+ *
+ * A data structure representing an IO Channel. The fields should be
+ * considered private and should only be accessed with the following
+ * functions.
+ **/
+
+/**
+ * GIOFuncs:
+ * @io_read: reads raw bytes from the channel.  This is called from
+ *           various functions such as g_io_channel_read_chars() to
+ *           read raw bytes from the channel.  Encoding and buffering
+ *           issues are dealt with at a higher level.
+ * @io_write: writes raw bytes to the channel.  This is called from
+ *            various functions such as g_io_channel_write_chars() to
+ *            write raw bytes to the channel.  Encoding and buffering
+ *            issues are dealt with at a higher level.
+ * @io_seek: (optional) seeks the channel.  This is called from
+ *           g_io_channel_seek() on channels that support it.
+ * @io_close: closes the channel.  This is called from
+ *            g_io_channel_close() after flushing the buffers.
+ * @io_create_watch: creates a watch on the channel.  This call
+ *                   corresponds directly to g_io_create_watch().
+ * @io_free: called from g_io_channel_unref() when the channel needs to
+ *           be freed.  This function must free the memory associated
+ *           with the channel, including freeing the #GIOChannel
+ *           structure itself.  The channel buffers have been flushed
+ *           and possibly @io_close has been called by the time this
+ *           function is called.
+ * @io_set_flags: sets the #GIOFlags on the channel.  This is called
+ *                from g_io_channel_set_flags() with all flags except
+ *                for %G_IO_FLAG_APPEND and %G_IO_FLAG_NONBLOCK masked
+ *                out.
+ * @io_get_flags: gets the #GIOFlags for the channel.  This function
+ *                need only return the %G_IO_FLAG_APPEND and
+ *                %G_IO_FLAG_NONBLOCK flags; g_io_channel_get_flags()
+ *                automatically adds the others as appropriate.
+ *
+ * A table of functions used to handle different types of #GIOChannel
+ * in a generic way.
+ **/
+
+/**
+ * GIOStatus:
+ * @G_IO_STATUS_ERROR: An error occurred.
+ * @G_IO_STATUS_NORMAL: Success.
+ * @G_IO_STATUS_EOF: End of file.
+ * @G_IO_STATUS_AGAIN: Resource temporarily unavailable.
+ *
+ * Stati returned by most of the #GIOFuncs functions.
+ **/
+
+/**
+ * GIOError:
+ * @G_IO_ERROR_NONE: no error
+ * @G_IO_ERROR_AGAIN: an EAGAIN error occurred
+ * @G_IO_ERROR_INVAL: an EINVAL error occurred
+ * @G_IO_ERROR_UNKNOWN: another error occurred
+ *
+ * #GIOError is only used by the deprecated functions
+ * g_io_channel_read(), g_io_channel_write(), and g_io_channel_seek().
+ **/
+
+#define G_IO_NICE_BUF_SIZE     1024
+
+/* This needs to be as wide as the largest character in any possible encoding */
+#define MAX_CHAR_SIZE          10
+
+/* Some simplifying macros, which reduce the need to worry whether the
+ * buffers have been allocated. These also make USE_BUF () an lvalue,
+ * which is used in g_io_channel_read_to_end ().
+ */
+#define USE_BUF(channel)       ((channel)->encoding ? (channel)->encoded_read_buf \
+                                : (channel)->read_buf)
+#define BUF_LEN(string)                ((string) ? (string)->len : 0)
+
+static GIOError                g_io_error_get_from_g_error     (GIOStatus    status,
+                                                        GError      *err);
+static void            g_io_channel_purge              (GIOChannel  *channel);
+static GIOStatus       g_io_channel_fill_buffer        (GIOChannel  *channel,
+                                                        GError     **err);
+static GIOStatus       g_io_channel_read_line_backend  (GIOChannel  *channel,
+                                                        gsize       *length,
+                                                        gsize       *terminator_pos,
+                                                        GError     **error);
+
+/**
+ * g_io_channel_init:
+ * @channel: a #GIOChannel
+ *
+ * Initializes a #GIOChannel struct. 
+ *
+ * This is called by each of the above functions when creating a 
+ * #GIOChannel, and so is not often needed by the application 
+ * programmer (unless you are creating a new type of #GIOChannel).
+ */
+void
+g_io_channel_init (GIOChannel *channel)
+{
+  channel->ref_count = 1;
+  channel->encoding = g_strdup ("UTF-8");
+  channel->line_term = NULL;
+  channel->line_term_len = 0;
+  channel->buf_size = G_IO_NICE_BUF_SIZE;
+  channel->read_cd = (GIConv) -1;
+  channel->write_cd = (GIConv) -1;
+  channel->read_buf = NULL; /* Lazy allocate buffers */
+  channel->encoded_read_buf = NULL;
+  channel->write_buf = NULL;
+  channel->partial_write_buf[0] = '\0';
+  channel->use_buffer = TRUE;
+  channel->do_encode = FALSE;
+  channel->close_on_unref = FALSE;
+}
+
+/**
+ * g_io_channel_ref:
+ * @channel: a #GIOChannel
+ *
+ * Increments the reference count of a #GIOChannel.
+ *
+ * Returns: the @channel that was passed in (since 2.6)
+ */
+GIOChannel *
+g_io_channel_ref (GIOChannel *channel)
+{
+  g_return_val_if_fail (channel != NULL, NULL);
+
+  g_atomic_int_inc (&channel->ref_count);
+
+  return channel;
+}
+
+/**
+ * g_io_channel_unref:
+ * @channel: a #GIOChannel
+ *
+ * Decrements the reference count of a #GIOChannel.
+ */
+void 
+g_io_channel_unref (GIOChannel *channel)
+{
+  gboolean is_zero;
+
+  g_return_if_fail (channel != NULL);
+
+  is_zero = g_atomic_int_dec_and_test (&channel->ref_count);
+
+  if (G_UNLIKELY (is_zero))
+    {
+      if (channel->close_on_unref)
+        g_io_channel_shutdown (channel, TRUE, NULL);
+      else
+        g_io_channel_purge (channel);
+      g_free (channel->encoding);
+      if (channel->read_cd != (GIConv) -1)
+        g_iconv_close (channel->read_cd);
+      if (channel->write_cd != (GIConv) -1)
+        g_iconv_close (channel->write_cd);
+      g_free (channel->line_term);
+      if (channel->read_buf)
+        g_string_free (channel->read_buf, TRUE);
+      if (channel->write_buf)
+        g_string_free (channel->write_buf, TRUE);
+      if (channel->encoded_read_buf)
+        g_string_free (channel->encoded_read_buf, TRUE);
+      channel->funcs->io_free (channel);
+    }
+}
+
+static GIOError
+g_io_error_get_from_g_error (GIOStatus  status,
+                            GError    *err)
+{
+  switch (status)
+    {
+      case G_IO_STATUS_NORMAL:
+      case G_IO_STATUS_EOF:
+        return G_IO_ERROR_NONE;
+      case G_IO_STATUS_AGAIN:
+        return G_IO_ERROR_AGAIN;
+      case G_IO_STATUS_ERROR:
+       g_return_val_if_fail (err != NULL, G_IO_ERROR_UNKNOWN);
+       
+        if (err->domain != G_IO_CHANNEL_ERROR)
+          return G_IO_ERROR_UNKNOWN;
+        switch (err->code)
+          {
+            case G_IO_CHANNEL_ERROR_INVAL:
+              return G_IO_ERROR_INVAL;
+            default:
+              return G_IO_ERROR_UNKNOWN;
+          }
+      default:
+        g_assert_not_reached ();
+    }
+}
+
+/**
+ * g_io_channel_read:
+ * @channel: a #GIOChannel
+ * @buf: a buffer to read the data into (which should be at least 
+ *       count bytes long)
+ * @count: the number of bytes to read from the #GIOChannel
+ * @bytes_read: returns the number of bytes actually read
+ * 
+ * Reads data from a #GIOChannel. 
+ * 
+ * Return value: %G_IO_ERROR_NONE if the operation was successful. 
+ *
+ * Deprecated:2.2: Use g_io_channel_read_chars() instead.
+ **/
+GIOError 
+g_io_channel_read (GIOChannel *channel, 
+                  gchar      *buf, 
+                  gsize       count,
+                  gsize      *bytes_read)
+{
+  GError *err = NULL;
+  GIOError error;
+  GIOStatus status;
+
+  g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
+  g_return_val_if_fail (bytes_read != NULL, G_IO_ERROR_UNKNOWN);
+
+  if (count == 0)
+    {
+      if (bytes_read)
+        *bytes_read = 0;
+      return G_IO_ERROR_NONE;
+    }
+
+  g_return_val_if_fail (buf != NULL, G_IO_ERROR_UNKNOWN);
+
+  status = channel->funcs->io_read (channel, buf, count, bytes_read, &err);
+
+  error = g_io_error_get_from_g_error (status, err);
+
+  if (err)
+    g_error_free (err);
+
+  return error;
+}
+
+/**
+ * g_io_channel_write:
+ * @channel:  a #GIOChannel
+ * @buf: the buffer containing the data to write
+ * @count: the number of bytes to write
+ * @bytes_written: the number of bytes actually written
+ * 
+ * Writes data to a #GIOChannel. 
+ * 
+ * Return value:  %G_IO_ERROR_NONE if the operation was successful.
+ *
+ * Deprecated:2.2: Use g_io_channel_write_chars() instead.
+ **/
+GIOError 
+g_io_channel_write (GIOChannel  *channel, 
+                   const gchar *buf, 
+                   gsize        count,
+                   gsize       *bytes_written)
+{
+  GError *err = NULL;
+  GIOError error;
+  GIOStatus status;
+
+  g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
+  g_return_val_if_fail (bytes_written != NULL, G_IO_ERROR_UNKNOWN);
+
+  status = channel->funcs->io_write (channel, buf, count, bytes_written, &err);
+
+  error = g_io_error_get_from_g_error (status, err);
+
+  if (err)
+    g_error_free (err);
+
+  return error;
+}
+
+/**
+ * g_io_channel_seek:
+ * @channel: a #GIOChannel
+ * @offset: an offset, in bytes, which is added to the position specified 
+ *          by @type
+ * @type: the position in the file, which can be %G_SEEK_CUR (the current
+ *        position), %G_SEEK_SET (the start of the file), or %G_SEEK_END 
+ *        (the end of the file)
+ * 
+ * Sets the current position in the #GIOChannel, similar to the standard 
+ * library function fseek(). 
+ * 
+ * Return value: %G_IO_ERROR_NONE if the operation was successful.
+ *
+ * Deprecated:2.2: Use g_io_channel_seek_position() instead.
+ **/
+GIOError 
+g_io_channel_seek (GIOChannel *channel,
+                  gint64      offset, 
+                  GSeekType   type)
+{
+  GError *err = NULL;
+  GIOError error;
+  GIOStatus status;
+
+  g_return_val_if_fail (channel != NULL, G_IO_ERROR_UNKNOWN);
+  g_return_val_if_fail (channel->is_seekable, G_IO_ERROR_UNKNOWN);
+
+  switch (type)
+    {
+      case G_SEEK_CUR:
+      case G_SEEK_SET:
+      case G_SEEK_END:
+        break;
+      default:
+        g_warning ("g_io_channel_seek: unknown seek type");
+        return G_IO_ERROR_UNKNOWN;
+    }
+
+  status = channel->funcs->io_seek (channel, offset, type, &err);
+
+  error = g_io_error_get_from_g_error (status, err);
+
+  if (err)
+    g_error_free (err);
+
+  return error;
+}
+
+/* The function g_io_channel_new_file() is prototyped in both
+ * giounix.c and giowin32.c, so we stick its documentation here.
+ */
+
+/**
+ * g_io_channel_new_file:
+ * @filename: A string containing the name of a file
+ * @mode: One of "r", "w", "a", "r+", "w+", "a+". These have
+ *        the same meaning as in fopen()
+ * @error: A location to return an error of type %G_FILE_ERROR
+ *
+ * Open a file @filename as a #GIOChannel using mode @mode. This
+ * channel will be closed when the last reference to it is dropped,
+ * so there is no need to call g_io_channel_close() (though doing
+ * so will not cause problems, as long as no attempt is made to
+ * access the channel after it is closed).
+ *
+ * Return value: A #GIOChannel on success, %NULL on failure.
+ **/
+
+/**
+ * g_io_channel_close:
+ * @channel: A #GIOChannel
+ * 
+ * Close an IO channel. Any pending data to be written will be
+ * flushed, ignoring errors. The channel will not be freed until the
+ * last reference is dropped using g_io_channel_unref(). 
+ *
+ * Deprecated:2.2: Use g_io_channel_shutdown() instead.
+ **/
+void
+g_io_channel_close (GIOChannel *channel)
+{
+  GError *err = NULL;
+  
+  g_return_if_fail (channel != NULL);
+
+  g_io_channel_purge (channel);
+
+  channel->funcs->io_close (channel, &err);
+
+  if (err)
+    { /* No way to return the error */
+      g_warning ("Error closing channel: %s", err->message);
+      g_error_free (err);
+    }
+  
+  channel->close_on_unref = FALSE; /* Because we already did */
+  channel->is_readable = FALSE;
+  channel->is_writeable = FALSE;
+  channel->is_seekable = FALSE;
+}
+
+/**
+ * g_io_channel_shutdown:
+ * @channel: a #GIOChannel
+ * @flush: if %TRUE, flush pending
+ * @err: location to store a #GIOChannelError
+ * 
+ * Close an IO channel. Any pending data to be written will be
+ * flushed if @flush is %TRUE. The channel will not be freed until the
+ * last reference is dropped using g_io_channel_unref().
+ *
+ * Return value: the status of the operation.
+ **/
+GIOStatus
+g_io_channel_shutdown (GIOChannel  *channel,
+                      gboolean     flush,
+                      GError     **err)
+{
+  GIOStatus status, result;
+  GError *tmperr = NULL;
+  
+  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail (err == NULL || *err == NULL, G_IO_STATUS_ERROR);
+
+  if (channel->write_buf && channel->write_buf->len > 0)
+    {
+      if (flush)
+        {
+          GIOFlags flags;
+      
+          /* Set the channel to blocking, to avoid a busy loop
+           */
+          flags = g_io_channel_get_flags (channel);
+          /* Ignore any errors here, they're irrelevant */
+          g_io_channel_set_flags (channel, flags & ~G_IO_FLAG_NONBLOCK, NULL);
+
+          result = g_io_channel_flush (channel, &tmperr);
+        }
+      else
+        result = G_IO_STATUS_NORMAL;
+
+      g_string_truncate(channel->write_buf, 0);
+    }
+  else
+    result = G_IO_STATUS_NORMAL;
+
+  if (channel->partial_write_buf[0] != '\0')
+    {
+      if (flush)
+        g_warning ("Partial character at end of write buffer not flushed.\n");
+      channel->partial_write_buf[0] = '\0';
+    }
+
+  status = channel->funcs->io_close (channel, err);
+
+  channel->close_on_unref = FALSE; /* Because we already did */
+  channel->is_readable = FALSE;
+  channel->is_writeable = FALSE;
+  channel->is_seekable = FALSE;
+
+  if (status != G_IO_STATUS_NORMAL)
+    {
+      g_clear_error (&tmperr);
+      return status;
+    }
+  else if (result != G_IO_STATUS_NORMAL)
+    {
+      g_propagate_error (err, tmperr);
+      return result;
+    }
+  else
+    return G_IO_STATUS_NORMAL;
+}
+
+/* This function is used for the final flush on close or unref */
+static void
+g_io_channel_purge (GIOChannel *channel)
+{
+  GError *err = NULL;
+  GIOStatus status;
+
+  g_return_if_fail (channel != NULL);
+
+  if (channel->write_buf && channel->write_buf->len > 0)
+    {
+      GIOFlags flags;
+      
+      /* Set the channel to blocking, to avoid a busy loop
+       */
+      flags = g_io_channel_get_flags (channel);
+      g_io_channel_set_flags (channel, flags & ~G_IO_FLAG_NONBLOCK, NULL);
+
+      status = g_io_channel_flush (channel, &err);
+
+      if (err)
+       { /* No way to return the error */
+         g_warning ("Error flushing string: %s", err->message);
+         g_error_free (err);
+       }
+    }
+
+  /* Flush these in case anyone tries to close without unrefing */
+
+  if (channel->read_buf)
+    g_string_truncate (channel->read_buf, 0);
+  if (channel->write_buf)
+    g_string_truncate (channel->write_buf, 0);
+  if (channel->encoding)
+    {
+      if (channel->encoded_read_buf)
+        g_string_truncate (channel->encoded_read_buf, 0);
+
+      if (channel->partial_write_buf[0] != '\0')
+        {
+          g_warning ("Partial character at end of write buffer not flushed.\n");
+          channel->partial_write_buf[0] = '\0';
+        }
+    }
+}
+
+/**
+ * g_io_create_watch:
+ * @channel: a #GIOChannel to watch
+ * @condition: conditions to watch for
+ *
+ * Creates a #GSource that's dispatched when @condition is met for the 
+ * given @channel. For example, if condition is #G_IO_IN, the source will 
+ * be dispatched when there's data available for reading.
+ *
+ * g_io_add_watch() is a simpler interface to this same functionality, for 
+ * the case where you want to add the source to the default main loop context 
+ * at the default priority.
+ *
+ * On Windows, polling a #GSource created to watch a channel for a socket
+ * puts the socket in non-blocking mode. This is a side-effect of the
+ * implementation and unavoidable.
+ *
+ * Returns: a new #GSource
+ */
+GSource *
+g_io_create_watch (GIOChannel   *channel,
+                  GIOCondition  condition)
+{
+  g_return_val_if_fail (channel != NULL, NULL);
+
+  return channel->funcs->io_create_watch (channel, condition);
+}
+
+/**
+ * g_io_add_watch_full:
+ * @channel: a #GIOChannel
+ * @priority: the priority of the #GIOChannel source
+ * @condition: the condition to watch for
+ * @func: the function to call when the condition is satisfied
+ * @user_data: user data to pass to @func
+ * @notify: the function to call when the source is removed
+ *
+ * Adds the #GIOChannel into the default main loop context
+ * with the given priority.
+ *
+ * This internally creates a main loop source using g_io_create_watch()
+ * and attaches it to the main loop context with g_source_attach().
+ * You can do these steps manually if you need greater control.
+ *
+ * Returns: the event source id
+ */
+guint 
+g_io_add_watch_full (GIOChannel    *channel,
+                    gint           priority,
+                    GIOCondition   condition,
+                    GIOFunc        func,
+                    gpointer       user_data,
+                    GDestroyNotify notify)
+{
+  GSource *source;
+  guint id;
+  
+  g_return_val_if_fail (channel != NULL, 0);
+
+  source = g_io_create_watch (channel, condition);
+
+  if (priority != G_PRIORITY_DEFAULT)
+    g_source_set_priority (source, priority);
+  g_source_set_callback (source, (GSourceFunc)func, user_data, notify);
+
+  id = g_source_attach (source, NULL);
+  g_source_unref (source);
+
+  return id;
+}
+
+/**
+ * g_io_add_watch:
+ * @channel: a #GIOChannel
+ * @condition: the condition to watch for
+ * @func: the function to call when the condition is satisfied
+ * @user_data: user data to pass to @func
+ *
+ * Adds the #GIOChannel into the default main loop context
+ * with the default priority.
+ *
+ * Returns: the event source id
+ */
+/**
+ * GIOFunc:
+ * @source: the #GIOChannel event source
+ * @condition: the condition which has been satisfied
+ * @data: user data set in g_io_add_watch() or g_io_add_watch_full()
+ * @Returns: the function should return %FALSE if the event source
+ *           should be removed
+ *
+ * Specifies the type of function passed to g_io_add_watch() or
+ * g_io_add_watch_full(), which is called when the requested condition
+ * on a #GIOChannel is satisfied.
+ **/
+/**
+ * GIOCondition:
+ * @G_IO_IN: There is data to read.
+ * @G_IO_OUT: Data can be written (without blocking).
+ * @G_IO_PRI: There is urgent data to read.
+ * @G_IO_ERR: Error condition.
+ * @G_IO_HUP: Hung up (the connection has been broken, usually for
+ *            pipes and sockets).
+ * @G_IO_NVAL: Invalid request. The file descriptor is not open.
+ *
+ * A bitwise combination representing a condition to watch for on an
+ * event source.
+ **/
+guint 
+g_io_add_watch (GIOChannel   *channel,
+               GIOCondition  condition,
+               GIOFunc       func,
+               gpointer      user_data)
+{
+  return g_io_add_watch_full (channel, G_PRIORITY_DEFAULT, condition, func, user_data, NULL);
+}
+
+/**
+ * g_io_channel_get_buffer_condition:
+ * @channel: A #GIOChannel
+ *
+ * This function returns a #GIOCondition depending on whether there
+ * is data to be read/space to write data in the internal buffers in 
+ * the #GIOChannel. Only the flags %G_IO_IN and %G_IO_OUT may be set.
+ *
+ * Return value: A #GIOCondition
+ **/
+GIOCondition
+g_io_channel_get_buffer_condition (GIOChannel *channel)
+{
+  GIOCondition condition = 0;
+
+  if (channel->encoding)
+    {
+      if (channel->encoded_read_buf && (channel->encoded_read_buf->len > 0))
+        condition |= G_IO_IN; /* Only return if we have full characters */
+    }
+  else
+    {
+      if (channel->read_buf && (channel->read_buf->len > 0))
+        condition |= G_IO_IN;
+    }
+
+  if (channel->write_buf && (channel->write_buf->len < channel->buf_size))
+    condition |= G_IO_OUT;
+
+  return condition;
+}
+
+/**
+ * g_io_channel_error_from_errno:
+ * @en: an <literal>errno</literal> error number, e.g. %EINVAL
+ *
+ * Converts an <literal>errno</literal> error number to a #GIOChannelError.
+ *
+ * Return value: a #GIOChannelError error number, e.g. 
+ *      %G_IO_CHANNEL_ERROR_INVAL.
+ **/
+GIOChannelError
+g_io_channel_error_from_errno (gint en)
+{
+#ifdef EAGAIN
+  g_return_val_if_fail (en != EAGAIN, G_IO_CHANNEL_ERROR_FAILED);
+#endif
+
+  switch (en)
+    {
+#ifdef EBADF
+    case EBADF:
+      g_warning("Invalid file descriptor.\n");
+      return G_IO_CHANNEL_ERROR_FAILED;
+#endif
+
+#ifdef EFAULT
+    case EFAULT:
+      g_warning("Buffer outside valid address space.\n");
+      return G_IO_CHANNEL_ERROR_FAILED;
+#endif
+
+#ifdef EFBIG
+    case EFBIG:
+      return G_IO_CHANNEL_ERROR_FBIG;
+#endif
+
+#ifdef EINTR
+    /* In general, we should catch EINTR before we get here,
+     * but close() is allowed to return EINTR by POSIX, so
+     * we need to catch it here; EINTR from close() is
+     * unrecoverable, because it's undefined whether
+     * the fd was actually closed or not, so we just return
+     * a generic error code.
+     */
+    case EINTR:
+      return G_IO_CHANNEL_ERROR_FAILED;
+#endif
+
+#ifdef EINVAL
+    case EINVAL:
+      return G_IO_CHANNEL_ERROR_INVAL;
+#endif
+
+#ifdef EIO
+    case EIO:
+      return G_IO_CHANNEL_ERROR_IO;
+#endif
+
+#ifdef EISDIR
+    case EISDIR:
+      return G_IO_CHANNEL_ERROR_ISDIR;
+#endif
+
+#ifdef ENOSPC
+    case ENOSPC:
+      return G_IO_CHANNEL_ERROR_NOSPC;
+#endif
+
+#ifdef ENXIO
+    case ENXIO:
+      return G_IO_CHANNEL_ERROR_NXIO;
+#endif
+
+#ifdef EOVERFLOW
+    case EOVERFLOW:
+      return G_IO_CHANNEL_ERROR_OVERFLOW;
+#endif
+
+#ifdef EPIPE
+    case EPIPE:
+      return G_IO_CHANNEL_ERROR_PIPE;
+#endif
+
+    default:
+      return G_IO_CHANNEL_ERROR_FAILED;
+    }
+}
+
+/**
+ * g_io_channel_set_buffer_size:
+ * @channel: a #GIOChannel
+ * @size: the size of the buffer, or 0 to let GLib pick a good size
+ *
+ * Sets the buffer size.
+ **/  
+void
+g_io_channel_set_buffer_size (GIOChannel *channel,
+                              gsize       size)
+{
+  g_return_if_fail (channel != NULL);
+
+  if (size == 0)
+    size = G_IO_NICE_BUF_SIZE;
+
+  if (size < MAX_CHAR_SIZE)
+    size = MAX_CHAR_SIZE;
+
+  channel->buf_size = size;
+}
+
+/**
+ * g_io_channel_get_buffer_size:
+ * @channel: a #GIOChannel
+ *
+ * Gets the buffer size.
+ *
+ * Return value: the size of the buffer.
+ **/  
+gsize
+g_io_channel_get_buffer_size (GIOChannel *channel)
+{
+  g_return_val_if_fail (channel != NULL, 0);
+
+  return channel->buf_size;
+}
+
+/**
+ * g_io_channel_set_line_term:
+ * @channel: a #GIOChannel
+ * @line_term: The line termination string. Use %NULL for autodetect.
+ *             Autodetection breaks on "\n", "\r\n", "\r", "\0", and
+ *             the Unicode paragraph separator. Autodetection should
+ *             not be used for anything other than file-based channels.
+ * @length: The length of the termination string. If -1 is passed, the
+ *          string is assumed to be nul-terminated. This option allows
+ *          termination strings with embedded nuls.
+ *
+ * This sets the string that #GIOChannel uses to determine
+ * where in the file a line break occurs.
+ **/
+void
+g_io_channel_set_line_term (GIOChannel *channel,
+                            const gchar        *line_term,
+                           gint         length)
+{
+  g_return_if_fail (channel != NULL);
+  g_return_if_fail (line_term == NULL || length != 0); /* Disallow "" */
+
+  if (line_term == NULL)
+    length = 0;
+  else if (length < 0)
+    length = strlen (line_term);
+
+  g_free (channel->line_term);
+  channel->line_term = line_term ? g_memdup (line_term, length) : NULL;
+  channel->line_term_len = length;
+}
+
+/**
+ * g_io_channel_get_line_term:
+ * @channel: a #GIOChannel
+ * @length: a location to return the length of the line terminator
+ *
+ * This returns the string that #GIOChannel uses to determine
+ * where in the file a line break occurs. A value of %NULL
+ * indicates autodetection.
+ *
+ * Return value: The line termination string. This value
+ *   is owned by GLib and must not be freed.
+ **/
+G_CONST_RETURN gchar*
+g_io_channel_get_line_term (GIOChannel *channel,
+                           gint       *length)
+{
+  g_return_val_if_fail (channel != NULL, NULL);
+
+  if (length)
+    *length = channel->line_term_len;
+
+  return channel->line_term;
+}
+
+/**
+ * g_io_channel_set_flags:
+ * @channel: a #GIOChannel
+ * @flags: the flags to set on the IO channel
+ * @error: A location to return an error of type #GIOChannelError
+ *
+ * Sets the (writeable) flags in @channel to (@flags & %G_IO_CHANNEL_SET_MASK).
+ *
+ * Return value: the status of the operation. 
+ **/
+/**
+ * GIOFlags:
+ * @G_IO_FLAG_APPEND: turns on append mode, corresponds to %O_APPEND
+ *                    (see the documentation of the UNIX open()
+ *                    syscall).
+ * @G_IO_FLAG_NONBLOCK: turns on nonblocking mode, corresponds to
+ *                      %O_NONBLOCK/%O_NDELAY (see the documentation of
+ *                      the UNIX open() syscall).
+ * @G_IO_FLAG_IS_READABLE: indicates that the io channel is readable.
+ *                         This flag can not be changed.
+ * @G_IO_FLAG_IS_WRITEABLE: indicates that the io channel is writable.
+ *                          This flag can not be changed.
+ * @G_IO_FLAG_IS_SEEKABLE: indicates that the io channel is seekable,
+ *                         i.e. that g_io_channel_seek_position() can
+ *                         be used on it.  This flag can not be changed.
+ * @G_IO_FLAG_MASK: the mask that specifies all the valid flags.
+ * @G_IO_FLAG_GET_MASK: the mask of the flags that are returned from
+ *                      g_io_channel_get_flags().
+ * @G_IO_FLAG_SET_MASK: the mask of the flags that the user can modify
+ *                      with g_io_channel_set_flags().
+ *
+ * Specifies properties of a #GIOChannel. Some of the flags can only be
+ * read with g_io_channel_get_flags(), but not changed with
+ * g_io_channel_set_flags().
+ **/
+GIOStatus
+g_io_channel_set_flags (GIOChannel  *channel,
+                        GIOFlags     flags,
+                        GError     **error)
+{
+  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail ((error == NULL) || (*error == NULL),
+                       G_IO_STATUS_ERROR);
+
+  return (*channel->funcs->io_set_flags) (channel,
+                                         flags & G_IO_FLAG_SET_MASK,
+                                         error);
+}
+
+/**
+ * g_io_channel_get_flags:
+ * @channel: a #GIOChannel
+ *
+ * Gets the current flags for a #GIOChannel, including read-only
+ * flags such as %G_IO_FLAG_IS_READABLE.
+ *
+ * The values of the flags %G_IO_FLAG_IS_READABLE and %G_IO_FLAG_IS_WRITEABLE
+ * are cached for internal use by the channel when it is created.
+ * If they should change at some later point (e.g. partial shutdown
+ * of a socket with the UNIX shutdown() function), the user
+ * should immediately call g_io_channel_get_flags() to update
+ * the internal values of these flags.
+ *
+ * Return value: the flags which are set on the channel
+ **/
+GIOFlags
+g_io_channel_get_flags (GIOChannel *channel)
+{
+  GIOFlags flags;
+
+  g_return_val_if_fail (channel != NULL, 0);
+
+  flags = (* channel->funcs->io_get_flags) (channel);
+
+  /* Cross implementation code */
+
+  if (channel->is_seekable)
+    flags |= G_IO_FLAG_IS_SEEKABLE;
+  if (channel->is_readable)
+    flags |= G_IO_FLAG_IS_READABLE;
+  if (channel->is_writeable)
+    flags |= G_IO_FLAG_IS_WRITEABLE;
+
+  return flags;
+}
+
+/**
+ * g_io_channel_set_close_on_unref:
+ * @channel: a #GIOChannel
+ * @do_close: Whether to close the channel on the final unref of
+ *            the GIOChannel data structure. The default value of
+ *            this is %TRUE for channels created by g_io_channel_new_file (),
+ *            and %FALSE for all other channels.
+ *
+ * Setting this flag to %TRUE for a channel you have already closed
+ * can cause problems.
+ **/
+void
+g_io_channel_set_close_on_unref        (GIOChannel *channel,
+                                gboolean    do_close)
+{
+  g_return_if_fail (channel != NULL);
+
+  channel->close_on_unref = do_close;
+}
+
+/**
+ * g_io_channel_get_close_on_unref:
+ * @channel: a #GIOChannel.
+ *
+ * Returns whether the file/socket/whatever associated with @channel
+ * will be closed when @channel receives its final unref and is
+ * destroyed. The default value of this is %TRUE for channels created
+ * by g_io_channel_new_file (), and %FALSE for all other channels.
+ *
+ * Return value: Whether the channel will be closed on the final unref of
+ *               the GIOChannel data structure.
+ **/
+gboolean
+g_io_channel_get_close_on_unref        (GIOChannel *channel)
+{
+  g_return_val_if_fail (channel != NULL, FALSE);
+
+  return channel->close_on_unref;
+}
+
+/**
+ * g_io_channel_seek_position:
+ * @channel: a #GIOChannel
+ * @offset: The offset in bytes from the position specified by @type
+ * @type: a #GSeekType. The type %G_SEEK_CUR is only allowed in those
+ *                      cases where a call to g_io_channel_set_encoding ()
+ *                      is allowed. See the documentation for
+ *                      g_io_channel_set_encoding () for details.
+ * @error: A location to return an error of type #GIOChannelError
+ *
+ * Replacement for g_io_channel_seek() with the new API.
+ *
+ * Return value: the status of the operation.
+ **/
+/**
+ * GSeekType:
+ * @G_SEEK_CUR: the current position in the file.
+ * @G_SEEK_SET: the start of the file.
+ * @G_SEEK_END: the end of the file.
+ *
+ * An enumeration specifying the base position for a
+ * g_io_channel_seek_position() operation.
+ **/
+GIOStatus
+g_io_channel_seek_position (GIOChannel  *channel,
+                            gint64       offset,
+                            GSeekType    type,
+                            GError     **error)
+{
+  GIOStatus status;
+
+  /* For files, only one of the read and write buffers can contain data.
+   * For sockets, both can contain data.
+   */
+
+  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail ((error == NULL) || (*error == NULL),
+                       G_IO_STATUS_ERROR);
+  g_return_val_if_fail (channel->is_seekable, G_IO_STATUS_ERROR);
+
+  switch (type)
+    {
+      case G_SEEK_CUR: /* The user is seeking relative to the head of the buffer */
+        if (channel->use_buffer)
+          {
+            if (channel->do_encode && channel->encoded_read_buf
+                && channel->encoded_read_buf->len > 0)
+              {
+                g_warning ("Seek type G_SEEK_CUR not allowed for this"
+                  " channel's encoding.\n");
+                return G_IO_STATUS_ERROR;
+              }
+          if (channel->read_buf)
+            offset -= channel->read_buf->len;
+          if (channel->encoded_read_buf)
+            {
+              g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode);
+
+              /* If there's anything here, it's because the encoding is UTF-8,
+               * so we can just subtract the buffer length, the same as for
+               * the unencoded data.
+               */
+
+              offset -= channel->encoded_read_buf->len;
+            }
+          }
+        break;
+      case G_SEEK_SET:
+      case G_SEEK_END:
+        break;
+      default:
+        g_warning ("g_io_channel_seek_position: unknown seek type");
+        return G_IO_STATUS_ERROR;
+    }
+
+  if (channel->use_buffer)
+    {
+      status = g_io_channel_flush (channel, error);
+      if (status != G_IO_STATUS_NORMAL)
+        return status;
+    }
+
+  status = channel->funcs->io_seek (channel, offset, type, error);
+
+  if ((status == G_IO_STATUS_NORMAL) && (channel->use_buffer))
+    {
+      if (channel->read_buf)
+        g_string_truncate (channel->read_buf, 0);
+
+      /* Conversion state no longer matches position in file */
+      if (channel->read_cd != (GIConv) -1)
+        g_iconv (channel->read_cd, NULL, NULL, NULL, NULL);
+      if (channel->write_cd != (GIConv) -1)
+        g_iconv (channel->write_cd, NULL, NULL, NULL, NULL);
+
+      if (channel->encoded_read_buf)
+        {
+          g_assert (channel->encoded_read_buf->len == 0 || !channel->do_encode);
+          g_string_truncate (channel->encoded_read_buf, 0);
+        }
+
+      if (channel->partial_write_buf[0] != '\0')
+        {
+          g_warning ("Partial character at end of write buffer not flushed.\n");
+          channel->partial_write_buf[0] = '\0';
+        }
+    }
+
+  return status;
+}
+
+/**
+ * g_io_channel_flush:
+ * @channel: a #GIOChannel
+ * @error: location to store an error of type #GIOChannelError
+ *
+ * Flushes the write buffer for the GIOChannel.
+ *
+ * Return value: the status of the operation: One of
+ *   #G_IO_STATUS_NORMAL, #G_IO_STATUS_AGAIN, or
+ *   #G_IO_STATUS_ERROR.
+ **/
+GIOStatus
+g_io_channel_flush (GIOChannel *channel,
+                   GError     **error)
+{
+  GIOStatus status;
+  gsize this_time = 1, bytes_written = 0;
+
+  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR);
+
+  if (channel->write_buf == NULL || channel->write_buf->len == 0)
+    return G_IO_STATUS_NORMAL;
+
+  do
+    {
+      g_assert (this_time > 0);
+
+      status = channel->funcs->io_write (channel,
+                                        channel->write_buf->str + bytes_written,
+                                        channel->write_buf->len - bytes_written,
+                                        &this_time, error);
+      bytes_written += this_time;
+    }
+  while ((bytes_written < channel->write_buf->len)
+         && (status == G_IO_STATUS_NORMAL));
+
+  g_string_erase (channel->write_buf, 0, bytes_written);
+
+  return status;
+}
+
+/**
+ * g_io_channel_set_buffered:
+ * @channel: a #GIOChannel
+ * @buffered: whether to set the channel buffered or unbuffered
+ *
+ * The buffering state can only be set if the channel's encoding
+ * is %NULL. For any other encoding, the channel must be buffered.
+ *
+ * A buffered channel can only be set unbuffered if the channel's
+ * internal buffers have been flushed. Newly created channels or
+ * channels which have returned %G_IO_STATUS_EOF
+ * not require such a flush. For write-only channels, a call to
+ * g_io_channel_flush () is sufficient. For all other channels,
+ * the buffers may be flushed by a call to g_io_channel_seek_position ().
+ * This includes the possibility of seeking with seek type %G_SEEK_CUR
+ * and an offset of zero. Note that this means that socket-based
+ * channels cannot be set unbuffered once they have had data
+ * read from them.
+ *
+ * On unbuffered channels, it is safe to mix read and write
+ * calls from the new and old APIs, if this is necessary for
+ * maintaining old code.
+ *
+ * The default state of the channel is buffered.
+ **/
+void
+g_io_channel_set_buffered (GIOChannel *channel,
+                           gboolean    buffered)
+{
+  g_return_if_fail (channel != NULL);
+
+  if (channel->encoding != NULL)
+    {
+      g_warning ("Need to have NULL encoding to set the buffering state of the "
+                 "channel.\n");
+      return;
+    }
+
+  g_return_if_fail (!channel->read_buf || channel->read_buf->len == 0);
+  g_return_if_fail (!channel->write_buf || channel->write_buf->len == 0);
+
+  channel->use_buffer = buffered;
+}
+
+/**
+ * g_io_channel_get_buffered:
+ * @channel: a #GIOChannel
+ *
+ * Returns whether @channel is buffered.
+ *
+ * Return Value: %TRUE if the @channel is buffered. 
+ **/
+gboolean
+g_io_channel_get_buffered (GIOChannel *channel)
+{
+  g_return_val_if_fail (channel != NULL, FALSE);
+
+  return channel->use_buffer;
+}
+
+/**
+ * g_io_channel_set_encoding:
+ * @channel: a #GIOChannel
+ * @encoding: the encoding type
+ * @error: location to store an error of type #GConvertError
+ *
+ * Sets the encoding for the input/output of the channel. 
+ * The internal encoding is always UTF-8. The default encoding 
+ * for the external file is UTF-8.
+ *
+ * The encoding %NULL is safe to use with binary data.
+ *
+ * The encoding can only be set if one of the following conditions
+ * is true:
+ * <itemizedlist>
+ * <listitem><para>
+ *    The channel was just created, and has not been written to or read 
+ *    from yet.
+ * </para></listitem>
+ * <listitem><para>
+ *    The channel is write-only.
+ * </para></listitem>
+ * <listitem><para>
+ *    The channel is a file, and the file pointer was just
+ *    repositioned by a call to g_io_channel_seek_position().
+ *    (This flushes all the internal buffers.)
+ * </para></listitem>
+ * <listitem><para>
+ *    The current encoding is %NULL or UTF-8.
+ * </para></listitem>
+ * <listitem><para>
+ *    One of the (new API) read functions has just returned %G_IO_STATUS_EOF
+ *    (or, in the case of g_io_channel_read_to_end(), %G_IO_STATUS_NORMAL).
+ * </para></listitem>
+ * <listitem><para>
+ *    One of the functions g_io_channel_read_chars() or 
+ *    g_io_channel_read_unichar() has returned %G_IO_STATUS_AGAIN or 
+ *    %G_IO_STATUS_ERROR. This may be useful in the case of 
+ *    %G_CONVERT_ERROR_ILLEGAL_SEQUENCE.
+ *    Returning one of these statuses from g_io_channel_read_line(),
+ *    g_io_channel_read_line_string(), or g_io_channel_read_to_end()
+ *    does <emphasis>not</emphasis> guarantee that the encoding can 
+ *    be changed.
+ * </para></listitem>
+ * </itemizedlist>
+ * Channels which do not meet one of the above conditions cannot call
+ * g_io_channel_seek_position() with an offset of %G_SEEK_CUR, and, if 
+ * they are "seekable", cannot call g_io_channel_write_chars() after 
+ * calling one of the API "read" functions.
+ *
+ * Return Value: %G_IO_STATUS_NORMAL if the encoding was successfully set.
+ **/
+GIOStatus
+g_io_channel_set_encoding (GIOChannel  *channel,
+                           const gchar *encoding,
+                          GError      **error)
+{
+  GIConv read_cd, write_cd;
+  gboolean did_encode;
+
+  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail ((error == NULL) || (*error == NULL), G_IO_STATUS_ERROR);
+
+  /* Make sure the encoded buffers are empty */
+
+  g_return_val_if_fail (!channel->do_encode || !channel->encoded_read_buf ||
+                       channel->encoded_read_buf->len == 0, G_IO_STATUS_ERROR);
+
+  if (!channel->use_buffer)
+    {
+      g_warning ("Need to set the channel buffered before setting the encoding.\n");
+      g_warning ("Assuming this is what you meant and acting accordingly.\n");
+
+      channel->use_buffer = TRUE;
+    }
+
+  if (channel->partial_write_buf[0] != '\0')
+    {
+      g_warning ("Partial character at end of write buffer not flushed.\n");
+      channel->partial_write_buf[0] = '\0';
+    }
+
+  did_encode = channel->do_encode;
+
+  if (!encoding || strcmp (encoding, "UTF8") == 0 || strcmp (encoding, "UTF-8") == 0)
+    {
+      channel->do_encode = FALSE;
+      read_cd = write_cd = (GIConv) -1;
+    }
+  else
+    {
+      gint err = 0;
+      const gchar *from_enc = NULL, *to_enc = NULL;
+
+      if (channel->is_readable)
+        {
+          read_cd = g_iconv_open ("UTF-8", encoding);
+
+          if (read_cd == (GIConv) -1)
+            {
+              err = errno;
+              from_enc = encoding;
+              to_enc = "UTF-8";
+            }
+        }
+      else
+        read_cd = (GIConv) -1;
+
+      if (channel->is_writeable && err == 0)
+        {
+          write_cd = g_iconv_open (encoding, "UTF-8");
+
+          if (write_cd == (GIConv) -1)
+            {
+              err = errno;
+              from_enc = "UTF-8";
+              to_enc = encoding;
+            }
+        }
+      else
+        write_cd = (GIConv) -1;
+
+      if (err != 0)
+        {
+          g_assert (from_enc);
+          g_assert (to_enc);
+
+          if (err == EINVAL)
+            g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_NO_CONVERSION,
+                         _("Conversion from character set '%s' to '%s' is not supported"),
+                         from_enc, to_enc);
+          else
+            g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+                         _("Could not open converter from '%s' to '%s': %s"),
+                         from_enc, to_enc, g_strerror (err));
+
+          if (read_cd != (GIConv) -1)
+            g_iconv_close (read_cd);
+          if (write_cd != (GIConv) -1)
+            g_iconv_close (write_cd);
+
+          return G_IO_STATUS_ERROR;
+        }
+
+      channel->do_encode = TRUE;
+    }
+
+  /* The encoding is ok, so set the fields in channel */
+
+  if (channel->read_cd != (GIConv) -1)
+    g_iconv_close (channel->read_cd);
+  if (channel->write_cd != (GIConv) -1)
+    g_iconv_close (channel->write_cd);
+
+  if (channel->encoded_read_buf && channel->encoded_read_buf->len > 0)
+    {
+      g_assert (!did_encode); /* Encoding UTF-8, NULL doesn't use encoded_read_buf */
+
+      /* This is just validated UTF-8, so we can copy it back into read_buf
+       * so it can be encoded in whatever the new encoding is.
+       */
+
+      g_string_prepend_len (channel->read_buf, channel->encoded_read_buf->str,
+                            channel->encoded_read_buf->len);
+      g_string_truncate (channel->encoded_read_buf, 0);
+    }
+
+  channel->read_cd = read_cd;
+  channel->write_cd = write_cd;
+
+  g_free (channel->encoding);
+  channel->encoding = g_strdup (encoding);
+
+  return G_IO_STATUS_NORMAL;
+}
+
+/**
+ * g_io_channel_get_encoding:
+ * @channel: a #GIOChannel
+ *
+ * Gets the encoding for the input/output of the channel. 
+ * The internal encoding is always UTF-8. The encoding %NULL 
+ * makes the channel safe for binary data.
+ *
+ * Return value: A string containing the encoding, this string is
+ *   owned by GLib and must not be freed.
+ **/
+G_CONST_RETURN gchar*
+g_io_channel_get_encoding (GIOChannel *channel)
+{
+  g_return_val_if_fail (channel != NULL, NULL);
+
+  return channel->encoding;
+}
+
+static GIOStatus
+g_io_channel_fill_buffer (GIOChannel  *channel,
+                          GError     **err)
+{
+  gsize read_size, cur_len, oldlen;
+  GIOStatus status;
+
+  if (channel->is_seekable && channel->write_buf && channel->write_buf->len > 0)
+    {
+      status = g_io_channel_flush (channel, err);
+      if (status != G_IO_STATUS_NORMAL)
+        return status;
+    }
+  if (channel->is_seekable && channel->partial_write_buf[0] != '\0')
+    {
+      g_warning ("Partial character at end of write buffer not flushed.\n");
+      channel->partial_write_buf[0] = '\0';
+    }
+
+  if (!channel->read_buf)
+    channel->read_buf = g_string_sized_new (channel->buf_size);
+
+  cur_len = channel->read_buf->len;
+
+  g_string_set_size (channel->read_buf, channel->read_buf->len + channel->buf_size);
+
+  status = channel->funcs->io_read (channel, channel->read_buf->str + cur_len,
+                                    channel->buf_size, &read_size, err);
+
+  g_assert ((status == G_IO_STATUS_NORMAL) || (read_size == 0));
+
+  g_string_truncate (channel->read_buf, read_size + cur_len);
+
+  if ((status != G_IO_STATUS_NORMAL) &&
+      ((status != G_IO_STATUS_EOF) || (channel->read_buf->len == 0)))
+    return status;
+
+  g_assert (channel->read_buf->len > 0);
+
+  if (channel->encoded_read_buf)
+    oldlen = channel->encoded_read_buf->len;
+  else
+    {
+      oldlen = 0;
+      if (channel->encoding)
+        channel->encoded_read_buf = g_string_sized_new (channel->buf_size);
+    }
+
+  if (channel->do_encode)
+    {
+      gsize errnum, inbytes_left, outbytes_left;
+      gchar *inbuf, *outbuf;
+      int errval;
+
+      g_assert (channel->encoded_read_buf);
+
+reencode:
+
+      inbytes_left = channel->read_buf->len;
+      outbytes_left = MAX (channel->read_buf->len,
+                           channel->encoded_read_buf->allocated_len
+                           - channel->encoded_read_buf->len - 1); /* 1 for NULL */
+      outbytes_left = MAX (outbytes_left, 6);
+
+      inbuf = channel->read_buf->str;
+      g_string_set_size (channel->encoded_read_buf,
+                         channel->encoded_read_buf->len + outbytes_left);
+      outbuf = channel->encoded_read_buf->str + channel->encoded_read_buf->len
+               - outbytes_left;
+
+      errnum = g_iconv (channel->read_cd, &inbuf, &inbytes_left,
+                       &outbuf, &outbytes_left);
+      errval = errno;
+
+      g_assert (inbuf + inbytes_left == channel->read_buf->str
+                + channel->read_buf->len);
+      g_assert (outbuf + outbytes_left == channel->encoded_read_buf->str
+                + channel->encoded_read_buf->len);
+
+      g_string_erase (channel->read_buf, 0,
+                     channel->read_buf->len - inbytes_left);
+      g_string_truncate (channel->encoded_read_buf,
+                        channel->encoded_read_buf->len - outbytes_left);
+
+      if (errnum == (gsize) -1)
+        {
+          switch (errval)
+            {
+              case EINVAL:
+                if ((oldlen == channel->encoded_read_buf->len)
+                  && (status == G_IO_STATUS_EOF))
+                  status = G_IO_STATUS_EOF;
+                else
+                  status = G_IO_STATUS_NORMAL;
+                break;
+              case E2BIG:
+                /* Buffer size at least 6, wrote at least on character */
+                g_assert (inbuf != channel->read_buf->str);
+                goto reencode;
+              case EILSEQ:
+                if (oldlen < channel->encoded_read_buf->len)
+                  status = G_IO_STATUS_NORMAL;
+                else
+                  {
+                    g_set_error_literal (err, G_CONVERT_ERROR,
+                      G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                      _("Invalid byte sequence in conversion input"));
+                    return G_IO_STATUS_ERROR;
+                  }
+                break;
+              default:
+                g_assert (errval != EBADF); /* The converter should be open */
+                g_set_error (err, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+                  _("Error during conversion: %s"), g_strerror (errval));
+                return G_IO_STATUS_ERROR;
+            }
+        }
+      g_assert ((status != G_IO_STATUS_NORMAL)
+               || (channel->encoded_read_buf->len > 0));
+    }
+  else if (channel->encoding) /* UTF-8 */
+    {
+      gchar *nextchar, *lastchar;
+
+      g_assert (channel->encoded_read_buf);
+
+      nextchar = channel->read_buf->str;
+      lastchar = channel->read_buf->str + channel->read_buf->len;
+
+      while (nextchar < lastchar)
+        {
+          gunichar val_char;
+
+          val_char = g_utf8_get_char_validated (nextchar, lastchar - nextchar);
+
+          switch (val_char)
+            {
+              case -2:
+                /* stop, leave partial character in buffer */
+                lastchar = nextchar;
+                break;
+              case -1:
+                if (oldlen < channel->encoded_read_buf->len)
+                  status = G_IO_STATUS_NORMAL;
+                else
+                  {
+                    g_set_error_literal (err, G_CONVERT_ERROR,
+                      G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                      _("Invalid byte sequence in conversion input"));
+                    status = G_IO_STATUS_ERROR;
+                  }
+                lastchar = nextchar;
+                break;
+              default:
+                nextchar = g_utf8_next_char (nextchar);
+                break;
+            }
+        }
+
+      if (lastchar > channel->read_buf->str)
+        {
+          gint copy_len = lastchar - channel->read_buf->str;
+
+          g_string_append_len (channel->encoded_read_buf, channel->read_buf->str,
+                               copy_len);
+          g_string_erase (channel->read_buf, 0, copy_len);
+        }
+    }
+
+  return status;
+}
+
+/**
+ * g_io_channel_read_line:
+ * @channel: a #GIOChannel
+ * @str_return: The line read from the #GIOChannel, including the
+ *              line terminator. This data should be freed with g_free()
+ *              when no longer needed. This is a nul-terminated string. 
+ *              If a @length of zero is returned, this will be %NULL instead.
+ * @length: location to store length of the read data, or %NULL
+ * @terminator_pos: location to store position of line terminator, or %NULL
+ * @error: A location to return an error of type #GConvertError
+ *         or #GIOChannelError
+ *
+ * Reads a line, including the terminating character(s),
+ * from a #GIOChannel into a newly-allocated string.
+ * @str_return will contain allocated memory if the return
+ * is %G_IO_STATUS_NORMAL.
+ *
+ * Return value: the status of the operation.
+ **/
+GIOStatus
+g_io_channel_read_line (GIOChannel  *channel,
+                        gchar      **str_return,
+                        gsize       *length,
+                       gsize       *terminator_pos,
+                       GError     **error)
+{
+  GIOStatus status;
+  gsize got_length;
+  
+  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail (str_return != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail ((error == NULL) || (*error == NULL),
+                       G_IO_STATUS_ERROR);
+  g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
+
+  status = g_io_channel_read_line_backend (channel, &got_length, terminator_pos, error);
+
+  if (length)
+    *length = got_length;
+
+  if (status == G_IO_STATUS_NORMAL)
+    {
+      g_assert (USE_BUF (channel));
+      *str_return = g_strndup (USE_BUF (channel)->str, got_length);
+      g_string_erase (USE_BUF (channel), 0, got_length);
+    }
+  else
+    *str_return = NULL;
+  
+  return status;
+}
+
+/**
+ * g_io_channel_read_line_string:
+ * @channel: a #GIOChannel
+ * @buffer: a #GString into which the line will be written.
+ *          If @buffer already contains data, the old data will
+ *          be overwritten.
+ * @terminator_pos: location to store position of line terminator, or %NULL
+ * @error: a location to store an error of type #GConvertError
+ *         or #GIOChannelError
+ *
+ * Reads a line from a #GIOChannel, using a #GString as a buffer.
+ *
+ * Return value: the status of the operation.
+ **/
+GIOStatus
+g_io_channel_read_line_string (GIOChannel  *channel,
+                               GString    *buffer,
+                              gsize       *terminator_pos,
+                               GError    **error)
+{
+  gsize length;
+  GIOStatus status;
+
+  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail (buffer != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail ((error == NULL) || (*error == NULL),
+                       G_IO_STATUS_ERROR);
+  g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
+
+  if (buffer->len > 0)
+    g_string_truncate (buffer, 0); /* clear out the buffer */
+
+  status = g_io_channel_read_line_backend (channel, &length, terminator_pos, error);
+
+  if (status == G_IO_STATUS_NORMAL)
+    {
+      g_assert (USE_BUF (channel));
+      g_string_append_len (buffer, USE_BUF (channel)->str, length);
+      g_string_erase (USE_BUF (channel), 0, length);
+    }
+
+  return status;
+}
+
+
+static GIOStatus
+g_io_channel_read_line_backend (GIOChannel  *channel,
+                                gsize       *length,
+                                gsize       *terminator_pos,
+                                GError     **error)
+{
+  GIOStatus status;
+  gsize checked_to, line_term_len, line_length, got_term_len;
+  gboolean first_time = TRUE;
+
+  if (!channel->use_buffer)
+    {
+      /* Can't do a raw read in read_line */
+      g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+                           _("Can't do a raw read in g_io_channel_read_line_string"));
+      return G_IO_STATUS_ERROR;
+    }
+
+  status = G_IO_STATUS_NORMAL;
+
+  if (channel->line_term)
+    line_term_len = channel->line_term_len;
+  else
+    line_term_len = 3;
+    /* This value used for setting checked_to, it's the longest of the four
+     * we autodetect for.
+     */
+
+  checked_to = 0;
+
+  while (TRUE)
+    {
+      gchar *nextchar, *lastchar;
+      GString *use_buf;
+
+      if (!first_time || (BUF_LEN (USE_BUF (channel)) == 0))
+        {
+read_again:
+          status = g_io_channel_fill_buffer (channel, error);
+          switch (status)
+            {
+              case G_IO_STATUS_NORMAL:
+                if (BUF_LEN (USE_BUF (channel)) == 0)
+                  /* Can happen when using conversion and only read
+                   * part of a character
+                   */
+                  {
+                    first_time = FALSE;
+                    continue;
+                  }
+                break;
+              case G_IO_STATUS_EOF:
+                if (BUF_LEN (USE_BUF (channel)) == 0)
+                  {
+                    if (length)
+                      *length = 0;
+
+                    if (channel->encoding && channel->read_buf->len != 0)
+                      {
+                        g_set_error_literal (error, G_CONVERT_ERROR,
+                                             G_CONVERT_ERROR_PARTIAL_INPUT,
+                                             _("Leftover unconverted data in "
+                                               "read buffer"));
+                        return G_IO_STATUS_ERROR;
+                      }
+                    else
+                      return G_IO_STATUS_EOF;
+                  }
+                break;
+              default:
+                if (length)
+                  *length = 0;
+                return status;
+            }
+        }
+
+      g_assert (BUF_LEN (USE_BUF (channel)) != 0);
+
+      use_buf = USE_BUF (channel); /* The buffer has been created by this point */
+
+      first_time = FALSE;
+
+      lastchar = use_buf->str + use_buf->len;
+
+      for (nextchar = use_buf->str + checked_to; nextchar < lastchar;
+           channel->encoding ? nextchar = g_utf8_next_char (nextchar) : nextchar++)
+        {
+          if (channel->line_term)
+            {
+              if (memcmp (channel->line_term, nextchar, line_term_len) == 0)
+                {
+                  line_length = nextchar - use_buf->str;
+                  got_term_len = line_term_len;
+                  goto done;
+                }
+            }
+          else /* auto detect */
+            {
+              switch (*nextchar)
+                {
+                  case '\n': /* unix */
+                    line_length = nextchar - use_buf->str;
+                    got_term_len = 1;
+                    goto done;
+                  case '\r': /* Warning: do not use with sockets */
+                    line_length = nextchar - use_buf->str;
+                    if ((nextchar == lastchar - 1) && (status != G_IO_STATUS_EOF)
+                       && (lastchar == use_buf->str + use_buf->len))
+                      goto read_again; /* Try to read more data */
+                    if ((nextchar < lastchar - 1) && (*(nextchar + 1) == '\n')) /* dos */
+                      got_term_len = 2;
+                    else /* mac */
+                      got_term_len = 1;
+                    goto done;
+                  case '\xe2': /* Unicode paragraph separator */
+                    if (strncmp ("\xe2\x80\xa9", nextchar, 3) == 0)
+                      {
+                        line_length = nextchar - use_buf->str;
+                        got_term_len = 3;
+                        goto done;
+                      }
+                    break;
+                  case '\0': /* Embeded null in input */
+                    line_length = nextchar - use_buf->str;
+                    got_term_len = 1;
+                    goto done;
+                  default: /* no match */
+                    break;
+                }
+            }
+        }
+
+      /* If encoding != NULL, valid UTF-8, didn't overshoot */
+      g_assert (nextchar == lastchar);
+
+      /* Check for EOF */
+
+      if (status == G_IO_STATUS_EOF)
+        {
+          if (channel->encoding && channel->read_buf->len > 0)
+            {
+              g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
+                                   _("Channel terminates in a partial character"));
+              return G_IO_STATUS_ERROR;
+            }
+          line_length = use_buf->len;
+          got_term_len = 0;
+          break;
+        }
+
+      if (use_buf->len > line_term_len - 1)
+       checked_to = use_buf->len - (line_term_len - 1);
+      else
+       checked_to = 0;
+    }
+
+done:
+
+  if (terminator_pos)
+    *terminator_pos = line_length;
+
+  if (length)
+    *length = line_length + got_term_len;
+
+  return G_IO_STATUS_NORMAL;
+}
+
+/**
+ * g_io_channel_read_to_end:
+ * @channel: a #GIOChannel
+ * @str_return: Location to store a pointer to a string holding
+ *              the remaining data in the #GIOChannel. This data should
+ *              be freed with g_free() when no longer needed. This
+ *              data is terminated by an extra nul character, but there 
+ *              may be other nuls in the intervening data.
+ * @length: location to store length of the data
+ * @error: location to return an error of type #GConvertError
+ *         or #GIOChannelError
+ *
+ * Reads all the remaining data from the file.
+ *
+ * Return value: %G_IO_STATUS_NORMAL on success. 
+ *     This function never returns %G_IO_STATUS_EOF.
+ **/
+GIOStatus
+g_io_channel_read_to_end (GIOChannel  *channel,
+                          gchar      **str_return,
+                          gsize              *length,
+                          GError     **error)
+{
+  GIOStatus status;
+    
+  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail ((error == NULL) || (*error == NULL),
+    G_IO_STATUS_ERROR);
+  g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
+
+  if (str_return)
+    *str_return = NULL;
+  if (length)
+    *length = 0;
+
+  if (!channel->use_buffer)
+    {
+      g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+                           _("Can't do a raw read in g_io_channel_read_to_end"));
+      return G_IO_STATUS_ERROR;
+    }
+
+  do
+    status = g_io_channel_fill_buffer (channel, error);
+  while (status == G_IO_STATUS_NORMAL);
+
+  if (status != G_IO_STATUS_EOF)
+    return status;
+
+  if (channel->encoding && channel->read_buf->len > 0)
+    {
+      g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
+                           _("Channel terminates in a partial character"));
+      return G_IO_STATUS_ERROR;
+    }
+
+  if (USE_BUF (channel) == NULL)
+    {
+      /* length is already set to zero */
+      if (str_return)
+        *str_return = g_strdup ("");
+    }
+  else
+    {
+      if (length)
+        *length = USE_BUF (channel)->len;
+
+      if (str_return)
+        *str_return = g_string_free (USE_BUF (channel), FALSE);
+      else
+        g_string_free (USE_BUF (channel), TRUE);
+
+      if (channel->encoding)
+       channel->encoded_read_buf = NULL;
+      else
+       channel->read_buf = NULL;
+    }
+
+  return G_IO_STATUS_NORMAL;
+}
+
+/**
+ * g_io_channel_read_chars:
+ * @channel: a #GIOChannel
+ * @buf: a buffer to read data into
+ * @count: the size of the buffer. Note that the buffer may
+ *         not be complelely filled even if there is data
+ *         in the buffer if the remaining data is not a
+ *         complete character.
+ * @bytes_read: The number of bytes read. This may be zero even on
+ *              success if count < 6 and the channel's encoding is non-%NULL.
+ *              This indicates that the next UTF-8 character is too wide for
+ *              the buffer.
+ * @error: a location to return an error of type #GConvertError
+ *         or #GIOChannelError.
+ *
+ * Replacement for g_io_channel_read() with the new API.
+ *
+ * Return value: the status of the operation.
+ **/
+GIOStatus
+g_io_channel_read_chars (GIOChannel  *channel,
+                         gchar      *buf,
+                         gsize       count,
+                        gsize       *bytes_read,
+                         GError     **error)
+{
+  GIOStatus status;
+  gsize got_bytes;
+
+  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail ((error == NULL) || (*error == NULL),
+                       G_IO_STATUS_ERROR);
+  g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
+
+  if (count == 0)
+    {
+      *bytes_read = 0;
+      return G_IO_STATUS_NORMAL;
+    }
+  g_return_val_if_fail (buf != NULL, G_IO_STATUS_ERROR);
+
+  if (!channel->use_buffer)
+    {
+      gsize tmp_bytes;
+      
+      g_assert (!channel->read_buf || channel->read_buf->len == 0);
+
+      status = channel->funcs->io_read (channel, buf, count, &tmp_bytes, error);
+      
+      if (bytes_read)
+       *bytes_read = tmp_bytes;
+
+      return status;
+    }
+
+  status = G_IO_STATUS_NORMAL;
+
+  while (BUF_LEN (USE_BUF (channel)) < count && status == G_IO_STATUS_NORMAL)
+    status = g_io_channel_fill_buffer (channel, error);
+
+  /* Only return an error if we have no data */
+
+  if (BUF_LEN (USE_BUF (channel)) == 0)
+    {
+      g_assert (status != G_IO_STATUS_NORMAL);
+
+      if (status == G_IO_STATUS_EOF && channel->encoding
+          && BUF_LEN (channel->read_buf) > 0)
+        {
+          g_set_error_literal (error, G_CONVERT_ERROR,
+                               G_CONVERT_ERROR_PARTIAL_INPUT,
+                               _("Leftover unconverted data in read buffer"));
+          status = G_IO_STATUS_ERROR;
+        }
+
+      if (bytes_read)
+        *bytes_read = 0;
+
+      return status;
+    }
+
+  if (status == G_IO_STATUS_ERROR)
+    g_clear_error (error);
+
+  got_bytes = MIN (count, BUF_LEN (USE_BUF (channel)));
+
+  g_assert (got_bytes > 0);
+
+  if (channel->encoding)
+    /* Don't validate for NULL encoding, binary safe */
+    {
+      gchar *nextchar, *prevchar;
+
+      g_assert (USE_BUF (channel) == channel->encoded_read_buf);
+
+      nextchar = channel->encoded_read_buf->str;
+
+      do
+        {
+          prevchar = nextchar;
+          nextchar = g_utf8_next_char (nextchar);
+          g_assert (nextchar != prevchar); /* Possible for *prevchar of -1 or -2 */
+        }
+      while (nextchar < channel->encoded_read_buf->str + got_bytes);
+
+      if (nextchar > channel->encoded_read_buf->str + got_bytes)
+        got_bytes = prevchar - channel->encoded_read_buf->str;
+
+      g_assert (got_bytes > 0 || count < 6);
+    }
+
+  memcpy (buf, USE_BUF (channel)->str, got_bytes);
+  g_string_erase (USE_BUF (channel), 0, got_bytes);
+
+  if (bytes_read)
+    *bytes_read = got_bytes;
+
+  return G_IO_STATUS_NORMAL;
+}
+
+/**
+ * g_io_channel_read_unichar:
+ * @channel: a #GIOChannel
+ * @thechar: a location to return a character
+ * @error: a location to return an error of type #GConvertError
+ *         or #GIOChannelError
+ *
+ * Reads a Unicode character from @channel.
+ * This function cannot be called on a channel with %NULL encoding.
+ *
+ * Return value: a #GIOStatus
+ **/
+GIOStatus
+g_io_channel_read_unichar (GIOChannel  *channel,
+                          gunichar    *thechar,
+                          GError     **error)
+{
+  GIOStatus status = G_IO_STATUS_NORMAL;
+
+  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail ((error == NULL) || (*error == NULL),
+                       G_IO_STATUS_ERROR);
+  g_return_val_if_fail (channel->is_readable, G_IO_STATUS_ERROR);
+
+  while (BUF_LEN (channel->encoded_read_buf) == 0 && status == G_IO_STATUS_NORMAL)
+    status = g_io_channel_fill_buffer (channel, error);
+
+  /* Only return an error if we have no data */
+
+  if (BUF_LEN (USE_BUF (channel)) == 0)
+    {
+      g_assert (status != G_IO_STATUS_NORMAL);
+
+      if (status == G_IO_STATUS_EOF && BUF_LEN (channel->read_buf) > 0)
+        {
+          g_set_error_literal (error, G_CONVERT_ERROR,
+                               G_CONVERT_ERROR_PARTIAL_INPUT,
+                               _("Leftover unconverted data in read buffer"));
+          status = G_IO_STATUS_ERROR;
+        }
+
+      if (thechar)
+        *thechar = (gunichar) -1;
+
+      return status;
+    }
+
+  if (status == G_IO_STATUS_ERROR)
+    g_clear_error (error);
+
+  if (thechar)
+    *thechar = g_utf8_get_char (channel->encoded_read_buf->str);
+
+  g_string_erase (channel->encoded_read_buf, 0,
+                  g_utf8_next_char (channel->encoded_read_buf->str)
+                  - channel->encoded_read_buf->str);
+
+  return G_IO_STATUS_NORMAL;
+}
+
+/**
+ * g_io_channel_write_chars:
+ * @channel: a #GIOChannel
+ * @buf: a buffer to write data from
+ * @count: the size of the buffer. If -1, the buffer
+ *         is taken to be a nul-terminated string.
+ * @bytes_written: The number of bytes written. This can be nonzero
+ *                 even if the return value is not %G_IO_STATUS_NORMAL.
+ *                 If the return value is %G_IO_STATUS_NORMAL and the
+ *                 channel is blocking, this will always be equal
+ *                 to @count if @count >= 0.
+ * @error: a location to return an error of type #GConvertError
+ *         or #GIOChannelError
+ *
+ * Replacement for g_io_channel_write() with the new API.
+ *
+ * On seekable channels with encodings other than %NULL or UTF-8, generic
+ * mixing of reading and writing is not allowed. A call to g_io_channel_write_chars ()
+ * may only be made on a channel from which data has been read in the
+ * cases described in the documentation for g_io_channel_set_encoding ().
+ *
+ * Return value: the status of the operation.
+ **/
+GIOStatus
+g_io_channel_write_chars (GIOChannel   *channel,
+                          const gchar  *buf,
+                          gssize        count,
+                         gsize        *bytes_written,
+                          GError      **error)
+{
+  GIOStatus status;
+  gssize wrote_bytes = 0;
+
+  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail ((error == NULL) || (*error == NULL),
+                       G_IO_STATUS_ERROR);
+  g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR);
+
+  if ((count < 0) && buf)
+    count = strlen (buf);
+  
+  if (count == 0)
+    {
+      if (bytes_written)
+        *bytes_written = 0;
+      return G_IO_STATUS_NORMAL;
+    }
+
+  g_return_val_if_fail (buf != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail (count > 0, G_IO_STATUS_ERROR);
+
+  /* Raw write case */
+
+  if (!channel->use_buffer)
+    {
+      gsize tmp_bytes;
+      
+      g_assert (!channel->write_buf || channel->write_buf->len == 0);
+      g_assert (channel->partial_write_buf[0] == '\0');
+      
+      status = channel->funcs->io_write (channel, buf, count, &tmp_bytes, error);
+
+      if (bytes_written)
+       *bytes_written = tmp_bytes;
+
+      return status;
+    }
+
+  /* General case */
+
+  if (channel->is_seekable && (( BUF_LEN (channel->read_buf) > 0)
+    || (BUF_LEN (channel->encoded_read_buf) > 0)))
+    {
+      if (channel->do_encode && BUF_LEN (channel->encoded_read_buf) > 0)
+        {
+          g_warning("Mixed reading and writing not allowed on encoded files");
+          return G_IO_STATUS_ERROR;
+        }
+      status = g_io_channel_seek_position (channel, 0, G_SEEK_CUR, error);
+      if (status != G_IO_STATUS_NORMAL)
+        {
+          if (bytes_written)
+            *bytes_written = 0;
+          return status;
+        }
+    }
+
+  if (!channel->write_buf)
+    channel->write_buf = g_string_sized_new (channel->buf_size);
+
+  while (wrote_bytes < count)
+    {
+      gsize space_in_buf;
+
+      /* If the buffer is full, try a write immediately. In
+       * the nonblocking case, this prevents the user from
+       * writing just a little bit to the buffer every time
+       * and never receiving an EAGAIN.
+       */
+
+      if (channel->write_buf->len >= channel->buf_size - MAX_CHAR_SIZE)
+        {
+          gsize did_write = 0, this_time;
+
+          do
+            {
+              status = channel->funcs->io_write (channel, channel->write_buf->str
+                                                 + did_write, channel->write_buf->len
+                                                 - did_write, &this_time, error);
+              did_write += this_time;
+            }
+          while (status == G_IO_STATUS_NORMAL &&
+                 did_write < MIN (channel->write_buf->len, MAX_CHAR_SIZE));
+
+          g_string_erase (channel->write_buf, 0, did_write);
+
+          if (status != G_IO_STATUS_NORMAL)
+            {
+              if (status == G_IO_STATUS_AGAIN && wrote_bytes > 0)
+                status = G_IO_STATUS_NORMAL;
+              if (bytes_written)
+                *bytes_written = wrote_bytes;
+              return status;
+            }
+        }
+
+      space_in_buf = MAX (channel->buf_size, channel->write_buf->allocated_len - 1)
+                     - channel->write_buf->len; /* 1 for NULL */
+
+      /* This is only true because g_io_channel_set_buffer_size ()
+       * ensures that channel->buf_size >= MAX_CHAR_SIZE.
+       */
+      g_assert (space_in_buf >= MAX_CHAR_SIZE);
+
+      if (!channel->encoding)
+        {
+          gssize write_this = MIN (space_in_buf, count - wrote_bytes);
+
+          g_string_append_len (channel->write_buf, buf, write_this);
+          buf += write_this;
+          wrote_bytes += write_this;
+        }
+      else
+        {
+          const gchar *from_buf;
+          gsize from_buf_len, from_buf_old_len, left_len;
+          gsize err;
+          gint errnum;
+
+          if (channel->partial_write_buf[0] != '\0')
+            {
+              g_assert (wrote_bytes == 0);
+
+              from_buf = channel->partial_write_buf;
+              from_buf_old_len = strlen (channel->partial_write_buf);
+              g_assert (from_buf_old_len > 0);
+              from_buf_len = MIN (6, from_buf_old_len + count);
+
+              memcpy (channel->partial_write_buf + from_buf_old_len, buf,
+                      from_buf_len - from_buf_old_len);
+            }
+          else
+            {
+              from_buf = buf;
+              from_buf_len = count - wrote_bytes;
+              from_buf_old_len = 0;
+            }
+
+reconvert:
+
+          if (!channel->do_encode) /* UTF-8 encoding */
+            {
+              const gchar *badchar;
+              gsize try_len = MIN (from_buf_len, space_in_buf);
+
+              /* UTF-8, just validate, emulate g_iconv */
+
+              if (!g_utf8_validate (from_buf, try_len, &badchar))
+                {
+                  gunichar try_char;
+                  gsize incomplete_len = from_buf + try_len - badchar;
+
+                  left_len = from_buf + from_buf_len - badchar;
+
+                  try_char = g_utf8_get_char_validated (badchar, incomplete_len);
+
+                  switch (try_char)
+                    {
+                      case -2:
+                        g_assert (incomplete_len < 6);
+                        if (try_len == from_buf_len)
+                          {
+                            errnum = EINVAL;
+                            err = (gsize) -1;
+                          }
+                        else
+                          {
+                            errnum = 0;
+                            err = (gsize) 0;
+                          }
+                        break;
+                      case -1:
+                        g_warning ("Invalid UTF-8 passed to g_io_channel_write_chars().");
+                        /* FIXME bail here? */
+                        errnum = EILSEQ;
+                        err = (gsize) -1;
+                        break;
+                      default:
+                        g_assert_not_reached ();
+                        err = (gsize) -1;
+                        errnum = 0; /* Don't confunse the compiler */
+                    }
+                }
+              else
+                {
+                  err = (gsize) 0;
+                  errnum = 0;
+                  left_len = from_buf_len - try_len;
+                }
+
+              g_string_append_len (channel->write_buf, from_buf,
+                                   from_buf_len - left_len);
+              from_buf += from_buf_len - left_len;
+            }
+          else
+            {
+               gchar *outbuf;
+
+               left_len = from_buf_len;
+               g_string_set_size (channel->write_buf, channel->write_buf->len
+                                  + space_in_buf);
+               outbuf = channel->write_buf->str + channel->write_buf->len
+                        - space_in_buf;
+               err = g_iconv (channel->write_cd, (gchar **) &from_buf, &left_len,
+                              &outbuf, &space_in_buf);
+               errnum = errno;
+               g_string_truncate (channel->write_buf, channel->write_buf->len
+                                  - space_in_buf);
+            }
+
+          if (err == (gsize) -1)
+            {
+              switch (errnum)
+               {
+                  case EINVAL:
+                    g_assert (left_len < 6);
+
+                    if (from_buf_old_len == 0)
+                      {
+                        /* Not from partial_write_buf */
+
+                        memcpy (channel->partial_write_buf, from_buf, left_len);
+                        channel->partial_write_buf[left_len] = '\0';
+                        if (bytes_written)
+                          *bytes_written = count;
+                        return G_IO_STATUS_NORMAL;
+                      }
+
+                    /* Working in partial_write_buf */
+
+                    if (left_len == from_buf_len)
+                      {
+                        /* Didn't convert anything, must still have
+                         * less than a full character
+                         */
+
+                        g_assert (count == from_buf_len - from_buf_old_len);
+
+                        channel->partial_write_buf[from_buf_len] = '\0';
+
+                        if (bytes_written)
+                          *bytes_written = count;
+
+                        return G_IO_STATUS_NORMAL;
+                      }
+
+                    g_assert (from_buf_len - left_len >= from_buf_old_len);
+
+                    /* We converted all the old data. This is fine */
+
+                    break;
+                  case E2BIG:
+                    if (from_buf_len == left_len)
+                      {
+                        /* Nothing was written, add enough space for
+                         * at least one character.
+                         */
+                        space_in_buf += MAX_CHAR_SIZE;
+                        goto reconvert;
+                      }
+                    break;
+                  case EILSEQ:
+                    g_set_error_literal (error, G_CONVERT_ERROR,
+                      G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                      _("Invalid byte sequence in conversion input"));
+                    if (from_buf_old_len > 0 && from_buf_len == left_len)
+                      g_warning ("Illegal sequence due to partial character "
+                                 "at the end of a previous write.\n");
+                    else
+                      wrote_bytes += from_buf_len - left_len - from_buf_old_len;
+                    if (bytes_written)
+                      *bytes_written = wrote_bytes;
+                    channel->partial_write_buf[0] = '\0';
+                    return G_IO_STATUS_ERROR;
+                  default:
+                    g_set_error (error, G_CONVERT_ERROR, G_CONVERT_ERROR_FAILED,
+                      _("Error during conversion: %s"), g_strerror (errnum));
+                    if (from_buf_len >= left_len + from_buf_old_len)
+                      wrote_bytes += from_buf_len - left_len - from_buf_old_len;
+                    if (bytes_written)
+                      *bytes_written = wrote_bytes;
+                    channel->partial_write_buf[0] = '\0';
+                    return G_IO_STATUS_ERROR;
+                }
+            }
+
+          g_assert (from_buf_len - left_len >= from_buf_old_len);
+
+          wrote_bytes += from_buf_len - left_len - from_buf_old_len;
+
+          if (from_buf_old_len > 0)
+            {
+              /* We were working in partial_write_buf */
+
+              buf += from_buf_len - left_len - from_buf_old_len;
+              channel->partial_write_buf[0] = '\0';
+            }
+          else
+            buf = from_buf;
+        }
+    }
+
+  if (bytes_written)
+    *bytes_written = count;
+
+  return G_IO_STATUS_NORMAL;
+}
+
+/**
+ * g_io_channel_write_unichar:
+ * @channel: a #GIOChannel
+ * @thechar: a character
+ * @error: location to return an error of type #GConvertError
+ *         or #GIOChannelError
+ *
+ * Writes a Unicode character to @channel.
+ * This function cannot be called on a channel with %NULL encoding.
+ *
+ * Return value: a #GIOStatus
+ **/
+GIOStatus
+g_io_channel_write_unichar (GIOChannel  *channel,
+                           gunichar     thechar,
+                           GError     **error)
+{
+  GIOStatus status;
+  gchar static_buf[6];
+  gsize char_len, wrote_len;
+
+  g_return_val_if_fail (channel != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail (channel->encoding != NULL, G_IO_STATUS_ERROR);
+  g_return_val_if_fail ((error == NULL) || (*error == NULL),
+                       G_IO_STATUS_ERROR);
+  g_return_val_if_fail (channel->is_writeable, G_IO_STATUS_ERROR);
+
+  char_len = g_unichar_to_utf8 (thechar, static_buf);
+
+  if (channel->partial_write_buf[0] != '\0')
+    {
+      g_warning ("Partial charater written before writing unichar.\n");
+      channel->partial_write_buf[0] = '\0';
+    }
+
+  status = g_io_channel_write_chars (channel, static_buf,
+                                     char_len, &wrote_len, error);
+
+  /* We validate UTF-8, so we can't get a partial write */
+
+  g_assert (wrote_len == char_len || status != G_IO_STATUS_NORMAL);
+
+  return status;
+}
+
+/**
+ * g_io_channel_error_quark:
+ *
+ * Return value: the quark used as %G_IO_CHANNEL_ERROR
+ **/
+/**
+ * G_IO_CHANNEL_ERROR:
+ *
+ * Error domain for #GIOChannel operations. Errors in this domain will
+ * be from the #GIOChannelError enumeration. See #GError for
+ * information on error domains.
+ **/
+/**
+ * GIOChannelError:
+ * @G_IO_CHANNEL_ERROR_FBIG: File too large.
+ * @G_IO_CHANNEL_ERROR_INVAL: Invalid argument.
+ * @G_IO_CHANNEL_ERROR_IO: IO error.
+ * @G_IO_CHANNEL_ERROR_ISDIR: File is a directory.
+ * @G_IO_CHANNEL_ERROR_NOSPC: No space left on device.
+ * @G_IO_CHANNEL_ERROR_NXIO: No such device or address.
+ * @G_IO_CHANNEL_ERROR_OVERFLOW: Value too large for defined datatype.
+ * @G_IO_CHANNEL_ERROR_PIPE: Broken pipe.
+ * @G_IO_CHANNEL_ERROR_FAILED: Some other error.
+ *
+ * Error codes returned by #GIOChannel operations.
+ **/
+GQuark
+g_io_channel_error_quark (void)
+{
+  return g_quark_from_static_string ("g-io-channel-error-quark");
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/giochannel.h b/resource/csdk/connectivity/lib/android/glib-master/glib/giochannel.h
new file mode 100644 (file)
index 0000000..2a40aa2
--- /dev/null
@@ -0,0 +1,366 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_IOCHANNEL_H__
+#define __G_IOCHANNEL_H__
+
+#include <glib/gconvert.h>
+#include <glib/gmain.h>
+#include <glib/gstring.h>
+
+G_BEGIN_DECLS
+
+/* GIOChannel
+ */
+
+typedef struct _GIOChannel     GIOChannel;
+typedef struct _GIOFuncs        GIOFuncs;
+
+typedef enum
+{
+  G_IO_ERROR_NONE,
+  G_IO_ERROR_AGAIN,
+  G_IO_ERROR_INVAL,
+  G_IO_ERROR_UNKNOWN
+} GIOError;
+
+#define G_IO_CHANNEL_ERROR g_io_channel_error_quark()
+
+typedef enum
+{
+  /* Derived from errno */
+  G_IO_CHANNEL_ERROR_FBIG,
+  G_IO_CHANNEL_ERROR_INVAL,
+  G_IO_CHANNEL_ERROR_IO,
+  G_IO_CHANNEL_ERROR_ISDIR,
+  G_IO_CHANNEL_ERROR_NOSPC,
+  G_IO_CHANNEL_ERROR_NXIO,
+  G_IO_CHANNEL_ERROR_OVERFLOW,
+  G_IO_CHANNEL_ERROR_PIPE,
+  /* Other */
+  G_IO_CHANNEL_ERROR_FAILED
+} GIOChannelError;
+
+typedef enum
+{
+  G_IO_STATUS_ERROR,
+  G_IO_STATUS_NORMAL,
+  G_IO_STATUS_EOF,
+  G_IO_STATUS_AGAIN
+} GIOStatus;
+
+typedef enum
+{
+  G_SEEK_CUR,
+  G_SEEK_SET,
+  G_SEEK_END
+} GSeekType;
+
+typedef enum
+{
+  G_IO_IN      GLIB_SYSDEF_POLLIN,
+  G_IO_OUT     GLIB_SYSDEF_POLLOUT,
+  G_IO_PRI     GLIB_SYSDEF_POLLPRI,
+  G_IO_ERR     GLIB_SYSDEF_POLLERR,
+  G_IO_HUP     GLIB_SYSDEF_POLLHUP,
+  G_IO_NVAL    GLIB_SYSDEF_POLLNVAL
+} GIOCondition;
+
+typedef enum
+{
+  G_IO_FLAG_APPEND = 1 << 0,
+  G_IO_FLAG_NONBLOCK = 1 << 1,
+  G_IO_FLAG_IS_READABLE = 1 << 2,      /* Read only flag */
+  G_IO_FLAG_IS_WRITEABLE = 1 << 3,     /* Read only flag */
+  G_IO_FLAG_IS_SEEKABLE = 1 << 4,      /* Read only flag */
+  G_IO_FLAG_MASK = (1 << 5) - 1,
+  G_IO_FLAG_GET_MASK = G_IO_FLAG_MASK,
+  G_IO_FLAG_SET_MASK = G_IO_FLAG_APPEND | G_IO_FLAG_NONBLOCK
+} GIOFlags;
+
+struct _GIOChannel
+{
+  /*< private >*/
+  gint ref_count;
+  GIOFuncs *funcs;
+
+  gchar *encoding;
+  GIConv read_cd;
+  GIConv write_cd;
+  gchar *line_term;            /* String which indicates the end of a line of text */
+  guint line_term_len;         /* So we can have null in the line term */
+
+  gsize buf_size;
+  GString *read_buf;           /* Raw data from the channel */
+  GString *encoded_read_buf;    /* Channel data converted to UTF-8 */
+  GString *write_buf;          /* Data ready to be written to the file */
+  gchar partial_write_buf[6];  /* UTF-8 partial characters, null terminated */
+
+  /* Group the flags together, immediately after partial_write_buf, to save memory */
+
+  guint use_buffer     : 1;    /* The encoding uses the buffers */
+  guint do_encode      : 1;    /* The encoding uses the GIConv coverters */
+  guint close_on_unref : 1;    /* Close the channel on final unref */
+  guint is_readable    : 1;    /* Cached GIOFlag */
+  guint is_writeable   : 1;    /* ditto */
+  guint is_seekable    : 1;    /* ditto */
+
+  gpointer reserved1;  
+  gpointer reserved2;  
+};
+
+typedef gboolean (*GIOFunc) (GIOChannel   *source,
+                            GIOCondition  condition,
+                            gpointer      data);
+struct _GIOFuncs
+{
+  GIOStatus (*io_read)           (GIOChannel   *channel, 
+                                 gchar        *buf, 
+                                 gsize         count,
+                                 gsize        *bytes_read,
+                                 GError      **err);
+  GIOStatus (*io_write)          (GIOChannel   *channel, 
+                                 const gchar  *buf, 
+                                 gsize         count,
+                                 gsize        *bytes_written,
+                                 GError      **err);
+  GIOStatus (*io_seek)           (GIOChannel   *channel, 
+                                 gint64        offset, 
+                                 GSeekType     type,
+                                 GError      **err);
+  GIOStatus  (*io_close)         (GIOChannel   *channel,
+                                 GError      **err);
+  GSource*   (*io_create_watch)  (GIOChannel   *channel,
+                                 GIOCondition  condition);
+  void       (*io_free)          (GIOChannel   *channel);
+  GIOStatus  (*io_set_flags)     (GIOChannel   *channel,
+                                  GIOFlags      flags,
+                                 GError      **err);
+  GIOFlags   (*io_get_flags)     (GIOChannel   *channel);
+};
+
+void        g_io_channel_init   (GIOChannel    *channel);
+GIOChannel *g_io_channel_ref    (GIOChannel    *channel);
+void        g_io_channel_unref  (GIOChannel    *channel);
+
+#ifndef G_DISABLE_DEPRECATED
+GIOError    g_io_channel_read   (GIOChannel    *channel, 
+                                gchar         *buf, 
+                                gsize          count,
+                                gsize         *bytes_read);
+GIOError  g_io_channel_write    (GIOChannel    *channel, 
+                                const gchar   *buf, 
+                                gsize          count,
+                                gsize         *bytes_written);
+GIOError  g_io_channel_seek     (GIOChannel    *channel,
+                                gint64         offset, 
+                                GSeekType      type);
+void      g_io_channel_close    (GIOChannel    *channel);
+#endif /* G_DISABLE_DEPRECATED */
+
+GIOStatus g_io_channel_shutdown (GIOChannel      *channel,
+                                gboolean         flush,
+                                GError         **err);
+guint     g_io_add_watch_full   (GIOChannel      *channel,
+                                gint             priority,
+                                GIOCondition     condition,
+                                GIOFunc          func,
+                                gpointer         user_data,
+                                GDestroyNotify   notify);
+GSource * g_io_create_watch     (GIOChannel      *channel,
+                                GIOCondition     condition);
+guint     g_io_add_watch        (GIOChannel      *channel,
+                                GIOCondition     condition,
+                                GIOFunc          func,
+                                gpointer         user_data);
+
+/* character encoding conversion involved functions.
+ */
+
+void                  g_io_channel_set_buffer_size      (GIOChannel   *channel,
+                                                        gsize         size);
+gsize                 g_io_channel_get_buffer_size      (GIOChannel   *channel);
+GIOCondition          g_io_channel_get_buffer_condition (GIOChannel   *channel);
+GIOStatus             g_io_channel_set_flags            (GIOChannel   *channel,
+                                                        GIOFlags      flags,
+                                                        GError      **error);
+GIOFlags              g_io_channel_get_flags            (GIOChannel   *channel);
+void                  g_io_channel_set_line_term        (GIOChannel   *channel,
+                                                        const gchar  *line_term,
+                                                        gint          length);
+G_CONST_RETURN gchar* g_io_channel_get_line_term        (GIOChannel   *channel,
+                                                        gint         *length);
+void                 g_io_channel_set_buffered         (GIOChannel   *channel,
+                                                        gboolean      buffered);
+gboolean             g_io_channel_get_buffered         (GIOChannel   *channel);
+GIOStatus             g_io_channel_set_encoding         (GIOChannel   *channel,
+                                                        const gchar  *encoding,
+                                                        GError      **error);
+G_CONST_RETURN gchar* g_io_channel_get_encoding         (GIOChannel   *channel);
+void                  g_io_channel_set_close_on_unref  (GIOChannel   *channel,
+                                                        gboolean      do_close);
+gboolean              g_io_channel_get_close_on_unref  (GIOChannel   *channel);
+
+
+GIOStatus   g_io_channel_flush            (GIOChannel   *channel,
+                                          GError      **error);
+GIOStatus   g_io_channel_read_line        (GIOChannel   *channel,
+                                          gchar       **str_return,
+                                          gsize        *length,
+                                          gsize        *terminator_pos,
+                                          GError      **error);
+GIOStatus   g_io_channel_read_line_string (GIOChannel   *channel,
+                                          GString      *buffer,
+                                          gsize        *terminator_pos,
+                                          GError      **error);
+GIOStatus   g_io_channel_read_to_end      (GIOChannel   *channel,
+                                          gchar       **str_return,
+                                          gsize        *length,
+                                          GError      **error);
+GIOStatus   g_io_channel_read_chars       (GIOChannel   *channel,
+                                          gchar        *buf,
+                                          gsize         count,
+                                          gsize        *bytes_read,
+                                          GError      **error);
+GIOStatus   g_io_channel_read_unichar     (GIOChannel   *channel,
+                                          gunichar     *thechar,
+                                          GError      **error);
+GIOStatus   g_io_channel_write_chars      (GIOChannel   *channel,
+                                          const gchar  *buf,
+                                          gssize        count,
+                                          gsize        *bytes_written,
+                                          GError      **error);
+GIOStatus   g_io_channel_write_unichar    (GIOChannel   *channel,
+                                          gunichar      thechar,
+                                          GError      **error);
+GIOStatus   g_io_channel_seek_position    (GIOChannel   *channel,
+                                          gint64        offset,
+                                          GSeekType     type,
+                                          GError      **error);
+#ifdef G_OS_WIN32
+#define g_io_channel_new_file g_io_channel_new_file_utf8
+#endif
+
+GIOChannel* g_io_channel_new_file         (const gchar  *filename,
+                                          const gchar  *mode,
+                                          GError      **error);
+
+/* Error handling */
+
+GQuark          g_io_channel_error_quark      (void);
+GIOChannelError g_io_channel_error_from_errno (gint en);
+
+/* On Unix, IO channels created with this function for any file
+ * descriptor or socket.
+ *
+ * On Win32, this can be used either for files opened with the MSVCRT
+ * (the Microsoft run-time C library) _open() or _pipe, including file
+ * descriptors 0, 1 and 2 (corresponding to stdin, stdout and stderr),
+ * or for Winsock SOCKETs. If the parameter is a legal file
+ * descriptor, it is assumed to be such, otherwise it should be a
+ * SOCKET. This relies on SOCKETs and file descriptors not
+ * overlapping. If you want to be certain, call either
+ * g_io_channel_win32_new_fd() or g_io_channel_win32_new_socket()
+ * instead as appropriate.
+ *
+ * The term file descriptor as used in the context of Win32 refers to
+ * the emulated Unix-like file descriptors MSVCRT provides. The native
+ * corresponding concept is file HANDLE. There isn't as of yet a way to
+ * get GIOChannels for Win32 file HANDLEs.
+ */
+GIOChannel* g_io_channel_unix_new    (int         fd);
+gint        g_io_channel_unix_get_fd (GIOChannel *channel);
+
+
+/* Hook for GClosure / GSource integration. Don't touch */
+GLIB_VAR GSourceFuncs g_io_watch_funcs;
+
+#ifdef G_OS_WIN32
+
+/* You can use this "pseudo file descriptor" in a GPollFD to add
+ * polling for Windows messages. GTK applications should not do that.
+ */
+
+#define G_WIN32_MSG_HANDLE 19981206
+
+/* Use this to get a GPollFD from a GIOChannel, so that you can call
+ * g_io_channel_win32_poll(). After calling this you should only use
+ * g_io_channel_read() to read from the GIOChannel, i.e. never read()
+ * from the underlying file descriptor. For SOCKETs, it is possible to call
+ * recv().
+ */
+void        g_io_channel_win32_make_pollfd (GIOChannel   *channel,
+                                           GIOCondition  condition,
+                                           GPollFD      *fd);
+
+/* This can be used to wait a until at least one of the channels is readable.
+ * On Unix you would do a select() on the file descriptors of the channels.
+ */
+gint        g_io_channel_win32_poll   (GPollFD    *fds,
+                                      gint        n_fds,
+                                      gint        timeout_);
+
+/* Create an IO channel for Windows messages for window handle hwnd. */
+#if GLIB_SIZEOF_VOID_P == 8
+/* We use gsize here so that it is still an integer type and not a
+ * pointer, like the guint in the traditional prototype. We can't use
+ * intptr_t as that is not portable enough.
+ */
+GIOChannel *g_io_channel_win32_new_messages (gsize hwnd);
+#else
+GIOChannel *g_io_channel_win32_new_messages (guint hwnd);
+#endif
+
+/* Create an IO channel for C runtime (emulated Unix-like) file
+ * descriptors. After calling g_io_add_watch() on a IO channel
+ * returned by this function, you shouldn't call read() on the file
+ * descriptor. This is because adding polling for a file descriptor is
+ * implemented on Win32 by starting a thread that sits blocked in a
+ * read() from the file descriptor most of the time. All reads from
+ * the file descriptor should be done by this internal GLib
+ * thread. Your code should call only g_io_channel_read_chars().
+ */
+GIOChannel* g_io_channel_win32_new_fd (gint         fd);
+
+/* Get the C runtime file descriptor of a channel. */
+gint        g_io_channel_win32_get_fd (GIOChannel *channel);
+
+/* Create an IO channel for a winsock socket. The parameter should be
+ * a SOCKET. Contrary to IO channels for file descriptors (on *Win32),
+ * you can use normal recv() or recvfrom() on sockets even if GLib
+ * is polling them.
+ */
+GIOChannel *g_io_channel_win32_new_socket (gint socket);
+
+#endif
+
+G_END_DECLS
+
+#endif /* __G_IOCHANNEL_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/giounix.c b/resource/csdk/connectivity/lib/android/glib-master/glib/giounix.c
new file mode 100644 (file)
index 0000000..72a3ed4
--- /dev/null
@@ -0,0 +1,647 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * giounix.c: IO Channels using unix file descriptors
+ * Copyright 1998 Owen Taylor
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#define _POSIX_SOURCE          /* for SSIZE_MAX */
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <errno.h>
+#include <string.h>
+#include <fcntl.h>
+
+#include "giochannel.h"
+
+#include "gerror.h"
+#include "gfileutils.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+
+/*
+ * Unix IO Channels
+ */
+
+typedef struct _GIOUnixChannel GIOUnixChannel;
+typedef struct _GIOUnixWatch GIOUnixWatch;
+
+struct _GIOUnixChannel
+{
+  GIOChannel channel;
+  gint fd;
+};
+
+struct _GIOUnixWatch
+{
+  GSource       source;
+  GPollFD       pollfd;
+  GIOChannel   *channel;
+  GIOCondition  condition;
+};
+
+
+static GIOStatus       g_io_unix_read          (GIOChannel   *channel,
+                                                gchar        *buf,
+                                                gsize         count,
+                                                gsize        *bytes_read,
+                                                GError      **err);
+static GIOStatus       g_io_unix_write         (GIOChannel   *channel,
+                                                const gchar  *buf,
+                                                gsize         count,
+                                                gsize        *bytes_written,
+                                                GError      **err);
+static GIOStatus       g_io_unix_seek          (GIOChannel   *channel,
+                                                gint64        offset,
+                                                GSeekType     type,
+                                                GError      **err);
+static GIOStatus       g_io_unix_close         (GIOChannel   *channel,
+                                                GError      **err);
+static void            g_io_unix_free          (GIOChannel   *channel);
+static GSource*                g_io_unix_create_watch  (GIOChannel   *channel,
+                                                GIOCondition  condition);
+static GIOStatus       g_io_unix_set_flags     (GIOChannel   *channel,
+                                                        GIOFlags      flags,
+                                                GError      **err);
+static GIOFlags        g_io_unix_get_flags     (GIOChannel   *channel);
+
+static gboolean g_io_unix_prepare  (GSource     *source,
+                                   gint        *timeout);
+static gboolean g_io_unix_check    (GSource     *source);
+static gboolean g_io_unix_dispatch (GSource     *source,
+                                   GSourceFunc  callback,
+                                   gpointer     user_data);
+static void     g_io_unix_finalize (GSource     *source);
+
+GSourceFuncs g_io_watch_funcs = {
+  g_io_unix_prepare,
+  g_io_unix_check,
+  g_io_unix_dispatch,
+  g_io_unix_finalize
+};
+
+static GIOFuncs unix_channel_funcs = {
+  g_io_unix_read,
+  g_io_unix_write,
+  g_io_unix_seek,
+  g_io_unix_close,
+  g_io_unix_create_watch,
+  g_io_unix_free,
+  g_io_unix_set_flags,
+  g_io_unix_get_flags,
+};
+
+static gboolean 
+g_io_unix_prepare (GSource  *source,
+                  gint     *timeout)
+{
+  GIOUnixWatch *watch = (GIOUnixWatch *)source;
+  GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
+
+  *timeout = -1;
+
+  /* Only return TRUE here if _all_ bits in watch->condition will be set
+   */
+  return ((watch->condition & buffer_condition) == watch->condition);
+}
+
+static gboolean 
+g_io_unix_check (GSource  *source)
+{
+  GIOUnixWatch *watch = (GIOUnixWatch *)source;
+  GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
+  GIOCondition poll_condition = watch->pollfd.revents;
+
+  return ((poll_condition | buffer_condition) & watch->condition);
+}
+
+static gboolean
+g_io_unix_dispatch (GSource     *source,
+                   GSourceFunc  callback,
+                   gpointer     user_data)
+
+{
+  GIOFunc func = (GIOFunc)callback;
+  GIOUnixWatch *watch = (GIOUnixWatch *)source;
+  GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
+
+  if (!func)
+    {
+      g_warning ("IO watch dispatched without callback\n"
+                "You must call g_source_connect().");
+      return FALSE;
+    }
+  
+  return (*func) (watch->channel,
+                 (watch->pollfd.revents | buffer_condition) & watch->condition,
+                 user_data);
+}
+
+static void 
+g_io_unix_finalize (GSource *source)
+{
+  GIOUnixWatch *watch = (GIOUnixWatch *)source;
+
+  g_io_channel_unref (watch->channel);
+}
+
+static GIOStatus
+g_io_unix_read (GIOChannel *channel, 
+               gchar      *buf, 
+               gsize       count,
+               gsize      *bytes_read,
+               GError    **err)
+{
+  GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+  gssize result;
+
+  if (count > SSIZE_MAX) /* At least according to the Debian manpage for read */
+    count = SSIZE_MAX;
+
+ retry:
+  result = read (unix_channel->fd, buf, count);
+
+  if (result < 0)
+    {
+      int errsv = errno;
+      *bytes_read = 0;
+
+      switch (errsv)
+        {
+#ifdef EINTR
+          case EINTR:
+            goto retry;
+#endif
+#ifdef EAGAIN
+          case EAGAIN:
+            return G_IO_STATUS_AGAIN;
+#endif
+          default:
+            g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                                 g_io_channel_error_from_errno (errsv),
+                                 g_strerror (errsv));
+            return G_IO_STATUS_ERROR;
+        }
+    }
+
+  *bytes_read = result;
+
+  return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
+}
+
+static GIOStatus
+g_io_unix_write (GIOChannel  *channel, 
+                const gchar *buf, 
+                gsize       count,
+                gsize      *bytes_written,
+                GError    **err)
+{
+  GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+  gssize result;
+
+ retry:
+  result = write (unix_channel->fd, buf, count);
+
+  if (result < 0)
+    {
+      int errsv = errno;
+      *bytes_written = 0;
+
+      switch (errsv)
+        {
+#ifdef EINTR
+          case EINTR:
+            goto retry;
+#endif
+#ifdef EAGAIN
+          case EAGAIN:
+            return G_IO_STATUS_AGAIN;
+#endif
+          default:
+            g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                                 g_io_channel_error_from_errno (errsv),
+                                 g_strerror (errsv));
+            return G_IO_STATUS_ERROR;
+        }
+    }
+
+  *bytes_written = result;
+
+  return G_IO_STATUS_NORMAL;
+}
+
+static GIOStatus
+g_io_unix_seek (GIOChannel *channel,
+               gint64      offset, 
+               GSeekType   type,
+                GError    **err)
+{
+  GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+  int whence;
+  off_t tmp_offset;
+  off_t result;
+
+  switch (type)
+    {
+    case G_SEEK_SET:
+      whence = SEEK_SET;
+      break;
+    case G_SEEK_CUR:
+      whence = SEEK_CUR;
+      break;
+    case G_SEEK_END:
+      whence = SEEK_END;
+      break;
+    default:
+      whence = -1; /* Shut the compiler up */
+      g_assert_not_reached ();
+    }
+
+  tmp_offset = offset;
+  if (tmp_offset != offset)
+    {
+      g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                           g_io_channel_error_from_errno (EINVAL),
+                           g_strerror (EINVAL));
+      return G_IO_STATUS_ERROR;
+    }
+  
+  result = lseek (unix_channel->fd, tmp_offset, whence);
+
+  if (result < 0)
+    {
+      int errsv = errno;
+      g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                           g_io_channel_error_from_errno (errsv),
+                           g_strerror (errsv));
+      return G_IO_STATUS_ERROR;
+    }
+
+  return G_IO_STATUS_NORMAL;
+}
+
+
+static GIOStatus
+g_io_unix_close (GIOChannel *channel,
+                GError    **err)
+{
+  GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+
+  if (close (unix_channel->fd) < 0)
+    {
+      int errsv = errno;
+      g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                           g_io_channel_error_from_errno (errsv),
+                           g_strerror (errsv));
+      return G_IO_STATUS_ERROR;
+    }
+
+  return G_IO_STATUS_NORMAL;
+}
+
+static void 
+g_io_unix_free (GIOChannel *channel)
+{
+  GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+
+  g_free (unix_channel);
+}
+
+static GSource *
+g_io_unix_create_watch (GIOChannel   *channel,
+                       GIOCondition  condition)
+{
+  GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+  GSource *source;
+  GIOUnixWatch *watch;
+
+
+  source = g_source_new (&g_io_watch_funcs, sizeof (GIOUnixWatch));
+  g_source_set_name (source, "GIOChannel (Unix)");
+  watch = (GIOUnixWatch *)source;
+  
+  watch->channel = channel;
+  g_io_channel_ref (channel);
+  
+  watch->condition = condition;
+
+  watch->pollfd.fd = unix_channel->fd;
+  watch->pollfd.events = condition;
+
+  g_source_add_poll (source, &watch->pollfd);
+
+  return source;
+}
+
+static GIOStatus
+g_io_unix_set_flags (GIOChannel *channel,
+                     GIOFlags    flags,
+                     GError    **err)
+{
+  glong fcntl_flags;
+  GIOUnixChannel *unix_channel = (GIOUnixChannel *) channel;
+
+  fcntl_flags = 0;
+
+  if (flags & G_IO_FLAG_APPEND)
+    fcntl_flags |= O_APPEND;
+  if (flags & G_IO_FLAG_NONBLOCK)
+#ifdef O_NONBLOCK
+    fcntl_flags |= O_NONBLOCK;
+#else
+    fcntl_flags |= O_NDELAY;
+#endif
+
+  if (fcntl (unix_channel->fd, F_SETFL, fcntl_flags) == -1)
+    {
+      int errsv = errno;
+      g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                           g_io_channel_error_from_errno (errsv),
+                           g_strerror (errsv));
+      return G_IO_STATUS_ERROR;
+    }
+
+  return G_IO_STATUS_NORMAL;
+}
+
+static GIOFlags
+g_io_unix_get_flags (GIOChannel *channel)
+{
+  GIOFlags flags = 0;
+  glong fcntl_flags;
+  GIOUnixChannel *unix_channel = (GIOUnixChannel *) channel;
+
+  fcntl_flags = fcntl (unix_channel->fd, F_GETFL);
+
+  if (fcntl_flags == -1)
+    {
+      int err = errno;
+      g_warning (G_STRLOC "Error while getting flags for FD: %s (%d)\n",
+                g_strerror (err), err);
+      return 0;
+    }
+
+  if (fcntl_flags & O_APPEND)
+    flags |= G_IO_FLAG_APPEND;
+#ifdef O_NONBLOCK
+  if (fcntl_flags & O_NONBLOCK)
+#else
+  if (fcntl_flags & O_NDELAY)
+#endif
+    flags |= G_IO_FLAG_NONBLOCK;
+
+  switch (fcntl_flags & (O_RDONLY | O_WRONLY | O_RDWR))
+    {
+      case O_RDONLY:
+        channel->is_readable = TRUE;
+        channel->is_writeable = FALSE;
+        break;
+      case O_WRONLY:
+        channel->is_readable = FALSE;
+        channel->is_writeable = TRUE;
+        break;
+      case O_RDWR:
+        channel->is_readable = TRUE;
+        channel->is_writeable = TRUE;
+        break;
+      default:
+        g_assert_not_reached ();
+    }
+
+  return flags;
+}
+
+GIOChannel *
+g_io_channel_new_file (const gchar *filename,
+                       const gchar *mode,
+                       GError     **error)
+{
+  int fid, flags;
+  mode_t create_mode;
+  GIOChannel *channel;
+  enum { /* Cheesy hack */
+    MODE_R = 1 << 0,
+    MODE_W = 1 << 1,
+    MODE_A = 1 << 2,
+    MODE_PLUS = 1 << 3
+  } mode_num;
+  struct stat buffer;
+
+  g_return_val_if_fail (filename != NULL, NULL);
+  g_return_val_if_fail (mode != NULL, NULL);
+  g_return_val_if_fail ((error == NULL) || (*error == NULL), NULL);
+
+  switch (mode[0])
+    {
+      case 'r':
+        mode_num = MODE_R;
+        break;
+      case 'w':
+        mode_num = MODE_W;
+        break;
+      case 'a':
+        mode_num = MODE_A;
+        break;
+      default:
+        g_warning ("Invalid GIOFileMode %s.\n", mode);
+        return NULL;
+    }
+
+  switch (mode[1])
+    {
+      case '\0':
+        break;
+      case '+':
+        if (mode[2] == '\0')
+          {
+            mode_num |= MODE_PLUS;
+            break;
+          }
+        /* Fall through */
+      default:
+        g_warning ("Invalid GIOFileMode %s.\n", mode);
+        return NULL;
+    }
+
+  switch (mode_num)
+    {
+      case MODE_R:
+        flags = O_RDONLY;
+        break;
+      case MODE_W:
+        flags = O_WRONLY | O_TRUNC | O_CREAT;
+        break;
+      case MODE_A:
+        flags = O_WRONLY | O_APPEND | O_CREAT;
+        break;
+      case MODE_R | MODE_PLUS:
+        flags = O_RDWR;
+        break;
+      case MODE_W | MODE_PLUS:
+        flags = O_RDWR | O_TRUNC | O_CREAT;
+        break;
+      case MODE_A | MODE_PLUS:
+        flags = O_RDWR | O_APPEND | O_CREAT;
+        break;
+      default:
+        g_assert_not_reached ();
+        flags = 0;
+    }
+
+  create_mode = S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH;
+  fid = open (filename, flags, create_mode);
+  if (fid == -1)
+    {
+      int err = errno;
+      g_set_error_literal (error, G_FILE_ERROR,
+                           g_file_error_from_errno (err),
+                           g_strerror (err));
+      return (GIOChannel *)NULL;
+    }
+
+  if (fstat (fid, &buffer) == -1) /* In case someone opens a FIFO */
+    {
+      int err = errno;
+      close (fid);
+      g_set_error_literal (error, G_FILE_ERROR,
+                           g_file_error_from_errno (err),
+                           g_strerror (err));
+      return (GIOChannel *)NULL;
+    }
+
+  channel = (GIOChannel *) g_new (GIOUnixChannel, 1);
+
+  channel->is_seekable = S_ISREG (buffer.st_mode) || S_ISCHR (buffer.st_mode)
+                         || S_ISBLK (buffer.st_mode);
+
+  switch (mode_num)
+    {
+      case MODE_R:
+        channel->is_readable = TRUE;
+        channel->is_writeable = FALSE;
+        break;
+      case MODE_W:
+      case MODE_A:
+        channel->is_readable = FALSE;
+        channel->is_writeable = TRUE;
+        break;
+      case MODE_R | MODE_PLUS:
+      case MODE_W | MODE_PLUS:
+      case MODE_A | MODE_PLUS:
+        channel->is_readable = TRUE;
+        channel->is_writeable = TRUE;
+        break;
+      default:
+        g_assert_not_reached ();
+    }
+
+  g_io_channel_init (channel);
+  channel->close_on_unref = TRUE; /* must be after g_io_channel_init () */
+  channel->funcs = &unix_channel_funcs;
+
+  ((GIOUnixChannel *) channel)->fd = fid;
+  return channel;
+}
+
+/**
+ * g_io_channel_unix_new:
+ * @fd: a file descriptor.
+ * @Returns: a new #GIOChannel.
+ *
+ * Creates a new #GIOChannel given a file descriptor. On UNIX systems
+ * this works for plain files, pipes, and sockets.
+ *
+ * The returned #GIOChannel has a reference count of 1.
+ *
+ * The default encoding for #GIOChannel is UTF-8. If your application
+ * is reading output from a command using via pipe, you may need to set
+ * the encoding to the encoding of the current locale (see
+ * g_get_charset()) with the g_io_channel_set_encoding() function.
+ *
+ * If you want to read raw binary data without interpretation, then
+ * call the g_io_channel_set_encoding() function with %NULL for the
+ * encoding argument.
+ *
+ * This function is available in GLib on Windows, too, but you should
+ * avoid using it on Windows. The domain of file descriptors and
+ * sockets overlap. There is no way for GLib to know which one you mean
+ * in case the argument you pass to this function happens to be both a
+ * valid file descriptor and socket. If that happens a warning is
+ * issued, and GLib assumes that it is the file descriptor you mean.
+ **/
+GIOChannel *
+g_io_channel_unix_new (gint fd)
+{
+  struct stat buffer;
+  GIOUnixChannel *unix_channel = g_new (GIOUnixChannel, 1);
+  GIOChannel *channel = (GIOChannel *)unix_channel;
+
+  g_io_channel_init (channel);
+  channel->funcs = &unix_channel_funcs;
+
+  unix_channel->fd = fd;
+
+  /* I'm not sure if fstat on a non-file (e.g., socket) works
+   * it should be safe to say if it fails, the fd isn't seekable.
+   */
+  /* Newer UNIX versions support S_ISSOCK(), fstat() will probably
+   * succeed in most cases.
+   */
+  if (fstat (unix_channel->fd, &buffer) == 0)
+    channel->is_seekable = S_ISREG (buffer.st_mode) || S_ISCHR (buffer.st_mode)
+                           || S_ISBLK (buffer.st_mode);
+  else /* Assume not seekable */
+    channel->is_seekable = FALSE;
+
+  g_io_unix_get_flags (channel); /* Sets is_readable, is_writeable */
+
+  return channel;
+}
+
+/**
+ * g_io_channel_unix_get_fd:
+ * @channel: a #GIOChannel, created with g_io_channel_unix_new().
+ * @Returns: the file descriptor of the #GIOChannel.
+ *
+ * Returns the file descriptor of the #GIOChannel.
+ *
+ * On Windows this function returns the file descriptor or socket of
+ * the #GIOChannel.
+ **/
+gint
+g_io_channel_unix_get_fd (GIOChannel *channel)
+{
+  GIOUnixChannel *unix_channel = (GIOUnixChannel *)channel;
+  return unix_channel->fd;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/giowin32.c b/resource/csdk/connectivity/lib/android/glib-master/glib/giowin32.c
new file mode 100644 (file)
index 0000000..c632c59
--- /dev/null
@@ -0,0 +1,2241 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * giowin32.c: IO Channels for Win32.
+ * Copyright 1998 Owen Taylor and Tor Lillqvist
+ * Copyright 1999-2000 Tor Lillqvist and Craig Setera
+ * Copyright 2001-2003 Andrew Lanoix
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * Bugs that are related to the code in this file:
+ *
+ * Bug 137968 - Sometimes a GIOFunc on Win32 is called with zero condition
+ * http://bugzilla.gnome.org/show_bug.cgi?id=137968
+ *
+ * Bug 324234 - Using g_io_add_watch_full() to wait for connect() to return on a non-blocking socket returns prematurely
+ * http://bugzilla.gnome.org/show_bug.cgi?id=324234
+ *
+ * Bug 331214 - g_io_channel async socket io stalls
+ * http://bugzilla.gnome.org/show_bug.cgi?id=331214
+ *
+ * Bug 338943 - Multiple watches on the same socket
+ * http://bugzilla.gnome.org/show_bug.cgi?id=338943
+ *
+ * Bug 357674 - 2 serious bugs in giowin32.c making glib iochannels useless
+ * http://bugzilla.gnome.org/show_bug.cgi?id=357674
+ *
+ * Bug 425156 - GIOChannel deadlocks on a win32 socket
+ * http://bugzilla.gnome.org/show_bug.cgi?id=425156
+ *
+ * Bug 468910 - giofunc condition=0
+ * http://bugzilla.gnome.org/show_bug.cgi?id=468910
+ *
+ * Bug 500246 - Bug fixes for giowin32
+ * http://bugzilla.gnome.org/show_bug.cgi?id=500246
+ *
+ * Bug 548278 - Async GETs connections are always terminated unexpectedly on windows
+ * http://bugzilla.gnome.org/show_bug.cgi?id=548278
+ *
+ * Bug 548536 - giowin32 problem when adding and removing watches
+ * http://bugzilla.gnome.org/show_bug.cgi?id=548536
+ *
+ * When fixing bugs related to the code in this file, either the above
+ * bugs or others, make sure that the test programs attached to the
+ * above bugs continue to work.
+ */
+
+#include "config.h"
+
+#include "glib.h"
+
+#include <stdlib.h>
+#include <winsock2.h>
+#include <windows.h>
+#include <conio.h>
+#include <fcntl.h>
+#include <io.h>
+#include <process.h>
+#include <errno.h>
+#include <sys/stat.h>
+
+#include "gstdio.h"
+#include "glibintl.h"
+
+
+typedef struct _GIOWin32Channel GIOWin32Channel;
+typedef struct _GIOWin32Watch GIOWin32Watch;
+
+#define BUFFER_SIZE 4096
+
+typedef enum {
+  G_IO_WIN32_WINDOWS_MESSAGES, /* Windows messages */
+
+  G_IO_WIN32_FILE_DESC,                /* Unix-like file descriptors from
+                                * _open() or _pipe(), except for
+                                * console IO. Separate thread to read
+                                * or write.
+                                */
+
+  G_IO_WIN32_CONSOLE,          /* Console IO (usually stdin, stdout, stderr) */
+
+  G_IO_WIN32_SOCKET            /* Sockets. No separate thread. */
+} GIOWin32ChannelType;
+
+struct _GIOWin32Channel {
+  GIOChannel channel;
+  gint fd;                     /* Either a Unix-like file handle as provided
+                                * by the Microsoft C runtime, or a SOCKET
+                                * as provided by WinSock.
+                                */
+  GIOWin32ChannelType type;
+  
+  gboolean debug;
+
+  /* Field used by G_IO_WIN32_WINDOWS_MESSAGES channels */
+  HWND hwnd;                   /* Handle of window, or NULL */
+  
+  /* Fields used by G_IO_WIN32_FILE_DESC channels. */
+  CRITICAL_SECTION mutex;
+
+  int direction;               /* 0 means we read from it,
+                                * 1 means we write to it.
+                                */
+
+  gboolean running;            /* Is reader or writer thread
+                                * running. FALSE if EOF has been
+                                * reached by the reader thread.
+                                */
+
+  gboolean needs_close;                /* If the channel has been closed while
+                                * the reader thread was still running.
+                                */
+
+  guint thread_id;             /* If non-NULL the channel has or has
+                                * had a reader or writer thread.
+                                */
+  HANDLE data_avail_event;
+
+  gushort revents;
+
+  /* Data is kept in a circular buffer. To be able to distinguish between
+   * empty and full buffers, we cannot fill it completely, but have to
+   * leave a one character gap.
+   *
+   * Data available is between indexes rdp and wrp-1 (modulo BUFFER_SIZE).
+   *
+   * Empty:    wrp == rdp
+   * Full:     (wrp + 1) % BUFFER_SIZE == rdp
+   * Partial:  otherwise
+   */
+  guchar *buffer;              /* (Circular) buffer */
+  gint wrp, rdp;               /* Buffer indices for writing and reading */
+  HANDLE space_avail_event;
+
+  /* Fields used by G_IO_WIN32_SOCKET channels */
+  int event_mask;
+  int last_events;
+  HANDLE event;
+  gboolean write_would_have_blocked;
+  gboolean ever_writable;
+};
+
+struct _GIOWin32Watch {
+  GSource       source;
+  GPollFD       pollfd;
+  GIOChannel   *channel;
+  GIOCondition  condition;
+};
+
+static void
+g_win32_print_access_mode (int flags)
+{
+  g_print ("%s%s%s%s%s%s%s%s%s%s",
+          ((flags & 0x3) == _O_RDWR ? "O_RDWR" :
+           ((flags & 0x3) == _O_RDONLY ? "O_RDONLY" :
+            ((flags & 0x3) == _O_WRONLY ? "O_WRONLY" : "0"))),
+          (flags & _O_APPEND ? "|O_APPEND" : ""),
+          (flags & _O_RANDOM ? "|O_RANDOM" : ""),
+          (flags & _O_SEQUENTIAL ? "|O_SEQUENTIAL" : ""),
+          (flags & _O_TEMPORARY ? "|O_TEMPORARY" : ""),
+          (flags & _O_CREAT ? "|O_CREAT" : ""),
+          (flags & _O_TRUNC ? "|O_TRUNC" : ""),
+          (flags & _O_EXCL ? "|O_EXCL" : ""),
+          (flags & _O_TEXT ? "|O_TEXT" : ""),
+          (flags & _O_BINARY ? "|O_BINARY" : ""));
+}
+
+static void
+g_win32_print_gioflags (GIOFlags flags)
+{
+  char *bar = "";
+
+  if (flags & G_IO_FLAG_APPEND)
+    bar = "|", g_print ("APPEND");
+  if (flags & G_IO_FLAG_NONBLOCK)
+    g_print ("%sNONBLOCK", bar), bar = "|";
+  if (flags & G_IO_FLAG_IS_READABLE)
+    g_print ("%sREADABLE", bar), bar = "|";
+  if (flags & G_IO_FLAG_IS_WRITEABLE)
+    g_print ("%sWRITEABLE", bar), bar = "|";
+  if (flags & G_IO_FLAG_IS_SEEKABLE)
+    g_print ("%sSEEKABLE", bar), bar = "|";
+}
+
+static const char *
+event_mask_to_string (int mask)
+{
+  char buf[100];
+  int checked_bits = 0;
+  char *bufp = buf;
+
+  if (mask == 0)
+    return "";
+
+#define BIT(n) checked_bits |= FD_##n; if (mask & FD_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
+
+  BIT (READ);
+  BIT (WRITE);
+  BIT (OOB);
+  BIT (ACCEPT);
+  BIT (CONNECT);
+  BIT (CLOSE);
+  BIT (QOS);
+  BIT (GROUP_QOS);
+  BIT (ROUTING_INTERFACE_CHANGE);
+  BIT (ADDRESS_LIST_CHANGE);
+  
+#undef BIT
+
+  if ((mask & ~checked_bits) != 0)
+         bufp += sprintf (bufp, "|%#x", mask & ~checked_bits);
+  
+  return g_quark_to_string (g_quark_from_string (buf));
+}
+
+static const char *
+condition_to_string (GIOCondition condition)
+{
+  char buf[100];
+  int checked_bits = 0;
+  char *bufp = buf;
+
+  if (condition == 0)
+    return "";
+
+#define BIT(n) checked_bits |= G_IO_##n; if (condition & G_IO_##n) bufp += sprintf (bufp, "%s" #n, (bufp>buf ? "|" : ""))
+
+  BIT (IN);
+  BIT (OUT);
+  BIT (PRI);
+  BIT (ERR);
+  BIT (HUP);
+  BIT (NVAL);
+  
+#undef BIT
+
+  if ((condition & ~checked_bits) != 0)
+         bufp += sprintf (bufp, "|%#x", condition & ~checked_bits);
+  
+  return g_quark_to_string (g_quark_from_string (buf));
+}
+
+static gboolean
+g_io_win32_get_debug_flag (void)
+{
+  return (getenv ("G_IO_WIN32_DEBUG") != NULL);
+}
+
+static void
+g_io_channel_win32_init (GIOWin32Channel *channel)
+{
+  channel->debug = g_io_win32_get_debug_flag ();
+
+  InitializeCriticalSection (&channel->mutex);
+  channel->running = FALSE;
+  channel->needs_close = FALSE;
+  channel->thread_id = 0;
+  channel->data_avail_event = NULL;
+  channel->revents = 0;
+  channel->buffer = NULL;
+  channel->space_avail_event = NULL;
+
+  channel->event_mask = 0;
+  channel->last_events = 0;
+  channel->event = NULL;
+  channel->write_would_have_blocked = FALSE;
+  channel->ever_writable = FALSE;
+}
+
+static void
+create_events (GIOWin32Channel *channel)
+{
+  SECURITY_ATTRIBUTES sec_attrs;
+  
+  sec_attrs.nLength = sizeof (SECURITY_ATTRIBUTES);
+  sec_attrs.lpSecurityDescriptor = NULL;
+  sec_attrs.bInheritHandle = FALSE;
+
+  /* The data available event is manual reset, the space available event
+   * is automatic reset.
+   */
+  if (!(channel->data_avail_event = CreateEvent (&sec_attrs, TRUE, FALSE, NULL))
+      || !(channel->space_avail_event = CreateEvent (&sec_attrs, FALSE, FALSE, NULL)))
+    {
+      gchar *emsg = g_win32_error_message (GetLastError ());
+
+      g_error ("Error creating event: %s", emsg);
+      g_free (emsg);
+    }
+}
+
+static unsigned __stdcall
+read_thread (void *parameter)
+{
+  GIOWin32Channel *channel = parameter;
+  guchar *buffer;
+  gint nbytes;
+
+  g_io_channel_ref ((GIOChannel *)channel);
+
+  if (channel->debug)
+    g_print ("read_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
+            channel->thread_id,
+            channel->fd,
+            channel->data_avail_event,
+            channel->space_avail_event);
+
+  channel->direction = 0;
+  channel->buffer = g_malloc (BUFFER_SIZE);
+  channel->rdp = channel->wrp = 0;
+  channel->running = TRUE;
+
+  SetEvent (channel->space_avail_event);
+  
+  EnterCriticalSection (&channel->mutex);
+  while (channel->running)
+    {
+      if (channel->debug)
+       g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
+                channel->thread_id, channel->rdp, channel->wrp);
+      if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
+       {
+         /* Buffer is full */
+         if (channel->debug)
+           g_print ("read_thread %#x: resetting space_avail\n",
+                    channel->thread_id);
+         ResetEvent (channel->space_avail_event);
+         if (channel->debug)
+           g_print ("read_thread %#x: waiting for space\n",
+                    channel->thread_id);
+         LeaveCriticalSection (&channel->mutex);
+         WaitForSingleObject (channel->space_avail_event, INFINITE);
+         EnterCriticalSection (&channel->mutex);
+         if (channel->debug)
+           g_print ("read_thread %#x: rdp=%d, wrp=%d\n",
+                    channel->thread_id, channel->rdp, channel->wrp);
+       }
+      
+      buffer = channel->buffer + channel->wrp;
+      
+      /* Always leave at least one byte unused gap to be able to
+       * distinguish between the full and empty condition...
+       */
+      nbytes = MIN ((channel->rdp + BUFFER_SIZE - channel->wrp - 1) % BUFFER_SIZE,
+                   BUFFER_SIZE - channel->wrp);
+
+      if (channel->debug)
+       g_print ("read_thread %#x: calling read() for %d bytes\n",
+                channel->thread_id, nbytes);
+
+      LeaveCriticalSection (&channel->mutex);
+
+      nbytes = read (channel->fd, buffer, nbytes);
+      
+      EnterCriticalSection (&channel->mutex);
+
+      channel->revents = G_IO_IN;
+      if (nbytes == 0)
+       channel->revents |= G_IO_HUP;
+      else if (nbytes < 0)
+       channel->revents |= G_IO_ERR;
+
+      if (channel->debug)
+       g_print ("read_thread %#x: read() returned %d, rdp=%d, wrp=%d\n",
+                channel->thread_id, nbytes, channel->rdp, channel->wrp);
+
+      if (nbytes <= 0)
+       break;
+
+      channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
+      if (channel->debug)
+       g_print ("read_thread %#x: rdp=%d, wrp=%d, setting data_avail\n",
+                channel->thread_id, channel->rdp, channel->wrp);
+      SetEvent (channel->data_avail_event);
+    }
+  
+  channel->running = FALSE;
+  if (channel->needs_close)
+    {
+      if (channel->debug)
+       g_print ("read_thread %#x: channel fd %d needs closing\n",
+                channel->thread_id, channel->fd);
+      close (channel->fd);
+      channel->fd = -1;
+    }
+
+  if (channel->debug)
+    g_print ("read_thread %#x: EOF, rdp=%d, wrp=%d, setting data_avail\n",
+            channel->thread_id, channel->rdp, channel->wrp);
+  SetEvent (channel->data_avail_event);
+  LeaveCriticalSection (&channel->mutex);
+  
+  g_io_channel_unref ((GIOChannel *)channel);
+  
+  /* No need to call _endthreadex(), the actual thread starter routine
+   * in MSVCRT (see crt/src/threadex.c:_threadstartex) calls
+   * _endthreadex() for us.
+   */
+
+  return 0;
+}
+
+static unsigned __stdcall
+write_thread (void *parameter)
+{
+  GIOWin32Channel *channel = parameter;
+  guchar *buffer;
+  gint nbytes;
+
+  g_io_channel_ref ((GIOChannel *)channel);
+
+  if (channel->debug)
+    g_print ("write_thread %#x: start fd=%d, data_avail=%p space_avail=%p\n",
+            channel->thread_id,
+            channel->fd,
+            channel->data_avail_event,
+            channel->space_avail_event);
+  
+  channel->direction = 1;
+  channel->buffer = g_malloc (BUFFER_SIZE);
+  channel->rdp = channel->wrp = 0;
+  channel->running = TRUE;
+
+  SetEvent (channel->space_avail_event);
+
+  /* We use the same event objects as for a reader thread, but with
+   * reversed meaning. So, space_avail is used if data is available
+   * for writing, and data_avail is used if space is available in the
+   * write buffer.
+   */
+
+  EnterCriticalSection (&channel->mutex);
+  while (channel->running || channel->rdp != channel->wrp)
+    {
+      if (channel->debug)
+       g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
+                channel->thread_id, channel->rdp, channel->wrp);
+      if (channel->wrp == channel->rdp)
+       {
+         /* Buffer is empty. */
+         if (channel->debug)
+           g_print ("write_thread %#x: resetting space_avail\n",
+                    channel->thread_id);
+         ResetEvent (channel->space_avail_event);
+         if (channel->debug)
+           g_print ("write_thread %#x: waiting for data\n",
+                    channel->thread_id);
+         channel->revents = G_IO_OUT;
+         SetEvent (channel->data_avail_event);
+         LeaveCriticalSection (&channel->mutex);
+         WaitForSingleObject (channel->space_avail_event, INFINITE);
+
+         EnterCriticalSection (&channel->mutex);
+         if (channel->rdp == channel->wrp)
+           break;
+
+         if (channel->debug)
+           g_print ("write_thread %#x: rdp=%d, wrp=%d\n",
+                    channel->thread_id, channel->rdp, channel->wrp);
+       }
+      
+      buffer = channel->buffer + channel->rdp;
+      if (channel->rdp < channel->wrp)
+       nbytes = channel->wrp - channel->rdp;
+      else
+       nbytes = BUFFER_SIZE - channel->rdp;
+
+      if (channel->debug)
+       g_print ("write_thread %#x: calling write() for %d bytes\n",
+                channel->thread_id, nbytes);
+
+      LeaveCriticalSection (&channel->mutex);
+      nbytes = write (channel->fd, buffer, nbytes);
+      EnterCriticalSection (&channel->mutex);
+
+      if (channel->debug)
+       g_print ("write_thread %#x: write(%i) returned %d, rdp=%d, wrp=%d\n",
+                channel->thread_id, channel->fd, nbytes, channel->rdp, channel->wrp);
+
+      channel->revents = 0;
+      if (nbytes > 0)
+       channel->revents |= G_IO_OUT;
+      else if (nbytes <= 0)
+       channel->revents |= G_IO_ERR;
+
+      channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE;
+
+      if (nbytes <= 0)
+       break;
+
+      if (channel->debug)
+       g_print ("write_thread: setting data_avail for thread %#x\n",
+                channel->thread_id);
+      SetEvent (channel->data_avail_event);
+    }
+  
+  channel->running = FALSE;
+  if (channel->needs_close)
+    {
+      if (channel->debug)
+       g_print ("write_thread %#x: channel fd %d needs closing\n",
+                channel->thread_id, channel->fd);
+      close (channel->fd);
+      channel->fd = -1;
+    }
+
+  LeaveCriticalSection (&channel->mutex);
+  
+  g_io_channel_unref ((GIOChannel *)channel);
+  
+  return 0;
+}
+
+static void
+create_thread (GIOWin32Channel     *channel,
+              GIOCondition         condition,
+              unsigned (__stdcall *thread) (void *parameter))
+{
+  HANDLE thread_handle;
+
+  thread_handle = (HANDLE) _beginthreadex (NULL, 0, thread, channel, 0,
+                                          &channel->thread_id);
+  if (thread_handle == 0)
+    g_warning ("Error creating thread: %s.",
+              g_strerror (errno));
+  else if (!CloseHandle (thread_handle))
+    {
+      gchar *emsg = g_win32_error_message (GetLastError ());
+
+      g_warning ("Error closing thread handle: %s.", emsg);
+      g_free (emsg);
+    }
+
+  WaitForSingleObject (channel->space_avail_event, INFINITE);
+}
+
+static GIOStatus
+buffer_read (GIOWin32Channel *channel,
+            gchar           *dest,
+            gsize            count,
+            gsize           *bytes_read,
+            GError         **err)
+{
+  guint nbytes;
+  guint left = count;
+  
+  EnterCriticalSection (&channel->mutex);
+  if (channel->debug)
+    g_print ("reading from thread %#x %" G_GSIZE_FORMAT " bytes, rdp=%d, wrp=%d\n",
+            channel->thread_id, count, channel->rdp, channel->wrp);
+  
+  if (channel->wrp == channel->rdp)
+    {
+      LeaveCriticalSection (&channel->mutex);
+      if (channel->debug)
+       g_print ("waiting for data from thread %#x\n", channel->thread_id);
+      WaitForSingleObject (channel->data_avail_event, INFINITE);
+      if (channel->debug)
+       g_print ("done waiting for data from thread %#x\n", channel->thread_id);
+      EnterCriticalSection (&channel->mutex);
+      if (channel->wrp == channel->rdp && !channel->running)
+       {
+         if (channel->debug)
+           g_print ("wrp==rdp, !running\n");
+         LeaveCriticalSection (&channel->mutex);
+          *bytes_read = 0;
+         return G_IO_STATUS_EOF;
+       }
+    }
+  
+  if (channel->rdp < channel->wrp)
+    nbytes = channel->wrp - channel->rdp;
+  else
+    nbytes = BUFFER_SIZE - channel->rdp;
+  LeaveCriticalSection (&channel->mutex);
+  nbytes = MIN (left, nbytes);
+  if (channel->debug)
+    g_print ("moving %d bytes from thread %#x\n",
+            nbytes, channel->thread_id);
+  memcpy (dest, channel->buffer + channel->rdp, nbytes);
+  dest += nbytes;
+  left -= nbytes;
+  EnterCriticalSection (&channel->mutex);
+  channel->rdp = (channel->rdp + nbytes) % BUFFER_SIZE;
+  if (channel->debug)
+    g_print ("setting space_avail for thread %#x\n", channel->thread_id);
+  SetEvent (channel->space_avail_event);
+  if (channel->debug)
+    g_print ("for thread %#x: rdp=%d, wrp=%d\n",
+            channel->thread_id, channel->rdp, channel->wrp);
+  if (channel->running && channel->wrp == channel->rdp)
+    {
+      if (channel->debug)
+       g_print ("resetting data_avail of thread %#x\n",
+                channel->thread_id);
+      ResetEvent (channel->data_avail_event);
+    };
+  LeaveCriticalSection (&channel->mutex);
+  
+  /* We have no way to indicate any errors form the actual
+   * read() or recv() call in the reader thread. Should we have?
+   */
+  *bytes_read = count - left;
+  return (*bytes_read > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
+}
+
+
+static GIOStatus
+buffer_write (GIOWin32Channel *channel,
+             const gchar     *dest,
+             gsize            count,
+             gsize           *bytes_written,
+             GError         **err)
+{
+  guint nbytes;
+  guint left = count;
+  
+  EnterCriticalSection (&channel->mutex);
+  if (channel->debug)
+    g_print ("buffer_write: writing to thread %#x %" G_GSIZE_FORMAT " bytes, rdp=%d, wrp=%d\n",
+            channel->thread_id, count, channel->rdp, channel->wrp);
+  
+  if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
+    {
+      /* Buffer is full */
+      if (channel->debug)
+       g_print ("buffer_write: tid %#x: resetting data_avail\n",
+                channel->thread_id);
+      ResetEvent (channel->data_avail_event);
+      if (channel->debug)
+       g_print ("buffer_write: tid %#x: waiting for space\n",
+                channel->thread_id);
+      LeaveCriticalSection (&channel->mutex);
+      WaitForSingleObject (channel->data_avail_event, INFINITE);
+      EnterCriticalSection (&channel->mutex);
+      if (channel->debug)
+       g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d\n",
+                channel->thread_id, channel->rdp, channel->wrp);
+    }
+   
+  nbytes = MIN ((channel->rdp + BUFFER_SIZE - channel->wrp - 1) % BUFFER_SIZE,
+               BUFFER_SIZE - channel->wrp);
+
+  LeaveCriticalSection (&channel->mutex);
+  nbytes = MIN (left, nbytes);
+  if (channel->debug)
+    g_print ("buffer_write: tid %#x: writing %d bytes\n",
+            channel->thread_id, nbytes);
+  memcpy (channel->buffer + channel->wrp, dest, nbytes);
+  dest += nbytes;
+  left -= nbytes;
+  EnterCriticalSection (&channel->mutex);
+
+  channel->wrp = (channel->wrp + nbytes) % BUFFER_SIZE;
+  if (channel->debug)
+    g_print ("buffer_write: tid %#x: rdp=%d, wrp=%d, setting space_avail\n",
+            channel->thread_id, channel->rdp, channel->wrp);
+  SetEvent (channel->space_avail_event);
+
+  if ((channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
+    {
+      /* Buffer is full */
+      if (channel->debug)
+       g_print ("buffer_write: tid %#x: resetting data_avail\n",
+                channel->thread_id);
+      ResetEvent (channel->data_avail_event);
+    }
+
+  LeaveCriticalSection (&channel->mutex);
+  
+  /* We have no way to indicate any errors form the actual
+   * write() call in the writer thread. Should we have?
+   */
+  *bytes_written = count - left;
+  return (*bytes_written > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
+}
+
+
+static gboolean
+g_io_win32_prepare (GSource *source,
+                   gint    *timeout)
+{
+  GIOWin32Watch *watch = (GIOWin32Watch *)source;
+  GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
+  GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
+  int event_mask;
+  
+  *timeout = -1;
+  
+  if (channel->debug)
+    g_print ("g_io_win32_prepare: source=%p channel=%p", source, channel);
+
+  switch (channel->type)
+    {
+    case G_IO_WIN32_WINDOWS_MESSAGES:
+      if (channel->debug)
+       g_print (" MSG");
+      break;
+
+    case G_IO_WIN32_CONSOLE:
+      if (channel->debug)
+       g_print (" CON");
+      break;
+
+    case G_IO_WIN32_FILE_DESC:
+      if (channel->debug)
+       g_print (" FD thread=%#x buffer_condition:{%s}"
+                "\n  watch->pollfd.events:{%s} watch->pollfd.revents:{%s} channel->revents:{%s}",
+                channel->thread_id, condition_to_string (buffer_condition),
+                condition_to_string (watch->pollfd.events),
+                condition_to_string (watch->pollfd.revents),
+                condition_to_string (channel->revents));
+      
+      EnterCriticalSection (&channel->mutex);
+      if (channel->running)
+       {
+         if (channel->direction == 0 && channel->wrp == channel->rdp)
+           {
+             if (channel->debug)
+               g_print ("\n  setting revents=0");
+             channel->revents = 0;
+           }
+       }
+      else
+       {
+         if (channel->direction == 1
+             && (channel->wrp + 1) % BUFFER_SIZE == channel->rdp)
+           {
+             if (channel->debug)
+               g_print ("\n setting revents=0");
+             channel->revents = 0;
+           }
+       }         
+      LeaveCriticalSection (&channel->mutex);
+      break;
+
+    case G_IO_WIN32_SOCKET:
+      if (channel->debug)
+       g_print (" SOCK");
+      event_mask = 0;
+      if (watch->condition & G_IO_IN)
+       event_mask |= (FD_READ | FD_ACCEPT);
+      if (watch->condition & G_IO_OUT)
+       event_mask |= (FD_WRITE | FD_CONNECT);
+      event_mask |= FD_CLOSE;
+
+      if (channel->event_mask != event_mask)
+       {
+         if (channel->debug)
+           g_print ("\n  WSAEventSelect(%d,%p,{%s})",
+                    channel->fd, (HANDLE) watch->pollfd.fd,
+                    event_mask_to_string (event_mask));
+         if (WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd,
+                             event_mask) == SOCKET_ERROR)
+           if (channel->debug)
+             {
+               gchar *emsg = g_win32_error_message (WSAGetLastError ());
+
+               g_print (" failed: %s", emsg);
+               g_free (emsg);
+             }
+         channel->event_mask = event_mask;
+
+         if (channel->debug)
+           g_print ("\n  setting last_events=0");
+         channel->last_events = 0;
+
+         if ((event_mask & FD_WRITE) &&
+             channel->ever_writable &&
+             !channel->write_would_have_blocked)
+           {
+             if (channel->debug)
+               g_print (" WSASetEvent(%p)", (WSAEVENT) watch->pollfd.fd);
+             WSASetEvent ((WSAEVENT) watch->pollfd.fd);
+           }
+       }
+      break;
+
+    default:
+      g_assert_not_reached ();
+      abort ();
+    }
+  if (channel->debug)
+    g_print ("\n");
+
+  return ((watch->condition & buffer_condition) == watch->condition);
+}
+
+static gboolean
+g_io_win32_check (GSource *source)
+{
+  MSG msg;
+  GIOWin32Watch *watch = (GIOWin32Watch *)source;
+  GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
+  GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
+  WSANETWORKEVENTS events;
+
+  if (channel->debug)
+    g_print ("g_io_win32_check: source=%p channel=%p", source, channel);
+
+  switch (channel->type)
+    {
+    case G_IO_WIN32_WINDOWS_MESSAGES:
+      if (channel->debug)
+       g_print (" MSG\n");
+      return (PeekMessage (&msg, channel->hwnd, 0, 0, PM_NOREMOVE));
+
+    case G_IO_WIN32_FILE_DESC:
+      if (channel->debug)
+       g_print (" FD thread=%#x buffer_condition=%s\n"
+                "  watch->pollfd.events={%s} watch->pollfd.revents={%s} channel->revents={%s}\n",
+                channel->thread_id, condition_to_string (buffer_condition),
+                condition_to_string (watch->pollfd.events),
+                condition_to_string (watch->pollfd.revents),
+                condition_to_string (channel->revents));
+      
+      watch->pollfd.revents = (watch->pollfd.events & channel->revents);
+
+      return ((watch->pollfd.revents | buffer_condition) & watch->condition);
+
+    case G_IO_WIN32_CONSOLE:
+      if (channel->debug)
+       g_print (" CON\n");
+      if (watch->channel->is_writeable)
+       return TRUE;
+      else if (watch->channel->is_readable)
+        {
+         INPUT_RECORD buffer;
+         DWORD n;
+         if (PeekConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n) &&
+             n == 1)
+           {
+             /* _kbhit() does quite complex processing to find out
+              * whether at least one of the key events pending corresponds
+              * to a "real" character that can be read.
+              */
+             if (_kbhit ())
+               return TRUE;
+             
+             /* Discard all other kinds of events */
+             ReadConsoleInput ((HANDLE) watch->pollfd.fd, &buffer, 1, &n);
+           }
+        }
+      return FALSE;
+
+    case G_IO_WIN32_SOCKET:
+      if (channel->debug)
+       g_print (" SOCK");
+      if (channel->last_events & FD_WRITE)
+       {
+         if (channel->debug)
+           g_print (" sock=%d event=%p last_events has FD_WRITE",
+                    channel->fd, (HANDLE) watch->pollfd.fd);
+       }
+      else
+       {
+         WSAEnumNetworkEvents (channel->fd, 0, &events);
+
+         if (channel->debug)
+           g_print ("\n  revents={%s} condition={%s}"
+                    "\n  WSAEnumNetworkEvents(%d,0) sets events={%s}",
+                    condition_to_string (watch->pollfd.revents),
+                    condition_to_string (watch->condition),
+                    channel->fd, 
+                    event_mask_to_string (events.lNetworkEvents));
+         
+         if (watch->pollfd.revents != 0 &&
+             events.lNetworkEvents == 0 &&
+             !(channel->event_mask & FD_WRITE))
+           {
+             channel->event_mask = 0;
+             if (channel->debug)
+               g_print ("\n  WSAEventSelect(%d,%p,{})",
+                        channel->fd, (HANDLE) watch->pollfd.fd);
+             WSAEventSelect (channel->fd, (HANDLE) watch->pollfd.fd, 0);
+             if (channel->debug)
+               g_print ("  ResetEvent(%p)",
+                        (HANDLE) watch->pollfd.fd);
+             ResetEvent ((HANDLE) watch->pollfd.fd);
+           }
+         else if (events.lNetworkEvents & FD_WRITE)
+           channel->ever_writable = TRUE;
+         channel->last_events = events.lNetworkEvents;
+       }
+
+      watch->pollfd.revents = 0;
+      if (channel->last_events & (FD_READ | FD_ACCEPT))
+       watch->pollfd.revents |= G_IO_IN;
+
+      if (channel->last_events & FD_WRITE)
+       watch->pollfd.revents |= G_IO_OUT;
+      else
+       {
+         /* We have called WSAEnumNetworkEvents() above but it didn't
+          * set FD_WRITE.
+          */
+         if (events.lNetworkEvents & FD_CONNECT)
+           {
+             if (events.iErrorCode[FD_CONNECT_BIT] == 0)
+               watch->pollfd.revents |= G_IO_OUT;
+             else
+               watch->pollfd.revents |= (G_IO_HUP | G_IO_ERR);
+           }
+         if (watch->pollfd.revents == 0 && (channel->last_events & (FD_CLOSE)))
+           watch->pollfd.revents |= G_IO_HUP;
+       }
+
+      /* Regardless of WSAEnumNetworkEvents() result, if watching for
+       * writability, and if we have ever got a FD_WRITE event, and
+       * unless last write would have blocked, set G_IO_OUT. But never
+       * set both G_IO_OUT and G_IO_HUP.
+       */
+      if (!(watch->pollfd.revents & G_IO_HUP) &&
+         channel->ever_writable &&
+         !channel->write_would_have_blocked &&
+         (channel->event_mask & FD_WRITE))
+       watch->pollfd.revents |= G_IO_OUT;
+
+      if (channel->debug)
+       g_print ("\n  revents={%s} retval={%s}\n",
+                condition_to_string (watch->pollfd.revents),
+                condition_to_string ((watch->pollfd.revents | buffer_condition) & watch->condition));
+
+      return ((watch->pollfd.revents | buffer_condition) & watch->condition);
+
+    default:
+      g_assert_not_reached ();
+      abort ();
+    }
+}
+
+static gboolean
+g_io_win32_dispatch (GSource     *source,
+                    GSourceFunc  callback,
+                    gpointer     user_data)
+{
+  GIOFunc func = (GIOFunc)callback;
+  GIOWin32Watch *watch = (GIOWin32Watch *)source;
+  GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
+  GIOCondition buffer_condition = g_io_channel_get_buffer_condition (watch->channel);
+  
+  if (!func)
+    {
+      g_warning ("IO Watch dispatched without callback\n"
+                "You must call g_source_connect().");
+      return FALSE;
+    }
+  
+  if (channel->debug)
+    g_print ("g_io_win32_dispatch: pollfd.revents=%s condition=%s result=%s\n",
+            condition_to_string (watch->pollfd.revents),
+            condition_to_string (watch->condition),
+            condition_to_string ((watch->pollfd.revents | buffer_condition) & watch->condition));
+
+  return (*func) (watch->channel,
+                 (watch->pollfd.revents | buffer_condition) & watch->condition,
+                 user_data);
+}
+
+static void
+g_io_win32_finalize (GSource *source)
+{
+  GIOWin32Watch *watch = (GIOWin32Watch *)source;
+  GIOWin32Channel *channel = (GIOWin32Channel *)watch->channel;
+  
+  if (channel->debug)
+    g_print ("g_io_win32_finalize: source=%p channel=%p", source, channel);
+
+  switch (channel->type)
+    {
+    case G_IO_WIN32_WINDOWS_MESSAGES:
+      if (channel->debug)
+       g_print (" MSG");
+      break;
+
+    case G_IO_WIN32_CONSOLE:
+      if (channel->debug)
+       g_print (" CON");
+      break;
+
+    case G_IO_WIN32_FILE_DESC:
+      if (channel->debug)
+       g_print (" FD thread=%#x", channel->thread_id);
+      break;
+
+    case G_IO_WIN32_SOCKET:
+      if (channel->debug)
+       g_print (" SOCK sock=%d", channel->fd);
+      break;
+
+    default:
+      g_assert_not_reached ();
+      abort ();
+    }
+  if (channel->debug)
+    g_print ("\n");
+  g_io_channel_unref (watch->channel);
+}
+
+GSourceFuncs g_io_watch_funcs = {
+  g_io_win32_prepare,
+  g_io_win32_check,
+  g_io_win32_dispatch,
+  g_io_win32_finalize
+};
+
+static GIOStatus
+g_io_win32_msg_read (GIOChannel *channel,
+                    gchar      *buf,
+                    gsize       count,
+                    gsize      *bytes_read,
+                    GError    **err)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  MSG msg;               /* In case of alignment problems */
+  
+  if (count < sizeof (MSG))
+    {
+      g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
+                           "Incorrect message size"); /* Informative enough error message? */
+      return G_IO_STATUS_ERROR;
+    }
+  
+  if (win32_channel->debug)
+    g_print ("g_io_win32_msg_read: channel=%p hwnd=%p\n",
+            channel, win32_channel->hwnd);
+  if (!PeekMessage (&msg, win32_channel->hwnd, 0, 0, PM_REMOVE))
+    return G_IO_STATUS_AGAIN;
+
+  memmove (buf, &msg, sizeof (MSG));
+  *bytes_read = sizeof (MSG);
+
+  return G_IO_STATUS_NORMAL;
+}
+
+static GIOStatus
+g_io_win32_msg_write (GIOChannel  *channel,
+                     const gchar *buf,
+                     gsize        count,
+                     gsize       *bytes_written,
+                     GError     **err)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  MSG msg;
+  
+  if (count != sizeof (MSG))
+    {
+      g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_INVAL,
+                           "Incorrect message size"); /* Informative enough error message? */
+      return G_IO_STATUS_ERROR;
+    }
+  
+  /* In case of alignment problems */
+  memmove (&msg, buf, sizeof (MSG));
+  if (!PostMessage (win32_channel->hwnd, msg.message, msg.wParam, msg.lParam))
+    {
+      gchar *emsg = g_win32_error_message (GetLastError ());
+
+      g_set_error_literal (err, G_IO_CHANNEL_ERROR, G_IO_CHANNEL_ERROR_FAILED, emsg);
+      g_free (emsg);
+
+      return G_IO_STATUS_ERROR;
+    }
+
+  *bytes_written = sizeof (MSG);
+
+  return G_IO_STATUS_NORMAL;
+}
+
+static GIOStatus
+g_io_win32_msg_close (GIOChannel *channel,
+                     GError    **err)
+{
+  /* Nothing to be done. Or should we set hwnd to some invalid value? */
+
+  return G_IO_STATUS_NORMAL;
+}
+
+static void
+g_io_win32_free (GIOChannel *channel)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  
+  if (win32_channel->debug)
+    g_print ("g_io_win32_free channel=%p fd=%d\n", channel, win32_channel->fd);
+
+  DeleteCriticalSection (&win32_channel->mutex);
+
+  if (win32_channel->data_avail_event)
+    if (!CloseHandle (win32_channel->data_avail_event))
+      if (win32_channel->debug)
+       {
+         gchar *emsg = g_win32_error_message (GetLastError ());
+
+         g_print ("  CloseHandle(%p) failed: %s\n",
+                  win32_channel->data_avail_event, emsg);
+         g_free (emsg);
+       }
+
+  g_free (win32_channel->buffer);
+
+  if (win32_channel->space_avail_event)
+    if (!CloseHandle (win32_channel->space_avail_event))
+      if (win32_channel->debug)
+       {
+         gchar *emsg = g_win32_error_message (GetLastError ());
+
+         g_print ("  CloseHandle(%p) failed: %s\n",
+                  win32_channel->space_avail_event, emsg);
+         g_free (emsg);
+       }
+
+  if (win32_channel->type == G_IO_WIN32_SOCKET &&
+      win32_channel->fd != -1)
+    if (WSAEventSelect (win32_channel->fd, NULL, 0) == SOCKET_ERROR)
+      if (win32_channel->debug)
+       {
+         gchar *emsg = g_win32_error_message (WSAGetLastError ());
+
+         g_print ("  WSAEventSelect(%d,NULL,{}) failed: %s\n",
+                  win32_channel->fd, emsg);
+         g_free (emsg);
+       }
+
+  if (win32_channel->event)
+    if (!WSACloseEvent (win32_channel->event))
+      if (win32_channel->debug)
+       {
+         gchar *emsg = g_win32_error_message (WSAGetLastError ());
+
+         g_print ("  WSACloseEvent(%p) failed: %s\n",
+                  win32_channel->event, emsg);
+         g_free (emsg);
+       }
+
+  g_free (win32_channel);
+}
+
+static GSource *
+g_io_win32_msg_create_watch (GIOChannel   *channel,
+                            GIOCondition  condition)
+{
+  GIOWin32Watch *watch;
+  GSource *source;
+
+  source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
+  g_source_set_name (source, "GIOChannel (Win32)");
+  watch = (GIOWin32Watch *)source;
+  
+  watch->channel = channel;
+  g_io_channel_ref (channel);
+  
+  watch->condition = condition;
+  
+  watch->pollfd.fd = (gintptr) G_WIN32_MSG_HANDLE;
+  watch->pollfd.events = condition;
+  
+  g_source_add_poll (source, &watch->pollfd);
+  
+  return source;
+}
+
+static GIOStatus
+g_io_win32_fd_and_console_read (GIOChannel *channel,
+                               gchar      *buf,
+                               gsize       count,
+                               gsize      *bytes_read,
+                               GError    **err)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  gint result;
+  
+  if (win32_channel->debug)
+    g_print ("g_io_win32_fd_read: fd=%d count=%" G_GSIZE_FORMAT "\n",
+            win32_channel->fd, count);
+  
+  if (win32_channel->thread_id)
+    {
+      return buffer_read (win32_channel, buf, count, bytes_read, err);
+    }
+
+  result = read (win32_channel->fd, buf, count);
+
+  if (win32_channel->debug)
+    g_print ("g_io_win32_fd_read: read() => %d\n", result);
+
+  if (result < 0)
+    {
+      *bytes_read = 0;
+
+      switch (errno)
+        {
+#ifdef EAGAIN
+       case EAGAIN:
+         return G_IO_STATUS_AGAIN;
+#endif
+       default:
+         g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                               g_io_channel_error_from_errno (errno),
+                               g_strerror (errno));
+         return G_IO_STATUS_ERROR;
+        }
+    }
+
+  *bytes_read = result;
+
+  return (result > 0) ? G_IO_STATUS_NORMAL : G_IO_STATUS_EOF;
+}
+
+static GIOStatus
+g_io_win32_fd_and_console_write (GIOChannel  *channel,
+                                const gchar *buf,
+                                gsize        count,
+                                gsize       *bytes_written,
+                                GError     **err)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  gint result;
+
+  if (win32_channel->thread_id)
+    {
+      return buffer_write (win32_channel, buf, count, bytes_written, err);
+    }
+  
+  result = write (win32_channel->fd, buf, count);
+  if (win32_channel->debug)
+    g_print ("g_io_win32_fd_write: fd=%d count=%" G_GSIZE_FORMAT " => %d\n",
+            win32_channel->fd, count, result);
+
+  if (result < 0)
+    {
+      *bytes_written = 0;
+
+      switch (errno)
+        {
+#ifdef EAGAIN
+       case EAGAIN:
+         return G_IO_STATUS_AGAIN;
+#endif
+       default:
+         g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                               g_io_channel_error_from_errno (errno),
+                               g_strerror (errno));
+         return G_IO_STATUS_ERROR;
+        }
+    }
+
+  *bytes_written = result;
+
+  return G_IO_STATUS_NORMAL;
+}
+
+static GIOStatus
+g_io_win32_fd_seek (GIOChannel *channel,
+                   gint64      offset,
+                   GSeekType   type,
+                   GError    **err)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  int whence;
+  off_t tmp_offset;
+  off_t result;
+  
+  switch (type)
+    {
+    case G_SEEK_SET:
+      whence = SEEK_SET;
+      break;
+    case G_SEEK_CUR:
+      whence = SEEK_CUR;
+      break;
+    case G_SEEK_END:
+      whence = SEEK_END;
+      break;
+    default:
+      whence = -1; /* Keep the compiler quiet */
+      g_assert_not_reached ();
+      abort ();
+    }
+
+  tmp_offset = offset;
+  if (tmp_offset != offset)
+    {
+      g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                           g_io_channel_error_from_errno (EINVAL),
+                           g_strerror (EINVAL));
+      return G_IO_STATUS_ERROR;
+    }
+  
+  result = lseek (win32_channel->fd, tmp_offset, whence);
+  
+  if (result < 0)
+    {
+      g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                           g_io_channel_error_from_errno (errno),
+                           g_strerror (errno));
+      return G_IO_STATUS_ERROR;
+    }
+
+  return G_IO_STATUS_NORMAL;
+}
+
+static GIOStatus
+g_io_win32_fd_close (GIOChannel *channel,
+                    GError    **err)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  
+  if (win32_channel->debug)
+    g_print ("g_io_win32_fd_close: thread=%#x: fd=%d\n",
+            win32_channel->thread_id,
+            win32_channel->fd);
+  EnterCriticalSection (&win32_channel->mutex);
+  if (win32_channel->running)
+    {
+      if (win32_channel->debug)
+       g_print ("thread %#x: running, marking fd %d for later close\n",
+                win32_channel->thread_id, win32_channel->fd);
+      win32_channel->running = FALSE;
+      win32_channel->needs_close = TRUE;
+      if (win32_channel->direction == 0)
+       SetEvent (win32_channel->data_avail_event);
+      else
+       SetEvent (win32_channel->space_avail_event);
+    }
+  else
+    {
+      if (win32_channel->debug)
+       g_print ("closing fd %d\n", win32_channel->fd);
+      close (win32_channel->fd);
+      if (win32_channel->debug)
+       g_print ("closed fd %d, setting to -1\n",
+                win32_channel->fd);
+      win32_channel->fd = -1;
+    }
+  LeaveCriticalSection (&win32_channel->mutex);
+
+  /* FIXME error detection? */
+
+  return G_IO_STATUS_NORMAL;
+}
+
+static GSource *
+g_io_win32_fd_create_watch (GIOChannel    *channel,
+                           GIOCondition   condition)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
+  GIOWin32Watch *watch = (GIOWin32Watch *)source;
+
+  watch->channel = channel;
+  g_io_channel_ref (channel);
+  
+  watch->condition = condition;
+  
+  if (win32_channel->data_avail_event == NULL)
+    create_events (win32_channel);
+
+  watch->pollfd.fd = (gintptr) win32_channel->data_avail_event;
+  watch->pollfd.events = condition;
+  
+  if (win32_channel->debug)
+    g_print ("g_io_win32_fd_create_watch: channel=%p fd=%d condition={%s} event=%p\n",
+            channel, win32_channel->fd,
+            condition_to_string (condition), (HANDLE) watch->pollfd.fd);
+
+  EnterCriticalSection (&win32_channel->mutex);
+  if (win32_channel->thread_id == 0)
+    {
+      if (condition & G_IO_IN)
+       create_thread (win32_channel, condition, read_thread);
+      else if (condition & G_IO_OUT)
+       create_thread (win32_channel, condition, write_thread);
+    }
+
+  g_source_add_poll (source, &watch->pollfd);
+  LeaveCriticalSection (&win32_channel->mutex);
+
+  return source;
+}
+
+static GIOStatus
+g_io_win32_console_close (GIOChannel *channel,
+                         GError    **err)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  
+  if (close (win32_channel->fd) < 0)
+    {
+      g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                           g_io_channel_error_from_errno (errno),
+                           g_strerror (errno));
+      return G_IO_STATUS_ERROR;
+    }
+
+  return G_IO_STATUS_NORMAL;
+}
+
+static GSource *
+g_io_win32_console_create_watch (GIOChannel    *channel,
+                                GIOCondition   condition)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
+  GIOWin32Watch *watch = (GIOWin32Watch *)source;
+
+  watch->channel = channel;
+  g_io_channel_ref (channel);
+  
+  watch->condition = condition;
+  
+  watch->pollfd.fd = _get_osfhandle (win32_channel->fd);
+  watch->pollfd.events = condition;
+  
+  g_source_add_poll (source, &watch->pollfd);
+
+  return source;
+}
+
+static GIOStatus
+g_io_win32_sock_read (GIOChannel *channel,
+                     gchar      *buf,
+                     gsize       count,
+                     gsize      *bytes_read,
+                     GError    **err)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  gint result;
+  GIOChannelError error;
+  int winsock_error;
+
+  if (win32_channel->debug)
+    g_print ("g_io_win32_sock_read: channel=%p sock=%d count=%" G_GSIZE_FORMAT,
+            channel, win32_channel->fd, count);
+
+  result = recv (win32_channel->fd, buf, count, 0);
+  if (result == SOCKET_ERROR)
+    winsock_error = WSAGetLastError ();
+
+  if (win32_channel->debug)
+    g_print (" recv=%d", result);
+  
+  if (result == SOCKET_ERROR)
+    {
+      gchar *emsg = g_win32_error_message (winsock_error);
+
+      if (win32_channel->debug)
+       g_print (" %s\n", emsg);
+
+      *bytes_read = 0;
+
+      switch (winsock_error)
+       {
+       case WSAEINVAL:
+          error = G_IO_CHANNEL_ERROR_INVAL;
+          break;
+       case WSAEWOULDBLOCK:
+         g_free (emsg);
+          return G_IO_STATUS_AGAIN;
+       default:
+         error = G_IO_CHANNEL_ERROR_FAILED;
+          break;
+       }
+      g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg);
+      g_free (emsg);
+
+      return G_IO_STATUS_ERROR;
+    }
+  else
+    {
+      if (win32_channel->debug)
+       g_print ("\n");
+      *bytes_read = result;
+      if (result == 0)
+       return G_IO_STATUS_EOF;
+      else
+       return G_IO_STATUS_NORMAL;
+    }
+}
+
+static GIOStatus
+g_io_win32_sock_write (GIOChannel  *channel,
+                      const gchar *buf,
+                      gsize        count,
+                      gsize       *bytes_written,
+                      GError     **err)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  gint result;
+  GIOChannelError error;
+  int winsock_error;
+  
+  if (win32_channel->debug)
+    g_print ("g_io_win32_sock_write: channel=%p sock=%d count=%" G_GSIZE_FORMAT,
+            channel, win32_channel->fd, count);
+
+  result = send (win32_channel->fd, buf, count, 0);
+  if (result == SOCKET_ERROR)
+    winsock_error = WSAGetLastError ();
+
+  if (win32_channel->debug)
+    g_print (" send=%d", result);
+  
+  if (result == SOCKET_ERROR)
+    {
+      gchar *emsg = g_win32_error_message (winsock_error);
+
+      if (win32_channel->debug)
+       g_print (" %s\n", emsg);
+
+      *bytes_written = 0;
+
+      switch (winsock_error)
+       {
+       case WSAEINVAL:
+         error = G_IO_CHANNEL_ERROR_INVAL;
+          break;
+       case WSAEWOULDBLOCK:
+         win32_channel->write_would_have_blocked = TRUE;
+         win32_channel->last_events = 0;
+         g_free (emsg);
+          return G_IO_STATUS_AGAIN;
+       default:
+         error = G_IO_CHANNEL_ERROR_FAILED;
+          break;
+       }
+      g_set_error_literal (err, G_IO_CHANNEL_ERROR, error, emsg);
+      g_free (emsg);
+
+      return G_IO_STATUS_ERROR;
+    }
+  else
+    {
+      if (win32_channel->debug)
+       g_print ("\n");
+      *bytes_written = result;
+      win32_channel->write_would_have_blocked = FALSE;
+
+      return G_IO_STATUS_NORMAL;
+    }
+}
+
+static GIOStatus
+g_io_win32_sock_close (GIOChannel *channel,
+                      GError    **err)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+  if (win32_channel->fd != -1)
+    {
+      if (win32_channel->debug)
+       g_print ("g_io_win32_sock_close: channel=%p sock=%d\n",
+                channel, win32_channel->fd);
+      
+      closesocket (win32_channel->fd);
+      win32_channel->fd = -1;
+    }
+
+  /* FIXME error detection? */
+
+  return G_IO_STATUS_NORMAL;
+}
+
+static GSource *
+g_io_win32_sock_create_watch (GIOChannel    *channel,
+                             GIOCondition   condition)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  GSource *source = g_source_new (&g_io_watch_funcs, sizeof (GIOWin32Watch));
+  GIOWin32Watch *watch = (GIOWin32Watch *)source;
+  
+  watch->channel = channel;
+  g_io_channel_ref (channel);
+  
+  watch->condition = condition;
+
+  if (win32_channel->event == 0)
+    win32_channel->event = WSACreateEvent ();
+
+  watch->pollfd.fd = (gintptr) win32_channel->event;
+  watch->pollfd.events = condition;
+  
+  if (win32_channel->debug)
+    g_print ("g_io_win32_sock_create_watch: channel=%p sock=%d event=%p condition={%s}\n",
+            channel, win32_channel->fd, (HANDLE) watch->pollfd.fd,
+            condition_to_string (watch->condition));
+
+  g_source_add_poll (source, &watch->pollfd);
+
+  return source;
+}
+
+GIOChannel *
+g_io_channel_new_file (const gchar  *filename,
+                       const gchar  *mode,
+                       GError      **error)
+{
+  int fid, flags, pmode;
+  GIOChannel *channel;
+
+  enum { /* Cheesy hack */
+    MODE_R = 1 << 0,
+    MODE_W = 1 << 1,
+    MODE_A = 1 << 2,
+    MODE_PLUS = 1 << 3,
+  } mode_num;
+
+  g_return_val_if_fail (filename != NULL, NULL);
+  g_return_val_if_fail (mode != NULL, NULL);
+  g_return_val_if_fail ((error == NULL) || (*error == NULL), NULL);
+
+  switch (mode[0])
+    {
+      case 'r':
+        mode_num = MODE_R;
+        break;
+      case 'w':
+        mode_num = MODE_W;
+        break;
+      case 'a':
+        mode_num = MODE_A;
+        break;
+      default:
+        g_warning ("Invalid GIOFileMode %s.", mode);
+        return NULL;
+    }
+
+  switch (mode[1])
+    {
+      case '\0':
+        break;
+      case '+':
+        if (mode[2] == '\0')
+          {
+            mode_num |= MODE_PLUS;
+            break;
+          }
+        /* Fall through */
+      default:
+        g_warning ("Invalid GIOFileMode %s.", mode);
+        return NULL;
+    }
+
+  switch (mode_num)
+    {
+      case MODE_R:
+        flags = O_RDONLY;
+        pmode = _S_IREAD;
+        break;
+      case MODE_W:
+        flags = O_WRONLY | O_TRUNC | O_CREAT;
+        pmode = _S_IWRITE;
+        break;
+      case MODE_A:
+        flags = O_WRONLY | O_APPEND | O_CREAT;
+        pmode = _S_IWRITE;
+        break;
+      case MODE_R | MODE_PLUS:
+        flags = O_RDWR;
+        pmode = _S_IREAD | _S_IWRITE;
+        break;
+      case MODE_W | MODE_PLUS:
+        flags = O_RDWR | O_TRUNC | O_CREAT;
+        pmode = _S_IREAD | _S_IWRITE;
+        break;
+      case MODE_A | MODE_PLUS:
+        flags = O_RDWR | O_APPEND | O_CREAT;
+        pmode = _S_IREAD | _S_IWRITE;
+        break;
+      default:
+        g_assert_not_reached ();
+       abort ();
+    }
+
+  /* always open 'untranslated' */
+  fid = g_open (filename, flags | _O_BINARY, pmode);
+
+  if (g_io_win32_get_debug_flag ())
+    {
+      g_print ("g_io_channel_win32_new_file: open(\"%s\",", filename);
+      g_win32_print_access_mode (flags|_O_BINARY);
+      g_print (",%#o)=%d\n", pmode, fid);
+    }
+
+  if (fid < 0)
+    {
+      g_set_error_literal (error, G_FILE_ERROR,
+                           g_file_error_from_errno (errno),
+                           g_strerror (errno));
+      return (GIOChannel *)NULL;
+    }
+
+  channel = g_io_channel_win32_new_fd (fid);
+
+  /* XXX: move this to g_io_channel_win32_new_fd () */
+  channel->close_on_unref = TRUE;
+  channel->is_seekable = TRUE;
+
+  /* g_io_channel_win32_new_fd sets is_readable and is_writeable to
+   * correspond to actual readability/writeability. Set to FALSE those
+   * that mode doesn't allow
+   */
+  switch (mode_num)
+    {
+      case MODE_R:
+        channel->is_writeable = FALSE;
+        break;
+      case MODE_W:
+      case MODE_A:
+        channel->is_readable = FALSE;
+        break;
+      case MODE_R | MODE_PLUS:
+      case MODE_W | MODE_PLUS:
+      case MODE_A | MODE_PLUS:
+        break;
+      default:
+        g_assert_not_reached ();
+       abort ();
+    }
+
+  return channel;
+}
+
+#if !defined (_WIN64)
+
+#undef g_io_channel_new_file
+
+/* Binary compatibility version. Not for newly compiled code. */
+
+GIOChannel *
+g_io_channel_new_file (const gchar  *filename,
+                       const gchar  *mode,
+                       GError      **error)
+{
+  gchar *utf8_filename = g_locale_to_utf8 (filename, -1, NULL, NULL, error);
+  GIOChannel *retval;
+
+  if (utf8_filename == NULL)
+    return NULL;
+
+  retval = g_io_channel_new_file_utf8 (utf8_filename, mode, error);
+
+  g_free (utf8_filename);
+
+  return retval;
+}
+
+#endif
+
+static GIOStatus
+g_io_win32_unimpl_set_flags (GIOChannel *channel,
+                            GIOFlags    flags,
+                            GError    **err)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+  if (win32_channel->debug)
+    {
+      g_print ("g_io_win32_unimpl_set_flags: ");
+      g_win32_print_gioflags (flags);
+      g_print ("\n");
+    }
+
+  g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                       G_IO_CHANNEL_ERROR_FAILED,
+                       "Not implemented on Win32");
+
+  return G_IO_STATUS_ERROR;
+}
+
+static GIOFlags
+g_io_win32_fd_get_flags_internal (GIOChannel      *channel,
+                                 struct _stati64 *st)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+  gchar c;
+  DWORD count;
+
+  if (st->st_mode & _S_IFIFO)
+    {
+      channel->is_readable =
+       (PeekNamedPipe ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL, NULL) != 0) || GetLastError () == ERROR_BROKEN_PIPE;
+      channel->is_writeable =
+       (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
+      channel->is_seekable  = FALSE;
+    }
+  else
+    {
+      channel->is_readable =
+       (ReadFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
+      channel->is_writeable =
+       (WriteFile ((HANDLE) _get_osfhandle (win32_channel->fd), &c, 0, &count, NULL) != 0);
+      channel->is_seekable = TRUE;
+    }
+
+  /* XXX: G_IO_FLAG_APPEND */
+  /* XXX: G_IO_FLAG_NONBLOCK */
+
+  return 0;
+}
+
+static GIOFlags
+g_io_win32_fd_get_flags (GIOChannel *channel)
+{
+  struct _stati64 st;
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+  g_return_val_if_fail (win32_channel != NULL, 0);
+  g_return_val_if_fail (win32_channel->type == G_IO_WIN32_FILE_DESC, 0);
+
+  if (0 == _fstati64 (win32_channel->fd, &st))
+    return g_io_win32_fd_get_flags_internal (channel, &st);
+  else
+    return 0;
+}
+
+static GIOFlags
+g_io_win32_console_get_flags_internal (GIOChannel  *channel)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *) channel;
+  HANDLE handle = (HANDLE) _get_osfhandle (win32_channel->fd);
+  gchar c;
+  DWORD count;
+  INPUT_RECORD record;
+
+  channel->is_readable = PeekConsoleInput (handle, &record, 1, &count);
+  channel->is_writeable = WriteFile (handle, &c, 0, &count, NULL);
+  channel->is_seekable = FALSE;
+
+  return 0;
+}
+
+static GIOFlags
+g_io_win32_console_get_flags (GIOChannel *channel)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+  g_return_val_if_fail (win32_channel != NULL, 0);
+  g_return_val_if_fail (win32_channel->type == G_IO_WIN32_CONSOLE, 0);
+
+  return g_io_win32_console_get_flags_internal (channel);
+}
+
+static GIOFlags
+g_io_win32_msg_get_flags (GIOChannel *channel)
+{
+  return 0;
+}
+
+static GIOStatus
+g_io_win32_sock_set_flags (GIOChannel *channel,
+                          GIOFlags    flags,
+                          GError    **err)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+  u_long arg;
+
+  if (win32_channel->debug)
+    {
+      g_print ("g_io_win32_sock_set_flags: ");
+      g_win32_print_gioflags (flags);
+      g_print ("\n");
+    }
+
+  if (flags & G_IO_FLAG_NONBLOCK)
+    {
+      arg = 1;
+      if (ioctlsocket (win32_channel->fd, FIONBIO, &arg) == SOCKET_ERROR)
+       {
+         gchar *emsg = g_win32_error_message (WSAGetLastError ());
+
+         g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                              G_IO_CHANNEL_ERROR_FAILED,
+                              emsg);
+         g_free (emsg);
+
+         return G_IO_STATUS_ERROR;
+       }
+    }
+  else
+    {
+      arg = 0;
+      if (ioctlsocket (win32_channel->fd, FIONBIO, &arg) == SOCKET_ERROR)
+       {
+         gchar *emsg = g_win32_error_message (WSAGetLastError ());
+
+         g_set_error_literal (err, G_IO_CHANNEL_ERROR,
+                              G_IO_CHANNEL_ERROR_FAILED,
+                              emsg);
+         g_free (emsg);
+
+         return G_IO_STATUS_ERROR;
+       }
+    }
+
+  return G_IO_STATUS_NORMAL;
+}
+
+static GIOFlags
+g_io_win32_sock_get_flags (GIOChannel *channel)
+{
+  /* Could we do something here? */
+  return 0;
+}
+
+static GIOFuncs win32_channel_msg_funcs = {
+  g_io_win32_msg_read,
+  g_io_win32_msg_write,
+  NULL,
+  g_io_win32_msg_close,
+  g_io_win32_msg_create_watch,
+  g_io_win32_free,
+  g_io_win32_unimpl_set_flags,
+  g_io_win32_msg_get_flags,
+};
+
+static GIOFuncs win32_channel_fd_funcs = {
+  g_io_win32_fd_and_console_read,
+  g_io_win32_fd_and_console_write,
+  g_io_win32_fd_seek,
+  g_io_win32_fd_close,
+  g_io_win32_fd_create_watch,
+  g_io_win32_free,
+  g_io_win32_unimpl_set_flags,
+  g_io_win32_fd_get_flags,
+};
+
+static GIOFuncs win32_channel_console_funcs = {
+  g_io_win32_fd_and_console_read,
+  g_io_win32_fd_and_console_write,
+  NULL,
+  g_io_win32_console_close,
+  g_io_win32_console_create_watch,
+  g_io_win32_free,
+  g_io_win32_unimpl_set_flags,
+  g_io_win32_console_get_flags,
+};
+
+static GIOFuncs win32_channel_sock_funcs = {
+  g_io_win32_sock_read,
+  g_io_win32_sock_write,
+  NULL,
+  g_io_win32_sock_close,
+  g_io_win32_sock_create_watch,
+  g_io_win32_free,
+  g_io_win32_sock_set_flags,
+  g_io_win32_sock_get_flags,
+};
+
+/**
+ * g_io_channel_win32_new_messages:
+ * @hwnd: a window handle.
+ * @Returns: a new #GIOChannel.
+ *
+ * Creates a new #GIOChannel given a window handle on Windows.
+ *
+ * This function creates a #GIOChannel that can be used to poll for
+ * Windows messages for the window in question.
+ **/
+GIOChannel *
+#if GLIB_SIZEOF_VOID_P == 8
+g_io_channel_win32_new_messages (gsize hwnd)
+#else
+g_io_channel_win32_new_messages (guint hwnd)
+#endif
+{
+  GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+  GIOChannel *channel = (GIOChannel *)win32_channel;
+
+  g_io_channel_init (channel);
+  g_io_channel_win32_init (win32_channel);
+  if (win32_channel->debug)
+    g_print ("g_io_channel_win32_new_messages: channel=%p hwnd=%p\n",
+            channel, (HWND) hwnd);
+  channel->funcs = &win32_channel_msg_funcs;
+  win32_channel->type = G_IO_WIN32_WINDOWS_MESSAGES;
+  win32_channel->hwnd = (HWND) hwnd;
+
+  /* XXX: check this. */
+  channel->is_readable = IsWindow (win32_channel->hwnd);
+  channel->is_writeable = IsWindow (win32_channel->hwnd);
+
+  channel->is_seekable = FALSE;
+
+  return channel;
+}
+
+static GIOChannel *
+g_io_channel_win32_new_fd_internal (gint             fd,
+                                   struct _stati64 *st)
+{
+  GIOWin32Channel *win32_channel;
+  GIOChannel *channel;
+
+  win32_channel = g_new (GIOWin32Channel, 1);
+  channel = (GIOChannel *)win32_channel;
+
+  g_io_channel_init (channel);
+  g_io_channel_win32_init (win32_channel);
+
+  win32_channel->fd = fd;
+
+  if (win32_channel->debug)
+    g_print ("g_io_channel_win32_new_fd: channel=%p fd=%u\n",
+            channel, fd);
+
+  if (st->st_mode & _S_IFCHR) /* console */
+    {
+      channel->funcs = &win32_channel_console_funcs;
+      win32_channel->type = G_IO_WIN32_CONSOLE;
+      g_io_win32_console_get_flags_internal (channel);
+    }
+  else
+    {
+      channel->funcs = &win32_channel_fd_funcs;
+      win32_channel->type = G_IO_WIN32_FILE_DESC;
+      g_io_win32_fd_get_flags_internal (channel, st);
+    }
+  
+  return channel;
+}
+
+/**
+ * g_io_channel_win32_new_fd:
+ * @fd: a C library file descriptor.
+ * @Returns: a new #GIOChannel.
+ *
+ * Creates a new #GIOChannel given a file descriptor on Windows. This
+ * works for file descriptors from the C runtime.
+ *
+ * This function works for file descriptors as returned by the open(),
+ * creat(), pipe() and fileno() calls in the Microsoft C runtime. In
+ * order to meaningfully use this function your code should use the
+ * same C runtime as GLib uses, which is msvcrt.dll. Note that in
+ * current Microsoft compilers it is near impossible to convince it to
+ * build code that would use msvcrt.dll. The last Microsoft compiler
+ * version that supported using msvcrt.dll as the C runtime was version
+ * 6. The GNU compiler and toolchain for Windows, also known as Mingw,
+ * fully supports msvcrt.dll.
+ *
+ * If you have created a #GIOChannel for a file descriptor and started
+ * watching (polling) it, you shouldn't call read() on the file
+ * descriptor. This is because adding polling for a file descriptor is
+ * implemented in GLib on Windows by starting a thread that sits
+ * blocked in a read() from the file descriptor most of the time. All
+ * reads from the file descriptor should be done by this internal GLib
+ * thread. Your code should call only g_io_channel_read().
+ *
+ * This function is available only in GLib on Windows.
+ **/
+GIOChannel *
+g_io_channel_win32_new_fd (gint fd)
+{
+  struct _stati64 st;
+
+  if (_fstati64 (fd, &st) == -1)
+    {
+      g_warning ("g_io_channel_win32_new_fd: %d isn't an open file descriptor in the C library GLib uses.", fd);
+      return NULL;
+    }
+
+  return g_io_channel_win32_new_fd_internal (fd, &st);
+}
+
+gint
+g_io_channel_win32_get_fd (GIOChannel *channel)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+  return win32_channel->fd;
+}
+
+/**
+ * g_io_channel_win32_new_socket:
+ * @socket: a Winsock socket
+ * @Returns: a new #GIOChannel
+ *
+ * Creates a new #GIOChannel given a socket on Windows.
+ *
+ * This function works for sockets created by Winsock. It's available
+ * only in GLib on Windows.
+ *
+ * Polling a #GSource created to watch a channel for a socket puts the
+ * socket in non-blocking mode. This is a side-effect of the
+ * implementation and unavoidable.
+ **/
+GIOChannel *
+g_io_channel_win32_new_socket (int socket)
+{
+  GIOWin32Channel *win32_channel = g_new (GIOWin32Channel, 1);
+  GIOChannel *channel = (GIOChannel *)win32_channel;
+
+  g_io_channel_init (channel);
+  g_io_channel_win32_init (win32_channel);
+  if (win32_channel->debug)
+    g_print ("g_io_channel_win32_new_socket: channel=%p sock=%d\n",
+            channel, socket);
+  channel->funcs = &win32_channel_sock_funcs;
+  win32_channel->type = G_IO_WIN32_SOCKET;
+  win32_channel->fd = socket;
+
+  channel->is_readable = TRUE;
+  channel->is_writeable = TRUE;
+  channel->is_seekable = FALSE;
+
+  return channel;
+}
+
+GIOChannel *
+g_io_channel_unix_new (gint fd)
+{
+  gboolean is_fd, is_socket;
+  struct _stati64 st;
+  int optval, optlen;
+
+  is_fd = (_fstati64 (fd, &st) == 0);
+
+  optlen = sizeof (optval);
+  is_socket = (getsockopt (fd, SOL_SOCKET, SO_TYPE, (char *) &optval, &optlen) != SOCKET_ERROR);
+
+  if (is_fd && is_socket)
+    g_warning ("g_io_channel_unix_new: %d is both a file descriptor and a socket. File descriptor interpretation assumed. To avoid ambiguity, call either g_io_channel_win32_new_fd() or g_io_channel_win32_new_socket() instead.", fd);
+
+  if (is_fd)
+    return g_io_channel_win32_new_fd_internal (fd, &st);
+
+  if (is_socket)
+    return g_io_channel_win32_new_socket(fd);
+
+  g_warning ("g_io_channel_unix_new: %d is neither a file descriptor or a socket.", fd);
+
+  return NULL;
+}
+
+gint
+g_io_channel_unix_get_fd (GIOChannel *channel)
+{
+  return g_io_channel_win32_get_fd (channel);
+}
+
+void
+g_io_channel_win32_set_debug (GIOChannel *channel,
+                             gboolean    flag)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+  win32_channel->debug = flag;
+}
+
+gint
+g_io_channel_win32_poll (GPollFD *fds,
+                        gint     n_fds,
+                        gint     timeout)
+{
+  g_return_val_if_fail (n_fds >= 0, 0);
+
+  return g_poll (fds, n_fds, timeout);
+}
+
+void
+g_io_channel_win32_make_pollfd (GIOChannel   *channel,
+                               GIOCondition  condition,
+                               GPollFD      *fd)
+{
+  GIOWin32Channel *win32_channel = (GIOWin32Channel *)channel;
+
+  switch (win32_channel->type)
+    {
+    case G_IO_WIN32_FILE_DESC:
+      if (win32_channel->data_avail_event == NULL)
+       create_events (win32_channel);
+
+      fd->fd = (gintptr) win32_channel->data_avail_event;
+
+      if (win32_channel->thread_id == 0)
+       {
+         /* Is it meaningful for a file descriptor to be polled for
+          * both IN and OUT? For what kind of file descriptor would
+          * that be? Doesn't seem to make sense, in practise the file
+          * descriptors handled here are always read or write ends of
+          * pipes surely, and thus unidirectional.
+          */
+         if (condition & G_IO_IN)
+           create_thread (win32_channel, condition, read_thread);
+         else if (condition & G_IO_OUT)
+           create_thread (win32_channel, condition, write_thread);
+       }
+      break;
+
+    case G_IO_WIN32_CONSOLE:
+      fd->fd = _get_osfhandle (win32_channel->fd);
+      break;
+
+    case G_IO_WIN32_SOCKET:
+      fd->fd = (gintptr) WSACreateEvent ();
+      break;
+      
+    case G_IO_WIN32_WINDOWS_MESSAGES:
+      fd->fd = G_WIN32_MSG_HANDLE;
+      break;
+
+    default:
+      g_assert_not_reached ();
+      abort ();
+    }
+  
+  fd->events = condition;
+}
+
+#ifndef _WIN64
+
+/* Binary compatibility */
+GIOChannel *
+g_io_channel_win32_new_stream_socket (int socket)
+{
+  return g_io_channel_win32_new_socket (socket);
+}
+
+#endif
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gkeyfile.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gkeyfile.c
new file mode 100644 (file)
index 0000000..10ca2a2
--- /dev/null
@@ -0,0 +1,3930 @@
+/* gkeyfile.c - key file parser
+ *
+ *  Copyright 2004  Red Hat, Inc.  
+ *  Copyright 2009-2010  Collabora Ltd.
+ *  Copyright 2009  Nokia Corporation
+ *
+ * Written by Ray Strode <rstrode@redhat.com>
+ *            Matthias Clasen <mclasen@redhat.com>
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *   Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gkeyfile.h"
+
+#include <errno.h>
+#include <fcntl.h>
+#include <locale.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef G_OS_WIN32
+#include <io.h>
+
+#define fstat(a,b) _fstati64(a,b)
+#define stat _stati64
+
+#ifndef S_ISREG
+#define S_ISREG(mode) ((mode)&_S_IFREG)
+#endif
+
+#endif  /* G_OS_WIN23 */
+
+#include "gconvert.h"
+#include "gdataset.h"
+#include "gerror.h"
+#include "gfileutils.h"
+#include "ghash.h"
+#include "glibintl.h"
+#include "glist.h"
+#include "gslist.h"
+#include "gmem.h"
+#include "gmessages.h"
+#include "gstdio.h"
+#include "gstring.h"
+#include "gstrfuncs.h"
+#include "gutils.h"
+
+
+typedef struct _GKeyFileGroup GKeyFileGroup;
+
+struct _GKeyFile
+{
+  GList *groups;
+  GHashTable *group_hash;
+
+  GKeyFileGroup *start_group;
+  GKeyFileGroup *current_group;
+
+  GString *parse_buffer; /* Holds up to one line of not-yet-parsed data */
+
+  /* Used for sizing the output buffer during serialization
+   */
+  gsize approximate_size;
+
+  gchar list_separator;
+
+  GKeyFileFlags flags;
+
+  gchar **locales;
+};
+
+typedef struct _GKeyFileKeyValuePair GKeyFileKeyValuePair;
+
+struct _GKeyFileGroup
+{
+  const gchar *name;  /* NULL for above first group (which will be comments) */
+
+  GKeyFileKeyValuePair *comment; /* Special comment that is stuck to the top of a group */
+  gboolean has_trailing_blank_line;
+
+  GList *key_value_pairs; 
+
+  /* Used in parallel with key_value_pairs for
+   * increased lookup performance
+   */
+  GHashTable *lookup_map;
+};
+
+struct _GKeyFileKeyValuePair
+{
+  gchar *key;  /* NULL for comments */
+  gchar *value;
+};
+
+static gint                  find_file_in_data_dirs            (const gchar            *file,
+                                                               const gchar           **data_dirs,
+                                                               gchar                 **output_file,
+                                                               GError                **error);
+static gboolean              g_key_file_load_from_fd           (GKeyFile               *key_file,
+                                                               gint                    fd,
+                                                               GKeyFileFlags           flags,
+                                                               GError                **error);
+static GList                *g_key_file_lookup_group_node      (GKeyFile               *key_file,
+                                                               const gchar            *group_name);
+static GKeyFileGroup        *g_key_file_lookup_group           (GKeyFile               *key_file,
+                                                               const gchar            *group_name);
+
+static GList                *g_key_file_lookup_key_value_pair_node  (GKeyFile       *key_file,
+                                                                    GKeyFileGroup  *group,
+                                                                     const gchar    *key);
+static GKeyFileKeyValuePair *g_key_file_lookup_key_value_pair       (GKeyFile       *key_file,
+                                                                     GKeyFileGroup  *group,
+                                                                     const gchar    *key);
+
+static void                  g_key_file_remove_group_node          (GKeyFile      *key_file,
+                                                                   GList         *group_node);
+static void                  g_key_file_remove_key_value_pair_node (GKeyFile      *key_file,
+                                                                    GKeyFileGroup *group,
+                                                                    GList         *pair_node);
+
+static void                  g_key_file_add_key                (GKeyFile               *key_file,
+                                                               GKeyFileGroup          *group,
+                                                               const gchar            *key,
+                                                               const gchar            *value);
+static void                  g_key_file_add_group              (GKeyFile               *key_file,
+                                                               const gchar            *group_name);
+static gboolean              g_key_file_is_group_name          (const gchar *name);
+static gboolean              g_key_file_is_key_name            (const gchar *name);
+static void                  g_key_file_key_value_pair_free    (GKeyFileKeyValuePair   *pair);
+static gboolean              g_key_file_line_is_comment        (const gchar            *line);
+static gboolean              g_key_file_line_is_group          (const gchar            *line);
+static gboolean              g_key_file_line_is_key_value_pair (const gchar            *line);
+static gchar                *g_key_file_parse_value_as_string  (GKeyFile               *key_file,
+                                                               const gchar            *value,
+                                                               GSList                **separators,
+                                                               GError                **error);
+static gchar                *g_key_file_parse_string_as_value  (GKeyFile               *key_file,
+                                                               const gchar            *string,
+                                                               gboolean                escape_separator);
+static gint                  g_key_file_parse_value_as_integer (GKeyFile               *key_file,
+                                                               const gchar            *value,
+                                                               GError                **error);
+static gchar                *g_key_file_parse_integer_as_value (GKeyFile               *key_file,
+                                                               gint                    value);
+static gdouble               g_key_file_parse_value_as_double  (GKeyFile               *key_file,
+                                                                const gchar            *value,
+                                                                GError                **error);
+static gboolean              g_key_file_parse_value_as_boolean (GKeyFile               *key_file,
+                                                               const gchar            *value,
+                                                               GError                **error);
+static gchar                *g_key_file_parse_boolean_as_value (GKeyFile               *key_file,
+                                                               gboolean                value);
+static gchar                *g_key_file_parse_value_as_comment (GKeyFile               *key_file,
+                                                                const gchar            *value);
+static gchar                *g_key_file_parse_comment_as_value (GKeyFile               *key_file,
+                                                                const gchar            *comment);
+static void                  g_key_file_parse_key_value_pair   (GKeyFile               *key_file,
+                                                               const gchar            *line,
+                                                               gsize                   length,
+                                                               GError                **error);
+static void                  g_key_file_parse_comment          (GKeyFile               *key_file,
+                                                               const gchar            *line,
+                                                               gsize                   length,
+                                                               GError                **error);
+static void                  g_key_file_parse_group            (GKeyFile               *key_file,
+                                                               const gchar            *line,
+                                                               gsize                   length,
+                                                               GError                **error);
+static gchar                *key_get_locale                    (const gchar            *key);
+static void                  g_key_file_parse_data             (GKeyFile               *key_file,
+                                                               const gchar            *data,
+                                                               gsize                   length,
+                                                               GError                **error);
+static void                  g_key_file_flush_parse_buffer     (GKeyFile               *key_file,
+                                                               GError                **error);
+
+
+GQuark
+g_key_file_error_quark (void)
+{
+  return g_quark_from_static_string ("g-key-file-error-quark");
+}
+
+static void
+g_key_file_init (GKeyFile *key_file)
+{  
+  key_file->current_group = g_slice_new0 (GKeyFileGroup);
+  key_file->groups = g_list_prepend (NULL, key_file->current_group);
+  key_file->group_hash = g_hash_table_new (g_str_hash, g_str_equal);
+  key_file->start_group = NULL;
+  key_file->parse_buffer = g_string_sized_new (128);
+  key_file->approximate_size = 0;
+  key_file->list_separator = ';';
+  key_file->flags = 0;
+  key_file->locales = g_strdupv ((gchar **)g_get_language_names ());
+}
+
+static void
+g_key_file_clear (GKeyFile *key_file)
+{
+  GList *tmp, *group_node;
+
+  if (key_file->locales) 
+    {
+      g_strfreev (key_file->locales);
+      key_file->locales = NULL;
+    }
+
+  if (key_file->parse_buffer)
+    {
+      g_string_free (key_file->parse_buffer, TRUE);
+      key_file->parse_buffer = NULL;
+    }
+
+  tmp = key_file->groups;
+  while (tmp != NULL)
+    {
+      group_node = tmp;
+      tmp = tmp->next;
+      g_key_file_remove_group_node (key_file, group_node);
+    }
+
+  g_hash_table_destroy (key_file->group_hash);
+  key_file->group_hash = NULL;
+
+  g_warn_if_fail (key_file->groups == NULL);
+}
+
+
+/**
+ * g_key_file_new:
+ *
+ * Creates a new empty #GKeyFile object. Use
+ * g_key_file_load_from_file(), g_key_file_load_from_data(),
+ * g_key_file_load_from_dirs() or g_key_file_load_from_data_dirs() to
+ * read an existing key file.
+ *
+ * Return value: an empty #GKeyFile.
+ *
+ * Since: 2.6
+ **/
+GKeyFile *
+g_key_file_new (void)
+{
+  GKeyFile *key_file;
+
+  key_file = g_slice_new0 (GKeyFile);
+  g_key_file_init (key_file);
+
+  return key_file;
+}
+
+/**
+ * g_key_file_set_list_separator:
+ * @key_file: a #GKeyFile 
+ * @separator: the separator
+ *
+ * Sets the character which is used to separate
+ * values in lists. Typically ';' or ',' are used
+ * as separators. The default list separator is ';'.
+ *
+ * Since: 2.6
+ */
+void
+g_key_file_set_list_separator (GKeyFile *key_file,
+                              gchar     separator)
+{
+  g_return_if_fail (key_file != NULL);
+
+  key_file->list_separator = separator;
+}
+
+
+/* Iterates through all the directories in *dirs trying to
+ * open file.  When it successfully locates and opens a file it
+ * returns the file descriptor to the open file.  It also
+ * outputs the absolute path of the file in output_file.
+ */
+static gint
+find_file_in_data_dirs (const gchar   *file,
+                        const gchar  **dirs,
+                        gchar        **output_file,
+                        GError       **error)
+{
+  const gchar **data_dirs, *data_dir;
+  gchar *path;
+  gint fd;
+
+  path = NULL;
+  fd = -1;
+
+  if (dirs == NULL)
+    return fd;
+
+  data_dirs = dirs;
+
+  while (data_dirs && (data_dir = *data_dirs) && fd < 0)
+    {
+      gchar *candidate_file, *sub_dir;
+
+      candidate_file = (gchar *) file;
+      sub_dir = g_strdup ("");
+      while (candidate_file != NULL && fd < 0)
+        {
+          gchar *p;
+
+          path = g_build_filename (data_dir, sub_dir,
+                                   candidate_file, NULL);
+
+          fd = g_open (path, O_RDONLY, 0);
+
+          if (fd < 0)
+            {
+              g_free (path);
+              path = NULL;
+            }
+
+          candidate_file = strchr (candidate_file, '-');
+
+          if (candidate_file == NULL)
+            break;
+
+          candidate_file++;
+
+          g_free (sub_dir);
+          sub_dir = g_strndup (file, candidate_file - file - 1);
+
+          for (p = sub_dir; *p != '\0'; p++)
+            {
+              if (*p == '-')
+                *p = G_DIR_SEPARATOR;
+            }
+        }
+      g_free (sub_dir);
+      data_dirs++;
+    }
+
+  if (fd < 0)
+    {
+      g_set_error_literal (error, G_KEY_FILE_ERROR,
+                           G_KEY_FILE_ERROR_NOT_FOUND,
+                           _("Valid key file could not be "
+                             "found in search dirs"));
+    }
+
+  if (output_file != NULL && fd > 0)
+    *output_file = g_strdup (path);
+
+  g_free (path);
+
+  return fd;
+}
+
+static gboolean
+g_key_file_load_from_fd (GKeyFile       *key_file,
+                        gint            fd,
+                        GKeyFileFlags   flags,
+                        GError        **error)
+{
+  GError *key_file_error = NULL;
+  gssize bytes_read;
+  struct stat stat_buf;
+  gchar read_buf[4096];
+  
+  if (fstat (fd, &stat_buf) < 0)
+    {
+      g_set_error_literal (error, G_FILE_ERROR,
+                           g_file_error_from_errno (errno),
+                           g_strerror (errno));
+      return FALSE;
+    }
+
+  if (!S_ISREG (stat_buf.st_mode))
+    {
+      g_set_error_literal (error, G_KEY_FILE_ERROR,
+                           G_KEY_FILE_ERROR_PARSE,
+                           _("Not a regular file"));
+      return FALSE;
+    }
+
+  if (stat_buf.st_size == 0)
+    {
+      g_set_error_literal (error, G_KEY_FILE_ERROR,
+                           G_KEY_FILE_ERROR_PARSE,
+                           _("File is empty"));
+      return FALSE;
+    }
+
+  if (key_file->approximate_size > 0)
+    {
+      g_key_file_clear (key_file);
+      g_key_file_init (key_file);
+    }
+  key_file->flags = flags;
+
+  do
+    {
+      bytes_read = read (fd, read_buf, 4096);
+
+      if (bytes_read == 0)  /* End of File */
+        break;
+
+      if (bytes_read < 0)
+        {
+          if (errno == EINTR || errno == EAGAIN)
+            continue;
+
+          g_set_error_literal (error, G_FILE_ERROR,
+                               g_file_error_from_errno (errno),
+                               g_strerror (errno));
+          return FALSE;
+        }
+
+      g_key_file_parse_data (key_file,
+                            read_buf, bytes_read,
+                            &key_file_error);
+    }
+  while (!key_file_error);
+
+  if (key_file_error)
+    {
+      g_propagate_error (error, key_file_error);
+      return FALSE;
+    }
+
+  g_key_file_flush_parse_buffer (key_file, &key_file_error);
+
+  if (key_file_error)
+    {
+      g_propagate_error (error, key_file_error);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+/**
+ * g_key_file_load_from_file:
+ * @key_file: an empty #GKeyFile struct
+ * @file: the path of a filename to load, in the GLib filename encoding
+ * @flags: flags from #GKeyFileFlags
+ * @error: return location for a #GError, or %NULL
+ *
+ * Loads a key file into an empty #GKeyFile structure.
+ * If the file could not be loaded then %error is set to 
+ * either a #GFileError or #GKeyFileError.
+ *
+ * Return value: %TRUE if a key file could be loaded, %FALSE otherwise
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_load_from_file (GKeyFile       *key_file,
+                          const gchar    *file,
+                          GKeyFileFlags   flags,
+                          GError        **error)
+{
+  GError *key_file_error = NULL;
+  gint fd;
+
+  g_return_val_if_fail (key_file != NULL, FALSE);
+  g_return_val_if_fail (file != NULL, FALSE);
+
+  fd = g_open (file, O_RDONLY, 0);
+
+  if (fd < 0)
+    {
+      g_set_error_literal (error, G_FILE_ERROR,
+                           g_file_error_from_errno (errno),
+                           g_strerror (errno));
+      return FALSE;
+    }
+
+  g_key_file_load_from_fd (key_file, fd, flags, &key_file_error);
+  close (fd);
+
+  if (key_file_error)
+    {
+      g_propagate_error (error, key_file_error);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+/**
+ * g_key_file_load_from_data:
+ * @key_file: an empty #GKeyFile struct
+ * @data: key file loaded in memory
+ * @length: the length of @data in bytes
+ * @flags: flags from #GKeyFileFlags
+ * @error: return location for a #GError, or %NULL
+ *
+ * Loads a key file from memory into an empty #GKeyFile structure.  
+ * If the object cannot be created then %error is set to a #GKeyFileError. 
+ *
+ * Return value: %TRUE if a key file could be loaded, %FALSE otherwise
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_load_from_data (GKeyFile       *key_file,
+                          const gchar    *data,
+                          gsize           length,
+                          GKeyFileFlags   flags,
+                          GError        **error)
+{
+  GError *key_file_error = NULL;
+
+  g_return_val_if_fail (key_file != NULL, FALSE);
+  g_return_val_if_fail (data != NULL, FALSE);
+  g_return_val_if_fail (length != 0, FALSE);
+
+  if (length == (gsize)-1)
+    length = strlen (data);
+
+  if (key_file->approximate_size > 0)
+    {
+      g_key_file_clear (key_file);
+      g_key_file_init (key_file);
+    }
+  key_file->flags = flags;
+
+  g_key_file_parse_data (key_file, data, length, &key_file_error);
+  
+  if (key_file_error)
+    {
+      g_propagate_error (error, key_file_error);
+      return FALSE;
+    }
+
+  g_key_file_flush_parse_buffer (key_file, &key_file_error);
+  
+  if (key_file_error)
+    {
+      g_propagate_error (error, key_file_error);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+/**
+ * g_key_file_load_from_dirs:
+ * @key_file: an empty #GKeyFile struct
+ * @file: a relative path to a filename to open and parse
+ * @search_dirs: %NULL-terminated array of directories to search
+ * @full_path: return location for a string containing the full path
+ *   of the file, or %NULL
+ * @flags: flags from #GKeyFileFlags
+ * @error: return location for a #GError, or %NULL
+ *
+ * This function looks for a key file named @file in the paths
+ * specified in @search_dirs, loads the file into @key_file and
+ * returns the file's full path in @full_path.  If the file could not
+ * be loaded then an %error is set to either a #GFileError or
+ * #GKeyFileError.
+ *
+ * Return value: %TRUE if a key file could be loaded, %FALSE otherwise
+ *
+ * Since: 2.14
+ **/
+gboolean
+g_key_file_load_from_dirs (GKeyFile       *key_file,
+                           const gchar    *file,
+                           const gchar   **search_dirs,
+                           gchar         **full_path,
+                           GKeyFileFlags   flags,
+                           GError        **error)
+{
+  GError *key_file_error = NULL;
+  const gchar **data_dirs;
+  gchar *output_path;
+  gint fd;
+  gboolean found_file;
+
+  g_return_val_if_fail (key_file != NULL, FALSE);
+  g_return_val_if_fail (!g_path_is_absolute (file), FALSE);
+  g_return_val_if_fail (search_dirs != NULL, FALSE);
+
+  found_file = FALSE;
+  data_dirs = search_dirs;
+  output_path = NULL;
+  while (*data_dirs != NULL && !found_file)
+    {
+      g_free (output_path);
+
+      fd = find_file_in_data_dirs (file, data_dirs, &output_path,
+                                   &key_file_error);
+
+      if (fd < 0)
+        {
+          if (key_file_error)
+            g_propagate_error (error, key_file_error);
+         break;
+        }
+
+      found_file = g_key_file_load_from_fd (key_file, fd, flags,
+                                           &key_file_error);
+      close (fd);
+
+      if (key_file_error)
+        {
+         g_propagate_error (error, key_file_error);
+         break;
+        }
+    }
+
+  if (found_file && full_path)
+    *full_path = output_path;
+  else
+    g_free (output_path);
+
+  return found_file;
+}
+
+/**
+ * g_key_file_load_from_data_dirs:
+ * @key_file: an empty #GKeyFile struct
+ * @file: a relative path to a filename to open and parse
+ * @full_path: return location for a string containing the full path
+ *   of the file, or %NULL
+ * @flags: flags from #GKeyFileFlags 
+ * @error: return location for a #GError, or %NULL
+ *
+ * This function looks for a key file named @file in the paths 
+ * returned from g_get_user_data_dir() and g_get_system_data_dirs(), 
+ * loads the file into @key_file and returns the file's full path in 
+ * @full_path.  If the file could not be loaded then an %error is
+ * set to either a #GFileError or #GKeyFileError.
+ *
+ * Return value: %TRUE if a key file could be loaded, %FALSE othewise
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_load_from_data_dirs (GKeyFile       *key_file,
+                               const gchar    *file,
+                               gchar         **full_path,
+                               GKeyFileFlags   flags,
+                               GError        **error)
+{
+  gchar **all_data_dirs;
+  const gchar * user_data_dir;
+  const gchar * const * system_data_dirs;
+  gsize i, j;
+  gboolean found_file;
+
+  g_return_val_if_fail (key_file != NULL, FALSE);
+  g_return_val_if_fail (!g_path_is_absolute (file), FALSE);
+
+  user_data_dir = g_get_user_data_dir ();
+  system_data_dirs = g_get_system_data_dirs ();
+  all_data_dirs = g_new (gchar *, g_strv_length ((gchar **)system_data_dirs) + 2);
+
+  i = 0;
+  all_data_dirs[i++] = g_strdup (user_data_dir);
+
+  j = 0;
+  while (system_data_dirs[j] != NULL)
+    all_data_dirs[i++] = g_strdup (system_data_dirs[j++]);
+  all_data_dirs[i] = NULL;
+
+  found_file = g_key_file_load_from_dirs (key_file,
+                                          file,
+                                          (const gchar **)all_data_dirs,
+                                          full_path,
+                                          flags,
+                                          error);
+
+  g_strfreev (all_data_dirs);
+
+  return found_file;
+}
+
+/**
+ * g_key_file_free:
+ * @key_file: a #GKeyFile
+ *
+ * Frees a #GKeyFile.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_free (GKeyFile *key_file)
+{
+  g_return_if_fail (key_file != NULL);
+  
+  g_key_file_clear (key_file);
+  g_slice_free (GKeyFile, key_file);
+}
+
+/* If G_KEY_FILE_KEEP_TRANSLATIONS is not set, only returns
+ * true for locales that match those in g_get_language_names().
+ */
+static gboolean
+g_key_file_locale_is_interesting (GKeyFile    *key_file,
+                                 const gchar *locale)
+{
+  gsize i;
+
+  if (key_file->flags & G_KEY_FILE_KEEP_TRANSLATIONS)
+    return TRUE;
+
+  for (i = 0; key_file->locales[i] != NULL; i++)
+    {
+      if (g_ascii_strcasecmp (key_file->locales[i], locale) == 0)
+       return TRUE;
+    }
+
+  return FALSE;
+}
+
+static void
+g_key_file_parse_line (GKeyFile     *key_file,
+                      const gchar  *line,
+                      gsize         length,
+                      GError      **error)
+{
+  GError *parse_error = NULL;
+  gchar *line_start;
+
+  g_return_if_fail (key_file != NULL);
+  g_return_if_fail (line != NULL);
+
+  line_start = (gchar *) line;
+  while (g_ascii_isspace (*line_start))
+    line_start++;
+
+  if (g_key_file_line_is_comment (line_start))
+    g_key_file_parse_comment (key_file, line, length, &parse_error);
+  else if (g_key_file_line_is_group (line_start))
+    g_key_file_parse_group (key_file, line_start,
+                           length - (line_start - line),
+                           &parse_error);
+  else if (g_key_file_line_is_key_value_pair (line_start))
+    g_key_file_parse_key_value_pair (key_file, line_start,
+                                    length - (line_start - line),
+                                    &parse_error);
+  else
+    {
+      gchar *line_utf8 = _g_utf8_make_valid (line);
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_PARSE,
+                   _("Key file contains line '%s' which is not "
+                     "a key-value pair, group, or comment"), 
+                  line_utf8);
+      g_free (line_utf8);
+
+      return;
+    }
+
+  if (parse_error)
+    g_propagate_error (error, parse_error);
+}
+
+static void
+g_key_file_parse_comment (GKeyFile     *key_file,
+                         const gchar  *line,
+                         gsize         length,
+                         GError      **error)
+{
+  GKeyFileKeyValuePair *pair;
+  
+  if (!(key_file->flags & G_KEY_FILE_KEEP_COMMENTS))
+    return;
+  
+  g_warn_if_fail (key_file->current_group != NULL);
+
+  pair = g_slice_new (GKeyFileKeyValuePair);
+  pair->key = NULL;
+  pair->value = g_strndup (line, length);
+  
+  key_file->current_group->key_value_pairs =
+    g_list_prepend (key_file->current_group->key_value_pairs, pair);
+
+  if (length == 0 || line[0] != '#')
+    key_file->current_group->has_trailing_blank_line = TRUE;
+}
+
+static void
+g_key_file_parse_group (GKeyFile     *key_file,
+                       const gchar  *line,
+                       gsize         length,
+                       GError      **error)
+{
+  gchar *group_name;
+  const gchar *group_name_start, *group_name_end;
+  
+  /* advance past opening '['
+   */
+  group_name_start = line + 1;
+  group_name_end = line + length - 1;
+  
+  while (*group_name_end != ']')
+    group_name_end--;
+
+  group_name = g_strndup (group_name_start, 
+                          group_name_end - group_name_start);
+  
+  if (!g_key_file_is_group_name (group_name))
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                  G_KEY_FILE_ERROR_PARSE,
+                  _("Invalid group name: %s"), group_name);
+      g_free (group_name);
+      return;
+    }
+
+  g_key_file_add_group (key_file, group_name);
+  g_free (group_name);
+}
+
+static void
+g_key_file_parse_key_value_pair (GKeyFile     *key_file,
+                                const gchar  *line,
+                                gsize         length,
+                                GError      **error)
+{
+  gchar *key, *value, *key_end, *value_start, *locale;
+  gsize key_len, value_len;
+
+  if (key_file->current_group == NULL || key_file->current_group->name == NULL)
+    {
+      g_set_error_literal (error, G_KEY_FILE_ERROR,
+                           G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+                           _("Key file does not start with a group"));
+      return;
+    }
+
+  key_end = value_start = strchr (line, '=');
+
+  g_warn_if_fail (key_end != NULL);
+
+  key_end--;
+  value_start++;
+
+  /* Pull the key name from the line (chomping trailing whitespace)
+   */
+  while (g_ascii_isspace (*key_end))
+    key_end--;
+
+  key_len = key_end - line + 2;
+
+  g_warn_if_fail (key_len <= length);
+
+  key = g_strndup (line, key_len - 1);
+
+  if (!g_key_file_is_key_name (key))
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_PARSE,
+                   _("Invalid key name: %s"), key);
+      g_free (key);
+      return; 
+    }
+
+  /* Pull the value from the line (chugging leading whitespace)
+   */
+  while (g_ascii_isspace (*value_start))
+    value_start++;
+
+  value_len = line + length - value_start + 1;
+
+  value = g_strndup (value_start, value_len);
+
+  g_warn_if_fail (key_file->start_group != NULL);
+
+  if (key_file->current_group
+      && key_file->current_group->name
+      && strcmp (key_file->start_group->name,
+                 key_file->current_group->name) == 0
+      && strcmp (key, "Encoding") == 0)
+    {
+      if (g_ascii_strcasecmp (value, "UTF-8") != 0)
+        {
+         gchar *value_utf8 = _g_utf8_make_valid (value);
+          g_set_error (error, G_KEY_FILE_ERROR,
+                       G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
+                       _("Key file contains unsupported "
+                        "encoding '%s'"), value_utf8);
+         g_free (value_utf8);
+
+          g_free (key);
+          g_free (value);
+          return;
+        }
+    }
+
+  /* Is this key a translation? If so, is it one that we care about?
+   */
+  locale = key_get_locale (key);
+
+  if (locale == NULL || g_key_file_locale_is_interesting (key_file, locale))
+    g_key_file_add_key (key_file, key_file->current_group, key, value);
+
+  g_free (locale);
+  g_free (key);
+  g_free (value);
+}
+
+static gchar *
+key_get_locale (const gchar *key)
+{
+  gchar *locale;
+
+  locale = g_strrstr (key, "[");
+
+  if (locale && strlen (locale) <= 2)
+    locale = NULL;
+
+  if (locale)
+    locale = g_strndup (locale + 1, strlen (locale) - 2);
+
+  return locale;
+}
+
+static void
+g_key_file_parse_data (GKeyFile     *key_file,
+                      const gchar  *data,
+                      gsize         length,
+                      GError      **error)
+{
+  GError *parse_error;
+  gsize i;
+
+  g_return_if_fail (key_file != NULL);
+  g_return_if_fail (data != NULL);
+
+  parse_error = NULL;
+
+  for (i = 0; i < length; i++)
+    {
+      if (data[i] == '\n')
+        {
+         if (i > 0 && data[i - 1] == '\r')
+           g_string_erase (key_file->parse_buffer,
+                           key_file->parse_buffer->len - 1,
+                           1);
+           
+          /* When a newline is encountered flush the parse buffer so that the
+           * line can be parsed.  Note that completely blank lines won't show
+           * up in the parse buffer, so they get parsed directly.
+           */
+          if (key_file->parse_buffer->len > 0)
+            g_key_file_flush_parse_buffer (key_file, &parse_error);
+          else
+            g_key_file_parse_comment (key_file, "", 1, &parse_error);
+
+          if (parse_error)
+            {
+              g_propagate_error (error, parse_error);
+              return;
+            }
+        }
+      else
+        g_string_append_c (key_file->parse_buffer, data[i]);
+    }
+
+  key_file->approximate_size += length;
+}
+
+static void
+g_key_file_flush_parse_buffer (GKeyFile  *key_file,
+                              GError   **error)
+{
+  GError *file_error = NULL;
+
+  g_return_if_fail (key_file != NULL);
+
+  file_error = NULL;
+
+  if (key_file->parse_buffer->len > 0)
+    {
+      g_key_file_parse_line (key_file, key_file->parse_buffer->str,
+                            key_file->parse_buffer->len,
+                            &file_error);
+      g_string_erase (key_file->parse_buffer, 0, -1);
+
+      if (file_error)
+        {
+          g_propagate_error (error, file_error);
+          return;
+        }
+    }
+}
+
+/**
+ * g_key_file_to_data:
+ * @key_file: a #GKeyFile
+ * @length: return location for the length of the 
+ *   returned string, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * This function outputs @key_file as a string.  
+ *
+ * Note that this function never reports an error,
+ * so it is safe to pass %NULL as @error.
+ *
+ * Return value: a newly allocated string holding
+ *   the contents of the #GKeyFile 
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_key_file_to_data (GKeyFile  *key_file,
+                   gsize     *length,
+                   GError   **error)
+{
+  GString *data_string;
+  GList *group_node, *key_file_node;
+  gboolean has_blank_line = TRUE;
+
+  g_return_val_if_fail (key_file != NULL, NULL);
+
+  data_string = g_string_sized_new (2 * key_file->approximate_size);
+  
+  for (group_node = g_list_last (key_file->groups);
+       group_node != NULL;
+       group_node = group_node->prev)
+    {
+      GKeyFileGroup *group;
+
+      group = (GKeyFileGroup *) group_node->data;
+
+      /* separate groups by at least an empty line */
+      if (!has_blank_line)
+       g_string_append_c (data_string, '\n');
+      has_blank_line = group->has_trailing_blank_line;
+
+      if (group->comment != NULL)
+        g_string_append_printf (data_string, "%s\n", group->comment->value);
+
+      if (group->name != NULL)
+        g_string_append_printf (data_string, "[%s]\n", group->name);
+
+      for (key_file_node = g_list_last (group->key_value_pairs);
+           key_file_node != NULL;
+           key_file_node = key_file_node->prev)
+        {
+          GKeyFileKeyValuePair *pair;
+
+          pair = (GKeyFileKeyValuePair *) key_file_node->data;
+
+          if (pair->key != NULL)
+            g_string_append_printf (data_string, "%s=%s\n", pair->key, pair->value);
+          else
+            g_string_append_printf (data_string, "%s\n", pair->value);
+        }
+    }
+
+  if (length)
+    *length = data_string->len;
+
+  return g_string_free (data_string, FALSE);
+}
+
+/**
+ * g_key_file_get_keys:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @length: return location for the number of keys returned, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns all keys for the group name @group_name.  The array of
+ * returned keys will be %NULL-terminated, so @length may
+ * optionally be %NULL. In the event that the @group_name cannot
+ * be found, %NULL is returned and @error is set to
+ * #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
+ *
+ * Return value: a newly-allocated %NULL-terminated array of strings. 
+ *     Use g_strfreev() to free it.
+ *
+ * Since: 2.6
+ **/
+gchar **
+g_key_file_get_keys (GKeyFile     *key_file,
+                    const gchar  *group_name,
+                    gsize        *length,
+                    GError      **error)
+{
+  GKeyFileGroup *group;
+  GList *tmp;
+  gchar **keys;
+  gsize i, num_keys;
+  
+  g_return_val_if_fail (key_file != NULL, NULL);
+  g_return_val_if_fail (group_name != NULL, NULL);
+  
+  group = g_key_file_lookup_group (key_file, group_name);
+  
+  if (!group)
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+                   _("Key file does not have group '%s'"),
+                   group_name ? group_name : "(null)");
+      return NULL;
+    }
+
+  num_keys = 0;
+  for (tmp = group->key_value_pairs; tmp; tmp = tmp->next)
+    {
+      GKeyFileKeyValuePair *pair;
+
+      pair = (GKeyFileKeyValuePair *) tmp->data;
+
+      if (pair->key)
+       num_keys++;
+    }
+  
+  keys = g_new (gchar *, num_keys + 1);
+
+  i = num_keys - 1;
+  for (tmp = group->key_value_pairs; tmp; tmp = tmp->next)
+    {
+      GKeyFileKeyValuePair *pair;
+
+      pair = (GKeyFileKeyValuePair *) tmp->data;
+
+      if (pair->key)
+       {
+         keys[i] = g_strdup (pair->key);
+         i--;
+       }
+    }
+
+  keys[num_keys] = NULL;
+
+  if (length)
+    *length = num_keys;
+
+  return keys;
+}
+
+/**
+ * g_key_file_get_start_group:
+ * @key_file: a #GKeyFile
+ *
+ * Returns the name of the start group of the file. 
+ *
+ * Return value: The start group of the key file.
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_key_file_get_start_group (GKeyFile *key_file)
+{
+  g_return_val_if_fail (key_file != NULL, NULL);
+
+  if (key_file->start_group)
+    return g_strdup (key_file->start_group->name);
+
+  return NULL;
+}
+
+/**
+ * g_key_file_get_groups:
+ * @key_file: a #GKeyFile
+ * @length: return location for the number of returned groups, or %NULL
+ *
+ * Returns all groups in the key file loaded with @key_file.  
+ * The array of returned groups will be %NULL-terminated, so 
+ * @length may optionally be %NULL.
+ *
+ * Return value: a newly-allocated %NULL-terminated array of strings. 
+ *   Use g_strfreev() to free it.
+ * Since: 2.6
+ **/
+gchar **
+g_key_file_get_groups (GKeyFile *key_file,
+                      gsize    *length)
+{
+  GList *group_node;
+  gchar **groups;
+  gsize i, num_groups;
+
+  g_return_val_if_fail (key_file != NULL, NULL);
+
+  num_groups = g_list_length (key_file->groups);
+
+  g_return_val_if_fail (num_groups > 0, NULL);
+
+  group_node = g_list_last (key_file->groups);
+  
+  g_return_val_if_fail (((GKeyFileGroup *) group_node->data)->name == NULL, NULL);
+
+  /* Only need num_groups instead of num_groups + 1
+   * because the first group of the file (last in the
+   * list) is always the comment group at the top,
+   * which we skip
+   */
+  groups = g_new (gchar *, num_groups);
+
+
+  i = 0;
+  for (group_node = group_node->prev;
+       group_node != NULL;
+       group_node = group_node->prev)
+    {
+      GKeyFileGroup *group;
+
+      group = (GKeyFileGroup *) group_node->data;
+
+      g_warn_if_fail (group->name != NULL);
+
+      groups[i++] = g_strdup (group->name);
+    }
+  groups[i] = NULL;
+
+  if (length)
+    *length = i;
+
+  return groups;
+}
+
+/**
+ * g_key_file_get_value:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns the raw value associated with @key under @group_name. 
+ * Use g_key_file_get_string() to retrieve an unescaped UTF-8 string. 
+ *
+ * In the event the key cannot be found, %NULL is returned and 
+ * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the 
+ * event that the @group_name cannot be found, %NULL is returned 
+ * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
+ *
+ *
+ * Return value: a newly allocated string or %NULL if the specified 
+ *  key cannot be found.
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_key_file_get_value (GKeyFile     *key_file,
+                     const gchar  *group_name,
+                     const gchar  *key,
+                     GError      **error)
+{
+  GKeyFileGroup *group;
+  GKeyFileKeyValuePair *pair;
+  gchar *value = NULL;
+
+  g_return_val_if_fail (key_file != NULL, NULL);
+  g_return_val_if_fail (group_name != NULL, NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+  
+  group = g_key_file_lookup_group (key_file, group_name);
+
+  if (!group)
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+                   _("Key file does not have group '%s'"),
+                   group_name ? group_name : "(null)");
+      return NULL;
+    }
+
+  pair = g_key_file_lookup_key_value_pair (key_file, group, key);
+
+  if (pair)
+    value = g_strdup (pair->value);
+  else
+    g_set_error (error, G_KEY_FILE_ERROR,
+                 G_KEY_FILE_ERROR_KEY_NOT_FOUND,
+                 _("Key file does not have key '%s'"), key);
+
+  return value;
+}
+
+/**
+ * g_key_file_set_value:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @value: a string
+ *
+ * Associates a new value with @key under @group_name.  
+ *
+ * If @key cannot be found then it is created. If @group_name cannot 
+ * be found then it is created. To set an UTF-8 string which may contain 
+ * characters that need escaping (such as newlines or spaces), use 
+ * g_key_file_set_string().
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_value (GKeyFile    *key_file,
+                     const gchar *group_name,
+                     const gchar *key,
+                     const gchar *value)
+{
+  GKeyFileGroup *group;
+  GKeyFileKeyValuePair *pair;
+
+  g_return_if_fail (key_file != NULL);
+  g_return_if_fail (g_key_file_is_group_name (group_name));
+  g_return_if_fail (g_key_file_is_key_name (key));
+  g_return_if_fail (value != NULL);
+
+  group = g_key_file_lookup_group (key_file, group_name);
+
+  if (!group)
+    {
+      g_key_file_add_group (key_file, group_name);
+      group = (GKeyFileGroup *) key_file->groups->data;
+
+      g_key_file_add_key (key_file, group, key, value);
+    }
+  else
+    {
+      pair = g_key_file_lookup_key_value_pair (key_file, group, key);
+
+      if (!pair)
+        g_key_file_add_key (key_file, group, key, value);
+      else
+        {
+          g_free (pair->value);
+          pair->value = g_strdup (value);
+        }
+    }
+}
+
+/**
+ * g_key_file_get_string:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns the string value associated with @key under @group_name.
+ * Unlike g_key_file_get_value(), this function handles escape sequences
+ * like \s.
+ *
+ * In the event the key cannot be found, %NULL is returned and 
+ * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the 
+ * event that the @group_name cannot be found, %NULL is returned 
+ * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
+ *
+ * Return value: a newly allocated string or %NULL if the specified 
+ *   key cannot be found.
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_key_file_get_string (GKeyFile     *key_file,
+                      const gchar  *group_name,
+                      const gchar  *key,
+                      GError      **error)
+{
+  gchar *value, *string_value;
+  GError *key_file_error;
+
+  g_return_val_if_fail (key_file != NULL, NULL);
+  g_return_val_if_fail (group_name != NULL, NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+
+  key_file_error = NULL;
+
+  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
+
+  if (key_file_error)
+    {
+      g_propagate_error (error, key_file_error);
+      return NULL;
+    }
+
+  if (!g_utf8_validate (value, -1, NULL))
+    {
+      gchar *value_utf8 = _g_utf8_make_valid (value);
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
+                   _("Key file contains key '%s' with value '%s' "
+                     "which is not UTF-8"), key, value_utf8);
+      g_free (value_utf8);
+      g_free (value);
+
+      return NULL;
+    }
+
+  string_value = g_key_file_parse_value_as_string (key_file, value, NULL,
+                                                  &key_file_error);
+  g_free (value);
+
+  if (key_file_error)
+    {
+      if (g_error_matches (key_file_error,
+                           G_KEY_FILE_ERROR,
+                           G_KEY_FILE_ERROR_INVALID_VALUE))
+        {
+          g_set_error (error, G_KEY_FILE_ERROR,
+                       G_KEY_FILE_ERROR_INVALID_VALUE,
+                       _("Key file contains key '%s' "
+                         "which has value that cannot be interpreted."),
+                       key);
+          g_error_free (key_file_error);
+        }
+      else
+        g_propagate_error (error, key_file_error);
+    }
+
+  return string_value;
+}
+
+/**
+ * g_key_file_set_string:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @string: a string
+ *
+ * Associates a new string value with @key under @group_name.  
+ * If @key cannot be found then it is created.  
+ * If @group_name cannot be found then it is created.
+ * Unlike g_key_file_set_value(), this function handles characters
+ * that need escaping, such as newlines.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_string (GKeyFile    *key_file,
+                      const gchar *group_name,
+                      const gchar *key,
+                      const gchar *string)
+{
+  gchar *value;
+
+  g_return_if_fail (key_file != NULL);
+  g_return_if_fail (string != NULL);
+
+  value = g_key_file_parse_string_as_value (key_file, string, FALSE);
+  g_key_file_set_value (key_file, group_name, key, value);
+  g_free (value);
+}
+
+/**
+ * g_key_file_get_string_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @length: return location for the number of returned strings, or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns the values associated with @key under @group_name.
+ *
+ * In the event the key cannot be found, %NULL is returned and
+ * @error is set to #G_KEY_FILE_ERROR_KEY_NOT_FOUND.  In the
+ * event that the @group_name cannot be found, %NULL is returned
+ * and @error is set to #G_KEY_FILE_ERROR_GROUP_NOT_FOUND.
+ *
+ * Return value: a %NULL-terminated string array or %NULL if the specified 
+ *   key cannot be found. The array should be freed with g_strfreev().
+ *
+ * Since: 2.6
+ **/
+gchar **
+g_key_file_get_string_list (GKeyFile     *key_file,
+                           const gchar  *group_name,
+                           const gchar  *key,
+                           gsize        *length,
+                           GError      **error)
+{
+  GError *key_file_error = NULL;
+  gchar *value, *string_value, **values;
+  gint i, len;
+  GSList *p, *pieces = NULL;
+
+  g_return_val_if_fail (key_file != NULL, NULL);
+  g_return_val_if_fail (group_name != NULL, NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+
+  if (length)
+    *length = 0;
+
+  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
+
+  if (key_file_error)
+    {
+      g_propagate_error (error, key_file_error);
+      return NULL;
+    }
+
+  if (!g_utf8_validate (value, -1, NULL))
+    {
+      gchar *value_utf8 = _g_utf8_make_valid (value);
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
+                   _("Key file contains key '%s' with value '%s' "
+                     "which is not UTF-8"), key, value_utf8);
+      g_free (value_utf8);
+      g_free (value);
+
+      return NULL;
+    }
+
+  string_value = g_key_file_parse_value_as_string (key_file, value, &pieces, &key_file_error);
+  g_free (value);
+  g_free (string_value);
+
+  if (key_file_error)
+    {
+      if (g_error_matches (key_file_error,
+                           G_KEY_FILE_ERROR,
+                           G_KEY_FILE_ERROR_INVALID_VALUE))
+        {
+          g_set_error (error, G_KEY_FILE_ERROR,
+                       G_KEY_FILE_ERROR_INVALID_VALUE,
+                       _("Key file contains key '%s' "
+                         "which has a value that cannot be interpreted."),
+                       key);
+          g_error_free (key_file_error);
+        }
+      else
+        g_propagate_error (error, key_file_error);
+
+      return NULL;
+    }
+
+  len = g_slist_length (pieces);
+  values = g_new (gchar *, len + 1);
+  for (p = pieces, i = 0; p; p = p->next)
+    values[i++] = p->data;
+  values[len] = NULL;
+
+  g_slist_free (pieces);
+
+  if (length)
+    *length = len;
+
+  return values;
+}
+
+/**
+ * g_key_file_set_string_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @list: an array of string values
+ * @length: number of string values in @list
+ *
+ * Associates a list of string values for @key under @group_name.
+ * If @key cannot be found then it is created.
+ * If @group_name cannot be found then it is created.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_string_list (GKeyFile            *key_file,
+                           const gchar         *group_name,
+                           const gchar         *key,
+                           const gchar * const  list[],
+                           gsize                length)
+{
+  GString *value_list;
+  gsize i;
+
+  g_return_if_fail (key_file != NULL);
+  g_return_if_fail (list != NULL || length == 0);
+
+  value_list = g_string_sized_new (length * 128);
+  for (i = 0; i < length && list[i] != NULL; i++)
+    {
+      gchar *value;
+
+      value = g_key_file_parse_string_as_value (key_file, list[i], TRUE);
+      g_string_append (value_list, value);
+      g_string_append_c (value_list, key_file->list_separator);
+
+      g_free (value);
+    }
+
+  g_key_file_set_value (key_file, group_name, key, value_list->str);
+  g_string_free (value_list, TRUE);
+}
+
+/**
+ * g_key_file_set_locale_string:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @locale: a locale identifier
+ * @string: a string
+ *
+ * Associates a string value for @key and @locale under @group_name.
+ * If the translation for @key cannot be found then it is created.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_locale_string (GKeyFile     *key_file,
+                             const gchar  *group_name,
+                             const gchar  *key,
+                             const gchar  *locale,
+                             const gchar  *string)
+{
+  gchar *full_key, *value;
+
+  g_return_if_fail (key_file != NULL);
+  g_return_if_fail (key != NULL);
+  g_return_if_fail (locale != NULL);
+  g_return_if_fail (string != NULL);
+
+  value = g_key_file_parse_string_as_value (key_file, string, FALSE);
+  full_key = g_strdup_printf ("%s[%s]", key, locale);
+  g_key_file_set_value (key_file, group_name, full_key, value);
+  g_free (full_key);
+  g_free (value);
+}
+
+extern GSList *_g_compute_locale_variants (const gchar *locale);
+
+/**
+ * g_key_file_get_locale_string:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @locale: a locale identifier or %NULL
+ * @error: return location for a #GError, or %NULL
+ *
+ * Returns the value associated with @key under @group_name
+ * translated in the given @locale if available.  If @locale is
+ * %NULL then the current locale is assumed. 
+ *
+ * If @key cannot be found then %NULL is returned and @error is set 
+ * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the value associated
+ * with @key cannot be interpreted or no suitable translation can
+ * be found then the untranslated value is returned.
+ *
+ * Return value: a newly allocated string or %NULL if the specified 
+ *   key cannot be found.
+ *
+ * Since: 2.6
+ **/
+gchar *
+g_key_file_get_locale_string (GKeyFile     *key_file,
+                             const gchar  *group_name,
+                             const gchar  *key,
+                             const gchar  *locale,
+                             GError      **error)
+{
+  gchar *candidate_key, *translated_value;
+  GError *key_file_error;
+  gchar **languages;
+  gboolean free_languages = FALSE;
+  gint i;
+
+  g_return_val_if_fail (key_file != NULL, NULL);
+  g_return_val_if_fail (group_name != NULL, NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+
+  candidate_key = NULL;
+  translated_value = NULL;
+  key_file_error = NULL;
+
+  if (locale)
+    {
+      GSList *l, *list;
+
+      list = _g_compute_locale_variants (locale);
+
+      languages = g_new (gchar *, g_slist_length (list) + 1);
+      for (l = list, i = 0; l; l = l->next, i++)
+       languages[i] = l->data;
+      languages[i] = NULL;
+
+      g_slist_free (list);
+      free_languages = TRUE;
+    }
+  else
+    {
+      languages = (gchar **) g_get_language_names ();
+      free_languages = FALSE;
+    }
+  
+  for (i = 0; languages[i]; i++)
+    {
+      candidate_key = g_strdup_printf ("%s[%s]", key, languages[i]);
+      
+      translated_value = g_key_file_get_string (key_file,
+                                               group_name,
+                                               candidate_key, NULL);
+      g_free (candidate_key);
+
+      if (translated_value)
+       break;
+
+      g_free (translated_value);
+      translated_value = NULL;
+   }
+
+  /* Fallback to untranslated key
+   */
+  if (!translated_value)
+    {
+      translated_value = g_key_file_get_string (key_file, group_name, key,
+                                               &key_file_error);
+      
+      if (!translated_value)
+        g_propagate_error (error, key_file_error);
+    }
+
+  if (free_languages)
+    g_strfreev (languages);
+
+  return translated_value;
+}
+
+/** 
+ * g_key_file_get_locale_string_list: 
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @locale: a locale identifier or %NULL
+ * @length: return location for the number of returned strings or %NULL
+ * @error: return location for a #GError or %NULL
+ *
+ * Returns the values associated with @key under @group_name
+ * translated in the given @locale if available.  If @locale is
+ * %NULL then the current locale is assumed.
+
+ * If @key cannot be found then %NULL is returned and @error is set 
+ * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. If the values associated
+ * with @key cannot be interpreted or no suitable translations
+ * can be found then the untranslated values are returned. The 
+ * returned array is %NULL-terminated, so @length may optionally 
+ * be %NULL.
+ *
+ * Return value: a newly allocated %NULL-terminated string array
+ *   or %NULL if the key isn't found. The string array should be freed
+ *   with g_strfreev().
+ *
+ * Since: 2.6
+ **/
+gchar **
+g_key_file_get_locale_string_list (GKeyFile     *key_file,
+                                  const gchar  *group_name,
+                                  const gchar  *key,
+                                  const gchar  *locale,
+                                  gsize        *length,
+                                  GError      **error)
+{
+  GError *key_file_error;
+  gchar **values, *value;
+  char list_separator[2];
+  gsize len;
+
+  g_return_val_if_fail (key_file != NULL, NULL);
+  g_return_val_if_fail (group_name != NULL, NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+
+  key_file_error = NULL;
+
+  value = g_key_file_get_locale_string (key_file, group_name, 
+                                       key, locale,
+                                       &key_file_error);
+  
+  if (key_file_error)
+    g_propagate_error (error, key_file_error);
+  
+  if (!value)
+    {
+      if (length)
+        *length = 0;
+      return NULL;
+    }
+
+  len = strlen (value);
+  if (value[len - 1] == key_file->list_separator)
+    value[len - 1] = '\0';
+
+  list_separator[0] = key_file->list_separator;
+  list_separator[1] = '\0';
+  values = g_strsplit (value, list_separator, 0);
+
+  g_free (value);
+
+  if (length)
+    *length = g_strv_length (values);
+
+  return values;
+}
+
+/**
+ * g_key_file_set_locale_string_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @locale: a locale identifier
+ * @list: a %NULL-terminated array of locale string values
+ * @length: the length of @list
+ *
+ * Associates a list of string values for @key and @locale under
+ * @group_name.  If the translation for @key cannot be found then
+ * it is created. 
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_locale_string_list (GKeyFile            *key_file,
+                                  const gchar         *group_name,
+                                  const gchar         *key,
+                                  const gchar         *locale,
+                                  const gchar * const  list[],
+                                  gsize                length)
+{
+  GString *value_list;
+  gchar *full_key;
+  gsize i;
+
+  g_return_if_fail (key_file != NULL);
+  g_return_if_fail (key != NULL);
+  g_return_if_fail (locale != NULL);
+  g_return_if_fail (length != 0);
+
+  value_list = g_string_sized_new (length * 128);
+  for (i = 0; i < length && list[i] != NULL; i++)
+    {
+      gchar *value;
+      
+      value = g_key_file_parse_string_as_value (key_file, list[i], TRUE);
+      g_string_append (value_list, value);
+      g_string_append_c (value_list, key_file->list_separator);
+
+      g_free (value);
+    }
+
+  full_key = g_strdup_printf ("%s[%s]", key, locale);
+  g_key_file_set_value (key_file, group_name, full_key, value_list->str);
+  g_free (full_key);
+  g_string_free (value_list, TRUE);
+}
+
+/**
+ * g_key_file_get_boolean:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @error: return location for a #GError
+ *
+ * Returns the value associated with @key under @group_name as a
+ * boolean. 
+ *
+ * If @key cannot be found then %FALSE is returned and @error is set
+ * to #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value
+ * associated with @key cannot be interpreted as a boolean then %FALSE
+ * is returned and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the value associated with the key as a boolean, 
+ *    or %FALSE if the key was not found or could not be parsed.
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_get_boolean (GKeyFile     *key_file,
+                       const gchar  *group_name,
+                       const gchar  *key,
+                       GError      **error)
+{
+  GError *key_file_error = NULL;
+  gchar *value;
+  gboolean bool_value;
+
+  g_return_val_if_fail (key_file != NULL, FALSE);
+  g_return_val_if_fail (group_name != NULL, FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
+
+  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
+
+  if (!value)
+    {
+      g_propagate_error (error, key_file_error);
+      return FALSE;
+    }
+
+  bool_value = g_key_file_parse_value_as_boolean (key_file, value,
+                                                 &key_file_error);
+  g_free (value);
+
+  if (key_file_error)
+    {
+      if (g_error_matches (key_file_error,
+                           G_KEY_FILE_ERROR,
+                           G_KEY_FILE_ERROR_INVALID_VALUE))
+        {
+          g_set_error (error, G_KEY_FILE_ERROR,
+                       G_KEY_FILE_ERROR_INVALID_VALUE,
+                       _("Key file contains key '%s' "
+                         "which has value that cannot be interpreted."),
+                       key);
+          g_error_free (key_file_error);
+        }
+      else
+        g_propagate_error (error, key_file_error);
+    }
+
+  return bool_value;
+}
+
+/**
+ * g_key_file_set_boolean:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @value: %TRUE or %FALSE
+ *
+ * Associates a new boolean value with @key under @group_name.
+ * If @key cannot be found then it is created. 
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_boolean (GKeyFile    *key_file,
+                       const gchar *group_name,
+                       const gchar *key,
+                       gboolean     value)
+{
+  gchar *result;
+
+  g_return_if_fail (key_file != NULL);
+
+  result = g_key_file_parse_boolean_as_value (key_file, value);
+  g_key_file_set_value (key_file, group_name, key, result);
+  g_free (result);
+}
+
+/**
+ * g_key_file_get_boolean_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @length: the number of booleans returned
+ * @error: return location for a #GError
+ *
+ * Returns the values associated with @key under @group_name as
+ * booleans. 
+ *
+ * If @key cannot be found then %NULL is returned and @error is set to
+ * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated
+ * with @key cannot be interpreted as booleans then %NULL is returned
+ * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the values associated with the key as a list of
+ *    booleans, or %NULL if the key was not found or could not be parsed.
+ * 
+ * Since: 2.6
+ **/
+gboolean *
+g_key_file_get_boolean_list (GKeyFile     *key_file,
+                            const gchar  *group_name,
+                            const gchar  *key,
+                            gsize        *length,
+                            GError      **error)
+{
+  GError *key_file_error;
+  gchar **values;
+  gboolean *bool_values;
+  gsize i, num_bools;
+
+  g_return_val_if_fail (key_file != NULL, NULL);
+  g_return_val_if_fail (group_name != NULL, NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+
+  if (length)
+    *length = 0;
+
+  key_file_error = NULL;
+
+  values = g_key_file_get_string_list (key_file, group_name, key,
+                                      &num_bools, &key_file_error);
+
+  if (key_file_error)
+    g_propagate_error (error, key_file_error);
+
+  if (!values)
+    return NULL;
+
+  bool_values = g_new (gboolean, num_bools);
+
+  for (i = 0; i < num_bools; i++)
+    {
+      bool_values[i] = g_key_file_parse_value_as_boolean (key_file,
+                                                         values[i],
+                                                         &key_file_error);
+
+      if (key_file_error)
+        {
+          g_propagate_error (error, key_file_error);
+          g_strfreev (values);
+          g_free (bool_values);
+
+          return NULL;
+        }
+    }
+  g_strfreev (values);
+
+  if (length)
+    *length = num_bools;
+
+  return bool_values;
+}
+
+/**
+ * g_key_file_set_boolean_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @list: an array of boolean values
+ * @length: length of @list
+ *
+ * Associates a list of boolean values with @key under @group_name.  
+ * If @key cannot be found then it is created.
+ * If @group_name is %NULL, the start_group is used.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_boolean_list (GKeyFile    *key_file,
+                            const gchar *group_name,
+                            const gchar *key,
+                            gboolean     list[],
+                            gsize        length)
+{
+  GString *value_list;
+  gsize i;
+
+  g_return_if_fail (key_file != NULL);
+  g_return_if_fail (list != NULL);
+
+  value_list = g_string_sized_new (length * 8);
+  for (i = 0; i < length; i++)
+    {
+      gchar *value;
+
+      value = g_key_file_parse_boolean_as_value (key_file, list[i]);
+
+      g_string_append (value_list, value);
+      g_string_append_c (value_list, key_file->list_separator);
+
+      g_free (value);
+    }
+
+  g_key_file_set_value (key_file, group_name, key, value_list->str);
+  g_string_free (value_list, TRUE);
+}
+
+/**
+ * g_key_file_get_integer:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @error: return location for a #GError
+ *
+ * Returns the value associated with @key under @group_name as an
+ * integer. 
+ *
+ * If @key cannot be found then 0 is returned and @error is set to
+ * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated
+ * with @key cannot be interpreted as an integer then 0 is returned
+ * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the value associated with the key as an integer, or
+ *     0 if the key was not found or could not be parsed.
+ *
+ * Since: 2.6
+ **/
+gint
+g_key_file_get_integer (GKeyFile     *key_file,
+                       const gchar  *group_name,
+                       const gchar  *key,
+                       GError      **error)
+{
+  GError *key_file_error;
+  gchar *value;
+  gint int_value;
+
+  g_return_val_if_fail (key_file != NULL, -1);
+  g_return_val_if_fail (group_name != NULL, -1);
+  g_return_val_if_fail (key != NULL, -1);
+
+  key_file_error = NULL;
+
+  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
+
+  if (key_file_error)
+    {
+      g_propagate_error (error, key_file_error);
+      return 0;
+    }
+
+  int_value = g_key_file_parse_value_as_integer (key_file, value,
+                                                &key_file_error);
+  g_free (value);
+
+  if (key_file_error)
+    {
+      if (g_error_matches (key_file_error,
+                           G_KEY_FILE_ERROR,
+                           G_KEY_FILE_ERROR_INVALID_VALUE))
+        {
+          g_set_error (error, G_KEY_FILE_ERROR,
+                       G_KEY_FILE_ERROR_INVALID_VALUE,
+                       _("Key file contains key '%s' in group '%s' "
+                         "which has value that cannot be interpreted."), key, 
+                       group_name);
+          g_error_free (key_file_error);
+        }
+      else
+        g_propagate_error (error, key_file_error);
+    }
+
+  return int_value;
+}
+
+/**
+ * g_key_file_set_integer:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @value: an integer value
+ *
+ * Associates a new integer value with @key under @group_name.
+ * If @key cannot be found then it is created.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_integer (GKeyFile    *key_file,
+                       const gchar *group_name,
+                       const gchar *key,
+                       gint         value)
+{
+  gchar *result;
+
+  g_return_if_fail (key_file != NULL);
+
+  result = g_key_file_parse_integer_as_value (key_file, value);
+  g_key_file_set_value (key_file, group_name, key, result);
+  g_free (result);
+}
+
+/**
+ * g_key_file_get_int64:
+ * @key_file: a non-%NULL #GKeyFile
+ * @group_name: a non-%NULL group name
+ * @key: a non-%NULL key
+ * @error: return location for a #GError
+ *
+ * Returns the value associated with @key under @group_name as a signed
+ * 64-bit integer. This is similar to g_key_file_get_integer() but can return
+ * 64-bit results without truncation.
+ *
+ * Returns: the value associated with the key as a signed 64-bit integer, or
+ * 0 if the key was not found or could not be parsed.
+ *
+ * Since: 2.26
+ */
+gint64
+g_key_file_get_int64 (GKeyFile     *key_file,
+                      const gchar  *group_name,
+                      const gchar  *key,
+                      GError      **error)
+{
+  gchar *s, *end;
+  gint64 v;
+
+  g_return_val_if_fail (key_file != NULL, -1);
+  g_return_val_if_fail (group_name != NULL, -1);
+  g_return_val_if_fail (key != NULL, -1);
+
+  s = g_key_file_get_value (key_file, group_name, key, error);
+
+  if (s == NULL)
+    return 0;
+
+  v = g_ascii_strtoll (s, &end, 10);
+
+  if (*s == '\0' || *end != '\0')
+    {
+      g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
+          "Key '%s' in group '%s' has value '%s' where int64 was expected",
+          key, group_name, s);
+      return 0;
+    }
+
+  g_free (s);
+  return v;
+}
+
+/**
+ * g_key_file_set_int64:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @value: an integer value
+ *
+ * Associates a new integer value with @key under @group_name.
+ * If @key cannot be found then it is created.
+ *
+ * Since: 2.26
+ **/
+void
+g_key_file_set_int64 (GKeyFile    *key_file,
+                      const gchar *group_name,
+                      const gchar *key,
+                      gint64       value)
+{
+  gchar *result;
+
+  g_return_if_fail (key_file != NULL);
+
+  result = g_strdup_printf ("%" G_GINT64_FORMAT, value);
+  g_key_file_set_value (key_file, group_name, key, result);
+  g_free (result);
+}
+
+/**
+ * g_key_file_get_uint64:
+ * @key_file: a non-%NULL #GKeyFile
+ * @group_name: a non-%NULL group name
+ * @key: a non-%NULL key
+ * @error: return location for a #GError
+ *
+ * Returns the value associated with @key under @group_name as an unsigned
+ * 64-bit integer. This is similar to g_key_file_get_integer() but can return
+ * large positive results without truncation.
+ *
+ * Returns: the value associated with the key as an unsigned 64-bit integer,
+ * or 0 if the key was not found or could not be parsed.
+ *
+ * Since: 2.26
+ */
+guint64
+g_key_file_get_uint64 (GKeyFile     *key_file,
+                       const gchar  *group_name,
+                       const gchar  *key,
+                       GError      **error)
+{
+  gchar *s, *end;
+  guint64 v;
+
+  g_return_val_if_fail (key_file != NULL, -1);
+  g_return_val_if_fail (group_name != NULL, -1);
+  g_return_val_if_fail (key != NULL, -1);
+
+  s = g_key_file_get_value (key_file, group_name, key, error);
+
+  if (s == NULL)
+    return 0;
+
+  v = g_ascii_strtoull (s, &end, 10);
+
+  if (*s == '\0' || *end != '\0')
+    {
+      g_set_error (error, G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE,
+          "Key '%s' in group '%s' has value '%s' where uint64 was expected",
+          key, group_name, s);
+      return 0;
+    }
+
+  g_free (s);
+  return v;
+}
+
+/**
+ * g_key_file_set_uint64:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @value: an integer value
+ *
+ * Associates a new integer value with @key under @group_name.
+ * If @key cannot be found then it is created.
+ *
+ * Since: 2.26
+ **/
+void
+g_key_file_set_uint64 (GKeyFile    *key_file,
+                       const gchar *group_name,
+                       const gchar *key,
+                       guint64      value)
+{
+  gchar *result;
+
+  g_return_if_fail (key_file != NULL);
+
+  result = g_strdup_printf ("%" G_GUINT64_FORMAT, value);
+  g_key_file_set_value (key_file, group_name, key, result);
+  g_free (result);
+}
+
+/**
+ * g_key_file_get_integer_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @length: the number of integers returned
+ * @error: return location for a #GError
+ *
+ * Returns the values associated with @key under @group_name as
+ * integers. 
+ *
+ * If @key cannot be found then %NULL is returned and @error is set to
+ * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated
+ * with @key cannot be interpreted as integers then %NULL is returned
+ * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the values associated with the key as a list of
+ *     integers, or %NULL if the key was not found or could not be parsed.
+ *
+ * Since: 2.6
+ **/
+gint *
+g_key_file_get_integer_list (GKeyFile     *key_file,
+                            const gchar  *group_name,
+                            const gchar  *key,
+                            gsize        *length,
+                            GError      **error)
+{
+  GError *key_file_error = NULL;
+  gchar **values;
+  gint *int_values;
+  gsize i, num_ints;
+
+  g_return_val_if_fail (key_file != NULL, NULL);
+  g_return_val_if_fail (group_name != NULL, NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+
+  if (length)
+    *length = 0;
+
+  values = g_key_file_get_string_list (key_file, group_name, key,
+                                      &num_ints, &key_file_error);
+
+  if (key_file_error)
+    g_propagate_error (error, key_file_error);
+
+  if (!values)
+    return NULL;
+
+  int_values = g_new (gint, num_ints);
+
+  for (i = 0; i < num_ints; i++)
+    {
+      int_values[i] = g_key_file_parse_value_as_integer (key_file,
+                                                        values[i],
+                                                        &key_file_error);
+
+      if (key_file_error)
+        {
+          g_propagate_error (error, key_file_error);
+          g_strfreev (values);
+          g_free (int_values);
+
+          return NULL;
+        }
+    }
+  g_strfreev (values);
+
+  if (length)
+    *length = num_ints;
+
+  return int_values;
+}
+
+/**
+ * g_key_file_set_integer_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @list: an array of integer values
+ * @length: number of integer values in @list
+ *
+ * Associates a list of integer values with @key under @group_name.  
+ * If @key cannot be found then it is created.
+ *
+ * Since: 2.6
+ **/
+void
+g_key_file_set_integer_list (GKeyFile    *key_file,
+                            const gchar *group_name,
+                            const gchar *key,
+                            gint         list[],
+                            gsize        length)
+{
+  GString *values;
+  gsize i;
+
+  g_return_if_fail (key_file != NULL);
+  g_return_if_fail (list != NULL);
+
+  values = g_string_sized_new (length * 16);
+  for (i = 0; i < length; i++)
+    {
+      gchar *value;
+
+      value = g_key_file_parse_integer_as_value (key_file, list[i]);
+
+      g_string_append (values, value);
+      g_string_append_c (values, key_file->list_separator);
+
+      g_free (value);
+    }
+
+  g_key_file_set_value (key_file, group_name, key, values->str);
+  g_string_free (values, TRUE);
+}
+
+/**
+ * g_key_file_get_double:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @error: return location for a #GError
+ *
+ * Returns the value associated with @key under @group_name as a
+ * double. If @group_name is %NULL, the start_group is used.
+ *
+ * If @key cannot be found then 0.0 is returned and @error is set to
+ * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the value associated
+ * with @key cannot be interpreted as a double then 0.0 is returned
+ * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the value associated with the key as a double, or
+ *     0.0 if the key was not found or could not be parsed.
+ *
+ * Since: 2.12
+ **/
+gdouble
+g_key_file_get_double  (GKeyFile     *key_file,
+                        const gchar  *group_name,
+                        const gchar  *key,
+                        GError      **error)
+{
+  GError *key_file_error;
+  gchar *value;
+  gdouble double_value;
+
+  g_return_val_if_fail (key_file != NULL, -1);
+  g_return_val_if_fail (group_name != NULL, -1);
+  g_return_val_if_fail (key != NULL, -1);
+
+  key_file_error = NULL;
+
+  value = g_key_file_get_value (key_file, group_name, key, &key_file_error);
+
+  if (key_file_error)
+    {
+      g_propagate_error (error, key_file_error);
+      return 0;
+    }
+
+  double_value = g_key_file_parse_value_as_double (key_file, value,
+                                                  &key_file_error);
+  g_free (value);
+
+  if (key_file_error)
+    {
+      if (g_error_matches (key_file_error,
+                           G_KEY_FILE_ERROR,
+                           G_KEY_FILE_ERROR_INVALID_VALUE))
+        {
+          g_set_error (error, G_KEY_FILE_ERROR,
+                       G_KEY_FILE_ERROR_INVALID_VALUE,
+                       _("Key file contains key '%s' in group '%s' "
+                         "which has value that cannot be interpreted."), key,
+                       group_name);
+          g_error_free (key_file_error);
+        }
+      else
+        g_propagate_error (error, key_file_error);
+    }
+
+  return double_value;
+}
+
+/**
+ * g_key_file_set_double:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @value: an double value
+ *
+ * Associates a new double value with @key under @group_name.
+ * If @key cannot be found then it is created. 
+ *
+ * Since: 2.12
+ **/
+void
+g_key_file_set_double  (GKeyFile    *key_file,
+                        const gchar *group_name,
+                        const gchar *key,
+                        gdouble      value)
+{
+  gchar result[G_ASCII_DTOSTR_BUF_SIZE];
+
+  g_return_if_fail (key_file != NULL);
+
+  g_ascii_dtostr (result, sizeof (result), value);
+  g_key_file_set_value (key_file, group_name, key, result);
+}
+
+/**
+ * g_key_file_get_double_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @length: the number of doubles returned
+ * @error: return location for a #GError
+ *
+ * Returns the values associated with @key under @group_name as
+ * doubles. 
+ *
+ * If @key cannot be found then %NULL is returned and @error is set to
+ * #G_KEY_FILE_ERROR_KEY_NOT_FOUND. Likewise, if the values associated
+ * with @key cannot be interpreted as doubles then %NULL is returned
+ * and @error is set to #G_KEY_FILE_ERROR_INVALID_VALUE.
+ *
+ * Return value: the values associated with the key as a list of
+ *     doubles, or %NULL if the key was not found or could not be parsed.
+ *
+ * Since: 2.12
+ **/
+gdouble *
+g_key_file_get_double_list  (GKeyFile     *key_file,
+                             const gchar  *group_name,
+                             const gchar  *key,
+                             gsize        *length,
+                             GError      **error)
+{
+  GError *key_file_error = NULL;
+  gchar **values;
+  gdouble *double_values;
+  gsize i, num_doubles;
+
+  g_return_val_if_fail (key_file != NULL, NULL);
+  g_return_val_if_fail (group_name != NULL, NULL);
+  g_return_val_if_fail (key != NULL, NULL);
+
+  if (length)
+    *length = 0;
+
+  values = g_key_file_get_string_list (key_file, group_name, key,
+                                       &num_doubles, &key_file_error);
+
+  if (key_file_error)
+    g_propagate_error (error, key_file_error);
+
+  if (!values)
+    return NULL;
+
+  double_values = g_new (gdouble, num_doubles);
+
+  for (i = 0; i < num_doubles; i++)
+    {
+      double_values[i] = g_key_file_parse_value_as_double (key_file,
+                                                          values[i],
+                                                          &key_file_error);
+
+      if (key_file_error)
+        {
+          g_propagate_error (error, key_file_error);
+          g_strfreev (values);
+          g_free (double_values);
+
+          return NULL;
+        }
+    }
+  g_strfreev (values);
+
+  if (length)
+    *length = num_doubles;
+
+  return double_values;
+}
+
+/**
+ * g_key_file_set_double_list:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key
+ * @list: an array of double values
+ * @length: number of double values in @list
+ *
+ * Associates a list of double values with @key under
+ * @group_name.  If @key cannot be found then it is created.
+ *
+ * Since: 2.12
+ **/
+void
+g_key_file_set_double_list (GKeyFile    *key_file,
+                           const gchar *group_name,
+                           const gchar *key,
+                           gdouble      list[],
+                           gsize        length)
+{
+  GString *values;
+  gsize i;
+
+  g_return_if_fail (key_file != NULL);
+  g_return_if_fail (list != NULL);
+
+  values = g_string_sized_new (length * 16);
+  for (i = 0; i < length; i++)
+    {
+      gchar result[G_ASCII_DTOSTR_BUF_SIZE];
+
+      g_ascii_dtostr( result, sizeof (result), list[i] );
+
+      g_string_append (values, result);
+      g_string_append_c (values, key_file->list_separator);
+    }
+
+  g_key_file_set_value (key_file, group_name, key, values->str);
+  g_string_free (values, TRUE);
+}
+
+static gboolean
+g_key_file_set_key_comment (GKeyFile     *key_file,
+                            const gchar  *group_name,
+                            const gchar  *key,
+                            const gchar  *comment,
+                            GError      **error)
+{
+  GKeyFileGroup *group;
+  GKeyFileKeyValuePair *pair;
+  GList *key_node, *comment_node, *tmp;
+  
+  group = g_key_file_lookup_group (key_file, group_name);
+  if (!group)
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+                   _("Key file does not have group '%s'"),
+                   group_name ? group_name : "(null)");
+
+      return FALSE;
+    }
+
+  /* First find the key the comments are supposed to be
+   * associated with
+   */
+  key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key);
+
+  if (key_node == NULL)
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_KEY_NOT_FOUND,
+                   _("Key file does not have key '%s' in group '%s'"),
+                   key, group->name);
+      return FALSE;
+    }
+
+  /* Then find all the comments already associated with the
+   * key and free them
+   */
+  tmp = key_node->next;
+  while (tmp != NULL)
+    {
+      pair = (GKeyFileKeyValuePair *) tmp->data;
+
+      if (pair->key != NULL)
+        break;
+
+      comment_node = tmp;
+      tmp = tmp->next;
+      g_key_file_remove_key_value_pair_node (key_file, group,
+                                             comment_node); 
+    }
+
+  if (comment == NULL)
+    return TRUE;
+
+  /* Now we can add our new comment
+   */
+  pair = g_slice_new (GKeyFileKeyValuePair);
+  pair->key = NULL;
+  pair->value = g_key_file_parse_comment_as_value (key_file, comment);
+  
+  key_node = g_list_insert (key_node, pair, 1);
+
+  return TRUE;
+}
+
+static gboolean
+g_key_file_set_group_comment (GKeyFile     *key_file,
+                              const gchar  *group_name,
+                              const gchar  *comment,
+                              GError      **error)
+{
+  GKeyFileGroup *group;
+  
+  g_return_val_if_fail (g_key_file_is_group_name (group_name), FALSE);
+
+  group = g_key_file_lookup_group (key_file, group_name);
+  if (!group)
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+                   _("Key file does not have group '%s'"),
+                   group_name ? group_name : "(null)");
+
+      return FALSE;
+    }
+
+  /* First remove any existing comment
+   */
+  if (group->comment)
+    {
+      g_key_file_key_value_pair_free (group->comment);
+      group->comment = NULL;
+    }
+
+  if (comment == NULL)
+    return TRUE;
+
+  /* Now we can add our new comment
+   */
+  group->comment = g_slice_new (GKeyFileKeyValuePair);
+  group->comment->key = NULL;
+  group->comment->value = g_key_file_parse_comment_as_value (key_file, comment);
+
+  return TRUE;
+}
+
+static gboolean
+g_key_file_set_top_comment (GKeyFile     *key_file,
+                            const gchar  *comment,
+                            GError      **error)
+{
+  GList *group_node;
+  GKeyFileGroup *group;
+  GKeyFileKeyValuePair *pair;
+
+  /* The last group in the list should be the top (comments only)
+   * group in the file
+   */
+  g_warn_if_fail (key_file->groups != NULL);
+  group_node = g_list_last (key_file->groups);
+  group = (GKeyFileGroup *) group_node->data;
+  g_warn_if_fail (group->name == NULL);
+
+  /* Note all keys must be comments at the top of
+   * the file, so we can just free it all.
+   */
+  if (group->key_value_pairs != NULL)
+    {
+      g_list_foreach (group->key_value_pairs, 
+                      (GFunc) g_key_file_key_value_pair_free, 
+                      NULL);
+      g_list_free (group->key_value_pairs);
+      group->key_value_pairs = NULL;
+    }
+
+  if (comment == NULL)
+     return TRUE;
+
+  pair = g_slice_new (GKeyFileKeyValuePair);
+  pair->key = NULL;
+  pair->value = g_key_file_parse_comment_as_value (key_file, comment);
+  
+  group->key_value_pairs =
+    g_list_prepend (group->key_value_pairs, pair);
+
+  return TRUE;
+}
+
+/**
+ * g_key_file_set_comment:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name, or %NULL
+ * @key: a key
+ * @comment: a comment
+ * @error: return location for a #GError
+ *
+ * Places a comment above @key from @group_name.
+ * If @key is %NULL then @comment will be written above @group_name.  
+ * If both @key and @group_name  are %NULL, then @comment will be 
+ * written above the first group in the file.
+ *
+ * Returns: %TRUE if the comment was written, %FALSE otherwise
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_set_comment (GKeyFile     *key_file,
+                        const gchar  *group_name,
+                        const gchar  *key,
+                        const gchar  *comment,
+                        GError      **error)
+{
+  g_return_val_if_fail (key_file != NULL, FALSE);
+
+  if (group_name != NULL && key != NULL) 
+    {
+      if (!g_key_file_set_key_comment (key_file, group_name, key, comment, error))
+        return FALSE;
+    } 
+  else if (group_name != NULL) 
+    {
+      if (!g_key_file_set_group_comment (key_file, group_name, comment, error))
+        return FALSE;
+    } 
+  else 
+    {
+      if (!g_key_file_set_top_comment (key_file, comment, error))
+        return FALSE;
+    }
+
+  if (comment != NULL)
+    key_file->approximate_size += strlen (comment);
+
+  return TRUE;
+}
+
+static gchar *
+g_key_file_get_key_comment (GKeyFile     *key_file,
+                            const gchar  *group_name,
+                            const gchar  *key,
+                            GError      **error)
+{
+  GKeyFileGroup *group;
+  GKeyFileKeyValuePair *pair;
+  GList *key_node, *tmp;
+  GString *string;
+  gchar *comment;
+
+  g_return_val_if_fail (g_key_file_is_group_name (group_name), NULL);
+
+  group = g_key_file_lookup_group (key_file, group_name);
+  if (!group)
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+                   _("Key file does not have group '%s'"),
+                   group_name ? group_name : "(null)");
+
+      return NULL;
+    }
+
+  /* First find the key the comments are supposed to be
+   * associated with
+   */
+  key_node = g_key_file_lookup_key_value_pair_node (key_file, group, key);
+
+  if (key_node == NULL)
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_KEY_NOT_FOUND,
+                   _("Key file does not have key '%s' in group '%s'"),
+                   key, group->name);
+      return NULL;
+    }
+
+  string = NULL;
+
+  /* Then find all the comments already associated with the
+   * key and concatentate them.
+   */
+  tmp = key_node->next;
+  if (!key_node->next)
+    return NULL;
+
+  pair = (GKeyFileKeyValuePair *) tmp->data;
+  if (pair->key != NULL)
+    return NULL;
+
+  while (tmp->next)
+    {
+      pair = (GKeyFileKeyValuePair *) tmp->next->data;
+      
+      if (pair->key != NULL)
+        break;
+
+      tmp = tmp->next;
+    }
+
+  while (tmp != key_node)
+    {
+      pair = (GKeyFileKeyValuePair *) tmp->data;
+      
+      if (string == NULL)
+       string = g_string_sized_new (512);
+      
+      comment = g_key_file_parse_value_as_comment (key_file, pair->value);
+      g_string_append (string, comment);
+      g_free (comment);
+      
+      tmp = tmp->prev;
+    }
+
+  if (string != NULL)
+    {
+      comment = string->str;
+      g_string_free (string, FALSE);
+    }
+  else
+    comment = NULL;
+
+  return comment;
+}
+
+static gchar *
+get_group_comment (GKeyFile       *key_file,
+                  GKeyFileGroup  *group,
+                  GError        **error)
+{
+  GString *string;
+  GList *tmp;
+  gchar *comment;
+
+  string = NULL;
+
+  tmp = group->key_value_pairs;
+  while (tmp)
+    {
+      GKeyFileKeyValuePair *pair;
+
+      pair = (GKeyFileKeyValuePair *) tmp->data;
+
+      if (pair->key != NULL)
+       {
+         tmp = tmp->prev;
+         break;
+       }
+
+      if (tmp->next == NULL)
+       break;
+
+      tmp = tmp->next;
+    }
+  
+  while (tmp != NULL)
+    {
+      GKeyFileKeyValuePair *pair;
+
+      pair = (GKeyFileKeyValuePair *) tmp->data;
+
+      if (string == NULL)
+        string = g_string_sized_new (512);
+
+      comment = g_key_file_parse_value_as_comment (key_file, pair->value);
+      g_string_append (string, comment);
+      g_free (comment);
+
+      tmp = tmp->prev;
+    }
+
+  if (string != NULL)
+    return g_string_free (string, FALSE);
+
+  return NULL;
+}
+
+static gchar *
+g_key_file_get_group_comment (GKeyFile     *key_file,
+                              const gchar  *group_name,
+                              GError      **error)
+{
+  GList *group_node;
+  GKeyFileGroup *group;
+  
+  group = g_key_file_lookup_group (key_file, group_name);
+  if (!group)
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+                   _("Key file does not have group '%s'"),
+                   group_name ? group_name : "(null)");
+
+      return NULL;
+    }
+
+  if (group->comment)
+    return g_strdup (group->comment->value);
+  
+  group_node = g_key_file_lookup_group_node (key_file, group_name);
+  group_node = group_node->next;
+  group = (GKeyFileGroup *)group_node->data;  
+  return get_group_comment (key_file, group, error);
+}
+
+static gchar *
+g_key_file_get_top_comment (GKeyFile  *key_file,
+                            GError   **error)
+{
+  GList *group_node;
+  GKeyFileGroup *group;
+
+  /* The last group in the list should be the top (comments only)
+   * group in the file
+   */
+  g_warn_if_fail (key_file->groups != NULL);
+  group_node = g_list_last (key_file->groups);
+  group = (GKeyFileGroup *) group_node->data;
+  g_warn_if_fail (group->name == NULL);
+
+  return get_group_comment (key_file, group, error);
+}
+
+/**
+ * g_key_file_get_comment:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name, or %NULL
+ * @key: a key
+ * @error: return location for a #GError
+ *
+ * Retrieves a comment above @key from @group_name.
+ * If @key is %NULL then @comment will be read from above 
+ * @group_name. If both @key and @group_name are %NULL, then 
+ * @comment will be read from above the first group in the file.
+ *
+ * Returns: a comment that should be freed with g_free()
+ *
+ * Since: 2.6
+ **/
+gchar * 
+g_key_file_get_comment (GKeyFile     *key_file,
+                        const gchar  *group_name,
+                        const gchar  *key,
+                        GError      **error)
+{
+  g_return_val_if_fail (key_file != NULL, NULL);
+
+  if (group_name != NULL && key != NULL)
+    return g_key_file_get_key_comment (key_file, group_name, key, error);
+  else if (group_name != NULL)
+    return g_key_file_get_group_comment (key_file, group_name, error);
+  else
+    return g_key_file_get_top_comment (key_file, error);
+}
+
+/**
+ * g_key_file_remove_comment:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name, or %NULL
+ * @key: a key
+ * @error: return location for a #GError
+ *
+ * Removes a comment above @key from @group_name.
+ * If @key is %NULL then @comment will be removed above @group_name. 
+ * If both @key and @group_name are %NULL, then @comment will
+ * be removed above the first group in the file.
+ *
+ * Returns: %TRUE if the comment was removed, %FALSE otherwise
+ *
+ * Since: 2.6
+ **/
+
+gboolean
+g_key_file_remove_comment (GKeyFile     *key_file,
+                           const gchar  *group_name,
+                           const gchar  *key,
+                           GError      **error)
+{
+  g_return_val_if_fail (key_file != NULL, FALSE);
+
+  if (group_name != NULL && key != NULL)
+    return g_key_file_set_key_comment (key_file, group_name, key, NULL, error);
+  else if (group_name != NULL)
+    return g_key_file_set_group_comment (key_file, group_name, NULL, error);
+  else
+    return g_key_file_set_top_comment (key_file, NULL, error);
+}
+
+/**
+ * g_key_file_has_group:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ *
+ * Looks whether the key file has the group @group_name.
+ *
+ * Return value: %TRUE if @group_name is a part of @key_file, %FALSE
+ * otherwise.
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_has_group (GKeyFile    *key_file,
+                     const gchar *group_name)
+{
+  g_return_val_if_fail (key_file != NULL, FALSE);
+  g_return_val_if_fail (group_name != NULL, FALSE);
+
+  return g_key_file_lookup_group (key_file, group_name) != NULL;
+}
+
+/**
+ * g_key_file_has_key:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key name
+ * @error: return location for a #GError
+ *
+ * Looks whether the key file has the key @key in the group
+ * @group_name. 
+ *
+ * Return value: %TRUE if @key is a part of @group_name, %FALSE
+ * otherwise.
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_has_key (GKeyFile     *key_file,
+                   const gchar  *group_name,
+                   const gchar  *key,
+                   GError      **error)
+{
+  GKeyFileKeyValuePair *pair;
+  GKeyFileGroup *group;
+
+  g_return_val_if_fail (key_file != NULL, FALSE);
+  g_return_val_if_fail (group_name != NULL, FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
+
+  group = g_key_file_lookup_group (key_file, group_name);
+
+  if (!group)
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+                   _("Key file does not have group '%s'"),
+                   group_name ? group_name : "(null)");
+
+      return FALSE;
+    }
+
+  pair = g_key_file_lookup_key_value_pair (key_file, group, key);
+
+  return pair != NULL;
+}
+
+static void
+g_key_file_add_group (GKeyFile    *key_file,
+                     const gchar *group_name)
+{
+  GKeyFileGroup *group;
+
+  g_return_if_fail (key_file != NULL);
+  g_return_if_fail (g_key_file_is_group_name (group_name));
+
+  group = g_key_file_lookup_group (key_file, group_name);
+  if (group != NULL)
+    {
+      key_file->current_group = group;
+      return;
+    }
+
+  group = g_slice_new0 (GKeyFileGroup);
+  group->name = g_strdup (group_name);
+  group->lookup_map = g_hash_table_new (g_str_hash, g_str_equal);
+  key_file->groups = g_list_prepend (key_file->groups, group);
+  key_file->approximate_size += strlen (group_name) + 3;
+  key_file->current_group = group;
+
+  if (key_file->start_group == NULL)
+    key_file->start_group = group;
+
+  g_hash_table_insert (key_file->group_hash, (gpointer)group->name, group);
+}
+
+static void
+g_key_file_key_value_pair_free (GKeyFileKeyValuePair *pair)
+{
+  if (pair != NULL)
+    {
+      g_free (pair->key);
+      g_free (pair->value);
+      g_slice_free (GKeyFileKeyValuePair, pair);
+    }
+}
+
+/* Be careful not to call this function on a node with data in the
+ * lookup map without removing it from the lookup map, first.
+ *
+ * Some current cases where this warning is not a concern are
+ * when:
+ *   - the node being removed is a comment node
+ *   - the entire lookup map is getting destroyed soon after
+ *     anyway.
+ */ 
+static void
+g_key_file_remove_key_value_pair_node (GKeyFile      *key_file,
+                                       GKeyFileGroup *group,
+                                      GList         *pair_node)
+{
+
+  GKeyFileKeyValuePair *pair;
+
+  pair = (GKeyFileKeyValuePair *) pair_node->data;
+
+  group->key_value_pairs = g_list_remove_link (group->key_value_pairs, pair_node);
+
+  if (pair->key != NULL)
+    key_file->approximate_size -= strlen (pair->key) + 1;
+
+  g_warn_if_fail (pair->value != NULL);
+  key_file->approximate_size -= strlen (pair->value);
+
+  g_key_file_key_value_pair_free (pair);
+
+  g_list_free_1 (pair_node);
+}
+
+static void
+g_key_file_remove_group_node (GKeyFile *key_file,
+                             GList    *group_node)
+{
+  GKeyFileGroup *group;
+  GList *tmp;
+
+  group = (GKeyFileGroup *) group_node->data;
+
+  if (group->name)
+    g_hash_table_remove (key_file->group_hash, group->name);
+
+  /* If the current group gets deleted make the current group the last
+   * added group.
+   */
+  if (key_file->current_group == group)
+    {
+      /* groups should always contain at least the top comment group,
+       * unless g_key_file_clear has been called
+       */
+      if (key_file->groups)
+        key_file->current_group = (GKeyFileGroup *) key_file->groups->data;
+      else
+        key_file->current_group = NULL;
+    }
+
+  /* If the start group gets deleted make the start group the first
+   * added group.
+   */
+  if (key_file->start_group == group)
+    {
+      tmp = g_list_last (key_file->groups);
+      while (tmp != NULL)
+       {
+         if (tmp != group_node &&
+             ((GKeyFileGroup *) tmp->data)->name != NULL)
+           break;
+
+         tmp = tmp->prev;
+       }
+
+      if (tmp)
+        key_file->start_group = (GKeyFileGroup *) tmp->data;
+      else
+        key_file->start_group = NULL;
+    }
+
+  key_file->groups = g_list_remove_link (key_file->groups, group_node);
+
+  if (group->name != NULL)
+    key_file->approximate_size -= strlen (group->name) + 3;
+
+  tmp = group->key_value_pairs;
+  while (tmp != NULL)
+    {
+      GList *pair_node;
+
+      pair_node = tmp;
+      tmp = tmp->next;
+      g_key_file_remove_key_value_pair_node (key_file, group, pair_node);
+    }
+
+  g_warn_if_fail (group->key_value_pairs == NULL);
+
+  if (group->lookup_map)
+    {
+      g_hash_table_destroy (group->lookup_map);
+      group->lookup_map = NULL;
+    }
+
+  g_free ((gchar *) group->name);
+  g_slice_free (GKeyFileGroup, group);
+  g_list_free_1 (group_node);
+}
+
+/**
+ * g_key_file_remove_group:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @error: return location for a #GError or %NULL
+ *
+ * Removes the specified group, @group_name, 
+ * from the key file. 
+ *
+ * Returns: %TRUE if the group was removed, %FALSE otherwise
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_remove_group (GKeyFile     *key_file,
+                        const gchar  *group_name,
+                        GError      **error)
+{
+  GList *group_node;
+
+  g_return_val_if_fail (key_file != NULL, FALSE);
+  g_return_val_if_fail (group_name != NULL, FALSE);
+
+  group_node = g_key_file_lookup_group_node (key_file, group_name);
+
+  if (!group_node)
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                  G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+                  _("Key file does not have group '%s'"),
+                  group_name);
+      return FALSE;
+    }
+
+  g_key_file_remove_group_node (key_file, group_node);
+
+  return TRUE;  
+}
+
+static void
+g_key_file_add_key (GKeyFile      *key_file,
+                   GKeyFileGroup *group,
+                   const gchar   *key,
+                   const gchar   *value)
+{
+  GKeyFileKeyValuePair *pair;
+
+  pair = g_slice_new (GKeyFileKeyValuePair);
+  pair->key = g_strdup (key);
+  pair->value = g_strdup (value);
+
+  g_hash_table_replace (group->lookup_map, pair->key, pair);
+  group->key_value_pairs = g_list_prepend (group->key_value_pairs, pair);
+  group->has_trailing_blank_line = FALSE;
+  key_file->approximate_size += strlen (key) + strlen (value) + 2;
+}
+
+/**
+ * g_key_file_remove_key:
+ * @key_file: a #GKeyFile
+ * @group_name: a group name
+ * @key: a key name to remove
+ * @error: return location for a #GError or %NULL
+ *
+ * Removes @key in @group_name from the key file. 
+ *
+ * Returns: %TRUE if the key was removed, %FALSE otherwise
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_key_file_remove_key (GKeyFile     *key_file,
+                      const gchar  *group_name,
+                      const gchar  *key,
+                      GError      **error)
+{
+  GKeyFileGroup *group;
+  GKeyFileKeyValuePair *pair;
+
+  g_return_val_if_fail (key_file != NULL, FALSE);
+  g_return_val_if_fail (group_name != NULL, FALSE);
+  g_return_val_if_fail (key != NULL, FALSE);
+
+  pair = NULL;
+
+  group = g_key_file_lookup_group (key_file, group_name);
+  if (!group)
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+                   _("Key file does not have group '%s'"),
+                   group_name ? group_name : "(null)");
+      return FALSE;
+    }
+
+  pair = g_key_file_lookup_key_value_pair (key_file, group, key);
+
+  if (!pair)
+    {
+      g_set_error (error, G_KEY_FILE_ERROR,
+                   G_KEY_FILE_ERROR_KEY_NOT_FOUND,
+                   _("Key file does not have key '%s' in group '%s'"),
+                  key, group->name);
+      return FALSE;
+    }
+
+  key_file->approximate_size -= strlen (pair->key) + strlen (pair->value) + 2;
+
+  group->key_value_pairs = g_list_remove (group->key_value_pairs, pair);
+  g_hash_table_remove (group->lookup_map, pair->key);  
+  g_key_file_key_value_pair_free (pair);
+
+  return TRUE;
+}
+
+static GList *
+g_key_file_lookup_group_node (GKeyFile    *key_file,
+                             const gchar *group_name)
+{
+  GKeyFileGroup *group;
+  GList *tmp;
+
+  for (tmp = key_file->groups; tmp != NULL; tmp = tmp->next)
+    {
+      group = (GKeyFileGroup *) tmp->data;
+
+      if (group && group->name && strcmp (group->name, group_name) == 0)
+        break;
+    }
+
+  return tmp;
+}
+
+static GKeyFileGroup *
+g_key_file_lookup_group (GKeyFile    *key_file,
+                        const gchar *group_name)
+{
+  return (GKeyFileGroup *)g_hash_table_lookup (key_file->group_hash, group_name);
+}
+
+static GList *
+g_key_file_lookup_key_value_pair_node (GKeyFile       *key_file,
+                                      GKeyFileGroup  *group,
+                                       const gchar    *key)
+{
+  GList *key_node;
+
+  for (key_node = group->key_value_pairs;
+       key_node != NULL;
+       key_node = key_node->next)
+    {
+      GKeyFileKeyValuePair *pair;
+
+      pair = (GKeyFileKeyValuePair *) key_node->data; 
+
+      if (pair->key && strcmp (pair->key, key) == 0)
+        break;
+    }
+
+  return key_node;
+}
+
+static GKeyFileKeyValuePair *
+g_key_file_lookup_key_value_pair (GKeyFile      *key_file,
+                                 GKeyFileGroup *group,
+                                 const gchar   *key)
+{
+  return (GKeyFileKeyValuePair *) g_hash_table_lookup (group->lookup_map, key);
+}
+
+/* Lines starting with # or consisting entirely of whitespace are merely
+ * recorded, not parsed. This function assumes all leading whitespace
+ * has been stripped.
+ */
+static gboolean
+g_key_file_line_is_comment (const gchar *line)
+{
+  return (*line == '#' || *line == '\0' || *line == '\n');
+}
+
+static gboolean 
+g_key_file_is_group_name (const gchar *name)
+{
+  gchar *p, *q;
+
+  if (name == NULL)
+    return FALSE;
+
+  p = q = (gchar *) name;
+  while (*q && *q != ']' && *q != '[' && !g_ascii_iscntrl (*q))
+    q = g_utf8_find_next_char (q, NULL);
+  
+  if (*q != '\0' || q == p)
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+g_key_file_is_key_name (const gchar *name)
+{
+  gchar *p, *q;
+
+  if (name == NULL)
+    return FALSE;
+
+  p = q = (gchar *) name;
+  /* We accept a little more than the desktop entry spec says,
+   * since gnome-vfs uses mime-types as keys in its cache.
+   */
+  while (*q && *q != '=' && *q != '[' && *q != ']')
+    q = g_utf8_find_next_char (q, NULL);
+  
+  /* No empty keys, please */
+  if (q == p)
+    return FALSE;
+
+  /* We accept spaces in the middle of keys to not break
+   * existing apps, but we don't tolerate initial or final
+   * spaces, which would lead to silent corruption when
+   * rereading the file.
+   */
+  if (*p == ' ' || q[-1] == ' ')
+    return FALSE;
+
+  if (*q == '[')
+    {
+      q++;
+      while (*q && (g_unichar_isalnum (g_utf8_get_char_validated (q, -1)) || *q == '-' || *q == '_' || *q == '.' || *q == '@'))
+        q = g_utf8_find_next_char (q, NULL);
+
+      if (*q != ']')
+        return FALSE;     
+
+      q++;
+    }
+
+  if (*q != '\0')
+    return FALSE;
+
+  return TRUE;
+}
+
+/* A group in a key file is made up of a starting '[' followed by one
+ * or more letters making up the group name followed by ']'.
+ */
+static gboolean
+g_key_file_line_is_group (const gchar *line)
+{
+  gchar *p;
+
+  p = (gchar *) line;
+  if (*p != '[')
+    return FALSE;
+
+  p++;
+
+  while (*p && *p != ']')
+    p = g_utf8_find_next_char (p, NULL);
+
+  if (*p != ']')
+    return FALSE;
+  /* silently accept whitespace after the ] */
+  p = g_utf8_find_next_char (p, NULL);
+  while (*p == ' ' || *p == '\t')
+    p = g_utf8_find_next_char (p, NULL);
+     
+  if (*p)
+    return FALSE;
+
+  return TRUE;
+}
+
+static gboolean
+g_key_file_line_is_key_value_pair (const gchar *line)
+{
+  gchar *p;
+
+  p = (gchar *) g_utf8_strchr (line, -1, '=');
+
+  if (!p)
+    return FALSE;
+
+  /* Key must be non-empty
+   */
+  if (*p == line[0])
+    return FALSE;
+
+  return TRUE;
+}
+
+static gchar *
+g_key_file_parse_value_as_string (GKeyFile     *key_file,
+                                 const gchar  *value,
+                                 GSList      **pieces,
+                                 GError      **error)
+{
+  gchar *string_value, *p, *q0, *q;
+
+  string_value = g_new (gchar, strlen (value) + 1);
+
+  p = (gchar *) value;
+  q0 = q = string_value;
+  while (*p)
+    {
+      if (*p == '\\')
+        {
+          p++;
+
+          switch (*p)
+            {
+            case 's':
+              *q = ' ';
+              break;
+
+            case 'n':
+              *q = '\n';
+              break;
+
+            case 't':
+              *q = '\t';
+              break;
+
+            case 'r':
+              *q = '\r';
+              break;
+
+            case '\\':
+              *q = '\\';
+              break;
+
+           case '\0':
+             g_set_error_literal (error, G_KEY_FILE_ERROR,
+                                   G_KEY_FILE_ERROR_INVALID_VALUE,
+                                   _("Key file contains escape character "
+                                     "at end of line"));
+             break;
+
+            default:
+             if (pieces && *p == key_file->list_separator)
+               *q = key_file->list_separator;
+             else
+               {
+                 *q++ = '\\';
+                 *q = *p;
+                 
+                 if (*error == NULL)
+                   {
+                     gchar sequence[3];
+                     
+                     sequence[0] = '\\';
+                     sequence[1] = *p;
+                     sequence[2] = '\0';
+                     
+                     g_set_error (error, G_KEY_FILE_ERROR,
+                                  G_KEY_FILE_ERROR_INVALID_VALUE,
+                                  _("Key file contains invalid escape "
+                                    "sequence '%s'"), sequence);
+                   }
+               }
+              break;
+            }
+        }
+      else
+       {
+         *q = *p;
+         if (pieces && (*p == key_file->list_separator))
+           {
+             *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0));
+             q0 = q + 1; 
+           }
+       }
+
+      if (*p == '\0')
+       break;
+
+      q++;
+      p++;
+    }
+
+  *q = '\0';
+  if (pieces)
+  {
+    if (q0 < q)
+      *pieces = g_slist_prepend (*pieces, g_strndup (q0, q - q0));
+    *pieces = g_slist_reverse (*pieces);
+  }
+
+  return string_value;
+}
+
+static gchar *
+g_key_file_parse_string_as_value (GKeyFile    *key_file,
+                                 const gchar *string,
+                                 gboolean     escape_separator)
+{
+  gchar *value, *p, *q;
+  gsize length;
+  gboolean parsing_leading_space;
+
+  length = strlen (string) + 1;
+
+  /* Worst case would be that every character needs to be escaped.
+   * In other words every character turns to two characters
+   */
+  value = g_new (gchar, 2 * length);
+
+  p = (gchar *) string;
+  q = value;
+  parsing_leading_space = TRUE;
+  while (p < (string + length - 1))
+    {
+      gchar escaped_character[3] = { '\\', 0, 0 };
+
+      switch (*p)
+        {
+        case ' ':
+          if (parsing_leading_space)
+            {
+              escaped_character[1] = 's';
+              strcpy (q, escaped_character);
+              q += 2;
+            }
+          else
+            {
+             *q = *p;
+             q++;
+            }
+          break;
+        case '\t':
+          if (parsing_leading_space)
+            {
+              escaped_character[1] = 't';
+              strcpy (q, escaped_character);
+              q += 2;
+            }
+          else
+            {
+             *q = *p;
+             q++;
+            }
+          break;
+        case '\n':
+          escaped_character[1] = 'n';
+          strcpy (q, escaped_character);
+          q += 2;
+          break;
+        case '\r':
+          escaped_character[1] = 'r';
+          strcpy (q, escaped_character);
+          q += 2;
+          break;
+        case '\\':
+          escaped_character[1] = '\\';
+          strcpy (q, escaped_character);
+          q += 2;
+          parsing_leading_space = FALSE;
+          break;
+        default:
+         if (escape_separator && *p == key_file->list_separator)
+           {
+             escaped_character[1] = key_file->list_separator;
+             strcpy (q, escaped_character);
+             q += 2;
+              parsing_leading_space = TRUE;
+           }
+         else 
+           {
+             *q = *p;
+             q++;
+              parsing_leading_space = FALSE;
+           }
+          break;
+        }
+      p++;
+    }
+  *q = '\0';
+
+  return value;
+}
+
+static gint
+g_key_file_parse_value_as_integer (GKeyFile     *key_file,
+                                  const gchar  *value,
+                                  GError      **error)
+{
+  gchar *end_of_valid_int;
+ glong long_value;
+  gint int_value;
+
+  errno = 0;
+  long_value = strtol (value, &end_of_valid_int, 10);
+
+  if (*value == '\0' || *end_of_valid_int != '\0')
+    {
+      gchar *value_utf8 = _g_utf8_make_valid (value);
+      g_set_error (error, G_KEY_FILE_ERROR,
+                  G_KEY_FILE_ERROR_INVALID_VALUE,
+                  _("Value '%s' cannot be interpreted "
+                    "as a number."), value_utf8);
+      g_free (value_utf8);
+
+      return 0;
+    }
+
+  int_value = long_value;
+  if (int_value != long_value || errno == ERANGE)
+    {
+      gchar *value_utf8 = _g_utf8_make_valid (value);
+      g_set_error (error,
+                  G_KEY_FILE_ERROR, 
+                  G_KEY_FILE_ERROR_INVALID_VALUE,
+                  _("Integer value '%s' out of range"), 
+                  value_utf8);
+      g_free (value_utf8);
+
+      return 0;
+    }
+  
+  return int_value;
+}
+
+static gchar *
+g_key_file_parse_integer_as_value (GKeyFile *key_file,
+                                  gint      value)
+
+{
+  return g_strdup_printf ("%d", value);
+}
+
+static gdouble
+g_key_file_parse_value_as_double  (GKeyFile     *key_file,
+                                   const gchar  *value,
+                                   GError      **error)
+{
+  gchar *end_of_valid_d;
+  gdouble double_value = 0;
+
+  double_value = g_ascii_strtod (value, &end_of_valid_d);
+
+  if (*end_of_valid_d != '\0' || end_of_valid_d == value)
+    {
+      gchar *value_utf8 = _g_utf8_make_valid (value);
+      g_set_error (error, G_KEY_FILE_ERROR,
+                  G_KEY_FILE_ERROR_INVALID_VALUE,
+                  _("Value '%s' cannot be interpreted "
+                    "as a float number."), 
+                  value_utf8);
+      g_free (value_utf8);
+    }
+
+  return double_value;
+}
+
+static gboolean
+g_key_file_parse_value_as_boolean (GKeyFile     *key_file,
+                                  const gchar  *value,
+                                  GError      **error)
+{
+  gchar *value_utf8;
+
+  if (strcmp (value, "true") == 0 || strcmp (value, "1") == 0)
+    return TRUE;
+  else if (strcmp (value, "false") == 0 || strcmp (value, "0") == 0)
+    return FALSE;
+
+  value_utf8 = _g_utf8_make_valid (value);
+  g_set_error (error, G_KEY_FILE_ERROR,
+               G_KEY_FILE_ERROR_INVALID_VALUE,
+               _("Value '%s' cannot be interpreted "
+                "as a boolean."), value_utf8);
+  g_free (value_utf8);
+
+  return FALSE;
+}
+
+static gchar *
+g_key_file_parse_boolean_as_value (GKeyFile *key_file,
+                                  gboolean  value)
+{
+  if (value)
+    return g_strdup ("true");
+  else
+    return g_strdup ("false");
+}
+
+static gchar *
+g_key_file_parse_value_as_comment (GKeyFile    *key_file,
+                                   const gchar *value)
+{
+  GString *string;
+  gchar **lines;
+  gsize i;
+
+  string = g_string_sized_new (512);
+
+  lines = g_strsplit (value, "\n", 0);
+
+  for (i = 0; lines[i] != NULL; i++)
+    {
+        if (lines[i][0] != '#')
+           g_string_append_printf (string, "%s\n", lines[i]);
+        else 
+           g_string_append_printf (string, "%s\n", lines[i] + 1);
+    }
+  g_strfreev (lines);
+
+  return g_string_free (string, FALSE);
+}
+
+static gchar *
+g_key_file_parse_comment_as_value (GKeyFile      *key_file,
+                                   const gchar   *comment)
+{
+  GString *string;
+  gchar **lines;
+  gsize i;
+
+  string = g_string_sized_new (512);
+
+  lines = g_strsplit (comment, "\n", 0);
+
+  for (i = 0; lines[i] != NULL; i++)
+    g_string_append_printf (string, "#%s%s", lines[i], 
+                            lines[i + 1] == NULL? "" : "\n");
+  g_strfreev (lines);
+
+  return g_string_free (string, FALSE);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gkeyfile.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gkeyfile.h
new file mode 100644 (file)
index 0000000..e16dc61
--- /dev/null
@@ -0,0 +1,266 @@
+/* gkeyfile.h - desktop entry file parser
+ *
+ *  Copyright 2004 Red Hat, Inc.
+ *
+ *  Ray Strode <halfline@hawaii.rr.com>
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *   Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_KEY_FILE_H__
+#define __G_KEY_FILE_H__
+
+#include <glib/gerror.h>
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+  G_KEY_FILE_ERROR_UNKNOWN_ENCODING,
+  G_KEY_FILE_ERROR_PARSE,
+  G_KEY_FILE_ERROR_NOT_FOUND,
+  G_KEY_FILE_ERROR_KEY_NOT_FOUND,
+  G_KEY_FILE_ERROR_GROUP_NOT_FOUND,
+  G_KEY_FILE_ERROR_INVALID_VALUE
+} GKeyFileError;
+
+#define G_KEY_FILE_ERROR g_key_file_error_quark()
+
+GQuark g_key_file_error_quark (void);
+
+typedef struct _GKeyFile GKeyFile;
+
+typedef enum
+{
+  G_KEY_FILE_NONE              = 0,
+  G_KEY_FILE_KEEP_COMMENTS     = 1 << 0,
+  G_KEY_FILE_KEEP_TRANSLATIONS = 1 << 1
+} GKeyFileFlags;
+
+GKeyFile *g_key_file_new                    (void);
+void      g_key_file_free                   (GKeyFile             *key_file);
+void      g_key_file_set_list_separator     (GKeyFile             *key_file,
+                                            gchar                 separator);
+gboolean  g_key_file_load_from_file         (GKeyFile             *key_file,
+                                            const gchar          *file,
+                                            GKeyFileFlags         flags,
+                                            GError              **error);
+gboolean  g_key_file_load_from_data         (GKeyFile             *key_file,
+                                            const gchar          *data,
+                                            gsize                 length,
+                                            GKeyFileFlags         flags,
+                                            GError              **error);
+gboolean g_key_file_load_from_dirs          (GKeyFile             *key_file,
+                                            const gchar          *file,
+                                            const gchar         **search_dirs,
+                                            gchar               **full_path,
+                                            GKeyFileFlags         flags,
+                                            GError              **error);
+gboolean g_key_file_load_from_data_dirs     (GKeyFile             *key_file,
+                                            const gchar          *file,
+                                            gchar               **full_path,
+                                            GKeyFileFlags         flags,
+                                            GError              **error);
+gchar    *g_key_file_to_data                (GKeyFile             *key_file,
+                                            gsize                *length,
+                                            GError              **error) G_GNUC_MALLOC;
+gchar    *g_key_file_get_start_group        (GKeyFile             *key_file) G_GNUC_MALLOC;
+gchar   **g_key_file_get_groups             (GKeyFile             *key_file,
+                                            gsize                *length) G_GNUC_MALLOC;
+gchar   **g_key_file_get_keys               (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            gsize                *length,
+                                            GError              **error) G_GNUC_MALLOC;
+gboolean  g_key_file_has_group              (GKeyFile             *key_file,
+                                            const gchar          *group_name);
+gboolean  g_key_file_has_key                (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            GError              **error);
+gchar    *g_key_file_get_value              (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            GError              **error) G_GNUC_MALLOC;
+void      g_key_file_set_value              (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            const gchar          *value);
+gchar    *g_key_file_get_string             (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            GError              **error) G_GNUC_MALLOC;
+void      g_key_file_set_string             (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            const gchar          *string);
+gchar    *g_key_file_get_locale_string      (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            const gchar          *locale,
+                                            GError              **error) G_GNUC_MALLOC;
+void      g_key_file_set_locale_string      (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            const gchar          *locale,
+                                            const gchar          *string);
+gboolean  g_key_file_get_boolean            (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            GError              **error);
+void      g_key_file_set_boolean            (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            gboolean              value);
+gint      g_key_file_get_integer            (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            GError              **error);
+void      g_key_file_set_integer            (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            gint                  value);
+gint64    g_key_file_get_int64              (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            GError              **error);
+void      g_key_file_set_int64              (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            gint64                value);
+guint64   g_key_file_get_uint64             (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            GError              **error);
+void      g_key_file_set_uint64             (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            guint64               value);
+gdouble   g_key_file_get_double             (GKeyFile             *key_file,
+                                             const gchar          *group_name,
+                                             const gchar          *key,
+                                             GError              **error);
+void      g_key_file_set_double             (GKeyFile             *key_file,
+                                             const gchar          *group_name,
+                                             const gchar          *key,
+                                             gdouble               value);
+gchar   **g_key_file_get_string_list        (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            gsize                *length,
+                                            GError              **error) G_GNUC_MALLOC;
+void      g_key_file_set_string_list        (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            const gchar * const   list[],
+                                            gsize                 length);
+gchar   **g_key_file_get_locale_string_list (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            const gchar          *locale,
+                                            gsize                *length,
+                                            GError              **error) G_GNUC_MALLOC;
+void      g_key_file_set_locale_string_list (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            const gchar          *locale,
+                                            const gchar * const   list[],
+                                            gsize                 length);
+gboolean *g_key_file_get_boolean_list       (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            gsize                *length,
+                                            GError              **error) G_GNUC_MALLOC;
+void      g_key_file_set_boolean_list       (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            gboolean              list[],
+                                            gsize                 length);
+gint     *g_key_file_get_integer_list       (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            gsize                *length,
+                                            GError              **error) G_GNUC_MALLOC;
+void      g_key_file_set_double_list        (GKeyFile             *key_file,
+                                             const gchar          *group_name,
+                                             const gchar          *key,
+                                             gdouble               list[],
+                                             gsize                 length);
+gdouble  *g_key_file_get_double_list        (GKeyFile             *key_file,
+                                             const gchar          *group_name,
+                                             const gchar          *key,
+                                             gsize                *length,
+                                             GError              **error) G_GNUC_MALLOC;
+void      g_key_file_set_integer_list       (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            gint                  list[],
+                                            gsize                 length);
+gboolean  g_key_file_set_comment            (GKeyFile             *key_file,
+                                             const gchar          *group_name,
+                                             const gchar          *key,
+                                             const gchar          *comment,
+                                             GError              **error);
+gchar    *g_key_file_get_comment            (GKeyFile             *key_file,
+                                             const gchar          *group_name,
+                                             const gchar          *key,
+                                             GError              **error) G_GNUC_MALLOC;
+
+gboolean  g_key_file_remove_comment         (GKeyFile             *key_file,
+                                             const gchar          *group_name,
+                                             const gchar          *key,
+                                            GError              **error);
+gboolean  g_key_file_remove_key             (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            const gchar          *key,
+                                            GError              **error);
+gboolean  g_key_file_remove_group           (GKeyFile             *key_file,
+                                            const gchar          *group_name,
+                                            GError              **error);
+
+/* Defines for handling freedesktop.org Desktop files */
+#define G_KEY_FILE_DESKTOP_GROUP                "Desktop Entry"
+
+#define G_KEY_FILE_DESKTOP_KEY_TYPE             "Type"
+#define G_KEY_FILE_DESKTOP_KEY_VERSION          "Version"
+#define G_KEY_FILE_DESKTOP_KEY_NAME             "Name"
+#define G_KEY_FILE_DESKTOP_KEY_GENERIC_NAME     "GenericName"
+#define G_KEY_FILE_DESKTOP_KEY_NO_DISPLAY       "NoDisplay"
+#define G_KEY_FILE_DESKTOP_KEY_COMMENT          "Comment"
+#define G_KEY_FILE_DESKTOP_KEY_ICON             "Icon"
+#define G_KEY_FILE_DESKTOP_KEY_HIDDEN           "Hidden"
+#define G_KEY_FILE_DESKTOP_KEY_ONLY_SHOW_IN     "OnlyShowIn"
+#define G_KEY_FILE_DESKTOP_KEY_NOT_SHOW_IN      "NotShowIn"
+#define G_KEY_FILE_DESKTOP_KEY_TRY_EXEC         "TryExec"
+#define G_KEY_FILE_DESKTOP_KEY_EXEC             "Exec"
+#define G_KEY_FILE_DESKTOP_KEY_PATH             "Path"
+#define G_KEY_FILE_DESKTOP_KEY_TERMINAL         "Terminal"
+#define G_KEY_FILE_DESKTOP_KEY_MIME_TYPE        "MimeType"
+#define G_KEY_FILE_DESKTOP_KEY_CATEGORIES       "Categories"
+#define G_KEY_FILE_DESKTOP_KEY_STARTUP_NOTIFY   "StartupNotify"
+#define G_KEY_FILE_DESKTOP_KEY_STARTUP_WM_CLASS "StartupWMClass"
+#define G_KEY_FILE_DESKTOP_KEY_URL              "URL"
+
+#define G_KEY_FILE_DESKTOP_TYPE_APPLICATION     "Application"
+#define G_KEY_FILE_DESKTOP_TYPE_LINK            "Link"
+#define G_KEY_FILE_DESKTOP_TYPE_DIRECTORY       "Directory"
+
+G_END_DECLS
+
+#endif /* __G_KEY_FILE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glib-mirroring-tab/Makefile b/resource/csdk/connectivity/lib/android/glib-master/glib/glib-mirroring-tab/Makefile
new file mode 100644 (file)
index 0000000..8ab193c
--- /dev/null
@@ -0,0 +1,11 @@
+
+CFLAGS = `pkg-config --cflags glib-2.0`
+LIBS = `pkg-config --libs glib-2.0`
+
+
+all: gen-mirroring-tab
+
+gen-mirroring-tab: gen-mirroring-tab.o packtab.o
+
+clean:
+       $(RM) gen-mirroring-tab *.o
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glib-mirroring-tab/gen-mirroring-tab.c b/resource/csdk/connectivity/lib/android/glib-master/glib/glib-mirroring-tab/gen-mirroring-tab.c
new file mode 100644 (file)
index 0000000..6b16376
--- /dev/null
@@ -0,0 +1,232 @@
+/* gen-mirroring-tab.c - generate gmirroringtable.h for glib
+ * copied from FriBidi.
+ *
+ * $Id$
+ * $Author$
+ * $Date$
+ * $Revision$
+ * $Source$
+ *
+ * Author:
+ *   Behdad Esfahbod, 2001, 2002, 2004
+ *
+ * Copyright (C) 2004 Sharif FarsiWeb, Inc
+ * Copyright (C) 2001,2002,2004 Behdad Esfahbod
+ * 
+ * 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, in a file named COPYING; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA
+ * 
+ * For licensing issues, contact <license@farsiweb.info>.
+ */
+
+#include <glib.h>
+
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "packtab.h"
+
+#define appname "gen-mirroring-tab"
+#define outputname "gmirroringtable.h"
+
+static void
+die (
+  const char *msg
+)
+{
+  fprintf (stderr, appname ": %s\n", msg);
+  exit (1);
+}
+
+static void
+die2 (
+  const char *fmt,
+  const char *p
+)
+{
+  fprintf (stderr, appname ": ");
+  fprintf (stderr, fmt, p);
+  fprintf (stderr, "\n");
+  exit (1);
+}
+
+static void
+die4 (
+  const char *fmt,
+  unsigned long l,
+  unsigned long p,
+  unsigned long q
+)
+{
+  fprintf (stderr, appname ": ");
+  fprintf (stderr, fmt, l, p, q);
+  fprintf (stderr, "\n");
+  exit (1);
+}
+
+#define table_name "Mir"
+#define macro_name "GLIB_GET_MIRRORING"
+
+#define UNICODE_CHARS 0x110000
+
+static signed int table[UNICODE_CHARS];
+static char buf[4000];
+static signed long max_dist;
+
+static void
+init (
+  void
+)
+{
+  max_dist = 0;
+}
+
+static void
+clear_tab (
+  void
+)
+{
+  register gunichar c;
+
+  for (c = 0; c < UNICODE_CHARS; c++)
+    table[c] = 0;
+}
+
+static void
+init_tab_mirroring_txt (
+  void
+)
+{
+  clear_tab ();
+}
+
+static void
+read_bidi_mirroring_txt (
+  FILE *f
+)
+{
+  unsigned long l;
+
+  init_tab_mirroring_txt ();
+
+  l = 0;
+  while (fgets (buf, sizeof buf, f))
+    {
+      unsigned long i, j;
+      signed long dist;
+      int k;
+      const char *s = buf;
+
+      l++;
+
+      while (*s == ' ')
+       s++;
+
+      if (s[0] == '#' || s[0] == '\0' || s[0] == '\n')
+       continue;
+
+      k = sscanf (s, "%lx; %lx", &i, &j);
+      if (k != 2 || i >= UNICODE_CHARS || j >= UNICODE_CHARS)
+       die4 ("invalid pair in input at line %ld: %04lX, %04lX", l, i, j);
+      dist = ((signed long) j - (signed long) i);
+      table[i] = dist;
+      if (dist > max_dist)
+       max_dist = dist;
+      else if (-dist > max_dist)
+       max_dist = -dist;
+    }
+}
+
+static void
+read_data (
+  const char *data_file_type,
+  const char *data_file_name
+)
+{
+  FILE *f;
+
+  fprintf (stderr, "Reading `%s'\n", data_file_name);
+  if (!(f = fopen (data_file_name, "rt")))
+    die2 ("error: cannot open `%s' for reading", data_file_name);
+
+  if (!strcmp (data_file_type, "BidiMirroring.txt"))
+    read_bidi_mirroring_txt (f);
+  else
+    die2 ("error: unknown data-file-type %s", data_file_type);
+
+  fclose (f);
+}
+
+static void
+gen_mirroring_tab (
+  int max_depth,
+  const char *data_file_type
+)
+{
+  int key_bytes;
+  const char *key_type;
+
+  fprintf (stderr,
+          "Generating `" outputname "', it may take up to a few minutes\n");
+  printf ("/* " outputname "\n * generated by " appname " "
+         "\n" " * from the file %s of */\n\n", data_file_type);
+
+  printf ("#define PACKTAB_UINT8 guint8\n"
+         "#define PACKTAB_UINT16 guint16\n"
+         "#define PACKTAB_UINT32 guint32\n\n");
+
+  key_bytes = max_dist <= 0x7f ? 1 : max_dist < 0x7fff ? 2 : 4;
+  key_type = key_bytes == 1 ? "gint8" : key_bytes == 2 ?
+    "gint16" : "gint32";
+
+  if (!pack_table
+      (table, UNICODE_CHARS, key_bytes, 0, max_depth, 1, NULL,
+       key_type, table_name, macro_name "_DELTA", stdout))
+    die ("error: insufficient memory, decrease max_depth");
+
+  printf ("#undef PACKTAB_UINT8\n"
+         "#undef PACKTAB_UINT16\n" "#undef PACKTAB_UINT32\n\n");
+
+  printf ("#define " macro_name "(x) ((x) + " macro_name "_DELTA(x))\n\n");
+
+  printf ("/* End of generated " outputname " */\n");
+}
+
+int
+main (
+  int argc,
+  const char **argv
+)
+{
+  const char *data_file_type = "BidiMirroring.txt";
+
+  if (argc < 3)
+    die2 ("usage:\n  " appname " max-lookups /path/to/%s [junk...]",
+         data_file_type);
+
+  {
+    int max_depth = atoi (argv[1]);
+    const char *data_file_name = argv[2];
+
+    if (max_depth < 2)
+      die ("invalid depth");
+
+    init ();
+    read_data (data_file_type, data_file_name);
+    gen_mirroring_tab (max_depth, data_file_type);
+  }
+
+  return 0;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glib-mirroring-tab/packtab.c b/resource/csdk/connectivity/lib/android/glib-master/glib/glib-mirroring-tab/packtab.c
new file mode 100644 (file)
index 0000000..7c0ff5d
--- /dev/null
@@ -0,0 +1,424 @@
+/* PackTab - Pack a static table
+ * Copyright (C) 2001 Behdad Esfahbod. 
+ * 
+ * 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, in a file named COPYING; if not, write to the 
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA  
+ * 
+ * For licensing issues, contact <fwpg@sharif.edu>. 
+ */
+
+/*
+  8 <= N <= 2^21
+  int key
+  1 <= max_depth <= 21
+*/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "packtab.h"
+
+typedef signed int uni_table[1024 * 1024 * 2];
+static int n, a, max_depth, digits, tab_width, per_row;
+static long N;
+signed int def_key;
+static uni_table temp, x, perm, *tab;
+static long pow[22], cluster, cmpcluster;
+static const char *const *name, *key_type_name, *table_name, *macro_name;
+static FILE *f;
+
+static long
+most_binary (
+  long min,
+  long max
+)
+{
+  /* min should be less than max */
+  register int i, ii;
+
+  if (min == max)
+    return max;
+
+  for (i = 21; max < pow[i]; i--)
+    ;
+  ii = i;
+  while (i && !((min ^ max) & pow[i]))
+    i--;
+
+  if (ii == i)
+    {
+      /* min is less than half of max */
+      for (i = 21 - 1; min < pow[i]; i--)
+       ;
+      i++;
+      return pow[i];
+    }
+
+  return max & (pow[i] - 1);
+}
+
+static void
+init (
+  const signed int *table
+)
+{
+  register int i;
+
+  /* initialize powers of two */
+  pow[0] = 1;
+  for (i = 1; i <= 21; i++)
+    pow[i] = pow[i - 1] << 1;
+
+  /* reduce number of elements to get a more binary number */
+  {
+    long essen;
+
+    /* find number of essential items */
+    essen = N - 1;
+    while (essen && table[essen] == def_key)
+      essen--;
+    essen++;
+
+    N = most_binary (essen, N);
+  }
+
+  for (n = 21; N % pow[n]; n--)
+    ;
+  digits = (n + 3) / 4;
+  for (i = 6; i; i--)
+    if (pow[i] * (tab_width + 1) < 80)
+      break;
+  per_row = pow[i];
+}
+
+static int
+compare (
+  const void *r,
+  const void *s
+)
+{
+  int i;
+  for (i = 0; i < cmpcluster; i++)
+    if (((int *) r)[i] != ((int *) s)[i])
+      return ((int *) r)[i] - ((int *) s)[i];
+  return 0;
+}
+
+static int lev, best_lev, p[22], best_p[22], nn;
+static long c[22], best_c[22], s, best_s;
+static long t[22], best_t[22], clusters[22], best_cluster[22];
+
+static void
+found (
+  void
+)
+{
+  int i;
+
+  if (s < best_s)
+    {
+      best_s = s;
+      best_lev = lev;
+      for (i = 0; i <= lev; i++)
+       {
+         best_p[i] = p[i];
+         best_c[i] = c[i];
+         best_t[i] = t[i];
+         best_cluster[i] = clusters[i];
+       }
+    }
+}
+
+static void
+bt (
+  int node_size
+)
+{
+  long i, j, k, y, sbak;
+  long key_bytes;
+
+  if (t[lev] == 1)
+    {
+      found ();
+      return;
+    }
+  if (lev == max_depth)
+    return;
+
+  for (i = 1 - t[lev] % 2; i <= nn + (t[lev] >> nn) % 2; i++)
+    {
+      nn -= (p[lev] = i);
+      clusters[lev] = cluster = (i && nn >= 0) ? pow[i] : t[lev];
+      cmpcluster = cluster + 1;
+
+      t[lev + 1] = (t[lev] - 1) / cluster + 1;
+      for (j = 0; j < t[lev + 1]; j++)
+       {
+         memmove (temp + j * cmpcluster, tab[lev] + j * cluster,
+                  cluster * sizeof (tab[lev][0]));
+         temp[j * cmpcluster + cluster] = j;
+       }
+      qsort (temp, t[lev + 1], cmpcluster * sizeof (temp[0]), compare);
+      for (j = 0; j < t[lev + 1]; j++)
+       {
+         perm[j] = temp[j * cmpcluster + cluster];
+         temp[j * cmpcluster + cluster] = 0;
+       }
+      k = 1;
+      y = 0;
+      tab[lev + 1][perm[0]] = perm[0];
+      for (j = 1; j < t[lev + 1]; j++)
+       {
+         if (compare (temp + y, temp + y + cmpcluster))
+           {
+             k++;
+             tab[lev + 1][perm[j]] = perm[j];
+           }
+         else
+           tab[lev + 1][perm[j]] = tab[lev + 1][perm[j - 1]];
+         y += cmpcluster;
+       }
+      sbak = s;
+      s += k * node_size * cluster;
+      c[lev] = k;
+
+      if (s >= best_s)
+       {
+         s = sbak;
+         nn += i;
+         return;
+       }
+
+      key_bytes = k * cluster;
+      key_bytes = key_bytes < 0xff ? 1 : key_bytes < 0xffff ? 2 : 4;
+      lev++;
+      bt (key_bytes);
+      lev--;
+
+      s = sbak;
+      nn += i;
+    }
+}
+
+static void
+solve (
+  void
+)
+{
+  best_lev = max_depth + 2;
+  best_s = N * a * 2;
+  lev = 0;
+  s = 0;
+  nn = n;
+  t[0] = N;
+  bt (a);
+}
+
+static void
+write_array (
+  long max_key
+)
+{
+  int i, j, k, y, ii, ofs;
+  const char *key_type;
+
+  if (best_t[lev] == 1)
+    return;
+
+  nn -= (i = best_p[lev]);
+  cluster = best_cluster[lev];
+  cmpcluster = cluster + 1;
+
+  t[lev + 1] = best_t[lev + 1];
+  for (j = 0; j < t[lev + 1]; j++)
+    {
+      memmove (temp + j * cmpcluster, tab[lev] + j * cluster,
+              cluster * sizeof (tab[lev][0]));
+      temp[j * cmpcluster + cluster] = j;
+    }
+  qsort (temp, t[lev + 1], cmpcluster * sizeof (temp[0]), compare);
+  for (j = 0; j < t[lev + 1]; j++)
+    {
+      perm[j] = temp[j * cmpcluster + cluster];
+      temp[j * cmpcluster + cluster] = 0;
+    }
+  k = 1;
+  y = 0;
+  tab[lev + 1][perm[0]] = x[0] = perm[0];
+  for (j = 1; j < t[lev + 1]; j++)
+    {
+      if (compare (temp + y, temp + y + cmpcluster))
+       {
+         x[k] = perm[j];
+         tab[lev + 1][perm[j]] = x[k];
+         k++;
+       }
+      else
+       tab[lev + 1][perm[j]] = tab[lev + 1][perm[j - 1]];
+      y += cmpcluster;
+    }
+
+  i = 0;
+  for (ii = 1; ii < k; ii++)
+    if (x[ii] < x[i])
+      i = ii;
+
+  key_type = !lev ? key_type_name :
+    max_key <= 0xff ? "PACKTAB_UINT8" :
+    max_key <= 0xffff ? "PACKTAB_UINT16" : "PACKTAB_UINT32";
+  fprintf (f, "static const %s %sLev%d[%ld*%d] = {", key_type, table_name,
+          best_lev - lev - 1, cluster, k);
+  ofs = 0;
+  for (ii = 0; ii < k; ii++)
+    {
+      int kk, jj;
+      fprintf (f, "\n#define %sLev%d_%0*lX 0x%0X", table_name,
+              best_lev - lev - 1, digits, x[i] * pow[n - nn], ofs);
+      kk = x[i] * cluster;
+      if (!lev)
+       if (name)
+         for (j = 0; j < cluster; j++)
+           {
+             if (!(j % per_row) && j != cluster - 1)
+               fprintf (f, "\n  ");
+             fprintf (f, "%*s,", tab_width, name[tab[lev][kk++]]);
+           }
+       else
+         for (j = 0; j < cluster; j++)
+           {
+             if (!(j % per_row) && j != cluster - 1)
+               fprintf (f, "\n  ");
+             fprintf (f, "%*d,", tab_width, tab[lev][kk++]);
+           }
+      else
+       for (j = 0; j < cluster; j++, kk++)
+         fprintf (f, "\n  %sLev%d_%0*lX,  /* %0*lX..%0*lX */", table_name,
+                  best_lev - lev, digits,
+                  tab[lev][kk] * pow[n - nn - best_p[lev]], digits,
+                  x[i] * pow[n - nn] + j * pow[n - nn - best_p[lev]], digits,
+                  x[i] * pow[n - nn] + (j + 1) * pow[n - nn - best_p[lev]] -
+                  1);
+      ofs += cluster;
+      jj = i;
+      for (j = 0; j < k; j++)
+       if (x[j] > x[i] && (x[j] < x[jj] || jj == i))
+         jj = j;
+      i = jj;
+    }
+  fprintf (f, "\n};\n\n");
+  lev++;
+  write_array (cluster * k);
+  lev--;
+}
+
+static void
+write_source (
+  void
+)
+{
+  int i, j;
+
+  lev = 0;
+  s = 0;
+  nn = n;
+  t[0] = N;
+  fprintf (f, "\n" "/* *IND" "ENT-OFF* */\n\n");
+  write_array (0);
+  fprintf (f, "/* *IND" "ENT-ON* */\n\n");
+
+  fprintf (f, "#define %s(x) \\\n", macro_name);
+  fprintf (f, "\t((x) >= 0x%lx ? ", N);
+  if (name)
+    fprintf (f, "%s", name[def_key]);
+  else
+    fprintf (f, "%d", def_key);
+  fprintf (f, " : ");
+  j = 0;
+  for (i = best_lev - 1; i >= 0; i--)
+    {
+      fprintf (f, " \\\n\t%sLev%d[((x)", table_name, i);
+      if (j != 0)
+       fprintf (f, " >> %d", j);
+      if (i)
+       fprintf (f, " & 0x%02lx) +", pow[best_p[best_lev - 1 - i]] - 1);
+      j += best_p[best_lev - 1 - i];
+    }
+  fprintf (f, ")");
+  for (i = 0; i < best_lev; i++)
+    fprintf (f, "]");
+  fprintf (f, ")\n\n");
+}
+
+static void
+write_out (
+  void
+)
+{
+  int i;
+  fprintf (f, "/*\n"
+          "  generated by packtab.c version %d\n\n"
+          "  use %s(key) to access your table\n\n"
+          "  assumed sizeof(%s): %d\n"
+          "  required memory: %ld\n"
+          "  lookups: %d\n"
+          "  partition shape: %s",
+          packtab_version, macro_name, key_type_name, a, best_s, best_lev,
+          table_name);
+  for (i = best_lev - 1; i >= 0; i--)
+    fprintf (f, "[%ld]", best_cluster[i]);
+  fprintf (f, "\n" "  different table entries:");
+  for (i = best_lev - 1; i >= 0; i--)
+    fprintf (f, " %ld", best_c[i]);
+  fprintf (f, "\n*/\n");
+  write_source ();
+}
+
+int
+pack_table (
+  const signed int *base,
+  long key_num,
+  int key_size,
+  signed int default_key,
+  int p_max_depth,
+  int p_tab_width,
+  const char *const *p_name,
+  const char *p_key_type_name,
+  const char *p_table_name,
+  const char *p_macro_name,
+  FILE *out
+)
+{
+  N = key_num;
+  a = key_size;
+  def_key = default_key;
+  max_depth = p_max_depth;
+  tab_width = p_tab_width;
+  name = p_name;
+  key_type_name = p_key_type_name;
+  table_name = p_table_name;
+  macro_name = p_macro_name;
+  f = out;
+  init (base);
+  if (!(tab = malloc ((n + 1) * sizeof (tab[0]))))
+    return 0;
+  memmove (tab[0], base, N * sizeof (base[0]));
+  solve ();
+  write_out ();
+  free (tab);
+  return 1;
+}
+
+/* End of packtab.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glib-mirroring-tab/packtab.h b/resource/csdk/connectivity/lib/android/glib-master/glib/glib-mirroring-tab/packtab.h
new file mode 100644 (file)
index 0000000..7cab9be
--- /dev/null
@@ -0,0 +1,50 @@
+/* PackTab - Pack a static table
+ * Copyright (C) 2001 Behdad Esfahbod. 
+ * 
+ * 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, in a file named COPYING; if not, write to the 
+ * Free Software Foundation, Inc., 59 Temple Place, Suite 330, 
+ * Boston, MA 02111-1307, USA  
+ * 
+ * For licensing issues, contact <fwpg@sharif.edu>. 
+ */
+
+#ifndef PACKTAB_H
+#define PACKTAB_H
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+#define packtab_version 3
+
+  int pack_table (
+  const signed int *base,
+  long key_num,
+  int key_size,
+  signed int default_key,
+  int max_depth,
+  int tab_width,
+  const char *const *name,
+  const char *key_type_name,
+  const char *table_name,
+  const char *macro_name,
+  FILE *out
+  );
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif                         /* PACKTAB_H */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glib-object.h b/resource/csdk/connectivity/lib/android/glib-master/glib/glib-object.h
new file mode 100644 (file)
index 0000000..10cff1b
--- /dev/null
@@ -0,0 +1,42 @@
+/* GObject - GLib Type, Object, Parameter and Signal Library
+ * Copyright (C) 1998, 1999, 2000 Tim Janik and Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __GLIB_GOBJECT_H__
+#define __GLIB_GOBJECT_H__
+
+#define __GLIB_GOBJECT_H_INSIDE__
+
+/* topmost include file for GObject header files */
+#include        <gobject/gbinding.h>
+#include       <gobject/gboxed.h>
+#include       <gobject/genums.h>
+#include       <gobject/gobject.h>
+#include       <gobject/gparam.h>
+#include       <gobject/gparamspecs.h>
+#include       <gobject/gsignal.h>
+#include       <gobject/gsourceclosure.h>
+#include       <gobject/gtype.h>
+#include       <gobject/gtypemodule.h>
+#include       <gobject/gtypeplugin.h>
+#include       <gobject/gvalue.h>
+#include       <gobject/gvaluearray.h>
+#include       <gobject/gvaluetypes.h>
+
+#undef __GLIB_GOBJECT_H_INSIDE__
+
+#endif /* __GLIB_GOBJECT_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glib.h b/resource/csdk/connectivity/lib/android/glib-master/glib/glib.h
new file mode 100644 (file)
index 0000000..06d0190
--- /dev/null
@@ -0,0 +1,99 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#ifndef __G_LIB_H__
+#define __G_LIB_H__
+
+#define __GLIB_H_INSIDE__
+
+#include <glib/galloca.h>
+#include <glib/garray.h>
+#include <glib/gasyncqueue.h>
+#include <glib/gatomic.h>
+#include <glib/gbacktrace.h>
+#include <glib/gbase64.h>
+#include <glib/gbitlock.h>
+#include <glib/gbookmarkfile.h>
+#include <glib/gcache.h>
+#include <glib/gchecksum.h>
+#include <glib/gcompletion.h>
+#include <glib/gconvert.h>
+#include <glib/gdataset.h>
+#include <glib/gdate.h>
+#include <glib/gdatetime.h>
+#include <glib/gdir.h>
+#include <glib/gerror.h>
+#include <glib/gfileutils.h>
+#include <glib/ghash.h>
+#include <glib/ghook.h>
+#include <glib/ghostutils.h>
+#include <glib/giochannel.h>
+#include <glib/gkeyfile.h>
+#include <glib/glist.h>
+#include <glib/gmacros.h>
+#include <glib/gmain.h>
+#include <glib/gmappedfile.h>
+#include <glib/gmarkup.h>
+#include <glib/gmem.h>
+#include <glib/gmessages.h>
+#include <glib/gnode.h>
+#include <glib/goption.h>
+#include <glib/gpattern.h>
+#include <glib/gpoll.h>
+#include <glib/gprimes.h>
+#include <glib/gqsort.h>
+#include <glib/gquark.h>
+#include <glib/gqueue.h>
+#include <glib/grand.h>
+#include <glib/grel.h>
+#include <glib/gregex.h>
+#include <glib/gscanner.h>
+#include <glib/gsequence.h>
+#include <glib/gshell.h>
+#include <glib/gslice.h>
+#include <glib/gslist.h>
+#include <glib/gspawn.h>
+#include <glib/gstrfuncs.h>
+#include <glib/gstring.h>
+#include <glib/gtestutils.h>
+#include <glib/gthread.h>
+#include <glib/gthreadpool.h>
+#include <glib/gtimer.h>
+#include <glib/gtimezone.h>
+#include <glib/gtree.h>
+#include <glib/gtypes.h>
+#include <glib/gunicode.h>
+#include <glib/gurifuncs.h>
+#include <glib/gutils.h>
+#include <glib/gvarianttype.h>
+#include <glib/gvariant.h>
+#ifdef G_PLATFORM_WIN32
+#include <glib/gwin32.h>
+#endif
+
+#undef __GLIB_H_INSIDE__
+
+#endif /* __G_LIB_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glib.py b/resource/csdk/connectivity/lib/android/glib-master/glib/glib.py
new file mode 100644 (file)
index 0000000..135f4bc
--- /dev/null
@@ -0,0 +1,249 @@
+import gdb
+
+# This is not quite right, as local vars may override symname
+def read_global_var (symname):
+    return gdb.selected_frame().read_var(symname)
+
+def g_quark_to_string (quark):
+    if quark == None:
+        return None
+    quark = long(quark)
+    if quark == 0:
+        return None
+    val = read_global_var ("g_quarks")
+    max_q = long(read_global_var ("g_quark_seq_id"))
+    if quark < max_q:
+        return val[quark].string()
+    return None
+
+# We override the node printers too, so that node->next is not expanded
+class GListNodePrinter:
+    "Prints a GList node"
+
+    def __init__ (self, val):
+        self.val = val
+
+    def to_string (self):
+        return "{data=%s, next=0x%x, prev=0x%x}" % (str(self.val["data"]), long(self.val["next"]), long(self.val["prev"]))
+
+class GSListNodePrinter:
+    "Prints a GSList node"
+
+    def __init__ (self, val):
+        self.val = val
+
+    def to_string (self):
+        return "{data=%s, next=0x%x}" % (str(self.val["data"]), long(self.val["next"]))
+
+class GListPrinter:
+    "Prints a GList"
+
+    class _iterator:
+        def __init__(self, head, listtype):
+            self.link = head
+            self.listtype = listtype
+            self.count = 0
+
+        def __iter__(self):
+            return self
+
+        def next(self):
+            if self.link == 0:
+                raise StopIteration
+            data = self.link['data']
+            self.link = self.link['next']
+            count = self.count
+            self.count = self.count + 1
+            return ('[%d]' % count, data)
+
+    def __init__ (self, val, listtype):
+        self.val = val
+        self.listtype = listtype
+
+    def children(self):
+        return self._iterator(self.val, self.listtype)
+
+    def to_string (self):
+        return  "0x%x" % (long(self.val))
+
+    def display_hint (self):
+        return "array"
+
+class GHashPrinter:
+    "Prints a GHashTable"
+
+    class _iterator:
+        def __init__(self, ht, keys_are_strings):
+            self.ht = ht
+            if ht != 0:
+                self.array = ht["nodes"]
+                self.size = ht["size"]
+            self.pos = 0
+            self.keys_are_strings = keys_are_strings
+            self.value = None
+
+        def __iter__(self):
+            return self
+
+        def next(self):
+            if self.ht == 0:
+                raise StopIteration
+            if self.value != None:
+                v = self.value
+                self.value = None
+                return v
+            while long(self.pos) < long(self.size):
+                node = self.array[self.pos]
+                self.pos = self.pos + 1
+                if long (node["key_hash"]) >= 2:
+                    key = node["key"]
+                    val = node["value"]
+
+                    if self.keys_are_strings:
+                        key = key.cast (gdb.lookup_type("char").pointer())
+
+                    # Queue value for next result
+                    self.value = ('[%dv]'% (self.pos), val)
+
+                    # Return key
+                    return ('[%dk]'% (self.pos), key)
+            raise StopIteration
+
+    def __init__ (self, val):
+        self.val = val
+        self.keys_are_strings = False
+        try:
+            string_hash = read_global_var ("g_str_hash")
+        except:
+            string_hash = None
+        if self.val != 0 and string_hash != None and self.val["hash_func"] == string_hash:
+            self.keys_are_strings = True
+
+    def children(self):
+        return self._iterator(self.val, self.keys_are_strings)
+
+    def to_string (self):
+        return  "0x%x" % (long(self.val))
+
+    def display_hint (self):
+        return "map"
+
+def pretty_printer_lookup (val):
+    if is_g_type_instance (val):
+        return GTypePrettyPrinter (val)
+
+def pretty_printer_lookup (val):
+    # None yet, want things like hash table and list
+
+    type = val.type.unqualified()
+
+    # If it points to a reference, get the reference.
+    if type.code == gdb.TYPE_CODE_REF:
+        type = type.target ()
+
+    if type.code == gdb.TYPE_CODE_PTR:
+        type = type.target().unqualified()
+        t = str(type)
+        if t == "GList":
+            return GListPrinter(val, "GList")
+        if t == "GSList":
+            return GListPrinter(val, "GSList")
+        if t == "GHashTable":
+            return GHashPrinter(val)
+    else:
+        t = str(type)
+        if t == "GList":
+            return GListNodePrinter(val)
+        if t == "GSList *":
+            return GListPrinter(val, "GSList")
+    return None
+
+def register (obj):
+    if obj == None:
+        obj = gdb
+
+    obj.pretty_printers.append(pretty_printer_lookup)
+
+class ForeachCommand (gdb.Command):
+    """Foreach on list"""
+
+    def __init__ (self):
+        super (ForeachCommand, self).__init__ ("gforeach",
+                                               gdb.COMMAND_DATA,
+                                               gdb.COMPLETE_SYMBOL)
+
+    def valid_name (self, name):
+        if not name[0].isalpha():
+            return False
+        return True
+
+    def parse_args (self, arg):
+        i = arg.find(" ")
+        if i <= 0:
+            raise Exception ("No var specified")
+        var = arg[:i]
+        if not self.valid_name(var):
+            raise Exception ("Invalid variable name")
+
+        while i < len (arg) and arg[i].isspace():
+            i = i + 1
+
+        if arg[i:i+2] != "in":
+            raise Exception ("Invalid syntax, missing in")
+
+        i = i + 2
+
+        while i < len (arg) and arg[i].isspace():
+            i = i + 1
+
+        colon = arg.find (":", i)
+        if colon == -1:
+            raise Exception ("Invalid syntax, missing colon")
+
+        val = arg[i:colon]
+
+        colon = colon + 1
+        while colon < len (arg) and arg[colon].isspace():
+            colon = colon + 1
+
+        command = arg[colon:]
+
+        return (var, val, command)
+
+    def do_iter(self, arg, item, command):
+        item = item.cast (gdb.lookup_type("void").pointer())
+        item = long(item)
+        to_eval = "set $%s = (void *)0x%x\n"%(arg, item)
+        gdb.execute(to_eval)
+        gdb.execute(command)
+
+    def slist_iterator (self, arg, container, command):
+        l = container.cast (gdb.lookup_type("GSList").pointer())
+        while long(l) != 0:
+            self.do_iter (arg, l["data"], command)
+            l = l["next"]
+
+    def list_iterator (self, arg, container, command):
+        l = container.cast (gdb.lookup_type("GList").pointer())
+        while long(l) != 0:
+            self.do_iter (arg, l["data"], command)
+            l = l["next"]
+
+    def pick_iterator (self, container):
+        t = container.type.unqualified()
+        if t.code == gdb.TYPE_CODE_PTR:
+            t = t.target().unqualified()
+            t = str(t)
+            if t == "GSList":
+                return self.slist_iterator
+            if t == "GList":
+                return self.list_iterator
+        raise Exception("Invalid container type %s"%(str(container.type)))
+
+    def invoke (self, arg, from_tty):
+        (var, container, command) = self.parse_args(arg)
+        container = gdb.parse_and_eval (container)
+        func = self.pick_iterator(container)
+        func(var, container, command)
+
+ForeachCommand ()
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glib.rc.in b/resource/csdk/connectivity/lib/android/glib-master/glib/glib.rc.in
new file mode 100644 (file)
index 0000000..60b3035
--- /dev/null
@@ -0,0 +1,30 @@
+#include <winver.h>
+
+VS_VERSION_INFO VERSIONINFO
+  FILEVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
+  PRODUCTVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
+  FILEFLAGSMASK 0
+  FILEFLAGS 0
+  FILEOS VOS__WINDOWS32
+  FILETYPE VFT_DLL
+  FILESUBTYPE VFT2_UNKNOWN
+  BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+      BLOCK "040904B0"
+      BEGIN
+       VALUE "CompanyName", "The GLib developer community"
+       VALUE "FileDescription", "GLib"
+       VALUE "FileVersion", "@GLIB_VERSION@.0"
+       VALUE "InternalName", "libglib-2.0-@LT_CURRENT_MINUS_AGE@"
+       VALUE "LegalCopyright", "Copyright © 1995-2010 Peter Mattis, Spencer Kimball, Josh MacDonald and others."
+       VALUE "OriginalFilename", "libglib-2.0-@LT_CURRENT_MINUS_AGE@.dll"
+       VALUE "ProductName", "GLib"
+       VALUE "ProductVersion", "@GLIB_VERSION@"
+      END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+      VALUE "Translation", 0x409, 1200
+    END
+  END
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glib.stp.in b/resource/csdk/connectivity/lib/android/glib-master/glib/glib.stp.in
new file mode 100644 (file)
index 0000000..95d3351
--- /dev/null
@@ -0,0 +1,84 @@
+global gquarks
+
+/* This is needed to keep track of gquark for use in other probes.*/
+probe process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("quark__new")
+{
+  gquarks[pid(), $arg2] = user_string($arg1)
+}
+
+/**
+ * probe glib.quark_new - Called when a #GQuark is initially created
+ * @quark: integer value for the quark
+ * @str: string form of the quark
+ */
+probe glib.quark_new = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("quark__new")
+{
+  str = user_string ($arg1); 
+  quark = $arg2; 
+  probestr = sprintf("glib.quark_new(%s) -> %d", str, quark);
+}
+
+/**
+ * probe glib.mem_alloc - Called when a malloc block is initially requested
+ * @mem: Raw memory pointer returned
+ * @n_bytes: number of bytes
+ * @zeroed: Boolean value, %TRUE if this block was filled with NUL bytes
+ * @failable: Boolean value, %TRUE if program execution can continue on allocation failure
+ */
+probe glib.mem_alloc = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("mem__alloc")
+{
+  mem = $arg1; 
+  n_bytes = $arg2; 
+  zeroed = $arg3; 
+  failable = $arg4; 
+  probestr = sprintf("glib.mem_alloc(n_bytes=%d) -> %p", n_bytes, mem);
+}
+
+/**
+ * probe glib.mem_free - Called when a malloc block freed
+ */
+probe glib.mem_free = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("mem__free")
+{
+  mem = $arg1;  /* ARG: @mem: Raw memory pointer */
+  probestr = sprintf("glib.mem_free(mem=%p)", mem);
+}
+
+/**
+ * probe glib.mem_realloc - Called when a malloc block is resized
+ * @mem: Raw memory pointer returned
+ * @old_mem: Original memory pointer
+ * @n_bytes: number of bytes
+ * @failable: Boolean value, %TRUE if program execution can continue on allocation failure
+ */
+probe glib.mem_realloc = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("mem__realloc")
+{
+  mem = $arg1; 
+  old_mem = $arg2; 
+  n_bytes = $arg3;  
+  failable = $arg4; 
+  probestr = sprintf("glib.mem_realloc(old_mem=%p, n_bytes=%d) -> %p", old_mem, n_bytes, mem);
+}
+
+/**
+ * probe glib.slice_alloc - Called when g_slice_alloc() is used
+ * @mem: Raw memory pointer returned
+ * @n_bytes: number of bytes
+ */
+probe glib.slice_alloc = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("slice__alloc")
+{
+  mem = $arg1; 
+  n_bytes = $arg2; 
+  probestr = sprintf("glib.slice_alloc(n_bytes=%d) -> %p", n_bytes, mem);
+}
+
+/**
+ * probe glib.slice_free - Called when memory slice is freed
+ * @mem: Raw memory pointer returned
+ * @n_bytes: Number of bytes
+ */
+probe glib.slice_free = process("@ABS_GLIB_RUNTIME_LIBDIR@/libglib-2.0.so.0.@LT_CURRENT@.@LT_REVISION@").mark("slice__free")
+{
+  mem = $arg1; 
+  n_bytes = $arg2; 
+  probestr = sprintf("glib.slice_free(n_bytes=%d) -> %p", n_bytes, mem);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glib.symbols b/resource/csdk/connectivity/lib/android/glib-master/glib/glib.symbols
new file mode 100644 (file)
index 0000000..970fc08
--- /dev/null
@@ -0,0 +1,1967 @@
+/* This file lists all exported symbols. It is used to generate
+ * the glib.def file used to control exports on Windows.
+ * 
+ * Every symbol must be included in the right
+ * #ifdef IN_HEADER(sym) #endif and
+ * #ifdef IN_FILE(sym) #endif sections. 
+ */
+#ifdef ALL_FILES
+#define IN_FILE(x) 1
+#define IN_HEADER(x) 1
+#endif
+#if IN_HEADER(__G_ARRAY_H__)
+#if IN_FILE(__G_ARRAY_C__)
+g_array_append_vals
+g_array_free
+g_array_insert_vals
+g_array_new
+g_array_ref
+g_array_unref
+g_array_get_element_size
+g_array_prepend_vals
+g_array_remove_index
+g_array_remove_index_fast
+g_array_remove_range
+g_array_set_size
+g_array_sized_new
+g_array_sort
+g_array_sort_with_data
+g_byte_array_append
+g_byte_array_free
+g_byte_array_unref
+g_byte_array_ref
+g_byte_array_new
+g_byte_array_prepend
+g_byte_array_remove_index
+g_byte_array_remove_index_fast
+g_byte_array_remove_range
+g_byte_array_set_size
+g_byte_array_sized_new
+g_byte_array_sort
+g_byte_array_sort_with_data
+g_ptr_array_add
+g_ptr_array_foreach
+g_ptr_array_free
+g_ptr_array_unref
+g_ptr_array_ref
+g_ptr_array_new
+g_ptr_array_new_with_free_func
+g_ptr_array_set_free_func
+g_ptr_array_remove
+g_ptr_array_remove_fast
+g_ptr_array_remove_index
+g_ptr_array_remove_index_fast
+g_ptr_array_remove_range
+g_ptr_array_set_size
+g_ptr_array_sized_new
+g_ptr_array_sort
+g_ptr_array_sort_with_data
+#endif
+#endif
+
+#if IN_HEADER(__G_ASYNCQUEUE_H__)
+#if IN_FILE(__G_ASYNCQUEUE_C__)
+g_async_queue_length
+g_async_queue_length_unlocked
+g_async_queue_lock
+g_async_queue_new
+g_async_queue_new_full
+g_async_queue_pop
+g_async_queue_pop_unlocked
+g_async_queue_push
+g_async_queue_push_unlocked
+g_async_queue_push_sorted
+g_async_queue_push_sorted_unlocked
+g_async_queue_ref
+g_async_queue_sort
+g_async_queue_sort_unlocked
+g_async_queue_timed_pop
+g_async_queue_timed_pop_unlocked
+g_async_queue_try_pop
+g_async_queue_try_pop_unlocked
+g_async_queue_unlock
+g_async_queue_unref
+#ifndef G_DISABLE_DEPRECATED
+g_async_queue_ref_unlocked
+g_async_queue_unref_and_unlock
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_ATOMIC_H__)
+#if IN_FILE(__G_ATOMIC_C__)
+g_atomic_int_add
+g_atomic_int_compare_and_exchange
+g_atomic_int_exchange_and_add
+g_atomic_pointer_compare_and_exchange
+#ifdef INCLUDE_INTERNAL_SYMBOLS
+ /* these are not internal, but we don't want to alias them */
+g_atomic_int_get
+g_atomic_pointer_get
+g_atomic_int_set
+g_atomic_pointer_set
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_BACKTRACE_H__)
+#if IN_FILE(__G_BACKTRACE_C__)
+g_on_error_query
+g_on_error_stack_trace
+#endif
+#endif
+
+#if IN_HEADER(__G_BASE64_H__)
+#if IN_FILE(__G_BASE64_C__)
+g_base64_encode_step
+g_base64_encode_close
+g_base64_encode G_GNUC_MALLOC
+g_base64_decode_step
+g_base64_decode G_GNUC_MALLOC
+g_base64_decode_inplace
+#endif
+#endif
+
+#if IN_HEADER(__G_BOOKMARK_FILE_H__)
+#if IN_FILE(__G_BOOKMARK_FILE_C__)
+g_bookmark_file_error_quark
+g_bookmark_file_new
+g_bookmark_file_free
+g_bookmark_file_load_from_file
+g_bookmark_file_load_from_data
+g_bookmark_file_load_from_data_dirs
+g_bookmark_file_to_data
+g_bookmark_file_to_file
+g_bookmark_file_set_title
+g_bookmark_file_get_title G_GNUC_MALLOC
+g_bookmark_file_set_description
+g_bookmark_file_get_description G_GNUC_MALLOC
+g_bookmark_file_set_mime_type
+g_bookmark_file_get_mime_type G_GNUC_MALLOC
+g_bookmark_file_set_groups
+g_bookmark_file_add_group
+g_bookmark_file_has_group
+g_bookmark_file_get_groups G_GNUC_MALLOC
+g_bookmark_file_add_application
+g_bookmark_file_has_application
+g_bookmark_file_get_applications G_GNUC_MALLOC
+g_bookmark_file_set_app_info
+g_bookmark_file_get_app_info
+g_bookmark_file_set_is_private
+g_bookmark_file_get_is_private
+g_bookmark_file_set_icon
+g_bookmark_file_get_icon
+g_bookmark_file_set_added
+g_bookmark_file_get_added
+g_bookmark_file_set_modified
+g_bookmark_file_get_modified
+g_bookmark_file_set_visited
+g_bookmark_file_get_visited
+g_bookmark_file_has_item
+g_bookmark_file_get_size
+g_bookmark_file_get_uris G_GNUC_MALLOC
+g_bookmark_file_remove_group
+g_bookmark_file_remove_application
+g_bookmark_file_remove_item
+g_bookmark_file_move_item
+#endif
+#endif
+
+#if IN_HEADER(__G_CACHE_H__)
+#if IN_FILE(__G_CACHE_C__)
+g_cache_destroy
+g_cache_insert
+g_cache_key_foreach
+g_cache_new
+g_cache_remove
+#ifndef G_DISABLE_DEPRECATED
+g_cache_value_foreach
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_CHECKSUM_H__)
+#if IN_FILE(__G_CHECKSUM_C__)
+g_checksum_type_get_length
+g_checksum_new
+g_checksum_copy
+g_checksum_free
+g_checksum_update
+g_checksum_reset
+g_checksum_get_string
+g_checksum_get_digest
+g_compute_checksum_for_data
+g_compute_checksum_for_string
+#endif
+#endif
+
+#if IN_HEADER(__G_COMPLETION_H__)
+#if IN_FILE(__G_COMPLETION_C__)
+g_completion_add_items
+g_completion_clear_items
+g_completion_complete
+g_completion_complete_utf8
+g_completion_free
+g_completion_new
+g_completion_remove_items
+g_completion_set_compare
+#endif
+#endif
+
+#if IN_HEADER(__G_CONVERT_H__)
+#if IN_FILE(__G_CONVERT_C__)
+g_get_filename_charsets
+g_convert G_GNUC_MALLOC
+g_convert_error_quark
+g_convert_with_fallback G_GNUC_MALLOC
+g_convert_with_iconv G_GNUC_MALLOC
+g_iconv
+g_iconv_close
+g_iconv_open
+g_locale_from_utf8 G_GNUC_MALLOC
+g_locale_to_utf8 G_GNUC_MALLOC
+g_filename_display_name G_GNUC_MALLOC
+g_filename_display_basename G_GNUC_MALLOC
+#ifndef _WIN64
+g_filename_from_uri PRIVATE G_GNUC_MALLOC
+g_filename_from_utf8 PRIVATE G_GNUC_MALLOC
+g_filename_to_uri PRIVATE G_GNUC_MALLOC
+g_filename_to_utf8 PRIVATE G_GNUC_MALLOC 
+#endif
+#ifdef G_OS_WIN32
+g_filename_from_uri_utf8 G_GNUC_MALLOC
+g_filename_from_utf8_utf8
+g_filename_to_uri_utf8 G_GNUC_MALLOC
+g_filename_to_utf8_utf8
+#endif
+g_uri_list_extract_uris G_GNUC_MALLOC
+#endif
+#endif
+
+#if IN_HEADER(__G_DATASET_H__)
+#if IN_FILE(__G_DATASET_C__)
+g_datalist_clear
+g_datalist_foreach
+g_datalist_get_flags
+g_datalist_id_get_data
+g_datalist_id_remove_no_notify
+g_datalist_id_set_data_full
+g_datalist_set_flags
+g_datalist_unset_flags
+g_datalist_init
+g_dataset_destroy
+g_dataset_foreach
+g_dataset_id_get_data
+g_dataset_id_remove_no_notify
+g_dataset_id_set_data_full
+#endif
+#endif
+
+#if IN_HEADER(__G_QUARK_H__)
+#if IN_FILE(__G_DATASET_C__)
+g_quark_from_static_string
+g_quark_from_string
+g_quark_to_string G_GNUC_CONST
+g_quark_try_string
+g_intern_string
+g_intern_static_string
+#endif
+#endif
+
+#if IN_HEADER(__G_DATE_H__)
+#if IN_FILE(__G_DATE_C__)
+g_date_add_days
+g_date_add_months
+g_date_add_years
+g_date_clamp
+g_date_clear
+g_date_compare
+g_date_days_between
+g_date_free
+g_date_get_day
+g_date_get_day_of_year
+g_date_get_days_in_month
+g_date_get_iso8601_week_of_year
+g_date_get_julian
+g_date_get_monday_week_of_year
+g_date_get_monday_weeks_in_year G_GNUC_CONST
+g_date_get_month
+g_date_get_sunday_week_of_year
+g_date_get_sunday_weeks_in_year G_GNUC_CONST
+g_date_get_weekday
+g_date_get_year
+g_date_is_first_of_month
+g_date_is_last_of_month
+g_date_is_leap_year G_GNUC_CONST
+g_date_new
+g_date_new_dmy
+g_date_new_julian
+g_date_order
+g_date_set_day
+g_date_set_dmy
+g_date_set_julian
+g_date_set_month
+g_date_set_parse
+#ifndef G_DISABLE_DEPRECATED
+g_date_set_time
+#endif
+g_date_set_time_t
+g_date_set_time_val
+g_date_set_year
+g_date_strftime
+g_date_subtract_days
+g_date_subtract_months
+g_date_subtract_years
+g_date_to_struct_tm
+g_date_valid
+g_date_valid_day G_GNUC_CONST
+g_date_valid_dmy
+g_date_valid_julian G_GNUC_CONST
+g_date_valid_month G_GNUC_CONST
+g_date_valid_weekday G_GNUC_CONST
+g_date_valid_year G_GNUC_CONST
+#endif
+#endif
+
+#if IN_HEADER(__G_DATE_TIME_H__)
+#if IN_FILE(__G_DATE_TIME_C__)
+g_date_time_add
+g_date_time_add_days
+g_date_time_add_full
+g_date_time_add_hours
+g_date_time_add_minutes
+g_date_time_add_months
+g_date_time_add_seconds
+g_date_time_add_weeks
+g_date_time_add_years
+g_date_time_compare
+g_date_time_difference
+g_date_time_equal
+g_date_time_format G_GNUC_MALLOC
+g_date_time_get_day_of_month
+g_date_time_get_day_of_week
+g_date_time_get_day_of_year
+g_date_time_get_hour
+g_date_time_get_microsecond
+g_date_time_get_minute
+g_date_time_get_month
+g_date_time_get_second
+g_date_time_get_seconds
+g_date_time_get_timezone_abbreviation
+g_date_time_get_utc_offset
+g_date_time_get_week_numbering_year
+g_date_time_get_week_of_year
+g_date_time_get_year
+g_date_time_get_ymd
+g_date_time_hash
+g_date_time_is_daylight_savings
+g_date_time_new
+g_date_time_new_from_timeval_local
+g_date_time_new_from_timeval_utc
+g_date_time_new_from_unix_local
+g_date_time_new_from_unix_utc
+g_date_time_new_local
+g_date_time_new_now
+g_date_time_new_now_local
+g_date_time_new_now_utc
+g_date_time_new_utc
+g_date_time_ref
+g_date_time_to_local
+g_date_time_to_timeval
+g_date_time_to_timezone
+g_date_time_to_unix
+g_date_time_to_utc
+g_date_time_unref
+#endif
+#endif
+
+#if IN_HEADER(__G_TIME_ZONE_H__)
+#if IN_FILE(__G_TIME_ZONE_C__)
+g_time_zone_new
+g_time_zone_new_local
+g_time_zone_new_utc
+g_time_zone_ref
+g_time_zone_unref
+#endif
+#endif
+
+#if IN_HEADER(__G_DIR_H__)
+#if IN_FILE(__G_DIR_C__)
+g_dir_close
+#ifndef _WIN64
+g_dir_open PRIVATE
+g_dir_read_name PRIVATE
+#endif
+#ifdef G_OS_WIN32
+g_dir_open_utf8
+g_dir_read_name_utf8
+#endif
+g_dir_rewind
+#endif
+#endif
+
+#if IN_HEADER(__G_ERROR_H__)
+#if IN_FILE(__G_ERROR_C__)
+g_clear_error
+g_error_copy
+g_error_free
+g_error_matches
+g_error_new G_GNUC_PRINTF(3,4)
+g_error_new_literal
+g_error_new_valist
+g_propagate_error
+g_set_error G_GNUC_PRINTF(4,5)
+g_set_error_literal
+g_prefix_error G_GNUC_PRINTF(2,3)
+g_propagate_prefixed_error G_GNUC_PRINTF(3,4)
+#endif
+#endif
+
+#if IN_HEADER(__G_FILEUTILS_H__)
+#if IN_FILE(__G_FILEUTILS_C__)
+g_build_filename G_GNUC_MALLOC G_GNUC_NULL_TERMINATED
+g_build_filenamev G_GNUC_MALLOC
+g_build_path G_GNUC_MALLOC G_GNUC_NULL_TERMINATED
+g_build_pathv G_GNUC_MALLOC 
+g_file_error_from_errno
+g_file_error_quark
+#ifndef _WIN64
+g_file_get_contents PRIVATE
+#endif
+g_file_set_contents
+#ifndef _WIN64
+g_file_open_tmp PRIVATE
+g_file_test PRIVATE
+#endif
+g_file_read_link
+g_format_size_for_display
+#ifndef _WIN64
+g_mkstemp PRIVATE
+#endif
+g_mkstemp_full
+g_mkdir_with_parents
+#ifdef G_OS_WIN32
+g_file_get_contents_utf8
+g_file_open_tmp_utf8
+g_file_test_utf8
+g_mkstemp_utf8
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_HASH_H__)
+#if IN_FILE(__G_HASH_C__)
+g_hash_table_destroy
+g_hash_table_unref
+g_hash_table_ref
+g_hash_table_find
+g_hash_table_foreach
+g_hash_table_foreach_remove
+g_hash_table_foreach_steal
+g_hash_table_get_keys
+g_hash_table_get_values
+g_hash_table_insert
+g_hash_table_lookup
+g_hash_table_lookup_extended
+g_hash_table_new
+g_hash_table_new_full
+g_hash_table_remove
+g_hash_table_remove_all
+g_hash_table_replace
+g_hash_table_size
+g_hash_table_steal
+g_hash_table_steal_all
+g_hash_table_iter_init
+g_hash_table_iter_next
+g_hash_table_iter_get_hash_table
+g_hash_table_iter_remove
+g_hash_table_iter_steal
+#endif
+#endif
+
+#if IN_HEADER(__G_HOOK_H__)
+#if IN_FILE(__G_HOOK_C__)
+g_hook_alloc
+g_hook_compare_ids
+g_hook_destroy
+g_hook_destroy_link
+g_hook_find
+g_hook_find_data
+g_hook_find_func
+g_hook_find_func_data
+g_hook_first_valid
+g_hook_free
+g_hook_get
+g_hook_insert_before
+g_hook_insert_sorted
+g_hook_list_clear
+g_hook_list_init
+g_hook_list_invoke
+g_hook_list_invoke_check
+g_hook_list_marshal
+g_hook_list_marshal_check
+g_hook_next_valid
+g_hook_prepend
+g_hook_ref
+g_hook_unref
+#endif
+#endif
+
+#if IN_HEADER(__G_IOCHANNEL_H__)
+#if IN_FILE(__G_IOCHANNEL_C__)
+g_io_add_watch
+g_io_add_watch_full
+g_io_create_watch
+g_io_channel_error_from_errno
+g_io_channel_error_quark
+g_io_channel_flush
+g_io_channel_get_buffer_condition
+g_io_channel_get_buffered
+g_io_channel_get_buffer_size
+g_io_channel_get_close_on_unref
+g_io_channel_get_encoding
+g_io_channel_get_flags
+g_io_channel_get_line_term
+g_io_channel_init
+g_io_channel_read_chars
+g_io_channel_read_line
+g_io_channel_read_line_string
+g_io_channel_read_to_end
+g_io_channel_read_unichar
+g_io_channel_ref
+g_io_channel_seek_position
+g_io_channel_set_buffered
+g_io_channel_set_buffer_size
+g_io_channel_set_close_on_unref
+g_io_channel_set_encoding
+g_io_channel_set_flags
+g_io_channel_set_line_term
+g_io_channel_shutdown
+g_io_channel_unref
+#ifndef G_DISABLE_DEPRECATED
+g_io_channel_close
+g_io_channel_read
+g_io_channel_seek
+g_io_channel_write
+#endif
+g_io_channel_write_chars
+g_io_channel_write_unichar
+#endif
+#endif
+
+#if IN_HEADER(__G_IOCHANNEL_H__)
+#if IN_FILE(__G_IO_UNIX_C__)
+#ifdef G_OS_UNIX
+g_io_channel_unix_get_fd
+g_io_channel_unix_new
+g_io_channel_new_file PRIVATE
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_IOCHANNEL_H__)
+#if IN_FILE(__G_IO_WIN32_C__)
+#ifdef G_OS_WIN32
+g_io_channel_unix_get_fd
+g_io_channel_unix_new
+#ifndef _WIN64
+g_io_channel_new_file PRIVATE
+#endif
+g_io_channel_new_file_utf8
+g_io_channel_win32_get_fd
+g_io_channel_win32_make_pollfd
+g_io_channel_win32_new_fd
+g_io_channel_win32_new_messages
+g_io_channel_win32_new_socket
+#ifndef _WIN64
+g_io_channel_win32_new_stream_socket PRIVATE
+#endif
+g_io_channel_win32_poll
+g_io_channel_win32_set_debug
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_KEY_FILE_H__)
+#if IN_FILE(__G_KEY_FILE_C__)
+g_key_file_error_quark
+g_key_file_free
+g_key_file_get_boolean
+g_key_file_get_boolean_list G_GNUC_MALLOC
+g_key_file_get_comment G_GNUC_MALLOC
+g_key_file_get_groups G_GNUC_MALLOC
+g_key_file_get_double
+g_key_file_get_double_list G_GNUC_MALLOC
+g_key_file_get_integer
+g_key_file_get_int64
+g_key_file_get_uint64
+g_key_file_get_integer_list G_GNUC_MALLOC
+g_key_file_get_keys G_GNUC_MALLOC
+g_key_file_get_locale_string G_GNUC_MALLOC
+g_key_file_get_locale_string_list G_GNUC_MALLOC
+g_key_file_get_start_group G_GNUC_MALLOC
+g_key_file_get_string G_GNUC_MALLOC
+g_key_file_get_string_list G_GNUC_MALLOC
+g_key_file_get_value G_GNUC_MALLOC
+g_key_file_has_group
+g_key_file_has_key
+g_key_file_load_from_dirs
+g_key_file_load_from_data
+g_key_file_load_from_data_dirs
+g_key_file_load_from_file
+g_key_file_new
+g_key_file_remove_comment
+g_key_file_remove_group
+g_key_file_remove_key
+g_key_file_set_boolean
+g_key_file_set_boolean_list
+g_key_file_set_comment
+g_key_file_set_double
+g_key_file_set_double_list
+g_key_file_set_integer
+g_key_file_set_int64
+g_key_file_set_uint64
+g_key_file_set_integer_list
+g_key_file_set_list_separator
+g_key_file_set_locale_string
+g_key_file_set_locale_string_list
+g_key_file_set_string
+g_key_file_set_string_list
+g_key_file_set_value
+g_key_file_to_data G_GNUC_MALLOC
+#endif
+#endif
+
+#if IN_HEADER(__G_LIST_H__)
+#if IN_FILE(__G_LIST_C__)
+g_list_alloc
+g_list_append
+g_list_concat
+g_list_copy
+g_list_delete_link
+g_list_find
+g_list_find_custom
+g_list_first
+g_list_foreach
+g_list_free
+g_list_free_1
+g_list_index
+g_list_insert
+g_list_insert_before
+g_list_insert_sorted
+g_list_insert_sorted_with_data
+g_list_last
+g_list_length
+g_list_nth
+g_list_nth_data
+g_list_nth_prev
+#ifndef G_DISABLE_DEPRECATED
+g_list_pop_allocator
+#endif
+g_list_position
+g_list_prepend
+#ifndef G_DISABLE_DEPRECATED
+g_list_push_allocator
+#endif
+g_list_remove
+g_list_remove_all
+g_list_remove_link
+g_list_reverse
+g_list_sort
+g_list_sort_with_data
+#endif
+#endif
+
+#if IN_HEADER(__G_MAIN_H__)
+#if IN_FILE(__G_MAIN_C__)
+g_child_watch_add
+g_child_watch_add_full
+g_child_watch_source_new
+g_get_current_time
+g_main_context_acquire
+g_main_context_add_poll
+g_main_context_check
+g_main_context_default
+g_main_context_dispatch
+g_main_context_find_source_by_funcs_user_data
+g_main_context_find_source_by_id
+g_main_context_find_source_by_user_data
+g_main_context_get_poll_func
+g_main_context_get_thread_default
+g_main_context_is_owner
+g_main_context_iteration
+g_main_context_new
+g_main_context_pending
+g_main_context_pop_thread_default
+g_main_context_prepare
+g_main_context_push_thread_default
+g_main_context_query
+g_main_context_ref
+g_main_context_release
+g_main_context_remove_poll
+g_main_context_set_poll_func
+g_main_context_unref
+g_main_context_wait
+g_main_context_wakeup
+g_main_depth
+g_main_current_source
+g_main_loop_get_context
+g_main_loop_is_running
+g_main_loop_new
+g_main_loop_quit
+g_main_loop_ref
+g_main_loop_run
+g_main_loop_unref
+g_source_add_poll
+g_source_attach
+g_source_destroy
+g_source_get_can_recurse
+g_source_get_context
+g_source_get_current_time
+g_source_get_id
+g_source_get_name
+g_source_get_priority
+g_source_new
+g_source_ref
+g_source_remove
+g_source_remove_by_funcs_user_data
+g_source_remove_by_user_data
+g_source_remove_poll
+g_source_set_callback
+g_source_set_callback_indirect
+g_source_set_can_recurse
+g_source_set_funcs
+g_source_set_name
+g_source_set_name_by_id
+g_source_is_destroyed
+g_source_set_priority
+g_source_unref
+g_idle_add
+g_idle_add_full
+g_idle_remove_by_data
+g_idle_source_new
+g_timeout_add
+g_timeout_add_seconds
+g_timeout_add_full
+g_timeout_add_seconds_full
+g_timeout_source_new
+g_timeout_source_new_seconds
+#endif
+#endif
+
+#if IN_HEADER(__G_MAPPED_FILE_H__)
+#if IN_FILE(__G_MAPPED_FILE_C__)
+g_mapped_file_new G_GNUC_MALLOC
+g_mapped_file_get_length
+g_mapped_file_get_contents
+g_mapped_file_ref
+g_mapped_file_unref
+#ifndef G_DISABLE_DEPRECATED
+g_mapped_file_free
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_MARKUP_H__)
+#if IN_FILE(__G_MARKUP_C__)
+g_markup_error_quark
+g_markup_escape_text
+g_markup_parse_context_end_parse
+g_markup_parse_context_free
+g_markup_parse_context_get_element
+g_markup_parse_context_get_element_stack
+g_markup_parse_context_get_position
+g_markup_parse_context_get_user_data
+g_markup_parse_context_new
+g_markup_parse_context_parse
+g_markup_parse_context_push
+g_markup_parse_context_pop
+g_markup_printf_escaped G_GNUC_PRINTF(1,2)
+g_markup_vprintf_escaped
+g_markup_collect_attributes
+#endif
+#endif
+
+#if IN_HEADER(__G_MEM_H__)
+#if IN_FILE(__G_MEM_C__)
+g_free
+g_malloc G_GNUC_MALLOC
+g_malloc0 G_GNUC_MALLOC
+g_malloc_n G_GNUC_MALLOC
+g_malloc0_n G_GNUC_MALLOC
+g_mem_is_system_malloc
+g_mem_profile
+g_mem_set_vtable
+g_realloc
+g_realloc_n
+g_try_malloc G_GNUC_MALLOC
+g_try_malloc0 G_GNUC_MALLOC
+g_try_malloc_n G_GNUC_MALLOC
+g_try_malloc0_n G_GNUC_MALLOC
+g_try_realloc
+g_try_realloc_n
+#ifndef G_DISABLE_DEPRECATED
+g_allocator_free
+g_allocator_new
+g_mem_chunk_alloc
+g_mem_chunk_alloc0
+g_mem_chunk_clean
+g_mem_chunk_destroy
+g_mem_chunk_free
+g_mem_chunk_info
+g_mem_chunk_new
+g_mem_chunk_print
+g_mem_chunk_reset
+g_blow_chunks
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_SLICE_H__)
+#if IN_FILE(__G_SLICE_C__)
+g_slice_alloc G_GNUC_MALLOC
+g_slice_alloc0 G_GNUC_MALLOC
+g_slice_copy G_GNUC_MALLOC
+g_slice_free1
+g_slice_free_chain_with_offset
+g_slice_set_config
+g_slice_get_config
+g_slice_get_config_state
+#ifdef G_ENABLE_DEBUG
+#ifdef INCLUDE_INTERNAL_SYMBOLS
+g_slice_debug_tree_statistics
+#endif
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_MESSAGES_H__)
+#if IN_FILE(__G_MESSAGES_C__)
+g_printf_string_upper_bound
+g_log G_GNUC_PRINTF(3,4)
+g_log_default_handler
+g_log_remove_handler
+g_log_set_always_fatal
+g_log_set_default_handler
+g_log_set_fatal_mask
+g_log_set_handler
+g_logv
+g_return_if_fail_warning
+g_warn_message
+#ifndef G_DISABLE_DEPRECATED
+g_assert_warning G_GNUC_NORETURN
+#endif
+g_print G_GNUC_PRINTF(1,2)
+g_printerr G_GNUC_PRINTF(1,2)
+g_set_printerr_handler
+g_set_print_handler
+#endif
+#endif
+
+#if IN_HEADER(__G_NODE_H__)
+#if IN_FILE(__G_NODE_C__)
+g_node_child_index
+g_node_child_position
+g_node_children_foreach
+g_node_copy
+g_node_copy_deep
+g_node_depth
+g_node_destroy
+g_node_find
+g_node_find_child
+g_node_first_sibling
+g_node_get_root
+g_node_insert
+g_node_insert_after
+g_node_insert_before
+g_node_is_ancestor
+g_node_last_child
+g_node_last_sibling
+g_node_max_height
+g_node_n_children
+g_node_new
+g_node_n_nodes
+g_node_nth_child
+#ifndef G_DISABLE_DEPRECATED
+g_node_pop_allocator
+#endif
+g_node_prepend
+#ifndef G_DISABLE_DEPRECATED
+g_node_push_allocator
+#endif
+g_node_reverse_children
+g_node_traverse
+g_node_unlink
+#endif
+#endif
+
+#if IN_HEADER(__G_OPTION_H__)
+#if IN_FILE(__G_OPTION_C__)
+g_option_context_add_group
+g_option_context_add_main_entries
+g_option_error_quark
+g_option_context_free
+g_option_context_get_description
+g_option_context_get_help_enabled
+g_option_context_get_ignore_unknown_options
+g_option_context_get_main_group
+g_option_context_get_summary
+g_option_context_new
+g_option_context_parse
+g_option_context_set_description
+g_option_context_set_help_enabled
+g_option_context_set_ignore_unknown_options
+g_option_context_set_main_group
+g_option_context_set_summary
+g_option_context_set_translate_func
+g_option_context_set_translation_domain
+g_option_context_get_help
+g_option_group_add_entries
+g_option_group_free
+g_option_group_new
+g_option_group_set_error_hook
+g_option_group_set_parse_hooks
+g_option_group_set_translate_func
+g_option_group_set_translation_domain
+#endif
+#endif
+
+#if IN_HEADER(__G_PATTERN_H__)
+#if IN_FILE(__G_PATTERN_C__)
+g_pattern_match
+g_pattern_match_simple
+g_pattern_match_string
+g_pattern_spec_equal
+g_pattern_spec_free
+g_pattern_spec_new
+#endif
+#endif
+
+#if IN_HEADER(__G_POLL_H__)
+#if IN_FILE(__G_POLL_C__)
+g_poll
+#endif
+#endif
+
+#if IN_HEADER(__G_PRIMES_H__)
+#if IN_FILE(__G_PRIMES_C__)
+g_spaced_primes_closest G_GNUC_CONST
+#endif
+#endif
+
+#if IN_HEADER(__G_PRINTF_H__)
+#if IN_FILE(__G_PRINTF_C__)
+g_fprintf G_GNUC_PRINTF(2,3)
+g_printf G_GNUC_PRINTF(1,2)
+g_sprintf G_GNUC_PRINTF(2,3)
+g_vasprintf
+g_vfprintf
+g_vprintf
+g_vsprintf
+#endif
+#endif
+
+#if IN_HEADER(__G_UTILS_H__)
+#if IN_FILE(__G_PRINTF_C__)
+g_snprintf G_GNUC_PRINTF(3,4)
+g_vsnprintf
+#endif
+#endif
+
+#if IN_HEADER(__G_QSORT_H__)
+#if IN_FILE(__G_QSORT_C__)
+g_qsort_with_data
+#endif
+#endif
+
+#if IN_HEADER(__G_QUEUE_H__)
+#if IN_FILE(__G_QUEUE_C__)
+g_queue_clear
+g_queue_copy
+g_queue_delete_link
+g_queue_find
+g_queue_find_custom
+g_queue_foreach
+g_queue_free
+g_queue_get_length
+g_queue_index
+g_queue_init
+g_queue_insert_after
+g_queue_insert_before
+g_queue_insert_sorted
+g_queue_is_empty
+g_queue_link_index
+g_queue_new
+g_queue_peek_head
+g_queue_peek_head_link
+g_queue_peek_nth
+g_queue_peek_nth_link
+g_queue_peek_tail
+g_queue_peek_tail_link
+g_queue_pop_head
+g_queue_pop_head_link
+g_queue_pop_nth
+g_queue_pop_nth_link
+g_queue_pop_tail
+g_queue_pop_tail_link
+g_queue_push_head
+g_queue_push_head_link
+g_queue_push_nth
+g_queue_push_nth_link
+g_queue_push_tail
+g_queue_push_tail_link
+g_queue_remove
+g_queue_remove_all
+g_queue_reverse
+g_queue_sort
+g_queue_unlink
+#endif
+#endif
+
+#if IN_HEADER(__G_RAND_H__)
+#if IN_FILE(__G_RAND_C__)
+g_rand_copy
+g_rand_double
+g_rand_double_range
+g_rand_free
+g_rand_int
+g_rand_int_range
+g_rand_new
+g_rand_new_with_seed
+g_rand_new_with_seed_array
+g_random_double
+g_random_double_range
+g_random_int
+g_random_int_range
+g_random_set_seed
+g_rand_set_seed
+g_rand_set_seed_array
+#endif
+#endif
+
+#if IN_HEADER(__G_REL_H__)
+#if IN_FILE(__G_REL_C__)
+g_relation_count
+g_relation_delete
+g_relation_destroy
+g_relation_exists
+g_relation_index
+g_relation_insert
+g_relation_new
+g_relation_print
+g_relation_select
+g_tuples_destroy
+g_tuples_index
+#endif
+#endif
+
+#if IN_HEADER(__G_SCANNER_H__)
+#if IN_FILE(__G_SCANNER_C__)
+g_scanner_cur_line
+g_scanner_cur_position
+g_scanner_cur_token
+g_scanner_cur_value
+g_scanner_destroy
+g_scanner_eof
+g_scanner_error G_GNUC_PRINTF(2,3)
+g_scanner_get_next_token
+g_scanner_input_file
+g_scanner_input_text
+g_scanner_lookup_symbol
+g_scanner_new
+g_scanner_peek_next_token
+g_scanner_scope_add_symbol
+g_scanner_scope_foreach_symbol
+g_scanner_scope_lookup_symbol
+g_scanner_scope_remove_symbol
+g_scanner_set_scope
+g_scanner_sync_file_offset
+g_scanner_unexp_token
+g_scanner_warn G_GNUC_PRINTF(2,3)
+#endif
+#endif
+
+#if IN_HEADER(__G_SEQUENCE_H__)
+#if IN_FILE(__G_SEQUENCE_C__)
+g_sequence_new
+g_sequence_free
+g_sequence_get_length
+g_sequence_foreach
+g_sequence_foreach_range
+g_sequence_sort
+g_sequence_sort_iter
+g_sequence_get_begin_iter
+g_sequence_get_end_iter
+g_sequence_get_iter_at_pos
+g_sequence_append
+g_sequence_prepend
+g_sequence_insert_before
+g_sequence_move
+g_sequence_swap
+g_sequence_insert_sorted
+g_sequence_insert_sorted_iter
+g_sequence_sort_changed
+g_sequence_sort_changed_iter
+g_sequence_remove
+g_sequence_remove_range
+g_sequence_move_range
+g_sequence_search
+g_sequence_search_iter
+g_sequence_get
+g_sequence_set
+g_sequence_iter_is_begin
+g_sequence_iter_is_end
+g_sequence_iter_next
+g_sequence_iter_prev
+g_sequence_iter_get_position
+g_sequence_iter_move
+g_sequence_iter_get_sequence
+g_sequence_iter_compare
+g_sequence_range_get_midpoint
+#endif
+#endif
+
+#if IN_HEADER(__G_SHELL_H__)
+#if IN_FILE(__G_SHELL_C__)
+g_shell_error_quark
+g_shell_parse_argv
+g_shell_quote
+g_shell_unquote
+#endif
+#endif
+
+#if IN_HEADER(__G_SLIST_H__)
+#if IN_FILE(__G_SLIST_C__)
+g_slist_alloc
+g_slist_append
+g_slist_concat
+g_slist_copy
+g_slist_delete_link
+g_slist_find
+g_slist_find_custom
+g_slist_foreach
+g_slist_free
+g_slist_free_1
+g_slist_index
+g_slist_insert
+g_slist_insert_before
+g_slist_insert_sorted
+g_slist_insert_sorted_with_data
+g_slist_last
+g_slist_length
+g_slist_nth
+g_slist_nth_data
+#ifndef G_DISABLE_DEPRECATED
+g_slist_pop_allocator
+#endif
+g_slist_position
+g_slist_prepend
+#ifndef G_DISABLE_DEPRECATED
+g_slist_push_allocator
+#endif
+g_slist_remove
+g_slist_remove_all
+g_slist_remove_link
+g_slist_reverse
+g_slist_sort
+g_slist_sort_with_data
+#endif
+#endif
+
+#if IN_HEADER(__G_SPAWN_H__)
+#if IN_FILE(__G_SPAWN_C__)
+#ifndef _WIN64
+g_spawn_async PRIVATE
+g_spawn_async_with_pipes PRIVATE
+#endif
+g_spawn_close_pid
+#ifndef _WIN64
+g_spawn_command_line_async PRIVATE
+g_spawn_command_line_sync PRIVATE
+#endif
+g_spawn_error_quark
+#ifndef _WIN64
+g_spawn_sync PRIVATE
+#endif
+#ifdef G_OS_WIN32
+g_spawn_async_utf8
+g_spawn_async_with_pipes_utf8
+g_spawn_command_line_async_utf8
+g_spawn_command_line_sync_utf8
+g_spawn_sync_utf8
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_STDIO_H__)
+#if IN_FILE(__G_STDIO_C__)
+#if !defined(G_OS_UNIX) || defined(G_STDIO_NO_WRAP_ON_UNIX)
+/* gstdio wrappers */
+g_chmod
+g_open
+g_creat
+g_rename
+g_mkdir
+g_stat
+g_lstat
+g_remove
+g_fopen
+g_freopen
+g_utime
+#endif
+g_access
+g_chdir
+g_unlink
+g_rmdir
+#endif
+#endif
+
+#if IN_HEADER(__G_STRFUNCS_H__)
+#if IN_FILE(__G_STRFUNCS_C__)
+g_ascii_digit_value G_GNUC_CONST
+g_ascii_dtostr
+g_ascii_formatd
+g_ascii_strdown G_GNUC_MALLOC
+g_ascii_strtod
+g_ascii_strtoull
+g_ascii_strtoll
+g_ascii_strup G_GNUC_MALLOC
+g_ascii_tolower G_GNUC_CONST
+g_ascii_toupper G_GNUC_CONST
+g_ascii_xdigit_value G_GNUC_CONST
+g_ascii_strcasecmp
+g_ascii_strncasecmp
+g_memdup G_GNUC_MALLOC
+g_stpcpy
+g_strcanon
+g_strchomp
+g_strchug
+g_strcompress G_GNUC_MALLOC
+g_strconcat G_GNUC_MALLOC G_GNUC_NULL_TERMINATED
+g_strdelimit
+g_strdup G_GNUC_MALLOC
+g_strdup_printf G_GNUC_PRINTF(1,2) G_GNUC_MALLOC
+g_strdupv G_GNUC_MALLOC
+g_strdup_vprintf G_GNUC_MALLOC
+g_strerror G_GNUC_CONST
+g_strescape G_GNUC_MALLOC
+g_strfreev
+g_str_has_prefix
+g_str_has_suffix
+g_strjoin G_GNUC_MALLOC G_GNUC_NULL_TERMINATED
+g_strjoinv G_GNUC_MALLOC
+g_strlcat
+g_strlcpy
+g_strndup G_GNUC_MALLOC
+g_strnfill G_GNUC_MALLOC
+g_strreverse
+g_strrstr
+g_strrstr_len
+g_strsignal G_GNUC_CONST
+g_strsplit G_GNUC_MALLOC
+g_strsplit_set G_GNUC_MALLOC
+g_strstr_len
+g_strtod
+#ifndef G_DISABLE_DEPRECATED
+g_strcasecmp
+g_strncasecmp
+g_strup
+g_strdown
+#endif
+g_strv_length
+g_strip_context G_GNUC_FORMAT(1)
+g_dgettext G_GNUC_FORMAT(2)
+g_dcgettext G_GNUC_FORMAT(2)
+g_dngettext G_GNUC_FORMAT(3)
+g_dpgettext G_GNUC_FORMAT(2)
+g_dpgettext2 G_GNUC_FORMAT(3)
+#endif
+#endif
+
+#if IN_HEADER(__G_URI_FUNCS_H__)
+#if IN_FILE(__G_URI_FUNCS_C__)
+g_uri_unescape_string 
+g_uri_unescape_segment 
+g_uri_parse_scheme 
+g_uri_escape_string 
+#endif
+#endif
+
+#if IN_HEADER(__G_STRING_H__)
+#if IN_FILE(__G_STRING_C__)
+g_string_append
+g_string_append_len
+g_string_append_printf G_GNUC_PRINTF(2,3)
+g_string_append_unichar
+g_string_append_vprintf
+g_string_ascii_down
+g_string_ascii_up
+g_string_assign
+g_string_chunk_free
+g_string_chunk_clear
+g_string_chunk_insert
+g_string_chunk_insert_const
+g_string_chunk_insert_len
+g_string_chunk_new
+g_string_equal
+g_string_erase
+g_string_free
+g_string_hash
+g_string_insert
+g_string_insert_c
+g_string_insert_len
+g_string_insert_unichar
+g_string_new
+g_string_new_len
+g_string_overwrite
+g_string_overwrite_len
+g_string_prepend
+g_string_prepend_c
+g_string_prepend_len
+g_string_prepend_unichar
+g_string_printf G_GNUC_PRINTF(2,3)
+g_string_set_size
+g_string_sized_new
+g_string_truncate
+g_string_append_uri_escaped
+#ifndef G_DISABLE_DEPRECATED
+g_string_down
+g_string_up
+#endif
+g_string_vprintf
+#ifdef INCLUDE_INTERNAL_SYMBOLS
+ /* these are not internal, but we don't want to alias them */
+g_string_append_c
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_BITLOCK_H__)
+#if IN_FILE(__G_BITLOCK_C__)
+g_bit_lock
+g_bit_trylock
+g_bit_unlock
+#endif
+#endif
+
+#if IN_HEADER(__G_THREAD_H__)
+#if IN_FILE(__G_THREAD_C__)
+g_once_impl
+g_once_init_enter_impl
+g_once_init_leave
+#ifdef INCLUDE_INTERNAL_SYMBOLS
+g_thread_init_glib
+g_once_init_enter
+#endif
+#ifdef INCLUDE_VARIABLES
+g_thread_functions_for_glib_use
+g_threads_got_initialized
+g_thread_use_default_impl
+g_thread_gettime
+#endif
+g_thread_create_full
+g_thread_error_quark
+g_thread_exit
+g_thread_join
+g_thread_self
+g_thread_set_priority
+g_static_mutex_free
+g_static_mutex_get_mutex_impl
+g_static_mutex_init
+g_static_private_free
+g_static_private_get
+g_static_private_init
+g_static_private_set
+g_static_rec_mutex_free
+g_static_rec_mutex_init
+g_static_rec_mutex_lock
+g_static_rec_mutex_lock_full
+g_static_rec_mutex_trylock
+g_static_rec_mutex_unlock
+g_static_rec_mutex_unlock_full
+g_static_rw_lock_free
+g_static_rw_lock_init
+g_static_rw_lock_reader_lock
+g_static_rw_lock_reader_trylock
+g_static_rw_lock_reader_unlock
+g_static_rw_lock_writer_lock
+g_static_rw_lock_writer_trylock
+g_static_rw_lock_writer_unlock
+g_thread_foreach
+g_thread_get_initialized
+#endif
+#endif
+
+#if IN_HEADER(__G_THREADPOOL_H__)
+#if IN_FILE(__G_THREADPOOL_C__)
+g_thread_pool_free
+g_thread_pool_get_max_threads
+g_thread_pool_get_max_unused_threads
+g_thread_pool_get_max_idle_time
+g_thread_pool_get_num_threads
+g_thread_pool_get_num_unused_threads
+g_thread_pool_new
+g_thread_pool_push
+g_thread_pool_set_max_threads
+g_thread_pool_set_max_unused_threads
+g_thread_pool_set_max_idle_time
+g_thread_pool_stop_unused_threads
+g_thread_pool_unprocessed
+g_thread_pool_set_sort_function
+#endif
+#endif
+
+#if IN_HEADER(__G_TEST_UTILS_H__)
+#if IN_FILE(__G_MESSAGES_C__)
+g_test_log_set_fatal_handler
+#endif
+#if IN_FILE(__G_TEST_UTILS_C__)
+g_assertion_message G_GNUC_NORETURN
+g_assertion_message_cmpnum G_GNUC_NORETURN
+g_assertion_message_cmpstr G_GNUC_NORETURN
+g_assertion_message_expr G_GNUC_NORETURN
+g_assertion_message_error G_GNUC_NORETURN
+g_strcmp0
+g_test_add_data_func
+g_test_add_func
+g_test_add_vtable
+g_test_bug
+g_test_bug_base
+#ifdef INCLUDE_VARIABLES
+g_test_config_vars
+#endif
+g_test_create_case
+g_test_create_suite
+g_test_get_root
+g_test_init
+g_test_log_buffer_free
+g_test_log_buffer_new
+g_test_log_buffer_pop
+g_test_log_buffer_push
+g_test_log_msg_free
+g_test_log_type_name
+g_test_maximized_result
+g_test_message
+g_test_minimized_result
+g_test_queue_destroy
+g_test_queue_free
+g_test_rand_double
+g_test_rand_double_range
+g_test_rand_int
+g_test_rand_int_range
+g_test_run
+g_test_run_suite
+g_test_suite_add
+g_test_suite_add_suite
+g_test_timer_elapsed
+g_test_timer_last
+g_test_timer_start
+g_test_trap_assertions
+g_test_trap_fork
+g_test_trap_has_passed
+g_test_trap_reached_timeout
+#endif
+#endif
+
+#if IN_HEADER(__G_TIMER_H__)
+#if IN_FILE(__G_TIMER_C__)
+g_timer_continue
+g_timer_destroy
+g_timer_elapsed
+g_timer_new
+g_timer_reset
+g_timer_start
+g_timer_stop
+g_time_val_add
+g_time_val_from_iso8601
+g_time_val_to_iso8601 G_GNUC_MALLOC
+g_usleep
+#endif
+#endif
+
+#if IN_HEADER(__G_TREE_H__)
+#if IN_FILE(__G_TREE_C__)
+g_tree_destroy
+g_tree_foreach
+g_tree_height
+g_tree_insert
+g_tree_lookup
+g_tree_lookup_extended
+g_tree_new
+g_tree_ref
+g_tree_unref
+g_tree_new_full
+g_tree_new_with_data
+g_tree_nnodes
+g_tree_remove
+g_tree_replace
+g_tree_search
+g_tree_steal
+#ifndef G_DISABLE_DEPRECATED
+g_tree_traverse
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UNIBREAK_C__)
+g_unichar_break_type G_GNUC_CONST
+#endif
+#endif
+
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UNICOLLATE_C__)
+g_utf8_collate
+g_utf8_collate_key G_GNUC_MALLOC
+g_utf8_collate_key_for_filename G_GNUC_MALLOC
+#endif
+#endif
+
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UNIDECOMP_C__)
+g_unicode_canonical_decomposition G_GNUC_MALLOC
+g_unicode_canonical_ordering
+g_unichar_combining_class G_GNUC_CONST
+g_utf8_normalize
+#endif
+#endif
+
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UNIPROP_C__)
+g_unichar_isalnum G_GNUC_CONST
+g_unichar_isalpha G_GNUC_CONST
+g_unichar_iscntrl G_GNUC_CONST
+g_unichar_isdefined G_GNUC_CONST
+g_unichar_isdigit G_GNUC_CONST
+g_unichar_isgraph G_GNUC_CONST
+g_unichar_islower G_GNUC_CONST
+g_unichar_isprint G_GNUC_CONST
+g_unichar_ispunct G_GNUC_CONST
+g_unichar_isspace G_GNUC_CONST
+g_unichar_istitle G_GNUC_CONST
+g_unichar_isupper G_GNUC_CONST
+g_unichar_iswide G_GNUC_CONST
+g_unichar_iswide_cjk G_GNUC_CONST
+g_unichar_isxdigit G_GNUC_CONST
+g_unichar_iszerowidth G_GNUC_CONST
+g_unichar_tolower G_GNUC_CONST
+g_unichar_totitle G_GNUC_CONST
+g_unichar_toupper G_GNUC_CONST
+g_unichar_ismark G_GNUC_CONST
+g_unichar_get_mirror_char
+g_unichar_get_script
+g_unichar_digit_value G_GNUC_CONST
+g_unichar_xdigit_value G_GNUC_CONST
+g_unichar_type G_GNUC_CONST
+g_utf8_casefold G_GNUC_MALLOC
+g_utf8_strup G_GNUC_MALLOC
+g_utf8_strdown G_GNUC_MALLOC
+#endif
+#endif
+
+#if IN_HEADER(__G_UNICODE_H__)
+#if IN_FILE(__G_UTF8_C__)
+g_get_charset
+g_ucs4_to_utf16 G_GNUC_MALLOC
+g_ucs4_to_utf8 G_GNUC_MALLOC
+g_utf16_to_ucs4 G_GNUC_MALLOC
+g_utf16_to_utf8 G_GNUC_MALLOC
+g_utf8_find_next_char
+g_utf8_find_prev_char
+g_utf8_get_char
+g_utf8_get_char_validated
+g_utf8_offset_to_pointer
+g_utf8_pointer_to_offset
+g_utf8_prev_char
+g_utf8_strchr
+g_utf8_strlen
+g_utf8_strncpy
+g_utf8_strrchr
+g_utf8_strreverse
+g_utf8_to_ucs4 G_GNUC_MALLOC
+g_utf8_to_ucs4_fast G_GNUC_MALLOC
+g_utf8_to_utf16 G_GNUC_MALLOC
+g_utf8_validate
+g_unichar_to_utf8
+g_unichar_validate
+#endif
+#endif
+
+#if IN_HEADER(__GLIBINTL_H__)
+#if IN_FILE(__G_UTILS_C__)
+glib_gettext G_GNUC_FORMAT(1)
+#endif
+#endif
+
+#if IN_HEADER(__G_HASH_H__)
+#if IN_FILE(__G_UTILS_C__)
+g_int_equal
+g_int_hash
+g_int64_equal
+g_int64_hash
+g_double_equal
+g_double_hash
+g_direct_equal G_GNUC_CONST
+g_direct_hash G_GNUC_CONST
+#endif
+#if IN_FILE(__G_STRING_C__)
+g_str_equal
+g_str_hash
+#endif
+#endif
+
+#if IN_HEADER(__G_UTILS_H__)
+#if IN_FILE(__G_UTILS_C__)
+g_atexit
+#ifndef G_DISABLE_DEPRECATED
+g_basename
+#endif
+g_get_application_name
+#ifndef _WIN64
+g_find_program_in_path PRIVATE
+g_get_current_dir PRIVATE
+g_getenv PRIVATE
+g_unsetenv PRIVATE
+g_get_home_dir PRIVATE
+#endif
+g_get_host_name
+#ifndef _WIN64
+g_setenv PRIVATE
+#endif
+g_listenv
+#ifdef G_OS_WIN32
+g_find_program_in_path_utf8
+g_get_current_dir_utf8
+g_getenv_utf8
+g_unsetenv_utf8
+g_setenv_utf8
+g_get_home_dir_utf8
+#endif
+g_get_language_names
+g_get_prgname
+#ifndef _WIN64
+g_get_real_name PRIVATE
+#endif
+#ifdef G_OS_WIN32
+g_get_real_name_utf8
+#endif
+g_get_system_config_dirs
+g_get_system_data_dirs
+#ifdef G_OS_WIN32
+g_win32_get_system_data_dirs_for_module
+#endif
+#ifndef _WIN64
+g_get_tmp_dir PRIVATE
+#endif
+#ifdef G_OS_WIN32
+g_get_tmp_dir_utf8
+#endif
+g_get_user_cache_dir
+g_get_user_config_dir
+g_get_user_data_dir
+g_reload_user_special_dirs_cache
+g_get_user_special_dir
+#ifndef _WIN64
+g_get_user_name PRIVATE
+#endif
+#ifdef G_OS_WIN32
+g_get_user_name_utf8
+#endif
+glib_check_version
+g_nullify_pointer
+g_parse_debug_string
+g_path_get_basename G_GNUC_MALLOC
+g_path_get_dirname G_GNUC_MALLOC
+g_path_is_absolute
+g_path_skip_root
+g_set_application_name
+g_set_prgname
+#ifdef INCLUDE_INTERNAL_SYMBOLS
+g_bit_nth_lsf
+g_bit_nth_msf
+g_bit_storage
+g_trash_stack_height
+g_trash_stack_peek
+g_trash_stack_pop
+g_trash_stack_push
+g_get_codeset
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_REGEX_H__)
+#if IN_FILE(__G_REGEX_C__)
+g_regex_error_quark
+g_regex_new
+g_regex_ref
+g_regex_unref
+g_regex_get_pattern
+g_regex_get_max_backref
+g_regex_get_capture_count
+g_regex_get_string_number
+g_regex_get_compile_flags
+g_regex_get_match_flags
+g_regex_escape_string
+g_regex_match_simple
+g_regex_match
+g_regex_match_full
+g_regex_match_all
+g_regex_match_all_full
+g_regex_split_simple
+g_regex_split
+g_regex_split_full
+g_regex_replace
+g_regex_replace_literal
+g_regex_replace_eval
+g_regex_check_replacement
+g_match_info_get_regex
+g_match_info_get_string
+g_match_info_free
+g_match_info_next
+g_match_info_matches
+g_match_info_get_match_count
+g_match_info_is_partial_match
+g_match_info_expand_references
+g_match_info_fetch
+g_match_info_fetch_pos
+g_match_info_fetch_named
+g_match_info_fetch_named_pos
+g_match_info_fetch_all
+#endif
+#endif
+
+#if IN_HEADER(__G_VARIANT_TYPE_H__)
+#if IN_FILE(__G_VARIANT_TYPE_C__)
+g_variant_type_string_is_valid
+g_variant_type_string_scan
+g_variant_type_free
+g_variant_type_copy
+g_variant_type_new
+g_variant_type_get_string_length
+g_variant_type_peek_string
+g_variant_type_dup_string
+g_variant_type_is_definite
+g_variant_type_is_container
+g_variant_type_is_basic
+g_variant_type_is_maybe
+g_variant_type_is_array
+g_variant_type_is_tuple
+g_variant_type_is_dict_entry
+g_variant_type_is_variant
+g_variant_type_hash
+g_variant_type_equal
+g_variant_type_is_subtype_of
+g_variant_type_element
+g_variant_type_first
+g_variant_type_next
+g_variant_type_n_items
+g_variant_type_key
+g_variant_type_value
+g_variant_type_new_array
+g_variant_type_new_maybe
+g_variant_type_new_tuple
+g_variant_type_new_dict_entry
+g_variant_type_checked_
+#endif
+#endif
+
+#if IN_HEADER(__G_VARIANT_H__)
+#if IN_FILE(__G_VARIANT_CORE_C__)
+g_variant_unref
+g_variant_ref
+g_variant_ref_sink
+g_variant_is_floating
+g_variant_n_children
+g_variant_get_child_value
+g_variant_get_size
+g_variant_get_data
+g_variant_store
+g_variant_is_normal_form
+#endif
+
+#if IN_FILE(__G_VARIANT_C__)
+g_variant_get_type
+g_variant_get_type_string
+g_variant_is_of_type
+g_variant_is_container
+g_variant_classify
+g_variant_compare
+
+g_variant_new_boolean
+g_variant_new_byte
+g_variant_new_int16
+g_variant_new_uint16
+g_variant_new_int32
+g_variant_new_uint32
+g_variant_new_int64
+g_variant_new_uint64
+g_variant_new_handle
+g_variant_new_double
+g_variant_new_string
+g_variant_new_object_path
+g_variant_is_object_path
+g_variant_new_signature
+g_variant_is_signature
+g_variant_new_variant
+g_variant_new_strv
+g_variant_new_bytestring
+g_variant_new_bytestring_array
+
+g_variant_get_boolean
+g_variant_get_byte
+g_variant_get_int16
+g_variant_get_uint16
+g_variant_get_int32
+g_variant_get_uint32
+g_variant_get_int64
+g_variant_get_uint64
+g_variant_get_handle
+g_variant_get_double
+g_variant_get_string
+g_variant_dup_string
+g_variant_get_variant
+g_variant_get_strv
+g_variant_dup_strv
+g_variant_get_bytestring
+g_variant_dup_bytestring
+g_variant_get_bytestring_array
+g_variant_dup_bytestring_array
+
+g_variant_new_maybe
+g_variant_new_array
+g_variant_new_tuple
+g_variant_new_dict_entry
+
+g_variant_get_maybe
+g_variant_get_fixed_array
+
+g_variant_print
+g_variant_print_string
+
+g_variant_hash
+g_variant_equal
+
+g_variant_iter_copy
+g_variant_iter_free
+g_variant_iter_init
+g_variant_iter_n_children
+g_variant_iter_new
+g_variant_iter_next_value
+
+g_variant_builder_add_value
+g_variant_builder_init
+g_variant_builder_clear
+g_variant_builder_open
+g_variant_builder_close
+g_variant_builder_end
+g_variant_builder_new
+g_variant_builder_unref
+g_variant_builder_ref
+
+g_variant_new_va
+g_variant_get_va
+g_variant_new
+g_variant_get
+
+g_variant_builder_add
+g_variant_get_child
+g_variant_iter_next
+g_variant_iter_loop
+
+g_variant_new_from_data
+g_variant_get_normal_form
+g_variant_byteswap
+#endif
+
+#if IN_FILE(__G_VARIANT_PARSER_C__)
+g_variant_new_parsed
+g_variant_new_parsed_va
+g_variant_builder_add_parsed
+g_variant_parse
+g_variant_parser_get_error_quark
+#endif
+#endif
+
+#if IN_HEADER(__G_VARIANT_TYPE_INFO_H__)
+#if IN_FILE(__G_VARIANT_TYPE_INFO_C__)
+g_variant_type_info_get_type_string
+g_variant_type_info_query
+g_variant_type_info_element
+g_variant_type_info_query_element
+g_variant_type_info_n_members
+g_variant_type_info_member_info
+g_variant_type_info_get
+g_variant_type_info_ref
+g_variant_type_info_unref
+g_variant_type_info_assert_no_infos
+#endif
+#endif
+
+#if IN_HEADER(__G_VARIANT_SERIALISER_H__)
+#if IN_FILE(__G_VARIANT_SERIALISER_C__)
+g_variant_serialised_byteswap
+g_variant_serialised_get_child
+g_variant_serialised_is_normal
+g_variant_serialised_n_children
+g_variant_serialiser_is_object_path
+g_variant_serialiser_is_signature
+g_variant_serialiser_is_string
+g_variant_serialiser_needed_size
+g_variant_serialiser_serialise
+#endif
+#endif
+
+#if IN_HEADER(__G_VARIANT_INTERNAL_H__)
+#if IN_FILE(__G_VARIANT_C__)
+g_variant_format_string_scan_type
+g_variant_format_string_scan
+#endif
+#endif
+
+#if IN_HEADER(__G_WIN32_H__)
+#if IN_FILE(__G_WIN32_H__)
+#ifdef G_OS_WIN32
+g_win32_error_message
+g_win32_ftruncate
+g_win32_get_package_installation_directory_of_module
+#ifndef _WIN64
+g_win32_get_package_installation_directory PRIVATE
+#endif
+g_win32_get_package_installation_directory_utf8
+#ifndef _WIN64
+g_win32_get_package_installation_subdirectory PRIVATE
+#endif
+g_win32_get_package_installation_subdirectory_utf8
+g_win32_get_windows_version
+g_win32_getlocale
+g_win32_locale_filename_from_utf8
+#endif
+#endif
+#endif
+
+#if IN_HEADER(__G_HOST_UTILS_H__)
+#if IN_FILE(__G_HOST_UTILS_C__)
+g_hostname_is_non_ascii
+g_hostname_is_ascii_encoded
+g_hostname_is_ip_address
+g_hostname_to_ascii
+g_hostname_to_unicode
+#endif
+#endif
+
+#ifdef INCLUDE_VARIABLES
+g_ascii_table
+g_utf8_skip
+g_idle_funcs
+g_timeout_funcs
+g_io_watch_funcs
+g_child_watch_funcs
+glib_binary_age
+glib_interface_age
+glib_major_version
+glib_mem_profiler_table
+glib_micro_version
+glib_minor_version
+glib_on_error_halt
+g_mem_gc_friendly
+#endif
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glib_probes.d b/resource/csdk/connectivity/lib/android/glib-master/glib/glib_probes.d
new file mode 100644 (file)
index 0000000..9232e1b
--- /dev/null
@@ -0,0 +1,8 @@
+provider glib {
+       probe mem__alloc(void*, unsigned int, unsigned int, unsigned int);
+       probe mem__realloc(void*, void *, unsigned int, unsigned int);
+       probe mem__free(void*);
+       probe slice__alloc(void*, unsigned int);
+       probe slice__free(void*, unsigned int);
+       probe quark__new(char *, unsigned int);
+};
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glib_trace.h b/resource/csdk/connectivity/lib/android/glib-master/glib/glib_trace.h
new file mode 100644 (file)
index 0000000..789e88d
--- /dev/null
@@ -0,0 +1,43 @@
+/* GLIB - Library of useful routines for C programming
+ * 
+ * Copyright (C) 2009,2010 Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#ifndef __GLIBTRACE_H__
+#define __GLIBTRACE_H__
+
+#ifndef SIZEOF_CHAR
+#error "config.h must be included prior to glib_trace.h"
+#endif
+
+#ifdef HAVE_DTRACE
+
+/* include the generated probes header and put markers in code */
+#include "glib_probes.h"
+#define TRACE(probe) probe
+
+#else
+
+/* Wrap the probe to allow it to be removed when no systemtap available */
+#define TRACE(probe)
+
+#endif
+
+#endif /* __GLIBTRACE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glibconfig.h.win32.in b/resource/csdk/connectivity/lib/android/glib-master/glib/glibconfig.h.win32.in
new file mode 100644 (file)
index 0000000..fbac9d2
--- /dev/null
@@ -0,0 +1,284 @@
+/* glibconfig.h.win32.in. Originally merged from two versions of
+ * glibconfig.h, generated by the GLib configure script, for gcc and
+ * MSVC.
+ */
+
+/* glibconfig.h
+ *
+ * This is a generated file.  Please modify 'glibconfig.h.win32.in'
+ */
+
+#ifndef __G_LIBCONFIG_H__
+#define __G_LIBCONFIG_H__
+
+#include <glib/gmacros.h>
+
+#include <limits.h>
+#include <float.h>
+
+G_BEGIN_DECLS
+
+#define G_MINFLOAT     FLT_MIN
+#define G_MAXFLOAT     FLT_MAX
+#define G_MINDOUBLE    DBL_MIN
+#define G_MAXDOUBLE    DBL_MAX
+#define G_MINSHORT     SHRT_MIN
+#define G_MAXSHORT     SHRT_MAX
+#define G_MAXUSHORT    USHRT_MAX
+#define G_MININT       INT_MIN
+#define G_MAXINT       INT_MAX
+#define G_MAXUINT      UINT_MAX
+#define G_MINLONG      LONG_MIN
+#define G_MAXLONG      LONG_MAX
+#define G_MAXULONG     ULONG_MAX
+
+typedef signed char gint8;
+typedef unsigned char guint8;
+typedef signed short gint16;
+typedef unsigned short guint16;
+#define G_GINT16_MODIFIER "h"
+#define G_GINT16_FORMAT "hi"
+#define G_GUINT16_FORMAT "hu"
+typedef signed int gint32;
+typedef unsigned int guint32;
+#define G_GINT32_MODIFIER ""
+#define G_GINT32_FORMAT "i"
+#define G_GUINT32_FORMAT "u"
+#define G_HAVE_GINT64 1          /* deprecated, always true */
+
+#ifndef _MSC_VER
+G_GNUC_EXTENSION typedef signed long long gint64;
+G_GNUC_EXTENSION typedef unsigned long long guint64;
+#else /* _MSC_VER */
+typedef signed __int64 gint64;
+typedef unsigned __int64 guint64;
+#endif /* _MSC_VER */
+
+#ifndef _MSC_VER
+#define G_GINT64_CONSTANT(val) (G_GNUC_EXTENSION (val##LL))
+#else /* _MSC_VER */
+#define G_GINT64_CONSTANT(val) (val##i64)
+#endif /* _MSC_VER */
+#ifndef _MSC_VER
+#define G_GUINT64_CONSTANT(val)        (G_GNUC_EXTENSION (val##ULL))
+#else /* _MSC_VER */
+#define G_GUINT64_CONSTANT(val)        (val##Ui64)
+#endif /* _MSC_VER */
+#define G_GINT64_MODIFIER "I64"
+#define G_GINT64_FORMAT "I64i"
+#define G_GUINT64_FORMAT "I64u"
+
+#if defined(_WIN64) || defined(_M_X64) || defined(_M_AMD64)
+
+#define GLIB_SIZEOF_VOID_P 8
+#define GLIB_SIZEOF_LONG   4
+#define GLIB_SIZEOF_SIZE_T 8
+
+typedef signed long long gssize;
+typedef unsigned long long gsize;
+#define G_GSIZE_MODIFIER "I64"
+#define G_GSSIZE_FORMAT "I64d"
+#define G_GSIZE_FORMAT "I64u"
+
+#define G_MAXSIZE      G_MAXUINT64
+#define G_MINSSIZE     G_MININT64
+#define G_MAXSSIZE     G_MAXINT64
+
+#else
+
+#define GLIB_SIZEOF_VOID_P 4
+#define GLIB_SIZEOF_LONG   4
+#define GLIB_SIZEOF_SIZE_T 4
+
+typedef signed int gssize;
+typedef unsigned int gsize;
+#define G_GSIZE_MODIFIER ""
+#define G_GSSIZE_FORMAT "i"
+#define G_GSIZE_FORMAT "u"
+
+#define G_MAXSIZE      G_MAXUINT
+#define G_MINSSIZE     G_MININT
+#define G_MAXSSIZE     G_MAXINT
+
+#endif
+
+typedef gint64 goffset;
+#define G_MINOFFSET    G_MININT64
+#define G_MAXOFFSET    G_MAXINT64
+
+#define G_GOFFSET_MODIFIER      G_GINT64_MODIFIER
+#define G_GOFFSET_FORMAT        G_GINT64_FORMAT
+#define G_GOFFSET_CONSTANT(val) G_GINT64_CONSTANT(val)
+
+
+#ifndef _WIN64
+
+#define GPOINTER_TO_INT(p)     ((gint)   (p))
+#define GPOINTER_TO_UINT(p)    ((guint)  (p))
+
+#define GINT_TO_POINTER(i)     ((gpointer)  (i))
+#define GUINT_TO_POINTER(u)    ((gpointer)  (u))
+
+typedef signed int gintptr;
+typedef unsigned int guintptr;
+
+#define G_GINTPTR_MODIFIER      ""
+#define G_GINTPTR_FORMAT        "i"
+#define G_GUINTPTR_FORMAT       "u"
+
+#else
+
+#define GPOINTER_TO_INT(p)     ((gint)  (gint64) (p))
+#define GPOINTER_TO_UINT(p)    ((guint) (guint64) (p))
+
+#define GINT_TO_POINTER(i)     ((gpointer) (gint64) (i))
+#define GUINT_TO_POINTER(u)    ((gpointer) (guint64) (u))
+
+#ifndef _MSC_VER
+typedef signed long long gintptr;
+typedef unsigned long long guintptr;
+#else
+typedef signed __int64 gintptr;
+typedef unsigned __int64 guintptr;
+#endif
+
+#define G_GINTPTR_MODIFIER      "I64"
+#define G_GINTPTR_FORMAT        "I64i"
+#define G_GUINTPTR_FORMAT       "I64u"
+
+#endif
+
+#ifdef NeXT /* @#%@! NeXTStep */
+# define g_ATEXIT(proc)        (!atexit (proc))
+#else
+# define g_ATEXIT(proc)        (atexit (proc))
+#endif
+
+#define g_memmove(dest,src,len) G_STMT_START { memmove ((dest), (src), (len)); } G_STMT_END
+
+#define GLIB_MAJOR_VERSION @GLIB_MAJOR_VERSION@
+#define GLIB_MINOR_VERSION @GLIB_MINOR_VERSION@
+#define GLIB_MICRO_VERSION @GLIB_MICRO_VERSION@
+
+#define G_OS_WIN32
+#define G_PLATFORM_WIN32
+@GLIB_WIN32_STATIC_COMPILATION_DEFINE@
+
+#ifndef _MSC_VER
+#define G_VA_COPY      va_copy
+#endif /* not _MSC_VER */
+
+#ifdef __cplusplus
+#define        G_HAVE_INLINE   1
+#else  /* !__cplusplus */
+#ifndef _MSC_VER
+#define G_HAVE_INLINE 1
+#endif /* _MSC_VER */
+#define G_HAVE___INLINE 1
+#if !defined(_MSC_VER) && !defined(__DMC__)
+#define G_HAVE___INLINE__ 1
+#endif /* !_MSC_VER and !__DMC__ */
+#endif /* !__cplusplus */
+
+#define G_CAN_INLINE   1
+
+#ifndef _MSC_VER
+#define G_HAVE_ISO_VARARGS 1
+
+/* gcc-2.95.x supports both gnu style and ISO varargs, but if -ansi
+ * is passed ISO vararg support is turned off, and there is no work
+ * around to turn it on, so we unconditionally turn it off.
+ */
+#if __GNUC__ == 2 && __GNUC_MINOR__ == 95
+#  undef G_HAVE_ISO_VARARGS
+#endif
+
+#define G_HAVE_GNUC_VARARGS 1
+#else /* _MSC_VER */
+/* varargs macros available since msvc8 (vs2005) */
+#  if _MSC_VER >= 1400
+#    define G_HAVE_ISO_VARARGS 1
+#   endif
+#endif /* not _MSC_VER */
+#define G_HAVE_GROWING_STACK 0
+
+#define G_GNUC_INTERNAL
+
+#define G_THREADS_ENABLED
+#define G_THREADS_IMPL_WIN32
+typedef struct _GMutex* GStaticMutex;
+#define G_STATIC_MUTEX_INIT NULL
+#define g_static_mutex_get_mutex(mutex) \
+  (g_static_mutex_get_mutex_impl_shortcut (mutex))
+/* This represents a system thread as used by the implementation. An
+ * alien implementaion, as loaded by g_thread_init can only count on
+ * "sizeof (gpointer)" bytes to store their info. We however need more
+ * for some of our native implementations. */
+typedef union _GSystemThread GSystemThread;
+union _GSystemThread
+{
+#ifndef _WIN64
+  char   data[4];
+#else
+  char   data[8];
+#endif
+  double dummy_double;
+  void  *dummy_pointer;
+  long   dummy_long;
+};
+
+#define GINT16_TO_LE(val)      ((gint16) (val))
+#define GUINT16_TO_LE(val)     ((guint16) (val))
+#define GINT16_TO_BE(val)      ((gint16) GUINT16_SWAP_LE_BE (val))
+#define GUINT16_TO_BE(val)     (GUINT16_SWAP_LE_BE (val))
+#define GINT32_TO_LE(val)      ((gint32) (val))
+#define GUINT32_TO_LE(val)     ((guint32) (val))
+#define GINT32_TO_BE(val)      ((gint32) GUINT32_SWAP_LE_BE (val))
+#define GUINT32_TO_BE(val)     (GUINT32_SWAP_LE_BE (val))
+#define GINT64_TO_LE(val)      ((gint64) (val))
+#define GUINT64_TO_LE(val)     ((guint64) (val))
+#define GINT64_TO_BE(val)      ((gint64) GUINT64_SWAP_LE_BE (val))
+#define GUINT64_TO_BE(val)     (GUINT64_SWAP_LE_BE (val))
+#define GLONG_TO_LE(val)       ((glong) GINT32_TO_LE (val))
+#define GULONG_TO_LE(val)      ((gulong) GUINT32_TO_LE (val))
+#define GLONG_TO_BE(val)       ((glong) GINT32_TO_BE (val))
+#define GULONG_TO_BE(val)      ((gulong) GUINT32_TO_BE (val))
+#define GINT_TO_LE(val)                ((gint) GINT32_TO_LE (val))
+#define GUINT_TO_LE(val)       ((guint) GUINT32_TO_LE (val))
+#define GINT_TO_BE(val)                ((gint) GINT32_TO_BE (val))
+#define GUINT_TO_BE(val)       ((guint) GUINT32_TO_BE (val))
+#define GSIZE_TO_LE(val)       ((gsize) GUINT32_TO_LE (val))
+#define GSSIZE_TO_LE(val)      ((gssize) GINT32_TO_LE (val))
+#define GSIZE_TO_BE(val)       ((gsize) GUINT32_TO_BE (val))
+#define GSSIZE_TO_BE(val)      ((gssize) GINT32_TO_BE (val))
+#define G_BYTE_ORDER G_LITTLE_ENDIAN
+
+#define GLIB_SYSDEF_POLLIN =1
+#define GLIB_SYSDEF_POLLOUT =4
+#define GLIB_SYSDEF_POLLPRI =2
+#define GLIB_SYSDEF_POLLHUP =16
+#define GLIB_SYSDEF_POLLERR =8
+#define GLIB_SYSDEF_POLLNVAL =32
+
+#define G_MODULE_SUFFIX "dll"
+
+/* A GPid is an abstraction for a process "handle". It is *not* an
+ * abstraction for a process identifier in general. GPid is used in
+ * GLib only for descendant processes spawned with the g_spawn*
+ * functions. On POSIX there is no "process handle" concept as such,
+ * but on Windows a GPid is a handle to a process, a kind of pointer,
+ * not a process identifier.
+ */
+typedef void * GPid;
+
+#define GLIB_SYSDEF_AF_UNIX 1
+#define GLIB_SYSDEF_AF_INET 2
+#define GLIB_SYSDEF_AF_INET6 23
+
+#define GLIB_SYSDEF_MSG_OOB       1
+#define GLIB_SYSDEF_MSG_PEEK      2
+#define GLIB_SYSDEF_MSG_DONTROUTE 4
+
+G_END_DECLS
+
+#endif /* GLIBCONFIG_H */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glibintl.h b/resource/csdk/connectivity/lib/android/glib-master/glib/glibintl.h
new file mode 100644 (file)
index 0000000..6d79a26
--- /dev/null
@@ -0,0 +1,40 @@
+#ifndef __GLIBINTL_H__
+#define __GLIBINTL_H__
+
+#ifndef SIZEOF_CHAR
+#error "config.h must be included prior to glibintl.h"
+#endif
+
+G_CONST_RETURN gchar *glib_gettext (const gchar *str) G_GNUC_FORMAT(1);
+
+#ifdef ENABLE_NLS
+
+#include <libintl.h>
+#define _(String) glib_gettext(String)
+/* Split out this in the code, but keep it in the same domain for now */
+#define P_(String) glib_gettext(String)
+#define C_(Context,String) g_dpgettext (NULL, Context "\004" String, strlen (Context) + 1)
+
+#ifdef gettext_noop
+#define N_(String) gettext_noop(String)
+#else
+#define N_(String) (String)
+#endif
+#else /* NLS is disabled */
+#define _(String) (String)
+#define N_(String) (String)
+#define P_(String) (String)
+#define C_(Context,String) (String)
+#define textdomain(String) ((String) ? (String) : "messages")
+#define gettext(String) (String)
+#define dgettext(Domain,String) (String)
+#define dcgettext(Domain,String,Type) (String)
+#define dngettext(Domain,String1,String2,N) ((N) == 1 ? (String1) : (String2))
+#define bindtextdomain(Domain,Directory) (Domain) 
+#define bind_textdomain_codeset(Domain,Codeset)
+#endif
+
+/* not really I18N-related, but also a string marker macro */
+#define I_(string) g_intern_static_string (string)
+
+#endif /* __GLIBINTL_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glist.c b/resource/csdk/connectivity/lib/android/glib-master/glib/glist.c
new file mode 100644 (file)
index 0000000..c8f7434
--- /dev/null
@@ -0,0 +1,1151 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "glist.h"
+
+#include "gtestutils.h"
+
+/**
+ * SECTION: linked_lists_double
+ * @title: Doubly-Linked Lists
+ * @short_description: linked lists containing integer values or
+ *                     pointers to data, with the ability to iterate
+ *                     over the list in both directions
+ *
+ * The #GList structure and its associated functions provide a standard
+ * doubly-linked list data structure.
+ *
+ * Each element in the list contains a piece of data, together with
+ * pointers which link to the previous and next elements in the list.
+ * Using these pointers it is possible to move through the list in both
+ * directions (unlike the <link
+ * linkend="glib-Singly-Linked-lists">Singly-Linked Lists</link> which
+ * only allows movement through the list in the forward direction).
+ *
+ * The data contained in each element can be either integer values, by
+ * using one of the <link linkend="glib-Type-Conversion-Macros">Type
+ * Conversion Macros</link>, or simply pointers to any type of data.
+ *
+ * List elements are allocated from the <link
+ * linkend="glib-Memory-Slices">slice allocator</link>, which is more
+ * efficient than allocating elements individually.
+ *
+ * Note that most of the #GList functions expect to be passed a pointer
+ * to the first element in the list. The functions which insert
+ * elements return the new start of the list, which may have changed.
+ *
+ * There is no function to create a #GList. %NULL is considered to be
+ * the empty list so you simply set a #GList* to %NULL.
+ *
+ * To add elements, use g_list_append(), g_list_prepend(),
+ * g_list_insert() and g_list_insert_sorted().
+ *
+ * To remove elements, use g_list_remove().
+ *
+ * To find elements in the list use g_list_first(), g_list_last(),
+ * g_list_next(), g_list_previous(), g_list_nth(), g_list_nth_data(),
+ * g_list_find() and g_list_find_custom().
+ *
+ * To find the index of an element use g_list_position() and
+ * g_list_index().
+ *
+ * To call a function for each element in the list use g_list_foreach().
+ *
+ * To free the entire list, use g_list_free().
+ **/
+
+/**
+ * GList:
+ * @data: holds the element's data, which can be a pointer to any kind
+ *        of data, or any integer value using the <link
+ *        linkend="glib-Type-Conversion-Macros">Type Conversion
+ *        Macros</link>.
+ * @next: contains the link to the next element in the list.
+ * @prev: contains the link to the previous element in the list.
+ *
+ * The #GList struct is used for each element in a doubly-linked list.
+ **/
+
+/**
+ * g_list_previous:
+ * @list: an element in a #GList.
+ * @Returns: the previous element, or %NULL if there are no previous
+ *           elements.
+ *
+ * A convenience macro to get the previous element in a #GList.
+ **/
+
+/**
+ * g_list_next:
+ * @list: an element in a #GList.
+ * @Returns: the next element, or %NULL if there are no more elements.
+ *
+ * A convenience macro to get the next element in a #GList.
+ **/
+
+
+
+/**
+ * g_list_push_allocator:
+ * @allocator: the #GAllocator to use when allocating #GList elements.
+ *
+ * Sets the allocator to use to allocate #GList elements. Use
+ * g_list_pop_allocator() to restore the previous allocator.
+ *
+ * Note that this function is not available if GLib has been compiled
+ * with <option>--disable-mem-pools</option>
+ *
+ * Deprecated:2.10: It does nothing, since #GList has been converted
+ *                  to the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link>
+ **/
+void g_list_push_allocator (gpointer dummy) { /* present for binary compat only */ }
+
+/**
+ * g_list_pop_allocator:
+ *
+ * Restores the previous #GAllocator, used when allocating #GList
+ * elements.
+ *
+ * Note that this function is not available if GLib has been compiled
+ * with <option>--disable-mem-pools</option>
+ *
+ * Deprecated:2.10: It does nothing, since #GList has been converted
+ *                  to the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link>
+ **/
+void g_list_pop_allocator  (void)           { /* present for binary compat only */ }
+
+#define _g_list_alloc()         g_slice_new (GList)
+#define _g_list_alloc0()        g_slice_new0 (GList)
+#define _g_list_free1(list)     g_slice_free (GList, list)
+
+/**
+ * g_list_alloc:
+ * @Returns: a pointer to the newly-allocated #GList element.
+ *
+ * Allocates space for one #GList element. It is called by
+ * g_list_append(), g_list_prepend(), g_list_insert() and
+ * g_list_insert_sorted() and so is rarely used on its own.
+ **/
+GList*
+g_list_alloc (void)
+{
+  return _g_list_alloc0 ();
+}
+
+/**
+ * g_list_free: 
+ * @list: a #GList
+ *
+ * Frees all of the memory used by a #GList.
+ * The freed elements are returned to the slice allocator.
+ *
+ * <note><para>
+ * If list elements contain dynamically-allocated memory, 
+ * they should be freed first.
+ * </para></note>
+ */
+void
+g_list_free (GList *list)
+{
+  g_slice_free_chain (GList, list, next);
+}
+
+/**
+ * g_list_free_1:
+ * @list: a #GList element
+ *
+ * Frees one #GList element.
+ * It is usually used after g_list_remove_link().
+ */
+/**
+ * g_list_free1:
+ *
+ * Another name for g_list_free_1().
+ **/
+void
+g_list_free_1 (GList *list)
+{
+  _g_list_free1 (list);
+}
+
+/**
+ * g_list_append:
+ * @list: a pointer to a #GList
+ * @data: the data for the new element
+ *
+ * Adds a new element on to the end of the list.
+ *
+ * <note><para>
+ * The return value is the new start of the list, which 
+ * may have changed, so make sure you store the new value.
+ * </para></note>
+ *
+ * <note><para>
+ * Note that g_list_append() has to traverse the entire list 
+ * to find the end, which is inefficient when adding multiple 
+ * elements. A common idiom to avoid the inefficiency is to prepend 
+ * the elements and reverse the list when all elements have been added.
+ * </para></note>
+ *
+ * |[
+ * /&ast; Notice that these are initialized to the empty list. &ast;/
+ * GList *list = NULL, *number_list = NULL;
+ *
+ * /&ast; This is a list of strings. &ast;/
+ * list = g_list_append (list, "first");
+ * list = g_list_append (list, "second");
+ * 
+ * /&ast; This is a list of integers. &ast;/
+ * number_list = g_list_append (number_list, GINT_TO_POINTER (27));
+ * number_list = g_list_append (number_list, GINT_TO_POINTER (14));
+ * ]|
+ *
+ * Returns: the new start of the #GList
+ */
+GList*
+g_list_append (GList   *list,
+              gpointer  data)
+{
+  GList *new_list;
+  GList *last;
+  
+  new_list = _g_list_alloc ();
+  new_list->data = data;
+  new_list->next = NULL;
+  
+  if (list)
+    {
+      last = g_list_last (list);
+      /* g_assert (last != NULL); */
+      last->next = new_list;
+      new_list->prev = last;
+
+      return list;
+    }
+  else
+    {
+      new_list->prev = NULL;
+      return new_list;
+    }
+}
+
+/**
+ * g_list_prepend:
+ * @list: a pointer to a #GList
+ * @data: the data for the new element
+ *
+ * Adds a new element on to the start of the list.
+ *
+ * <note><para>
+ * The return value is the new start of the list, which 
+ * may have changed, so make sure you store the new value.
+ * </para></note>
+ *
+ * |[ 
+ * /&ast; Notice that it is initialized to the empty list. &ast;/
+ * GList *list = NULL;
+ * list = g_list_prepend (list, "last");
+ * list = g_list_prepend (list, "first");
+ * ]|
+ *
+ * Returns: the new start of the #GList
+ */
+GList*
+g_list_prepend (GList   *list,
+               gpointer  data)
+{
+  GList *new_list;
+  
+  new_list = _g_list_alloc ();
+  new_list->data = data;
+  new_list->next = list;
+  
+  if (list)
+    {
+      new_list->prev = list->prev;
+      if (list->prev)
+       list->prev->next = new_list;
+      list->prev = new_list;
+    }
+  else
+    new_list->prev = NULL;
+  
+  return new_list;
+}
+
+/**
+ * g_list_insert:
+ * @list: a pointer to a #GList
+ * @data: the data for the new element
+ * @position: the position to insert the element. If this is 
+ *     negative, or is larger than the number of elements in the 
+ *     list, the new element is added on to the end of the list.
+ * 
+ * Inserts a new element into the list at the given position.
+ *
+ * Returns: the new start of the #GList
+ */
+GList*
+g_list_insert (GList   *list,
+              gpointer  data,
+              gint      position)
+{
+  GList *new_list;
+  GList *tmp_list;
+  
+  if (position < 0)
+    return g_list_append (list, data);
+  else if (position == 0)
+    return g_list_prepend (list, data);
+  
+  tmp_list = g_list_nth (list, position);
+  if (!tmp_list)
+    return g_list_append (list, data);
+  
+  new_list = _g_list_alloc ();
+  new_list->data = data;
+  new_list->prev = tmp_list->prev;
+  if (tmp_list->prev)
+    tmp_list->prev->next = new_list;
+  new_list->next = tmp_list;
+  tmp_list->prev = new_list;
+  
+  if (tmp_list == list)
+    return new_list;
+  else
+    return list;
+}
+
+/**
+ * g_list_insert_before:
+ * @list: a pointer to a #GList
+ * @sibling: the list element before which the new element 
+ *     is inserted or %NULL to insert at the end of the list
+ * @data: the data for the new element
+ *
+ * Inserts a new element into the list before the given position.
+ *
+ * Returns: the new start of the #GList
+ */
+GList*
+g_list_insert_before (GList   *list,
+                     GList   *sibling,
+                     gpointer data)
+{
+  if (!list)
+    {
+      list = g_list_alloc ();
+      list->data = data;
+      g_return_val_if_fail (sibling == NULL, list);
+      return list;
+    }
+  else if (sibling)
+    {
+      GList *node;
+
+      node = _g_list_alloc ();
+      node->data = data;
+      node->prev = sibling->prev;
+      node->next = sibling;
+      sibling->prev = node;
+      if (node->prev)
+       {
+         node->prev->next = node;
+         return list;
+       }
+      else
+       {
+         g_return_val_if_fail (sibling == list, node);
+         return node;
+       }
+    }
+  else
+    {
+      GList *last;
+
+      last = list;
+      while (last->next)
+       last = last->next;
+
+      last->next = _g_list_alloc ();
+      last->next->data = data;
+      last->next->prev = last;
+      last->next->next = NULL;
+
+      return list;
+    }
+}
+
+/**
+ * g_list_concat:
+ * @list1: a #GList
+ * @list2: the #GList to add to the end of the first #GList
+ *
+ * Adds the second #GList onto the end of the first #GList.
+ * Note that the elements of the second #GList are not copied.
+ * They are used directly.
+ *
+ * Returns: the start of the new #GList
+ */
+GList *
+g_list_concat (GList *list1, GList *list2)
+{
+  GList *tmp_list;
+  
+  if (list2)
+    {
+      tmp_list = g_list_last (list1);
+      if (tmp_list)
+       tmp_list->next = list2;
+      else
+       list1 = list2;
+      list2->prev = tmp_list;
+    }
+  
+  return list1;
+}
+
+/**
+ * g_list_remove:
+ * @list: a #GList
+ * @data: the data of the element to remove
+ *
+ * Removes an element from a #GList.
+ * If two elements contain the same data, only the first is removed.
+ * If none of the elements contain the data, the #GList is unchanged.
+ *
+ * Returns: the new start of the #GList
+ */
+GList*
+g_list_remove (GList        *list,
+              gconstpointer  data)
+{
+  GList *tmp;
+  
+  tmp = list;
+  while (tmp)
+    {
+      if (tmp->data != data)
+       tmp = tmp->next;
+      else
+       {
+         if (tmp->prev)
+           tmp->prev->next = tmp->next;
+         if (tmp->next)
+           tmp->next->prev = tmp->prev;
+         
+         if (list == tmp)
+           list = list->next;
+         
+         _g_list_free1 (tmp);
+         
+         break;
+       }
+    }
+  return list;
+}
+
+/**
+ * g_list_remove_all:
+ * @list: a #GList
+ * @data: data to remove
+ *
+ * Removes all list nodes with data equal to @data. 
+ * Returns the new head of the list. Contrast with 
+ * g_list_remove() which removes only the first node 
+ * matching the given data.
+ *
+ * Returns: new head of @list
+ */
+GList*
+g_list_remove_all (GList       *list,
+                  gconstpointer data)
+{
+  GList *tmp = list;
+
+  while (tmp)
+    {
+      if (tmp->data != data)
+       tmp = tmp->next;
+      else
+       {
+         GList *next = tmp->next;
+
+         if (tmp->prev)
+           tmp->prev->next = next;
+         else
+           list = next;
+         if (next)
+           next->prev = tmp->prev;
+
+         _g_list_free1 (tmp);
+         tmp = next;
+       }
+    }
+  return list;
+}
+
+static inline GList*
+_g_list_remove_link (GList *list,
+                    GList *link)
+{
+  if (link)
+    {
+      if (link->prev)
+       link->prev->next = link->next;
+      if (link->next)
+       link->next->prev = link->prev;
+      
+      if (link == list)
+       list = list->next;
+      
+      link->next = NULL;
+      link->prev = NULL;
+    }
+  
+  return list;
+}
+
+/**
+ * g_list_remove_link:
+ * @list: a #GList
+ * @llink: an element in the #GList
+ *
+ * Removes an element from a #GList, without freeing the element.
+ * The removed element's prev and next links are set to %NULL, so 
+ * that it becomes a self-contained list with one element.
+ *
+ * Returns: the new start of the #GList, without the element
+ */
+GList*
+g_list_remove_link (GList *list,
+                   GList *llink)
+{
+  return _g_list_remove_link (list, llink);
+}
+
+/**
+ * g_list_delete_link:
+ * @list: a #GList
+ * @link_: node to delete from @list
+ *
+ * Removes the node link_ from the list and frees it. 
+ * Compare this to g_list_remove_link() which removes the node 
+ * without freeing it.
+ *
+ * Returns: the new head of @list
+ */
+GList*
+g_list_delete_link (GList *list,
+                   GList *link_)
+{
+  list = _g_list_remove_link (list, link_);
+  _g_list_free1 (link_);
+
+  return list;
+}
+
+/**
+ * g_list_copy:
+ * @list: a #GList
+ *
+ * Copies a #GList.
+ *
+ * <note><para>
+ * Note that this is a "shallow" copy. If the list elements 
+ * consist of pointers to data, the pointers are copied but 
+ * the actual data is not.
+ * </para></note>
+ *
+ * Returns: a copy of @list
+ */
+GList*
+g_list_copy (GList *list)
+{
+  GList *new_list = NULL;
+
+  if (list)
+    {
+      GList *last;
+
+      new_list = _g_list_alloc ();
+      new_list->data = list->data;
+      new_list->prev = NULL;
+      last = new_list;
+      list = list->next;
+      while (list)
+       {
+         last->next = _g_list_alloc ();
+         last->next->prev = last;
+         last = last->next;
+         last->data = list->data;
+         list = list->next;
+       }
+      last->next = NULL;
+    }
+
+  return new_list;
+}
+
+/**
+ * g_list_reverse:
+ * @list: a #GList
+ *
+ * Reverses a #GList.
+ * It simply switches the next and prev pointers of each element.
+ *
+ * Returns: the start of the reversed #GList
+ */
+GList*
+g_list_reverse (GList *list)
+{
+  GList *last;
+  
+  last = NULL;
+  while (list)
+    {
+      last = list;
+      list = last->next;
+      last->next = last->prev;
+      last->prev = list;
+    }
+  
+  return last;
+}
+
+/**
+ * g_list_nth:
+ * @list: a #GList
+ * @n: the position of the element, counting from 0
+ *
+ * Gets the element at the given position in a #GList.
+ *
+ * Returns: the element, or %NULL if the position is off 
+ *     the end of the #GList
+ */
+GList*
+g_list_nth (GList *list,
+           guint  n)
+{
+  while ((n-- > 0) && list)
+    list = list->next;
+  
+  return list;
+}
+
+/**
+ * g_list_nth_prev:
+ * @list: a #GList
+ * @n: the position of the element, counting from 0
+ *
+ * Gets the element @n places before @list.
+ *
+ * Returns: the element, or %NULL if the position is 
+ *     off the end of the #GList
+ */
+GList*
+g_list_nth_prev (GList *list,
+                guint  n)
+{
+  while ((n-- > 0) && list)
+    list = list->prev;
+  
+  return list;
+}
+
+/**
+ * g_list_nth_data:
+ * @list: a #GList
+ * @n: the position of the element
+ *
+ * Gets the data of the element at the given position.
+ *
+ * Returns: the element's data, or %NULL if the position 
+ *     is off the end of the #GList
+ */
+gpointer
+g_list_nth_data (GList     *list,
+                guint      n)
+{
+  while ((n-- > 0) && list)
+    list = list->next;
+  
+  return list ? list->data : NULL;
+}
+
+/**
+ * g_list_find:
+ * @list: a #GList
+ * @data: the element data to find
+ *
+ * Finds the element in a #GList which 
+ * contains the given data.
+ *
+ * Returns: the found #GList element, 
+ *     or %NULL if it is not found
+ */
+GList*
+g_list_find (GList         *list,
+            gconstpointer  data)
+{
+  while (list)
+    {
+      if (list->data == data)
+       break;
+      list = list->next;
+    }
+  
+  return list;
+}
+
+/**
+ * g_list_find_custom:
+ * @list: a #GList
+ * @data: user data passed to the function
+ * @func: the function to call for each element. 
+ *     It should return 0 when the desired element is found
+ *
+ * Finds an element in a #GList, using a supplied function to 
+ * find the desired element. It iterates over the list, calling 
+ * the given function which should return 0 when the desired 
+ * element is found. The function takes two #gconstpointer arguments, 
+ * the #GList element's data as the first argument and the 
+ * given user data.
+ *
+ * Returns: the found #GList element, or %NULL if it is not found
+ */
+GList*
+g_list_find_custom (GList         *list,
+                   gconstpointer  data,
+                   GCompareFunc   func)
+{
+  g_return_val_if_fail (func != NULL, list);
+
+  while (list)
+    {
+      if (! func (list->data, data))
+       return list;
+      list = list->next;
+    }
+
+  return NULL;
+}
+
+
+/**
+ * g_list_position:
+ * @list: a #GList
+ * @llink: an element in the #GList
+ *
+ * Gets the position of the given element 
+ * in the #GList (starting from 0).
+ *
+ * Returns: the position of the element in the #GList, 
+ *     or -1 if the element is not found
+ */
+gint
+g_list_position (GList *list,
+                GList *llink)
+{
+  gint i;
+
+  i = 0;
+  while (list)
+    {
+      if (list == llink)
+       return i;
+      i++;
+      list = list->next;
+    }
+
+  return -1;
+}
+
+/**
+ * g_list_index:
+ * @list: a #GList
+ * @data: the data to find
+ *
+ * Gets the position of the element containing 
+ * the given data (starting from 0).
+ *
+ * Returns: the index of the element containing the data, 
+ *     or -1 if the data is not found
+ */
+gint
+g_list_index (GList         *list,
+             gconstpointer  data)
+{
+  gint i;
+
+  i = 0;
+  while (list)
+    {
+      if (list->data == data)
+       return i;
+      i++;
+      list = list->next;
+    }
+
+  return -1;
+}
+
+/**
+ * g_list_last:
+ * @list: a #GList
+ *
+ * Gets the last element in a #GList.
+ *
+ * Returns: the last element in the #GList, 
+ *     or %NULL if the #GList has no elements
+ */
+GList*
+g_list_last (GList *list)
+{
+  if (list)
+    {
+      while (list->next)
+       list = list->next;
+    }
+  
+  return list;
+}
+
+/**
+ * g_list_first:
+ * @list: a #GList
+ *
+ * Gets the first element in a #GList.
+ *
+ * Returns: the first element in the #GList, 
+ *     or %NULL if the #GList has no elements
+ */
+GList*
+g_list_first (GList *list)
+{
+  if (list)
+    {
+      while (list->prev)
+       list = list->prev;
+    }
+  
+  return list;
+}
+
+/**
+ * g_list_length:
+ * @list: a #GList
+ *
+ * Gets the number of elements in a #GList.
+ *
+ * <note><para>
+ * This function iterates over the whole list to 
+ * count its elements.
+ * </para></note>
+ *
+ * Returns: the number of elements in the #GList
+ */
+guint
+g_list_length (GList *list)
+{
+  guint length;
+  
+  length = 0;
+  while (list)
+    {
+      length++;
+      list = list->next;
+    }
+  
+  return length;
+}
+
+/**
+ * g_list_foreach:
+ * @list: a #GList
+ * @func: the function to call with each element's data
+ * @user_data: user data to pass to the function
+ *
+ * Calls a function for each element of a #GList.
+ */
+/**
+ * GFunc:
+ * @data: the element's data.
+ * @user_data: user data passed to g_list_foreach() or
+ *             g_slist_foreach().
+ *
+ * Specifies the type of functions passed to g_list_foreach() and
+ * g_slist_foreach().
+ **/
+void
+g_list_foreach (GList   *list,
+               GFunc     func,
+               gpointer  user_data)
+{
+  while (list)
+    {
+      GList *next = list->next;
+      (*func) (list->data, user_data);
+      list = next;
+    }
+}
+
+static GList*
+g_list_insert_sorted_real (GList    *list,
+                          gpointer  data,
+                          GFunc     func,
+                          gpointer  user_data)
+{
+  GList *tmp_list = list;
+  GList *new_list;
+  gint cmp;
+
+  g_return_val_if_fail (func != NULL, list);
+  
+  if (!list) 
+    {
+      new_list = _g_list_alloc0 ();
+      new_list->data = data;
+      return new_list;
+    }
+  
+  cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
+
+  while ((tmp_list->next) && (cmp > 0))
+    {
+      tmp_list = tmp_list->next;
+
+      cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
+    }
+
+  new_list = _g_list_alloc0 ();
+  new_list->data = data;
+
+  if ((!tmp_list->next) && (cmp > 0))
+    {
+      tmp_list->next = new_list;
+      new_list->prev = tmp_list;
+      return list;
+    }
+   
+  if (tmp_list->prev)
+    {
+      tmp_list->prev->next = new_list;
+      new_list->prev = tmp_list->prev;
+    }
+  new_list->next = tmp_list;
+  tmp_list->prev = new_list;
+  if (tmp_list == list)
+    return new_list;
+  else
+    return list;
+}
+
+/**
+ * g_list_insert_sorted:
+ * @list: a pointer to a #GList
+ * @data: the data for the new element
+ * @func: the function to compare elements in the list. It should 
+ *     return a number > 0 if the first parameter comes after the 
+ *     second parameter in the sort order.
+ *
+ * Inserts a new element into the list, using the given comparison 
+ * function to determine its position.
+ *
+ * Returns: the new start of the #GList
+ */
+GList*
+g_list_insert_sorted (GList        *list,
+                     gpointer      data,
+                     GCompareFunc  func)
+{
+  return g_list_insert_sorted_real (list, data, (GFunc) func, NULL);
+}
+
+/**
+ * g_list_insert_sorted_with_data:
+ * @list: a pointer to a #GList
+ * @data: the data for the new element
+ * @func: the function to compare elements in the list. 
+ *     It should return a number > 0 if the first parameter 
+ *     comes after the second parameter in the sort order.
+ * @user_data: user data to pass to comparison function.
+ *
+ * Inserts a new element into the list, using the given comparison 
+ * function to determine its position.
+ *
+ * Returns: the new start of the #GList
+ *
+ * Since: 2.10
+ */
+GList*
+g_list_insert_sorted_with_data (GList            *list,
+                               gpointer          data,
+                               GCompareDataFunc  func,
+                               gpointer          user_data)
+{
+  return g_list_insert_sorted_real (list, data, (GFunc) func, user_data);
+}
+
+static GList *
+g_list_sort_merge (GList     *l1, 
+                  GList     *l2,
+                  GFunc     compare_func,
+                  gpointer  user_data)
+{
+  GList list, *l, *lprev;
+  gint cmp;
+
+  l = &list; 
+  lprev = NULL;
+
+  while (l1 && l2)
+    {
+      cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
+
+      if (cmp <= 0)
+        {
+         l->next = l1;
+         l1 = l1->next;
+        } 
+      else 
+       {
+         l->next = l2;
+         l2 = l2->next;
+        }
+      l = l->next;
+      l->prev = lprev; 
+      lprev = l;
+    }
+  l->next = l1 ? l1 : l2;
+  l->next->prev = l;
+
+  return list.next;
+}
+
+static GList* 
+g_list_sort_real (GList    *list,
+                 GFunc     compare_func,
+                 gpointer  user_data)
+{
+  GList *l1, *l2;
+  
+  if (!list) 
+    return NULL;
+  if (!list->next) 
+    return list;
+  
+  l1 = list; 
+  l2 = list->next;
+
+  while ((l2 = l2->next) != NULL)
+    {
+      if ((l2 = l2->next) == NULL) 
+       break;
+      l1 = l1->next;
+    }
+  l2 = l1->next; 
+  l1->next = NULL; 
+
+  return g_list_sort_merge (g_list_sort_real (list, compare_func, user_data),
+                           g_list_sort_real (l2, compare_func, user_data),
+                           compare_func,
+                           user_data);
+}
+
+/**
+ * g_list_sort:
+ * @list: a #GList
+ * @compare_func: the comparison function used to sort the #GList.
+ *     This function is passed the data from 2 elements of the #GList 
+ *     and should return 0 if they are equal, a negative value if the 
+ *     first element comes before the second, or a positive value if 
+ *     the first element comes after the second.
+ *
+ * Sorts a #GList using the given comparison function.
+ *
+ * Returns: the start of the sorted #GList
+ */
+/**
+ * GCompareFunc:
+ * @a: a value.
+ * @b: a value to compare with.
+ * @Returns: negative value if @a &lt; @b; zero if @a = @b; positive
+ *           value if @a > @b.
+ *
+ * Specifies the type of a comparison function used to compare two
+ * values.  The function should return a negative integer if the first
+ * value comes before the second, 0 if they are equal, or a positive
+ * integer if the first value comes after the second.
+ **/
+GList *
+g_list_sort (GList        *list,
+            GCompareFunc  compare_func)
+{
+  return g_list_sort_real (list, (GFunc) compare_func, NULL);
+                           
+}
+
+/**
+ * g_list_sort_with_data:
+ * @list: a #GList
+ * @compare_func: comparison function
+ * @user_data: user data to pass to comparison function
+ *
+ * Like g_list_sort(), but the comparison function accepts 
+ * a user data argument.
+ *
+ * Returns: the new head of @list
+ */
+/**
+ * GCompareDataFunc:
+ * @a: a value.
+ * @b: a value to compare with.
+ * @user_data: user data to pass to comparison function.
+ * @Returns: negative value if @a &lt; @b; zero if @a = @b; positive
+ *           value if @a > @b.
+ *
+ * Specifies the type of a comparison function used to compare two
+ * values.  The function should return a negative integer if the first
+ * value comes before the second, 0 if they are equal, or a positive
+ * integer if the first value comes after the second.
+ **/
+GList *
+g_list_sort_with_data (GList            *list,
+                      GCompareDataFunc  compare_func,
+                      gpointer          user_data)
+{
+  return g_list_sort_real (list, (GFunc) compare_func, user_data);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/glist.h b/resource/csdk/connectivity/lib/android/glib-master/glib/glist.h
new file mode 100644 (file)
index 0000000..e74ed96
--- /dev/null
@@ -0,0 +1,120 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_LIST_H__
+#define __G_LIST_H__
+
+#include <glib/gmem.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GList GList;
+
+struct _GList
+{
+  gpointer data;
+  GList *next;
+  GList *prev;
+};
+
+/* Doubly linked lists
+ */
+GList*   g_list_alloc                   (void) G_GNUC_WARN_UNUSED_RESULT;
+void     g_list_free                    (GList            *list);
+void     g_list_free_1                  (GList            *list);
+#define  g_list_free1                   g_list_free_1
+GList*   g_list_append                  (GList            *list,
+                                        gpointer          data) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_prepend                 (GList            *list,
+                                        gpointer          data) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_insert                  (GList            *list,
+                                        gpointer          data,
+                                        gint              position) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_insert_sorted           (GList            *list,
+                                        gpointer          data,
+                                        GCompareFunc      func) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_insert_sorted_with_data (GList            *list,
+                                        gpointer          data,
+                                        GCompareDataFunc  func,
+                                        gpointer          user_data) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_insert_before           (GList            *list,
+                                        GList            *sibling,
+                                        gpointer          data) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_concat                  (GList            *list1,
+                                        GList            *list2) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_remove                  (GList            *list,
+                                        gconstpointer     data) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_remove_all              (GList            *list,
+                                        gconstpointer     data) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_remove_link             (GList            *list,
+                                        GList            *llink) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_delete_link             (GList            *list,
+                                        GList            *link_) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_reverse                 (GList            *list) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_copy                    (GList            *list) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_nth                     (GList            *list,
+                                        guint             n);
+GList*   g_list_nth_prev                (GList            *list,
+                                        guint             n);
+GList*   g_list_find                    (GList            *list,
+                                        gconstpointer     data);
+GList*   g_list_find_custom             (GList            *list,
+                                        gconstpointer     data,
+                                        GCompareFunc      func);
+gint     g_list_position                (GList            *list,
+                                        GList            *llink);
+gint     g_list_index                   (GList            *list,
+                                        gconstpointer     data);
+GList*   g_list_last                    (GList            *list);
+GList*   g_list_first                   (GList            *list);
+guint    g_list_length                  (GList            *list);
+void     g_list_foreach                 (GList            *list,
+                                        GFunc             func,
+                                        gpointer          user_data);
+GList*   g_list_sort                    (GList            *list,
+                                        GCompareFunc      compare_func) G_GNUC_WARN_UNUSED_RESULT;
+GList*   g_list_sort_with_data          (GList            *list,
+                                        GCompareDataFunc  compare_func,
+                                        gpointer          user_data)  G_GNUC_WARN_UNUSED_RESULT;
+gpointer g_list_nth_data                (GList            *list,
+                                        guint             n);
+
+
+#define g_list_previous(list)          ((list) ? (((GList *)(list))->prev) : NULL)
+#define g_list_next(list)              ((list) ? (((GList *)(list))->next) : NULL)
+
+#ifndef G_DISABLE_DEPRECATED
+void     g_list_push_allocator          (gpointer          allocator);
+void     g_list_pop_allocator           (void);
+#endif
+
+G_END_DECLS
+
+#endif /* __G_LIST_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gmacros.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gmacros.h
new file mode 100644 (file)
index 0000000..9f9c25d
--- /dev/null
@@ -0,0 +1,284 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/* This file must not include any other glib header file and must thus
+ * not refer to variables from glibconfig.h
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_MACROS_H__
+#define __G_MACROS_H__
+
+/* We include stddef.h to get the system's definition of NULL
+ */
+#include <stddef.h>
+
+/* Here we provide G_GNUC_EXTENSION as an alias for __extension__,
+ * where this is valid. This allows for warningless compilation of
+ * "long long" types even in the presence of '-ansi -pedantic'. 
+ */
+#if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8)
+#  define G_GNUC_EXTENSION __extension__
+#else
+#  define G_GNUC_EXTENSION
+#endif
+
+/* Provide macros to feature the GCC function attribute.
+ */
+#if    __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96)
+#define G_GNUC_PURE                            \
+  __attribute__((__pure__))
+#define G_GNUC_MALLOC                          \
+  __attribute__((__malloc__))
+#else
+#define G_GNUC_PURE
+#define G_GNUC_MALLOC
+#endif
+
+#if     __GNUC__ >= 4
+#define G_GNUC_NULL_TERMINATED __attribute__((__sentinel__))
+#else
+#define G_GNUC_NULL_TERMINATED
+#endif
+
+#if     (__GNUC__ > 4) || (__GNUC__ == 4 && __GNUC_MINOR__ >= 3)
+#define G_GNUC_ALLOC_SIZE(x) __attribute__((__alloc_size__(x)))
+#define G_GNUC_ALLOC_SIZE2(x,y) __attribute__((__alloc_size__(x,y)))
+#else
+#define G_GNUC_ALLOC_SIZE(x)
+#define G_GNUC_ALLOC_SIZE2(x,y)
+#endif
+
+#if     __GNUC__ > 2 || (__GNUC__ == 2 && __GNUC_MINOR__ > 4)
+#define G_GNUC_PRINTF( format_idx, arg_idx )    \
+  __attribute__((__format__ (__printf__, format_idx, arg_idx)))
+#define G_GNUC_SCANF( format_idx, arg_idx )     \
+  __attribute__((__format__ (__scanf__, format_idx, arg_idx)))
+#define G_GNUC_FORMAT( arg_idx )                \
+  __attribute__((__format_arg__ (arg_idx)))
+#define G_GNUC_NORETURN                         \
+  __attribute__((__noreturn__))
+#define G_GNUC_CONST                            \
+  __attribute__((__const__))
+#define G_GNUC_UNUSED                           \
+  __attribute__((__unused__))
+#define G_GNUC_NO_INSTRUMENT                   \
+  __attribute__((__no_instrument_function__))
+#else   /* !__GNUC__ */
+#define G_GNUC_PRINTF( format_idx, arg_idx )
+#define G_GNUC_SCANF( format_idx, arg_idx )
+#define G_GNUC_FORMAT( arg_idx )
+#define G_GNUC_NORETURN
+#define G_GNUC_CONST
+#define G_GNUC_UNUSED
+#define G_GNUC_NO_INSTRUMENT
+#endif  /* !__GNUC__ */
+
+#if    __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 1)
+#define G_GNUC_DEPRECATED                            \
+  __attribute__((__deprecated__))
+#else
+#define G_GNUC_DEPRECATED
+#endif /* __GNUC__ */
+
+#if    __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ >= 5)
+#define G_GNUC_DEPRECATED_FOR(f)                        \
+  __attribute__((deprecated("Use " #f " instead")))
+#else
+#define G_GNUC_DEPRECATED_FOR(f)        G_GNUC_DEPRECATED
+#endif /* __GNUC__ */
+
+#if     __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 3)
+#  define G_GNUC_MAY_ALIAS __attribute__((may_alias))
+#else
+#  define G_GNUC_MAY_ALIAS
+#endif
+
+#if    __GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ >= 4)
+#define G_GNUC_WARN_UNUSED_RESULT              \
+  __attribute__((warn_unused_result))
+#else
+#define G_GNUC_WARN_UNUSED_RESULT
+#endif /* __GNUC__ */
+
+#ifndef G_DISABLE_DEPRECATED
+/* Wrap the gcc __PRETTY_FUNCTION__ and __FUNCTION__ variables with
+ * macros, so we can refer to them as strings unconditionally.
+ * usage not-recommended since gcc-3.0
+ */
+#if defined (__GNUC__) && (__GNUC__ < 3)
+#define G_GNUC_FUNCTION         __FUNCTION__
+#define G_GNUC_PRETTY_FUNCTION  __PRETTY_FUNCTION__
+#else   /* !__GNUC__ */
+#define G_GNUC_FUNCTION         ""
+#define G_GNUC_PRETTY_FUNCTION  ""
+#endif  /* !__GNUC__ */
+#endif  /* !G_DISABLE_DEPRECATED */
+
+#define G_STRINGIFY(macro_or_string)   G_STRINGIFY_ARG (macro_or_string)
+#define        G_STRINGIFY_ARG(contents)       #contents
+
+#define G_PASTE_ARGS(identifier1,identifier2) identifier1 ## identifier2
+#define G_PASTE(identifier1,identifier2)      G_PASTE_ARGS (identifier1, identifier2)
+#define G_STATIC_ASSERT(expr) typedef struct { char Compile_Time_Assertion[(expr) ? 1 : -1]; } G_PASTE (_GStaticAssert_, __LINE__)
+
+/* Provide a string identifying the current code position */
+#if defined(__GNUC__) && (__GNUC__ < 3) && !defined(__cplusplus)
+#  define G_STRLOC     __FILE__ ":" G_STRINGIFY (__LINE__) ":" __PRETTY_FUNCTION__ "()"
+#else
+#  define G_STRLOC     __FILE__ ":" G_STRINGIFY (__LINE__)
+#endif
+
+/* Provide a string identifying the current function, non-concatenatable */
+#if defined (__GNUC__)
+#  define G_STRFUNC     ((const char*) (__PRETTY_FUNCTION__))
+#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 19901L
+#  define G_STRFUNC     ((const char*) (__func__))
+#else
+#  define G_STRFUNC     ((const char*) ("???"))
+#endif
+
+/* Guard C code in headers, while including them from C++ */
+#ifdef  __cplusplus
+# define G_BEGIN_DECLS  extern "C" {
+# define G_END_DECLS    }
+#else
+# define G_BEGIN_DECLS
+# define G_END_DECLS
+#endif
+
+/* Provide definitions for some commonly used macros.
+ *  Some of them are only provided if they haven't already
+ *  been defined. It is assumed that if they are already
+ *  defined then the current definition is correct.
+ */
+#ifndef NULL
+#  ifdef __cplusplus
+#    define NULL        (0L)
+#  else /* !__cplusplus */
+#    define NULL        ((void*) 0)
+#  endif /* !__cplusplus */
+#endif
+
+#ifndef        FALSE
+#define        FALSE   (0)
+#endif
+
+#ifndef        TRUE
+#define        TRUE    (!FALSE)
+#endif
+
+#undef MAX
+#define MAX(a, b)  (((a) > (b)) ? (a) : (b))
+
+#undef MIN
+#define MIN(a, b)  (((a) < (b)) ? (a) : (b))
+
+#undef ABS
+#define ABS(a)    (((a) < 0) ? -(a) : (a))
+
+#undef CLAMP
+#define CLAMP(x, low, high)  (((x) > (high)) ? (high) : (((x) < (low)) ? (low) : (x)))
+
+/* Count the number of elements in an array. The array must be defined
+ * as such; using this with a dynamically allocated array will give
+ * incorrect results.
+ */
+#define G_N_ELEMENTS(arr)              (sizeof (arr) / sizeof ((arr)[0]))
+
+/* Macros by analogy to GINT_TO_POINTER, GPOINTER_TO_INT
+ */
+#define GPOINTER_TO_SIZE(p)    ((gsize) (p))
+#define GSIZE_TO_POINTER(s)    ((gpointer) (gsize) (s))
+
+/* Provide convenience macros for handling structure
+ * fields through their offsets.
+ */
+
+#if defined(__GNUC__)  && __GNUC__ >= 4
+#  define G_STRUCT_OFFSET(struct_type, member) \
+      ((glong) offsetof (struct_type, member))
+#else
+#  define G_STRUCT_OFFSET(struct_type, member) \
+      ((glong) ((guint8*) &((struct_type*) 0)->member))
+#endif
+
+#define G_STRUCT_MEMBER_P(struct_p, struct_offset)   \
+    ((gpointer) ((guint8*) (struct_p) + (glong) (struct_offset)))
+#define G_STRUCT_MEMBER(member_type, struct_p, struct_offset)   \
+    (*(member_type*) G_STRUCT_MEMBER_P ((struct_p), (struct_offset)))
+
+/* Provide simple macro statement wrappers:
+ *   G_STMT_START { statements; } G_STMT_END;
+ * This can be used as a single statement, like:
+ *   if (x) G_STMT_START { ... } G_STMT_END; else ...
+ * This intentionally does not use compiler extensions like GCC's '({...})' to
+ * avoid portability issue or side effects when compiled with different compilers.
+ */
+#if !(defined (G_STMT_START) && defined (G_STMT_END))
+#  define G_STMT_START  do
+#  define G_STMT_END    while (0)
+#endif
+
+/* Allow the app programmer to select whether or not return values
+ * (usually char*) are const or not.  Don't try using this feature for
+ * functions with C++ linkage.
+ */
+#ifdef G_DISABLE_CONST_RETURNS
+#define G_CONST_RETURN
+#else
+#define G_CONST_RETURN const
+#endif
+
+/*
+ * The G_LIKELY and G_UNLIKELY macros let the programmer give hints to 
+ * the compiler about the expected result of an expression. Some compilers
+ * can use this information for optimizations.
+ *
+ * The _G_BOOLEAN_EXPR macro is intended to trigger a gcc warning when
+ * putting assignments in g_return_if_fail ().  
+ */
+#if defined(__GNUC__) && (__GNUC__ > 2) && defined(__OPTIMIZE__)
+#define _G_BOOLEAN_EXPR(expr)                   \
+ __extension__ ({                               \
+   int _g_boolean_var_;                         \
+   if (expr)                                    \
+      _g_boolean_var_ = 1;                      \
+   else                                         \
+      _g_boolean_var_ = 0;                      \
+   _g_boolean_var_;                             \
+})
+#define G_LIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 1))
+#define G_UNLIKELY(expr) (__builtin_expect (_G_BOOLEAN_EXPR(expr), 0))
+#else
+#define G_LIKELY(expr) (expr)
+#define G_UNLIKELY(expr) (expr)
+#endif
+
+#endif /* __G_MACROS_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gmain.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gmain.c
new file mode 100644 (file)
index 0000000..91e2a8e
--- /dev/null
@@ -0,0 +1,4358 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gmain.c: Main loop abstraction, timeouts, and idle functions
+ * Copyright 1998 Owen Taylor
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#ifndef _WIN32
+/* for pipe2; need to define it first to avoid
+ * other headers pulling in unistd.h
+ */
+/* The meaning of_GNU_SOURCE that is intended here is present only on
+ * Linux; avoid the possibility that some misguided header in MinGW
+ * looks at it. Ideally we should define _GNU_SOURCE only on platforms
+ * where we know what it means and that is what we want here
+ * (i.e. Linux with glibc). After all, there might be some other POSIX
+ * platform even where _GNU_SOURCE is used for some unrelated change
+ * in semantics that isn't wanted. Sigh.
+ */
+#define _GNU_SOURCE
+#endif
+
+#include "config.h"
+#include "glibconfig.h"
+
+/* Uncomment the next line (and the corresponding line in gpoll.c) to
+ * enable debugging printouts if the environment variable
+ * G_MAIN_POLL_DEBUG is set to some value.
+ */
+/* #define G_MAIN_POLL_DEBUG */
+
+#ifdef _WIN32
+/* Always enable debugging printout on Windows, as it is more often
+ * needed there...
+ */
+#define G_MAIN_POLL_DEBUG
+#endif
+
+#include <signal.h>
+#include <sys/types.h>
+#include <time.h>
+#include <stdlib.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif /* HAVE_SYS_TIME_H */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <errno.h>
+
+#ifdef G_OS_WIN32
+#define STRICT
+#include <windows.h>
+#endif /* G_OS_WIN32 */
+
+#ifdef G_OS_BEOS
+#include <sys/socket.h>
+#include <sys/wait.h>
+#endif /* G_OS_BEOS */
+
+#ifdef G_OS_UNIX
+#include <fcntl.h>
+#include <sys/wait.h>
+#endif
+
+#include "gmain.h"
+
+#include "garray.h"
+#include "giochannel.h"
+#include "ghash.h"
+#include "ghook.h"
+#include "gqueue.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "gthreadprivate.h"
+
+#ifdef G_OS_WIN32
+#include "gwin32.h"
+#endif
+
+#ifdef  G_MAIN_POLL_DEBUG
+#include "gtimer.h"
+#endif
+
+/**
+ * SECTION:main
+ * @title: The Main Event Loop
+ * @short_description: manages all available sources of events
+ *
+ * The main event loop manages all the available sources of events for
+ * GLib and GTK+ applications. These events can come from any number of
+ * different types of sources such as file descriptors (plain files,
+ * pipes or sockets) and timeouts. New types of event sources can also
+ * be added using g_source_attach().
+ *
+ * To allow multiple independent sets of sources to be handled in
+ * different threads, each source is associated with a #GMainContext.
+ * A GMainContext can only be running in a single thread, but
+ * sources can be added to it and removed from it from other threads.
+ *
+ * Each event source is assigned a priority. The default priority,
+ * #G_PRIORITY_DEFAULT, is 0. Values less than 0 denote higher priorities.
+ * Values greater than 0 denote lower priorities. Events from high priority
+ * sources are always processed before events from lower priority sources.
+ *
+ * Idle functions can also be added, and assigned a priority. These will
+ * be run whenever no events with a higher priority are ready to be processed.
+ *
+ * The #GMainLoop data type represents a main event loop. A GMainLoop is
+ * created with g_main_loop_new(). After adding the initial event sources,
+ * g_main_loop_run() is called. This continuously checks for new events from
+ * each of the event sources and dispatches them. Finally, the processing of
+ * an event from one of the sources leads to a call to g_main_loop_quit() to
+ * exit the main loop, and g_main_loop_run() returns.
+ *
+ * It is possible to create new instances of #GMainLoop recursively.
+ * This is often used in GTK+ applications when showing modal dialog
+ * boxes. Note that event sources are associated with a particular
+ * #GMainContext, and will be checked and dispatched for all main
+ * loops associated with that GMainContext.
+ *
+ * GTK+ contains wrappers of some of these functions, e.g. gtk_main(),
+ * gtk_main_quit() and gtk_events_pending().
+ *
+ * <refsect2><title>Creating new source types</title>
+ * <para>One of the unusual features of the #GMainLoop functionality
+ * is that new types of event source can be created and used in
+ * addition to the builtin type of event source. A new event source
+ * type is used for handling GDK events. A new source type is created
+ * by <firstterm>deriving</firstterm> from the #GSource structure.
+ * The derived type of source is represented by a structure that has
+ * the #GSource structure as a first element, and other elements specific
+ * to the new source type. To create an instance of the new source type,
+ * call g_source_new() passing in the size of the derived structure and
+ * a table of functions. These #GSourceFuncs determine the behavior of
+ * the new source type.</para>
+ * <para>New source types basically interact with the main context
+ * in two ways. Their prepare function in #GSourceFuncs can set a timeout
+ * to determine the maximum amount of time that the main loop will sleep
+ * before checking the source again. In addition, or as well, the source
+ * can add file descriptors to the set that the main context checks using
+ * g_source_add_poll().</para>
+ * </refsect2>
+ * <refsect2><title>Customizing the main loop iteration</title>
+ * <para>Single iterations of a #GMainContext can be run with
+ * g_main_context_iteration(). In some cases, more detailed control
+ * of exactly how the details of the main loop work is desired, for
+ * instance, when integrating the #GMainLoop with an external main loop.
+ * In such cases, you can call the component functions of
+ * g_main_context_iteration() directly. These functions are
+ * g_main_context_prepare(), g_main_context_query(),
+ * g_main_context_check() and g_main_context_dispatch().</para>
+ * <para>The operation of these functions can best be seen in terms
+ * of a state diagram, as shown in <xref linkend="mainloop-states"/>.</para>
+ * <figure id="mainloop-states"><title>States of a Main Context</title>
+ * <graphic fileref="mainloop-states.gif" format="GIF"></graphic>
+ * </figure>
+ * </refsect2>
+ */
+
+/* Types */
+
+typedef struct _GTimeoutSource GTimeoutSource;
+typedef struct _GChildWatchSource GChildWatchSource;
+typedef struct _GPollRec GPollRec;
+typedef struct _GSourceCallback GSourceCallback;
+
+typedef enum
+{
+  G_SOURCE_READY = 1 << G_HOOK_FLAG_USER_SHIFT,
+  G_SOURCE_CAN_RECURSE = 1 << (G_HOOK_FLAG_USER_SHIFT + 1)
+} GSourceFlags;
+
+#ifdef G_THREADS_ENABLED
+typedef struct _GMainWaiter GMainWaiter;
+
+struct _GMainWaiter
+{
+  GCond *cond;
+  GMutex *mutex;
+};
+#endif  
+
+typedef struct _GMainDispatch GMainDispatch;
+
+struct _GMainDispatch
+{
+  gint depth;
+  GSList *dispatching_sources; /* stack of current sources */
+};
+
+#ifdef G_MAIN_POLL_DEBUG
+gboolean _g_main_poll_debug = FALSE;
+#endif
+
+struct _GMainContext
+{
+#ifdef G_THREADS_ENABLED
+  /* The following lock is used for both the list of sources
+   * and the list of poll records
+   */
+  GStaticMutex mutex;
+  GCond *cond;
+  GThread *owner;
+  guint owner_count;
+  GSList *waiters;
+#endif  
+
+  gint ref_count;
+
+  GPtrArray *pending_dispatches;
+  gint timeout;                        /* Timeout for current iteration */
+
+  guint next_id;
+  GSource *source_list;
+  gint in_check_or_prepare;
+
+  GPollRec *poll_records;
+  guint n_poll_records;
+  GPollFD *cached_poll_array;
+  guint cached_poll_array_size;
+
+#ifdef G_THREADS_ENABLED  
+#ifndef G_OS_WIN32
+/* this pipe is used to wake up the main loop when a source is added.
+ */
+  gint wake_up_pipe[2];
+#else /* G_OS_WIN32 */
+  HANDLE wake_up_semaphore;
+#endif /* G_OS_WIN32 */
+
+  GPollFD wake_up_rec;
+  gboolean poll_waiting;
+
+/* Flag indicating whether the set of fd's changed during a poll */
+  gboolean poll_changed;
+#endif /* G_THREADS_ENABLED */
+
+  GPollFunc poll_func;
+
+  GTimeVal current_time;
+  gboolean time_is_current;
+};
+
+struct _GSourceCallback
+{
+  guint ref_count;
+  GSourceFunc func;
+  gpointer    data;
+  GDestroyNotify notify;
+};
+
+struct _GMainLoop
+{
+  GMainContext *context;
+  gboolean is_running;
+  gint ref_count;
+};
+
+struct _GTimeoutSource
+{
+  GSource     source;
+  GTimeVal    expiration;
+  guint       interval;
+  guint              granularity;
+};
+
+struct _GChildWatchSource
+{
+  GSource     source;
+  GPid        pid;
+  gint        child_status;
+#ifdef G_OS_WIN32
+  GPollFD     poll;
+#else /* G_OS_WIN32 */
+  gint        count;
+  gboolean    child_exited;
+#endif /* G_OS_WIN32 */
+};
+
+struct _GPollRec
+{
+  GPollFD *fd;
+  GPollRec *next;
+  gint priority;
+};
+
+#ifdef G_THREADS_ENABLED
+#define LOCK_CONTEXT(context) g_static_mutex_lock (&context->mutex)
+#define UNLOCK_CONTEXT(context) g_static_mutex_unlock (&context->mutex)
+#define G_THREAD_SELF g_thread_self ()
+#else
+#define LOCK_CONTEXT(context) (void)0
+#define UNLOCK_CONTEXT(context) (void)0
+#define G_THREAD_SELF NULL
+#endif
+
+#define SOURCE_DESTROYED(source) (((source)->flags & G_HOOK_FLAG_ACTIVE) == 0)
+#define SOURCE_BLOCKED(source) (((source)->flags & G_HOOK_FLAG_IN_CALL) != 0 && \
+                               ((source)->flags & G_SOURCE_CAN_RECURSE) == 0)
+
+#define SOURCE_UNREF(source, context)                       \
+   G_STMT_START {                                           \
+    if ((source)->ref_count > 1)                            \
+      (source)->ref_count--;                                \
+    else                                                    \
+      g_source_unref_internal ((source), (context), TRUE);  \
+   } G_STMT_END
+
+
+/* Forward declarations */
+
+static void g_source_unref_internal             (GSource      *source,
+                                                GMainContext *context,
+                                                gboolean      have_lock);
+static void g_source_destroy_internal           (GSource      *source,
+                                                GMainContext *context,
+                                                gboolean      have_lock);
+static void g_main_context_poll                 (GMainContext *context,
+                                                gint          timeout,
+                                                gint          priority,
+                                                GPollFD      *fds,
+                                                gint          n_fds);
+static void g_main_context_add_poll_unlocked    (GMainContext *context,
+                                                gint          priority,
+                                                GPollFD      *fd);
+static void g_main_context_remove_poll_unlocked (GMainContext *context,
+                                                GPollFD      *fd);
+static void g_main_context_wakeup_unlocked      (GMainContext *context);
+
+static gboolean g_timeout_prepare  (GSource     *source,
+                                   gint        *timeout);
+static gboolean g_timeout_check    (GSource     *source);
+static gboolean g_timeout_dispatch (GSource     *source,
+                                   GSourceFunc  callback,
+                                   gpointer     user_data);
+static gboolean g_child_watch_prepare  (GSource     *source,
+                                       gint        *timeout);
+static gboolean g_child_watch_check    (GSource     *source);
+static gboolean g_child_watch_dispatch (GSource     *source,
+                                       GSourceFunc  callback,
+                                       gpointer     user_data);
+static gboolean g_idle_prepare     (GSource     *source,
+                                   gint        *timeout);
+static gboolean g_idle_check       (GSource     *source);
+static gboolean g_idle_dispatch    (GSource     *source,
+                                   GSourceFunc  callback,
+                                   gpointer     user_data);
+
+G_LOCK_DEFINE_STATIC (main_loop);
+static GMainContext *default_main_context;
+static GSList *main_contexts_without_pipe = NULL;
+
+#ifndef G_OS_WIN32
+/* Child status monitoring code */
+enum {
+  CHILD_WATCH_UNINITIALIZED,
+  CHILD_WATCH_INITIALIZED_SINGLE,
+  CHILD_WATCH_INITIALIZED_THREADED
+};
+static gint child_watch_init_state = CHILD_WATCH_UNINITIALIZED;
+static gint child_watch_count = 1;
+static gint child_watch_wake_up_pipe[2] = {0, 0};
+#endif /* !G_OS_WIN32 */
+G_LOCK_DEFINE_STATIC (main_context_list);
+static GSList *main_context_list = NULL;
+
+static gint timer_perturb = -1;
+
+GSourceFuncs g_timeout_funcs =
+{
+  g_timeout_prepare,
+  g_timeout_check,
+  g_timeout_dispatch,
+  NULL
+};
+
+GSourceFuncs g_child_watch_funcs =
+{
+  g_child_watch_prepare,
+  g_child_watch_check,
+  g_child_watch_dispatch,
+  NULL
+};
+
+GSourceFuncs g_idle_funcs =
+{
+  g_idle_prepare,
+  g_idle_check,
+  g_idle_dispatch,
+  NULL
+};
+
+/**
+ * g_main_context_ref:
+ * @context: a #GMainContext
+ * 
+ * Increases the reference count on a #GMainContext object by one.
+ *
+ * Returns: the @context that was passed in (since 2.6)
+ **/
+GMainContext *
+g_main_context_ref (GMainContext *context)
+{
+  g_return_val_if_fail (context != NULL, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL); 
+
+  g_atomic_int_inc (&context->ref_count);
+
+  return context;
+}
+
+static inline void
+poll_rec_list_free (GMainContext *context,
+                   GPollRec     *list)
+{
+  g_slice_free_chain (GPollRec, list, next);
+}
+
+/**
+ * g_main_context_unref:
+ * @context: a #GMainContext
+ * 
+ * Decreases the reference count on a #GMainContext object by one. If
+ * the result is zero, free the context and free all associated memory.
+ **/
+void
+g_main_context_unref (GMainContext *context)
+{
+  GSource *source;
+  g_return_if_fail (context != NULL);
+  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0); 
+
+  if (!g_atomic_int_dec_and_test (&context->ref_count))
+    return;
+
+  G_LOCK (main_context_list);
+  main_context_list = g_slist_remove (main_context_list, context);
+  G_UNLOCK (main_context_list);
+
+  source = context->source_list;
+  while (source)
+    {
+      GSource *next = source->next;
+      g_source_destroy_internal (source, context, FALSE);
+      source = next;
+    }
+
+#ifdef G_THREADS_ENABLED  
+  g_static_mutex_free (&context->mutex);
+#endif
+
+  g_ptr_array_free (context->pending_dispatches, TRUE);
+  g_free (context->cached_poll_array);
+
+  poll_rec_list_free (context, context->poll_records);
+  
+#ifdef G_THREADS_ENABLED
+  if (g_thread_supported())
+    {
+#ifndef G_OS_WIN32
+      close (context->wake_up_pipe[0]);
+      close (context->wake_up_pipe[1]);
+#else
+      CloseHandle (context->wake_up_semaphore);
+#endif
+    } 
+  else
+    main_contexts_without_pipe = g_slist_remove (main_contexts_without_pipe, 
+                                                context);
+
+  if (context->cond != NULL)
+    g_cond_free (context->cond);
+#endif
+  
+  g_free (context);
+}
+
+#ifdef G_THREADS_ENABLED
+static void 
+g_main_context_init_pipe (GMainContext *context)
+{
+# ifndef G_OS_WIN32
+  if (context->wake_up_pipe[0] != -1)
+    return;
+
+#ifdef HAVE_PIPE2
+  /* if this fails, we fall through and try pipe */
+  pipe2 (context->wake_up_pipe, O_CLOEXEC);
+#endif
+  if (context->wake_up_pipe[0] == -1)
+    {
+      if (pipe (context->wake_up_pipe) < 0)
+        g_error ("Cannot create pipe main loop wake-up: %s\n",
+                g_strerror (errno));
+      fcntl (context->wake_up_pipe[0], F_SETFD, FD_CLOEXEC);
+      fcntl (context->wake_up_pipe[1], F_SETFD, FD_CLOEXEC);
+    }
+
+  context->wake_up_rec.fd = context->wake_up_pipe[0];
+  context->wake_up_rec.events = G_IO_IN;
+# else
+  if (context->wake_up_semaphore != NULL)
+    return;
+  context->wake_up_semaphore = CreateSemaphore (NULL, 0, 100, NULL);
+  if (context->wake_up_semaphore == NULL)
+    g_error ("Cannot create wake-up semaphore: %s",
+            g_win32_error_message (GetLastError ()));
+  context->wake_up_rec.fd = (gintptr) context->wake_up_semaphore;
+  context->wake_up_rec.events = G_IO_IN;
+
+  if (_g_main_poll_debug)
+    g_print ("wake-up semaphore: %p\n", context->wake_up_semaphore);
+# endif
+  g_main_context_add_poll_unlocked (context, 0, &context->wake_up_rec);
+}
+
+void
+_g_main_thread_init (void)
+{
+  GSList *curr = main_contexts_without_pipe;
+  while (curr)
+    {
+      g_main_context_init_pipe ((GMainContext *)curr->data);
+      curr = curr->next;
+    }
+  g_slist_free (main_contexts_without_pipe);
+  main_contexts_without_pipe = NULL;  
+}
+#endif /* G_THREADS_ENABLED */
+
+/**
+ * g_main_context_new:
+ * 
+ * Creates a new #GMainContext structure.
+ * 
+ * Return value: the new #GMainContext
+ **/
+GMainContext *
+g_main_context_new (void)
+{
+  GMainContext *context = g_new0 (GMainContext, 1);
+
+#ifdef G_MAIN_POLL_DEBUG
+  {
+    static gboolean beenhere = FALSE;
+
+    if (!beenhere)
+      {
+       if (getenv ("G_MAIN_POLL_DEBUG") != NULL)
+         _g_main_poll_debug = TRUE;
+       beenhere = TRUE;
+      }
+  }
+#endif
+
+#ifdef G_THREADS_ENABLED
+  g_static_mutex_init (&context->mutex);
+
+  context->owner = NULL;
+  context->waiters = NULL;
+
+# ifndef G_OS_WIN32
+  context->wake_up_pipe[0] = -1;
+  context->wake_up_pipe[1] = -1;
+# else
+  context->wake_up_semaphore = NULL;
+# endif
+#endif
+
+  context->ref_count = 1;
+
+  context->next_id = 1;
+  
+  context->source_list = NULL;
+  
+  context->poll_func = g_poll;
+  
+  context->cached_poll_array = NULL;
+  context->cached_poll_array_size = 0;
+  
+  context->pending_dispatches = g_ptr_array_new ();
+  
+  context->time_is_current = FALSE;
+  
+#ifdef G_THREADS_ENABLED
+  if (g_thread_supported ())
+    g_main_context_init_pipe (context);
+  else
+    main_contexts_without_pipe = g_slist_prepend (main_contexts_without_pipe, 
+                                                 context);
+#endif
+
+  G_LOCK (main_context_list);
+  main_context_list = g_slist_append (main_context_list, context);
+
+#ifdef G_MAIN_POLL_DEBUG
+  if (_g_main_poll_debug)
+    g_print ("created context=%p\n", context);
+#endif
+
+  G_UNLOCK (main_context_list);
+
+  return context;
+}
+
+/**
+ * g_main_context_default:
+ * 
+ * Returns the global default main context. This is the main context
+ * used for main loop functions when a main loop is not explicitly
+ * specified, and corresponds to the "main" main loop. See also
+ * g_main_context_get_thread_default().
+ * 
+ * Return value: the global default main context.
+ **/
+GMainContext *
+g_main_context_default (void)
+{
+  /* Slow, but safe */
+  
+  G_LOCK (main_loop);
+
+  if (!default_main_context)
+    {
+      default_main_context = g_main_context_new ();
+#ifdef G_MAIN_POLL_DEBUG
+      if (_g_main_poll_debug)
+       g_print ("default context=%p\n", default_main_context);
+#endif
+    }
+
+  G_UNLOCK (main_loop);
+
+  return default_main_context;
+}
+
+static GStaticPrivate thread_context_stack = G_STATIC_PRIVATE_INIT;
+
+static void
+free_context_stack (gpointer data)
+{
+  GQueue *stack = data;
+  GMainContext *context;
+
+  while (!g_queue_is_empty (stack))
+    {
+      context = g_queue_pop_head (stack);
+      g_main_context_release (context);
+      if (context)
+       g_main_context_unref (context);
+    }
+  g_queue_free (stack);
+}
+
+/**
+ * g_main_context_push_thread_default:
+ * @context: a #GMainContext, or %NULL for the global default context
+ *
+ * Acquires @context and sets it as the thread-default context for the
+ * current thread. This will cause certain asynchronous operations
+ * (such as most <link linkend="gio">gio</link>-based I/O) which are
+ * started in this thread to run under @context and deliver their
+ * results to its main loop, rather than running under the global
+ * default context in the main thread. Note that calling this function
+ * changes the context returned by
+ * g_main_context_get_thread_default(), <emphasis>not</emphasis> the
+ * one returned by g_main_context_default(), so it does not affect the
+ * context used by functions like g_idle_add().
+ *
+ * Normally you would call this function shortly after creating a new
+ * thread, passing it a #GMainContext which will be run by a
+ * #GMainLoop in that thread, to set a new default context for all
+ * async operations in that thread. (In this case, you don't need to
+ * ever call g_main_context_pop_thread_default().) In some cases
+ * however, you may want to schedule a single operation in a
+ * non-default context, or temporarily use a non-default context in
+ * the main thread. In that case, you can wrap the call to the
+ * asynchronous operation inside a
+ * g_main_context_push_thread_default() /
+ * g_main_context_pop_thread_default() pair, but it is up to you to
+ * ensure that no other asynchronous operations accidentally get
+ * started while the non-default context is active.
+ *
+ * Beware that libraries that predate this function may not correctly
+ * handle being used from a thread with a thread-default context. Eg,
+ * see g_file_supports_thread_contexts().
+ *
+ * Since: 2.22
+ **/
+void
+g_main_context_push_thread_default (GMainContext *context)
+{
+  GQueue *stack;
+  gboolean acquired_context;
+
+  acquired_context = g_main_context_acquire (context);
+  g_return_if_fail (acquired_context);
+
+  if (context == g_main_context_default ())
+    context = NULL;
+  else if (context)
+    g_main_context_ref (context);
+
+  stack = g_static_private_get (&thread_context_stack);
+  if (!stack)
+    {
+      stack = g_queue_new ();
+      g_static_private_set (&thread_context_stack, stack,
+                           free_context_stack);
+    }
+
+  g_queue_push_head (stack, context);
+}
+
+/**
+ * g_main_context_pop_thread_default:
+ * @context: a #GMainContext object, or %NULL
+ *
+ * Pops @context off the thread-default context stack (verifying that
+ * it was on the top of the stack).
+ *
+ * Since: 2.22
+ **/
+void
+g_main_context_pop_thread_default (GMainContext *context)
+{
+  GQueue *stack;
+
+  if (context == g_main_context_default ())
+    context = NULL;
+
+  stack = g_static_private_get (&thread_context_stack);
+
+  g_return_if_fail (stack != NULL);
+  g_return_if_fail (g_queue_peek_head (stack) == context);
+
+  g_queue_pop_head (stack);
+
+  g_main_context_release (context);
+  if (context)
+    g_main_context_unref (context);
+}
+
+/**
+ * g_main_context_get_thread_default:
+ *
+ * Gets the thread-default #GMainContext for this thread. Asynchronous
+ * operations that want to be able to be run in contexts other than
+ * the default one should call this method to get a #GMainContext to
+ * add their #GSource<!-- -->s to. (Note that even in single-threaded
+ * programs applications may sometimes want to temporarily push a
+ * non-default context, so it is not safe to assume that this will
+ * always return %NULL if threads are not initialized.)
+ *
+ * Returns: the thread-default #GMainContext, or %NULL if the
+ * thread-default context is the global default context.
+ *
+ * Since: 2.22
+ **/
+GMainContext *
+g_main_context_get_thread_default (void)
+{
+  GQueue *stack;
+
+  stack = g_static_private_get (&thread_context_stack);
+  if (stack)
+    return g_queue_peek_head (stack);
+  else
+    return NULL;
+}
+
+/* Hooks for adding to the main loop */
+
+/**
+ * g_source_new:
+ * @source_funcs: structure containing functions that implement
+ *                the sources behavior.
+ * @struct_size: size of the #GSource structure to create.
+ * 
+ * Creates a new #GSource structure. The size is specified to
+ * allow creating structures derived from #GSource that contain
+ * additional data. The size passed in must be at least
+ * <literal>sizeof (GSource)</literal>.
+ * 
+ * The source will not initially be associated with any #GMainContext
+ * and must be added to one with g_source_attach() before it will be
+ * executed.
+ * 
+ * Return value: the newly-created #GSource.
+ **/
+GSource *
+g_source_new (GSourceFuncs *source_funcs,
+             guint         struct_size)
+{
+  GSource *source;
+
+  g_return_val_if_fail (source_funcs != NULL, NULL);
+  g_return_val_if_fail (struct_size >= sizeof (GSource), NULL);
+  
+  source = (GSource*) g_malloc0 (struct_size);
+
+  source->source_funcs = source_funcs;
+  source->ref_count = 1;
+  
+  source->priority = G_PRIORITY_DEFAULT;
+
+  source->flags = G_HOOK_FLAG_ACTIVE;
+
+  /* NULL/0 initialization for all other fields */
+  
+  return source;
+}
+
+/* Holds context's lock
+ */
+static void
+g_source_list_add (GSource      *source,
+                  GMainContext *context)
+{
+  GSource *tmp_source, *last_source;
+  
+  last_source = NULL;
+  tmp_source = context->source_list;
+  while (tmp_source && tmp_source->priority <= source->priority)
+    {
+      last_source = tmp_source;
+      tmp_source = tmp_source->next;
+    }
+
+  source->next = tmp_source;
+  if (tmp_source)
+    tmp_source->prev = source;
+  
+  source->prev = last_source;
+  if (last_source)
+    last_source->next = source;
+  else
+    context->source_list = source;
+}
+
+/* Holds context's lock
+ */
+static void
+g_source_list_remove (GSource      *source,
+                     GMainContext *context)
+{
+  if (source->prev)
+    source->prev->next = source->next;
+  else
+    context->source_list = source->next;
+
+  if (source->next)
+    source->next->prev = source->prev;
+
+  source->prev = NULL;
+  source->next = NULL;
+}
+
+/**
+ * g_source_attach:
+ * @source: a #GSource
+ * @context: a #GMainContext (if %NULL, the default context will be used)
+ * 
+ * Adds a #GSource to a @context so that it will be executed within
+ * that context. Remove it by calling g_source_destroy().
+ *
+ * Return value: the ID (greater than 0) for the source within the 
+ *   #GMainContext. 
+ **/
+guint
+g_source_attach (GSource      *source,
+                GMainContext *context)
+{
+  guint result = 0;
+  GSList *tmp_list;
+
+  g_return_val_if_fail (source->context == NULL, 0);
+  g_return_val_if_fail (!SOURCE_DESTROYED (source), 0);
+  
+  if (!context)
+    context = g_main_context_default ();
+
+  LOCK_CONTEXT (context);
+
+  source->context = context;
+  result = source->source_id = context->next_id++;
+
+  source->ref_count++;
+  g_source_list_add (source, context);
+
+  tmp_list = source->poll_fds;
+  while (tmp_list)
+    {
+      g_main_context_add_poll_unlocked (context, source->priority, tmp_list->data);
+      tmp_list = tmp_list->next;
+    }
+
+#ifdef G_THREADS_ENABLED
+  /* Now wake up the main loop if it is waiting in the poll() */
+  g_main_context_wakeup_unlocked (context);
+#endif
+
+  UNLOCK_CONTEXT (context);
+
+  return result;
+}
+
+static void
+g_source_destroy_internal (GSource      *source,
+                          GMainContext *context,
+                          gboolean      have_lock)
+{
+  if (!have_lock)
+    LOCK_CONTEXT (context);
+  
+  if (!SOURCE_DESTROYED (source))
+    {
+      GSList *tmp_list;
+      gpointer old_cb_data;
+      GSourceCallbackFuncs *old_cb_funcs;
+      
+      source->flags &= ~G_HOOK_FLAG_ACTIVE;
+
+      old_cb_data = source->callback_data;
+      old_cb_funcs = source->callback_funcs;
+
+      source->callback_data = NULL;
+      source->callback_funcs = NULL;
+
+      if (old_cb_funcs)
+       {
+         UNLOCK_CONTEXT (context);
+         old_cb_funcs->unref (old_cb_data);
+         LOCK_CONTEXT (context);
+       }
+
+      if (!SOURCE_BLOCKED (source))
+       {
+         tmp_list = source->poll_fds;
+         while (tmp_list)
+           {
+             g_main_context_remove_poll_unlocked (context, tmp_list->data);
+             tmp_list = tmp_list->next;
+           }
+       }
+         
+      g_source_unref_internal (source, context, TRUE);
+    }
+
+  if (!have_lock)
+    UNLOCK_CONTEXT (context);
+}
+
+/**
+ * g_source_destroy:
+ * @source: a #GSource
+ * 
+ * Removes a source from its #GMainContext, if any, and mark it as
+ * destroyed.  The source cannot be subsequently added to another
+ * context.
+ **/
+void
+g_source_destroy (GSource *source)
+{
+  GMainContext *context;
+  
+  g_return_if_fail (source != NULL);
+  
+  context = source->context;
+  
+  if (context)
+    g_source_destroy_internal (source, context, FALSE);
+  else
+    source->flags &= ~G_HOOK_FLAG_ACTIVE;
+}
+
+/**
+ * g_source_get_id:
+ * @source: a #GSource
+ * 
+ * Returns the numeric ID for a particular source. The ID of a source
+ * is a positive integer which is unique within a particular main loop 
+ * context. The reverse
+ * mapping from ID to source is done by g_main_context_find_source_by_id().
+ *
+ * Return value: the ID (greater than 0) for the source
+ **/
+guint
+g_source_get_id (GSource *source)
+{
+  guint result;
+  
+  g_return_val_if_fail (source != NULL, 0);
+  g_return_val_if_fail (source->context != NULL, 0);
+
+  LOCK_CONTEXT (source->context);
+  result = source->source_id;
+  UNLOCK_CONTEXT (source->context);
+  
+  return result;
+}
+
+/**
+ * g_source_get_context:
+ * @source: a #GSource
+ * 
+ * Gets the #GMainContext with which the source is associated.
+ * Calling this function on a destroyed source is an error.
+ * 
+ * Return value: the #GMainContext with which the source is associated,
+ *               or %NULL if the context has not yet been added
+ *               to a source.
+ **/
+GMainContext *
+g_source_get_context (GSource *source)
+{
+  g_return_val_if_fail (!SOURCE_DESTROYED (source), NULL);
+
+  return source->context;
+}
+
+/**
+ * g_source_add_poll:
+ * @source:a #GSource 
+ * @fd: a #GPollFD structure holding information about a file
+ *      descriptor to watch.
+ * 
+ * Adds a file descriptor to the set of file descriptors polled for
+ * this source. This is usually combined with g_source_new() to add an
+ * event source. The event source's check function will typically test
+ * the @revents field in the #GPollFD struct and return %TRUE if events need
+ * to be processed.
+ **/
+void
+g_source_add_poll (GSource *source,
+                  GPollFD *fd)
+{
+  GMainContext *context;
+  
+  g_return_if_fail (source != NULL);
+  g_return_if_fail (fd != NULL);
+  g_return_if_fail (!SOURCE_DESTROYED (source));
+  
+  context = source->context;
+
+  if (context)
+    LOCK_CONTEXT (context);
+  
+  source->poll_fds = g_slist_prepend (source->poll_fds, fd);
+
+  if (context)
+    {
+      if (!SOURCE_BLOCKED (source))
+       g_main_context_add_poll_unlocked (context, source->priority, fd);
+      UNLOCK_CONTEXT (context);
+    }
+}
+
+/**
+ * g_source_remove_poll:
+ * @source:a #GSource 
+ * @fd: a #GPollFD structure previously passed to g_source_add_poll().
+ * 
+ * Removes a file descriptor from the set of file descriptors polled for
+ * this source. 
+ **/
+void
+g_source_remove_poll (GSource *source,
+                     GPollFD *fd)
+{
+  GMainContext *context;
+  
+  g_return_if_fail (source != NULL);
+  g_return_if_fail (fd != NULL);
+  g_return_if_fail (!SOURCE_DESTROYED (source));
+  
+  context = source->context;
+
+  if (context)
+    LOCK_CONTEXT (context);
+  
+  source->poll_fds = g_slist_remove (source->poll_fds, fd);
+
+  if (context)
+    {
+      if (!SOURCE_BLOCKED (source))
+       g_main_context_remove_poll_unlocked (context, fd);
+      UNLOCK_CONTEXT (context);
+    }
+}
+
+/**
+ * g_source_set_callback_indirect:
+ * @source: the source
+ * @callback_data: pointer to callback data "object"
+ * @callback_funcs: functions for reference counting @callback_data
+ *                  and getting the callback and data
+ * 
+ * Sets the callback function storing the data as a refcounted callback
+ * "object". This is used internally. Note that calling 
+ * g_source_set_callback_indirect() assumes
+ * an initial reference count on @callback_data, and thus
+ * @callback_funcs->unref will eventually be called once more
+ * than @callback_funcs->ref.
+ **/
+void
+g_source_set_callback_indirect (GSource              *source,
+                               gpointer              callback_data,
+                               GSourceCallbackFuncs *callback_funcs)
+{
+  GMainContext *context;
+  gpointer old_cb_data;
+  GSourceCallbackFuncs *old_cb_funcs;
+  
+  g_return_if_fail (source != NULL);
+  g_return_if_fail (callback_funcs != NULL || callback_data == NULL);
+
+  context = source->context;
+
+  if (context)
+    LOCK_CONTEXT (context);
+
+  old_cb_data = source->callback_data;
+  old_cb_funcs = source->callback_funcs;
+
+  source->callback_data = callback_data;
+  source->callback_funcs = callback_funcs;
+  
+  if (context)
+    UNLOCK_CONTEXT (context);
+  
+  if (old_cb_funcs)
+    old_cb_funcs->unref (old_cb_data);
+}
+
+static void
+g_source_callback_ref (gpointer cb_data)
+{
+  GSourceCallback *callback = cb_data;
+
+  callback->ref_count++;
+}
+
+
+static void
+g_source_callback_unref (gpointer cb_data)
+{
+  GSourceCallback *callback = cb_data;
+
+  callback->ref_count--;
+  if (callback->ref_count == 0)
+    {
+      if (callback->notify)
+       callback->notify (callback->data);
+      g_free (callback);
+    }
+}
+
+static void
+g_source_callback_get (gpointer     cb_data,
+                      GSource     *source, 
+                      GSourceFunc *func,
+                      gpointer    *data)
+{
+  GSourceCallback *callback = cb_data;
+
+  *func = callback->func;
+  *data = callback->data;
+}
+
+static GSourceCallbackFuncs g_source_callback_funcs = {
+  g_source_callback_ref,
+  g_source_callback_unref,
+  g_source_callback_get,
+};
+
+/**
+ * g_source_set_callback:
+ * @source: the source
+ * @func: a callback function
+ * @data: the data to pass to callback function
+ * @notify: a function to call when @data is no longer in use, or %NULL.
+ * 
+ * Sets the callback function for a source. The callback for a source is
+ * called from the source's dispatch function.
+ *
+ * The exact type of @func depends on the type of source; ie. you
+ * should not count on @func being called with @data as its first
+ * parameter.
+ * 
+ * Typically, you won't use this function. Instead use functions specific
+ * to the type of source you are using.
+ **/
+void
+g_source_set_callback (GSource        *source,
+                      GSourceFunc     func,
+                      gpointer        data,
+                      GDestroyNotify  notify)
+{
+  GSourceCallback *new_callback;
+
+  g_return_if_fail (source != NULL);
+
+  new_callback = g_new (GSourceCallback, 1);
+
+  new_callback->ref_count = 1;
+  new_callback->func = func;
+  new_callback->data = data;
+  new_callback->notify = notify;
+
+  g_source_set_callback_indirect (source, new_callback, &g_source_callback_funcs);
+}
+
+
+/**
+ * g_source_set_funcs:
+ * @source: a #GSource
+ * @funcs: the new #GSourceFuncs
+ * 
+ * Sets the source functions (can be used to override 
+ * default implementations) of an unattached source.
+ * 
+ * Since: 2.12
+ */
+void
+g_source_set_funcs (GSource     *source,
+                  GSourceFuncs *funcs)
+{
+  g_return_if_fail (source != NULL);
+  g_return_if_fail (source->context == NULL);
+  g_return_if_fail (source->ref_count > 0);
+  g_return_if_fail (funcs != NULL);
+
+  source->source_funcs = funcs;
+}
+
+/**
+ * g_source_set_priority:
+ * @source: a #GSource
+ * @priority: the new priority.
+ * 
+ * Sets the priority of a source. While the main loop is being
+ * run, a source will be dispatched if it is ready to be dispatched and no sources 
+ * at a higher (numerically smaller) priority are ready to be dispatched.
+ **/
+void
+g_source_set_priority (GSource  *source,
+                      gint      priority)
+{
+  GSList *tmp_list;
+  GMainContext *context;
+  
+  g_return_if_fail (source != NULL);
+
+  context = source->context;
+
+  if (context)
+    LOCK_CONTEXT (context);
+  
+  source->priority = priority;
+
+  if (context)
+    {
+      /* Remove the source from the context's source and then
+       * add it back so it is sorted in the correct plcae
+       */
+      g_source_list_remove (source, source->context);
+      g_source_list_add (source, source->context);
+
+      if (!SOURCE_BLOCKED (source))
+       {
+         tmp_list = source->poll_fds;
+         while (tmp_list)
+           {
+             g_main_context_remove_poll_unlocked (context, tmp_list->data);
+             g_main_context_add_poll_unlocked (context, priority, tmp_list->data);
+             
+             tmp_list = tmp_list->next;
+           }
+       }
+      
+      UNLOCK_CONTEXT (source->context);
+    }
+}
+
+/**
+ * g_source_get_priority:
+ * @source: a #GSource
+ * 
+ * Gets the priority of a source.
+ * 
+ * Return value: the priority of the source
+ **/
+gint
+g_source_get_priority (GSource *source)
+{
+  g_return_val_if_fail (source != NULL, 0);
+
+  return source->priority;
+}
+
+/**
+ * g_source_set_can_recurse:
+ * @source: a #GSource
+ * @can_recurse: whether recursion is allowed for this source
+ * 
+ * Sets whether a source can be called recursively. If @can_recurse is
+ * %TRUE, then while the source is being dispatched then this source
+ * will be processed normally. Otherwise, all processing of this
+ * source is blocked until the dispatch function returns.
+ **/
+void
+g_source_set_can_recurse (GSource  *source,
+                         gboolean  can_recurse)
+{
+  GMainContext *context;
+  
+  g_return_if_fail (source != NULL);
+
+  context = source->context;
+
+  if (context)
+    LOCK_CONTEXT (context);
+  
+  if (can_recurse)
+    source->flags |= G_SOURCE_CAN_RECURSE;
+  else
+    source->flags &= ~G_SOURCE_CAN_RECURSE;
+
+  if (context)
+    UNLOCK_CONTEXT (context);
+}
+
+/**
+ * g_source_get_can_recurse:
+ * @source: a #GSource
+ * 
+ * Checks whether a source is allowed to be called recursively.
+ * see g_source_set_can_recurse().
+ * 
+ * Return value: whether recursion is allowed.
+ **/
+gboolean
+g_source_get_can_recurse (GSource  *source)
+{
+  g_return_val_if_fail (source != NULL, FALSE);
+  
+  return (source->flags & G_SOURCE_CAN_RECURSE) != 0;
+}
+
+
+/**
+ * g_source_set_name:
+ * @source: a #GSource
+ * @name: debug name for the source
+ *
+ * Sets a name for the source, used in debugging and profiling.
+ * The name defaults to #NULL.
+ *
+ * The source name should describe in a human-readable way
+ * what the source does. For example, "X11 event queue"
+ * or "GTK+ repaint idle handler" or whatever it is.
+ *
+ * It is permitted to call this function multiple times, but is not
+ * recommended due to the potential performance impact.  For example,
+ * one could change the name in the "check" function of a #GSourceFuncs 
+ * to include details like the event type in the source name.
+ *
+ * Since: 2.26
+ **/
+void
+g_source_set_name (GSource    *source,
+                   const char *name)
+{
+  g_return_if_fail (source != NULL);
+
+  /* setting back to NULL is allowed, just because it's
+   * weird if get_name can return NULL but you can't
+   * set that.
+   */
+
+  g_free (source->name);
+  source->name = g_strdup (name);
+}
+
+/**
+ * g_source_get_name:
+ * @source: a #GSource
+ *
+ * Gets a name for the source, used in debugging and profiling.
+ * The name may be #NULL if it has never been set with
+ * g_source_set_name().
+ *
+ * Return value: the name of the source
+ * Since: 2.26
+ **/
+G_CONST_RETURN char*
+g_source_get_name (GSource *source)
+{
+  g_return_val_if_fail (source != NULL, NULL);
+
+  return source->name;
+}
+
+/**
+ * g_source_set_name_by_id:
+ * @tag: a #GSource ID
+ * @name: debug name for the source
+ *
+ * Sets the name of a source using its ID.
+ *
+ * This is a convenience utility to set source names from the return
+ * value of g_idle_add(), g_timeout_add(), etc.
+ *
+ * Since: 2.26
+ **/
+void
+g_source_set_name_by_id (guint           tag,
+                         const char     *name)
+{
+  GSource *source;
+
+  g_return_if_fail (tag > 0);
+
+  source = g_main_context_find_source_by_id (NULL, tag);
+  if (source == NULL)
+    return;
+
+  g_source_set_name (source, name);
+}
+
+
+/**
+ * g_source_ref:
+ * @source: a #GSource
+ * 
+ * Increases the reference count on a source by one.
+ * 
+ * Return value: @source
+ **/
+GSource *
+g_source_ref (GSource *source)
+{
+  GMainContext *context;
+  
+  g_return_val_if_fail (source != NULL, NULL);
+
+  context = source->context;
+
+  if (context)
+    LOCK_CONTEXT (context);
+
+  source->ref_count++;
+
+  if (context)
+    UNLOCK_CONTEXT (context);
+
+  return source;
+}
+
+/* g_source_unref() but possible to call within context lock
+ */
+static void
+g_source_unref_internal (GSource      *source,
+                        GMainContext *context,
+                        gboolean      have_lock)
+{
+  gpointer old_cb_data = NULL;
+  GSourceCallbackFuncs *old_cb_funcs = NULL;
+
+  g_return_if_fail (source != NULL);
+  
+  if (!have_lock && context)
+    LOCK_CONTEXT (context);
+
+  source->ref_count--;
+  if (source->ref_count == 0)
+    {
+      old_cb_data = source->callback_data;
+      old_cb_funcs = source->callback_funcs;
+
+      source->callback_data = NULL;
+      source->callback_funcs = NULL;
+
+      if (context && !SOURCE_DESTROYED (source))
+       {
+         g_warning (G_STRLOC ": ref_count == 0, but source is still attached to a context!");
+         source->ref_count++;
+       }
+      else if (context)
+       g_source_list_remove (source, context);
+
+      if (source->source_funcs->finalize)
+       source->source_funcs->finalize (source);
+
+      g_free (source->name);
+      source->name = NULL;
+
+      g_slist_free (source->poll_fds);
+      source->poll_fds = NULL;
+      g_free (source);
+    }
+  
+  if (!have_lock && context)
+    UNLOCK_CONTEXT (context);
+
+  if (old_cb_funcs)
+    {
+      if (have_lock)
+       UNLOCK_CONTEXT (context);
+      
+      old_cb_funcs->unref (old_cb_data);
+
+      if (have_lock)
+       LOCK_CONTEXT (context);
+    }
+}
+
+/**
+ * g_source_unref:
+ * @source: a #GSource
+ * 
+ * Decreases the reference count of a source by one. If the
+ * resulting reference count is zero the source and associated
+ * memory will be destroyed. 
+ **/
+void
+g_source_unref (GSource *source)
+{
+  g_return_if_fail (source != NULL);
+
+  g_source_unref_internal (source, source->context, FALSE);
+}
+
+/**
+ * g_main_context_find_source_by_id:
+ * @context: a #GMainContext (if %NULL, the default context will be used)
+ * @source_id: the source ID, as returned by g_source_get_id(). 
+ * 
+ * Finds a #GSource given a pair of context and ID.
+ * 
+ * Return value: the #GSource if found, otherwise, %NULL
+ **/
+GSource *
+g_main_context_find_source_by_id (GMainContext *context,
+                                 guint         source_id)
+{
+  GSource *source;
+  
+  g_return_val_if_fail (source_id > 0, NULL);
+
+  if (context == NULL)
+    context = g_main_context_default ();
+  
+  LOCK_CONTEXT (context);
+  
+  source = context->source_list;
+  while (source)
+    {
+      if (!SOURCE_DESTROYED (source) &&
+         source->source_id == source_id)
+       break;
+      source = source->next;
+    }
+
+  UNLOCK_CONTEXT (context);
+
+  return source;
+}
+
+/**
+ * g_main_context_find_source_by_funcs_user_data:
+ * @context: a #GMainContext (if %NULL, the default context will be used).
+ * @funcs: the @source_funcs passed to g_source_new().
+ * @user_data: the user data from the callback.
+ * 
+ * Finds a source with the given source functions and user data.  If
+ * multiple sources exist with the same source function and user data,
+ * the first one found will be returned.
+ * 
+ * Return value: the source, if one was found, otherwise %NULL
+ **/
+GSource *
+g_main_context_find_source_by_funcs_user_data (GMainContext *context,
+                                              GSourceFuncs *funcs,
+                                              gpointer      user_data)
+{
+  GSource *source;
+  
+  g_return_val_if_fail (funcs != NULL, NULL);
+
+  if (context == NULL)
+    context = g_main_context_default ();
+  
+  LOCK_CONTEXT (context);
+
+  source = context->source_list;
+  while (source)
+    {
+      if (!SOURCE_DESTROYED (source) &&
+         source->source_funcs == funcs &&
+         source->callback_funcs)
+       {
+         GSourceFunc callback;
+         gpointer callback_data;
+
+         source->callback_funcs->get (source->callback_data, source, &callback, &callback_data);
+         
+         if (callback_data == user_data)
+           break;
+       }
+      source = source->next;
+    }
+
+  UNLOCK_CONTEXT (context);
+
+  return source;
+}
+
+/**
+ * g_main_context_find_source_by_user_data:
+ * @context: a #GMainContext
+ * @user_data: the user_data for the callback.
+ * 
+ * Finds a source with the given user data for the callback.  If
+ * multiple sources exist with the same user data, the first
+ * one found will be returned.
+ * 
+ * Return value: the source, if one was found, otherwise %NULL
+ **/
+GSource *
+g_main_context_find_source_by_user_data (GMainContext *context,
+                                        gpointer      user_data)
+{
+  GSource *source;
+  
+  if (context == NULL)
+    context = g_main_context_default ();
+  
+  LOCK_CONTEXT (context);
+
+  source = context->source_list;
+  while (source)
+    {
+      if (!SOURCE_DESTROYED (source) &&
+         source->callback_funcs)
+       {
+         GSourceFunc callback;
+         gpointer callback_data = NULL;
+
+         source->callback_funcs->get (source->callback_data, source, &callback, &callback_data);
+
+         if (callback_data == user_data)
+           break;
+       }
+      source = source->next;
+    }
+
+  UNLOCK_CONTEXT (context);
+
+  return source;
+}
+
+/**
+ * g_source_remove:
+ * @tag: the ID of the source to remove.
+ * 
+ * Removes the source with the given id from the default main context. 
+ * The id of
+ * a #GSource is given by g_source_get_id(), or will be returned by the
+ * functions g_source_attach(), g_idle_add(), g_idle_add_full(),
+ * g_timeout_add(), g_timeout_add_full(), g_child_watch_add(),
+ * g_child_watch_add_full(), g_io_add_watch(), and g_io_add_watch_full().
+ *
+ * See also g_source_destroy(). You must use g_source_destroy() for sources
+ * added to a non-default main context.
+ *
+ * Return value: %TRUE if the source was found and removed.
+ **/
+gboolean
+g_source_remove (guint tag)
+{
+  GSource *source;
+  
+  g_return_val_if_fail (tag > 0, FALSE);
+
+  source = g_main_context_find_source_by_id (NULL, tag);
+  if (source)
+    g_source_destroy (source);
+
+  return source != NULL;
+}
+
+/**
+ * g_source_remove_by_user_data:
+ * @user_data: the user_data for the callback.
+ * 
+ * Removes a source from the default main loop context given the user
+ * data for the callback. If multiple sources exist with the same user
+ * data, only one will be destroyed.
+ * 
+ * Return value: %TRUE if a source was found and removed. 
+ **/
+gboolean
+g_source_remove_by_user_data (gpointer user_data)
+{
+  GSource *source;
+  
+  source = g_main_context_find_source_by_user_data (NULL, user_data);
+  if (source)
+    {
+      g_source_destroy (source);
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+/**
+ * g_source_remove_by_funcs_user_data:
+ * @funcs: The @source_funcs passed to g_source_new()
+ * @user_data: the user data for the callback
+ * 
+ * Removes a source from the default main loop context given the
+ * source functions and user data. If multiple sources exist with the
+ * same source functions and user data, only one will be destroyed.
+ * 
+ * Return value: %TRUE if a source was found and removed. 
+ **/
+gboolean
+g_source_remove_by_funcs_user_data (GSourceFuncs *funcs,
+                                   gpointer      user_data)
+{
+  GSource *source;
+
+  g_return_val_if_fail (funcs != NULL, FALSE);
+
+  source = g_main_context_find_source_by_funcs_user_data (NULL, funcs, user_data);
+  if (source)
+    {
+      g_source_destroy (source);
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+/**
+ * g_get_current_time:
+ * @result: #GTimeVal structure in which to store current time.
+ * 
+ * Equivalent to the UNIX gettimeofday() function, but portable.
+ **/
+void
+g_get_current_time (GTimeVal *result)
+{
+#ifndef G_OS_WIN32
+  struct timeval r;
+
+  g_return_if_fail (result != NULL);
+
+  /*this is required on alpha, there the timeval structs are int's
+    not longs and a cast only would fail horribly*/
+  gettimeofday (&r, NULL);
+  result->tv_sec = r.tv_sec;
+  result->tv_usec = r.tv_usec;
+#else
+  FILETIME ft;
+  guint64 time64;
+
+  g_return_if_fail (result != NULL);
+
+  GetSystemTimeAsFileTime (&ft);
+  memmove (&time64, &ft, sizeof (FILETIME));
+
+  /* Convert from 100s of nanoseconds since 1601-01-01
+   * to Unix epoch. Yes, this is Y2038 unsafe.
+   */
+  time64 -= G_GINT64_CONSTANT (116444736000000000);
+  time64 /= 10;
+
+  result->tv_sec = time64 / 1000000;
+  result->tv_usec = time64 % 1000000;
+#endif
+}
+
+static void
+g_main_dispatch_free (gpointer dispatch)
+{
+  g_slice_free (GMainDispatch, dispatch);
+}
+
+/* Running the main loop */
+
+static GMainDispatch *
+get_dispatch (void)
+{
+  static GStaticPrivate depth_private = G_STATIC_PRIVATE_INIT;
+  GMainDispatch *dispatch = g_static_private_get (&depth_private);
+  if (!dispatch)
+    {
+      dispatch = g_slice_new0 (GMainDispatch);
+      g_static_private_set (&depth_private, dispatch, g_main_dispatch_free);
+    }
+
+  return dispatch;
+}
+
+/**
+ * g_main_depth:
+ *
+ * Returns the depth of the stack of calls to
+ * g_main_context_dispatch() on any #GMainContext in the current thread.
+ *  That is, when called from the toplevel, it gives 0. When
+ * called from within a callback from g_main_context_iteration()
+ * (or g_main_loop_run(), etc.) it returns 1. When called from within 
+ * a callback to a recursive call to g_main_context_iterate(),
+ * it returns 2. And so forth.
+ *
+ * This function is useful in a situation like the following:
+ * Imagine an extremely simple "garbage collected" system.
+ *
+ * |[
+ * static GList *free_list;
+ * 
+ * gpointer
+ * allocate_memory (gsize size)
+ * { 
+ *   gpointer result = g_malloc (size);
+ *   free_list = g_list_prepend (free_list, result);
+ *   return result;
+ * }
+ * 
+ * void
+ * free_allocated_memory (void)
+ * {
+ *   GList *l;
+ *   for (l = free_list; l; l = l->next);
+ *     g_free (l->data);
+ *   g_list_free (free_list);
+ *   free_list = NULL;
+ *  }
+ * 
+ * [...]
+ * 
+ * while (TRUE); 
+ *  {
+ *    g_main_context_iteration (NULL, TRUE);
+ *    free_allocated_memory();
+ *   }
+ * ]|
+ *
+ * This works from an application, however, if you want to do the same
+ * thing from a library, it gets more difficult, since you no longer
+ * control the main loop. You might think you can simply use an idle
+ * function to make the call to free_allocated_memory(), but that
+ * doesn't work, since the idle function could be called from a
+ * recursive callback. This can be fixed by using g_main_depth()
+ *
+ * |[
+ * gpointer
+ * allocate_memory (gsize size)
+ * { 
+ *   FreeListBlock *block = g_new (FreeListBlock, 1);
+ *   block->mem = g_malloc (size);
+ *   block->depth = g_main_depth ();   
+ *   free_list = g_list_prepend (free_list, block);
+ *   return block->mem;
+ * }
+ * 
+ * void
+ * free_allocated_memory (void)
+ * {
+ *   GList *l;
+ *   
+ *   int depth = g_main_depth ();
+ *   for (l = free_list; l; );
+ *     {
+ *       GList *next = l->next;
+ *       FreeListBlock *block = l->data;
+ *       if (block->depth > depth)
+ *         {
+ *           g_free (block->mem);
+ *           g_free (block);
+ *           free_list = g_list_delete_link (free_list, l);
+ *         }
+ *               
+ *       l = next;
+ *     }
+ *   }
+ * ]|
+ *
+ * There is a temptation to use g_main_depth() to solve
+ * problems with reentrancy. For instance, while waiting for data
+ * to be received from the network in response to a menu item,
+ * the menu item might be selected again. It might seem that
+ * one could make the menu item's callback return immediately
+ * and do nothing if g_main_depth() returns a value greater than 1.
+ * However, this should be avoided since the user then sees selecting
+ * the menu item do nothing. Furthermore, you'll find yourself adding
+ * these checks all over your code, since there are doubtless many,
+ * many things that the user could do. Instead, you can use the
+ * following techniques:
+ *
+ * <orderedlist>
+ *  <listitem>
+ *   <para>
+ *     Use gtk_widget_set_sensitive() or modal dialogs to prevent
+ *     the user from interacting with elements while the main
+ *     loop is recursing.
+ *   </para>
+ *  </listitem>
+ *  <listitem>
+ *   <para>
+ *     Avoid main loop recursion in situations where you can't handle
+ *     arbitrary  callbacks. Instead, structure your code so that you
+ *     simply return to the main loop and then get called again when
+ *     there is more work to do.
+ *   </para>
+ *  </listitem>
+ * </orderedlist>
+ * 
+ * Return value: The main loop recursion level in the current thread
+ **/
+int
+g_main_depth (void)
+{
+  GMainDispatch *dispatch = get_dispatch ();
+  return dispatch->depth;
+}
+
+/**
+ * g_main_current_source:
+ *
+ * Returns the currently firing source for this thread.
+ * 
+ * Return value: The currently firing source or %NULL.
+ *
+ * Since: 2.12
+ */
+GSource *
+g_main_current_source (void)
+{
+  GMainDispatch *dispatch = get_dispatch ();
+  return dispatch->dispatching_sources ? dispatch->dispatching_sources->data : NULL;
+}
+
+/**
+ * g_source_is_destroyed:
+ * @source: a #GSource
+ *
+ * Returns whether @source has been destroyed.
+ *
+ * This is important when you operate upon your objects 
+ * from within idle handlers, but may have freed the object 
+ * before the dispatch of your idle handler.
+ *
+ * |[
+ * static gboolean 
+ * idle_callback (gpointer data)
+ * {
+ *   SomeWidget *self = data;
+ *    
+ *   GDK_THREADS_ENTER (<!-- -->);
+ *   /<!-- -->* do stuff with self *<!-- -->/
+ *   self->idle_id = 0;
+ *   GDK_THREADS_LEAVE (<!-- -->);
+ *    
+ *   return FALSE;
+ * }
+ *  
+ * static void 
+ * some_widget_do_stuff_later (SomeWidget *self)
+ * {
+ *   self->idle_id = g_idle_add (idle_callback, self);
+ * }
+ *  
+ * static void 
+ * some_widget_finalize (GObject *object)
+ * {
+ *   SomeWidget *self = SOME_WIDGET (object);
+ *    
+ *   if (self->idle_id)
+ *     g_source_remove (self->idle_id);
+ *    
+ *   G_OBJECT_CLASS (parent_class)->finalize (object);
+ * }
+ * ]|
+ *
+ * This will fail in a multi-threaded application if the 
+ * widget is destroyed before the idle handler fires due 
+ * to the use after free in the callback. A solution, to 
+ * this particular problem, is to check to if the source
+ * has already been destroy within the callback.
+ *
+ * |[
+ * static gboolean 
+ * idle_callback (gpointer data)
+ * {
+ *   SomeWidget *self = data;
+ *   
+ *   GDK_THREADS_ENTER ();
+ *   if (!g_source_is_destroyed (g_main_current_source ()))
+ *     {
+ *       /<!-- -->* do stuff with self *<!-- -->/
+ *     }
+ *   GDK_THREADS_LEAVE ();
+ *   
+ *   return FALSE;
+ * }
+ * ]|
+ *
+ * Return value: %TRUE if the source has been destroyed
+ *
+ * Since: 2.12
+ */
+gboolean
+g_source_is_destroyed (GSource *source)
+{
+  return SOURCE_DESTROYED (source);
+}
+
+/* Temporarily remove all this source's file descriptors from the
+ * poll(), so that if data comes available for one of the file descriptors
+ * we don't continually spin in the poll()
+ */
+/* HOLDS: source->context's lock */
+static void
+block_source (GSource *source)
+{
+  GSList *tmp_list;
+
+  g_return_if_fail (!SOURCE_BLOCKED (source));
+
+  tmp_list = source->poll_fds;
+  while (tmp_list)
+    {
+      g_main_context_remove_poll_unlocked (source->context, tmp_list->data);
+      tmp_list = tmp_list->next;
+    }
+}
+
+/* HOLDS: source->context's lock */
+static void
+unblock_source (GSource *source)
+{
+  GSList *tmp_list;
+  
+  g_return_if_fail (!SOURCE_BLOCKED (source)); /* Source already unblocked */
+  g_return_if_fail (!SOURCE_DESTROYED (source));
+  
+  tmp_list = source->poll_fds;
+  while (tmp_list)
+    {
+      g_main_context_add_poll_unlocked (source->context, source->priority, tmp_list->data);
+      tmp_list = tmp_list->next;
+    }
+}
+
+/* HOLDS: context's lock */
+static void
+g_main_dispatch (GMainContext *context)
+{
+  GMainDispatch *current = get_dispatch ();
+  guint i;
+
+  for (i = 0; i < context->pending_dispatches->len; i++)
+    {
+      GSource *source = context->pending_dispatches->pdata[i];
+
+      context->pending_dispatches->pdata[i] = NULL;
+      g_assert (source);
+
+      source->flags &= ~G_SOURCE_READY;
+
+      if (!SOURCE_DESTROYED (source))
+       {
+         gboolean was_in_call;
+         gpointer user_data = NULL;
+         GSourceFunc callback = NULL;
+         GSourceCallbackFuncs *cb_funcs;
+         gpointer cb_data;
+         gboolean need_destroy;
+
+         gboolean (*dispatch) (GSource *,
+                               GSourceFunc,
+                               gpointer);
+         GSList current_source_link;
+
+         dispatch = source->source_funcs->dispatch;
+         cb_funcs = source->callback_funcs;
+         cb_data = source->callback_data;
+
+         if (cb_funcs)
+           cb_funcs->ref (cb_data);
+         
+         if ((source->flags & G_SOURCE_CAN_RECURSE) == 0)
+           block_source (source);
+         
+         was_in_call = source->flags & G_HOOK_FLAG_IN_CALL;
+         source->flags |= G_HOOK_FLAG_IN_CALL;
+
+         if (cb_funcs)
+           cb_funcs->get (cb_data, source, &callback, &user_data);
+
+         UNLOCK_CONTEXT (context);
+
+         current->depth++;
+         /* The on-stack allocation of the GSList is unconventional, but
+          * we know that the lifetime of the link is bounded to this
+          * function as the link is kept in a thread specific list and
+          * not manipulated outside of this function and its descendants.
+          * Avoiding the overhead of a g_slist_alloc() is useful as many
+          * applications do little more than dispatch events.
+          *
+          * This is a performance hack - do not revert to g_slist_prepend()!
+          */
+         current_source_link.data = source;
+         current_source_link.next = current->dispatching_sources;
+         current->dispatching_sources = &current_source_link;
+         need_destroy = ! dispatch (source,
+                                    callback,
+                                    user_data);
+         g_assert (current->dispatching_sources == &current_source_link);
+         current->dispatching_sources = current_source_link.next;
+         current->depth--;
+         
+         if (cb_funcs)
+           cb_funcs->unref (cb_data);
+
+         LOCK_CONTEXT (context);
+         
+         if (!was_in_call)
+           source->flags &= ~G_HOOK_FLAG_IN_CALL;
+
+         if ((source->flags & G_SOURCE_CAN_RECURSE) == 0 &&
+             !SOURCE_DESTROYED (source))
+           unblock_source (source);
+         
+         /* Note: this depends on the fact that we can't switch
+          * sources from one main context to another
+          */
+         if (need_destroy && !SOURCE_DESTROYED (source))
+           {
+             g_assert (source->context == context);
+             g_source_destroy_internal (source, context, TRUE);
+           }
+       }
+      
+      SOURCE_UNREF (source, context);
+    }
+
+  g_ptr_array_set_size (context->pending_dispatches, 0);
+}
+
+/* Holds context's lock */
+static inline GSource *
+next_valid_source (GMainContext *context,
+                  GSource      *source)
+{
+  GSource *new_source = source ? source->next : context->source_list;
+
+  while (new_source)
+    {
+      if (!SOURCE_DESTROYED (new_source))
+       {
+         new_source->ref_count++;
+         break;
+       }
+      
+      new_source = new_source->next;
+    }
+
+  if (source)
+    SOURCE_UNREF (source, context);
+         
+  return new_source;
+}
+
+/**
+ * g_main_context_acquire:
+ * @context: a #GMainContext
+ * 
+ * Tries to become the owner of the specified context.
+ * If some other thread is the owner of the context,
+ * returns %FALSE immediately. Ownership is properly
+ * recursive: the owner can require ownership again
+ * and will release ownership when g_main_context_release()
+ * is called as many times as g_main_context_acquire().
+ *
+ * You must be the owner of a context before you
+ * can call g_main_context_prepare(), g_main_context_query(),
+ * g_main_context_check(), g_main_context_dispatch().
+ * 
+ * Return value: %TRUE if the operation succeeded, and
+ *   this thread is now the owner of @context.
+ **/
+gboolean 
+g_main_context_acquire (GMainContext *context)
+{
+#ifdef G_THREADS_ENABLED
+  gboolean result = FALSE;
+  GThread *self = G_THREAD_SELF;
+
+  if (context == NULL)
+    context = g_main_context_default ();
+  
+  LOCK_CONTEXT (context);
+
+  if (!context->owner)
+    {
+      context->owner = self;
+      g_assert (context->owner_count == 0);
+    }
+
+  if (context->owner == self)
+    {
+      context->owner_count++;
+      result = TRUE;
+    }
+
+  UNLOCK_CONTEXT (context); 
+  
+  return result;
+#else /* !G_THREADS_ENABLED */
+  return TRUE;
+#endif /* G_THREADS_ENABLED */
+}
+
+/**
+ * g_main_context_release:
+ * @context: a #GMainContext
+ * 
+ * Releases ownership of a context previously acquired by this thread
+ * with g_main_context_acquire(). If the context was acquired multiple
+ * times, the ownership will be released only when g_main_context_release()
+ * is called as many times as it was acquired.
+ **/
+void
+g_main_context_release (GMainContext *context)
+{
+#ifdef G_THREADS_ENABLED
+  if (context == NULL)
+    context = g_main_context_default ();
+  
+  LOCK_CONTEXT (context);
+
+  context->owner_count--;
+  if (context->owner_count == 0)
+    {
+      context->owner = NULL;
+
+      if (context->waiters)
+       {
+         GMainWaiter *waiter = context->waiters->data;
+         gboolean loop_internal_waiter =
+           (waiter->mutex == g_static_mutex_get_mutex (&context->mutex));
+         context->waiters = g_slist_delete_link (context->waiters,
+                                                 context->waiters);
+         if (!loop_internal_waiter)
+           g_mutex_lock (waiter->mutex);
+         
+         g_cond_signal (waiter->cond);
+         
+         if (!loop_internal_waiter)
+           g_mutex_unlock (waiter->mutex);
+       }
+    }
+
+  UNLOCK_CONTEXT (context); 
+#endif /* G_THREADS_ENABLED */
+}
+
+/**
+ * g_main_context_wait:
+ * @context: a #GMainContext
+ * @cond: a condition variable
+ * @mutex: a mutex, currently held
+ * 
+ * Tries to become the owner of the specified context,
+ * as with g_main_context_acquire(). But if another thread
+ * is the owner, atomically drop @mutex and wait on @cond until 
+ * that owner releases ownership or until @cond is signaled, then
+ * try again (once) to become the owner.
+ * 
+ * Return value: %TRUE if the operation succeeded, and
+ *   this thread is now the owner of @context.
+ **/
+gboolean
+g_main_context_wait (GMainContext *context,
+                    GCond        *cond,
+                    GMutex       *mutex)
+{
+#ifdef G_THREADS_ENABLED
+  gboolean result = FALSE;
+  GThread *self = G_THREAD_SELF;
+  gboolean loop_internal_waiter;
+  
+  if (context == NULL)
+    context = g_main_context_default ();
+
+  loop_internal_waiter = (mutex == g_static_mutex_get_mutex (&context->mutex));
+  
+  if (!loop_internal_waiter)
+    LOCK_CONTEXT (context);
+
+  if (context->owner && context->owner != self)
+    {
+      GMainWaiter waiter;
+
+      waiter.cond = cond;
+      waiter.mutex = mutex;
+
+      context->waiters = g_slist_append (context->waiters, &waiter);
+      
+      if (!loop_internal_waiter)
+       UNLOCK_CONTEXT (context);
+      g_cond_wait (cond, mutex);
+      if (!loop_internal_waiter)      
+       LOCK_CONTEXT (context);
+
+      context->waiters = g_slist_remove (context->waiters, &waiter);
+    }
+
+  if (!context->owner)
+    {
+      context->owner = self;
+      g_assert (context->owner_count == 0);
+    }
+
+  if (context->owner == self)
+    {
+      context->owner_count++;
+      result = TRUE;
+    }
+
+  if (!loop_internal_waiter)
+    UNLOCK_CONTEXT (context); 
+  
+  return result;
+#else /* !G_THREADS_ENABLED */
+  return TRUE;
+#endif /* G_THREADS_ENABLED */
+}
+
+/**
+ * g_main_context_prepare:
+ * @context: a #GMainContext
+ * @priority: location to store priority of highest priority
+ *            source already ready.
+ * 
+ * Prepares to poll sources within a main loop. The resulting information
+ * for polling is determined by calling g_main_context_query ().
+ * 
+ * Return value: %TRUE if some source is ready to be dispatched
+ *               prior to polling.
+ **/
+gboolean
+g_main_context_prepare (GMainContext *context,
+                       gint         *priority)
+{
+  gint i;
+  gint n_ready = 0;
+  gint current_priority = G_MAXINT;
+  GSource *source;
+
+  if (context == NULL)
+    context = g_main_context_default ();
+  
+  LOCK_CONTEXT (context);
+
+  context->time_is_current = FALSE;
+
+  if (context->in_check_or_prepare)
+    {
+      g_warning ("g_main_context_prepare() called recursively from within a source's check() or "
+                "prepare() member.");
+      UNLOCK_CONTEXT (context);
+      return FALSE;
+    }
+
+#ifdef G_THREADS_ENABLED
+  if (context->poll_waiting)
+    {
+      g_warning("g_main_context_prepare(): main loop already active in another thread");
+      UNLOCK_CONTEXT (context);
+      return FALSE;
+    }
+  
+  context->poll_waiting = TRUE;
+#endif /* G_THREADS_ENABLED */
+
+#if 0
+  /* If recursing, finish up current dispatch, before starting over */
+  if (context->pending_dispatches)
+    {
+      if (dispatch)
+       g_main_dispatch (context, &current_time);
+      
+      UNLOCK_CONTEXT (context);
+      return TRUE;
+    }
+#endif
+
+  /* If recursing, clear list of pending dispatches */
+
+  for (i = 0; i < context->pending_dispatches->len; i++)
+    {
+      if (context->pending_dispatches->pdata[i])
+       SOURCE_UNREF ((GSource *)context->pending_dispatches->pdata[i], context);
+    }
+  g_ptr_array_set_size (context->pending_dispatches, 0);
+  
+  /* Prepare all sources */
+
+  context->timeout = -1;
+  
+  source = next_valid_source (context, NULL);
+  while (source)
+    {
+      gint source_timeout = -1;
+
+      if ((n_ready > 0) && (source->priority > current_priority))
+       {
+         SOURCE_UNREF (source, context);
+         break;
+       }
+      if (SOURCE_BLOCKED (source))
+       goto next;
+
+      if (!(source->flags & G_SOURCE_READY))
+       {
+         gboolean result;
+         gboolean (*prepare)  (GSource  *source, 
+                               gint     *timeout);
+
+         prepare = source->source_funcs->prepare;
+         context->in_check_or_prepare++;
+         UNLOCK_CONTEXT (context);
+
+         result = (*prepare) (source, &source_timeout);
+
+         LOCK_CONTEXT (context);
+         context->in_check_or_prepare--;
+
+         if (result)
+           source->flags |= G_SOURCE_READY;
+       }
+
+      if (source->flags & G_SOURCE_READY)
+       {
+         n_ready++;
+         current_priority = source->priority;
+         context->timeout = 0;
+       }
+      
+      if (source_timeout >= 0)
+       {
+         if (context->timeout < 0)
+           context->timeout = source_timeout;
+         else
+           context->timeout = MIN (context->timeout, source_timeout);
+       }
+
+    next:
+      source = next_valid_source (context, source);
+    }
+
+  UNLOCK_CONTEXT (context);
+  
+  if (priority)
+    *priority = current_priority;
+  
+  return (n_ready > 0);
+}
+
+/**
+ * g_main_context_query:
+ * @context: a #GMainContext
+ * @max_priority: maximum priority source to check
+ * @timeout_: location to store timeout to be used in polling
+ * @fds: location to store #GPollFD records that need to be polled.
+ * @n_fds: length of @fds.
+ * 
+ * Determines information necessary to poll this main loop.
+ * 
+ * Return value: the number of records actually stored in @fds,
+ *   or, if more than @n_fds records need to be stored, the number
+ *   of records that need to be stored.
+ **/
+gint
+g_main_context_query (GMainContext *context,
+                     gint          max_priority,
+                     gint         *timeout,
+                     GPollFD      *fds,
+                     gint          n_fds)
+{
+  gint n_poll;
+  GPollRec *pollrec;
+  
+  LOCK_CONTEXT (context);
+
+  pollrec = context->poll_records;
+  n_poll = 0;
+  while (pollrec && max_priority >= pollrec->priority)
+    {
+      /* We need to include entries with fd->events == 0 in the array because
+       * otherwise if the application changes fd->events behind our back and 
+       * makes it non-zero, we'll be out of sync when we check the fds[] array.
+       * (Changing fd->events after adding an FD wasn't an anticipated use of 
+       * this API, but it occurs in practice.) */
+      if (n_poll < n_fds)
+       {
+         fds[n_poll].fd = pollrec->fd->fd;
+         /* In direct contradiction to the Unix98 spec, IRIX runs into
+          * difficulty if you pass in POLLERR, POLLHUP or POLLNVAL
+          * flags in the events field of the pollfd while it should
+          * just ignoring them. So we mask them out here.
+          */
+         fds[n_poll].events = pollrec->fd->events & ~(G_IO_ERR|G_IO_HUP|G_IO_NVAL);
+         fds[n_poll].revents = 0;
+       }
+
+      pollrec = pollrec->next;
+      n_poll++;
+    }
+
+#ifdef G_THREADS_ENABLED
+  context->poll_changed = FALSE;
+#endif
+  
+  if (timeout)
+    {
+      *timeout = context->timeout;
+      if (*timeout != 0)
+       context->time_is_current = FALSE;
+    }
+  
+  UNLOCK_CONTEXT (context);
+
+  return n_poll;
+}
+
+/**
+ * g_main_context_check:
+ * @context: a #GMainContext
+ * @max_priority: the maximum numerical priority of sources to check
+ * @fds: array of #GPollFD's that was passed to the last call to
+ *       g_main_context_query()
+ * @n_fds: return value of g_main_context_query()
+ * 
+ * Passes the results of polling back to the main loop.
+ * 
+ * Return value: %TRUE if some sources are ready to be dispatched.
+ **/
+gboolean
+g_main_context_check (GMainContext *context,
+                     gint          max_priority,
+                     GPollFD      *fds,
+                     gint          n_fds)
+{
+  GSource *source;
+  GPollRec *pollrec;
+  gint n_ready = 0;
+  gint i;
+   
+  LOCK_CONTEXT (context);
+
+  if (context->in_check_or_prepare)
+    {
+      g_warning ("g_main_context_check() called recursively from within a source's check() or "
+                "prepare() member.");
+      UNLOCK_CONTEXT (context);
+      return FALSE;
+    }
+  
+#ifdef G_THREADS_ENABLED
+  if (!context->poll_waiting)
+    {
+#ifndef G_OS_WIN32
+      gchar a;
+      read (context->wake_up_pipe[0], &a, 1);
+#endif
+    }
+  else
+    context->poll_waiting = FALSE;
+
+  /* If the set of poll file descriptors changed, bail out
+   * and let the main loop rerun
+   */
+  if (context->poll_changed)
+    {
+      UNLOCK_CONTEXT (context);
+      return FALSE;
+    }
+#endif /* G_THREADS_ENABLED */
+  
+  pollrec = context->poll_records;
+  i = 0;
+  while (i < n_fds)
+    {
+      if (pollrec->fd->events)
+       pollrec->fd->revents = fds[i].revents;
+
+      pollrec = pollrec->next;
+      i++;
+    }
+
+  source = next_valid_source (context, NULL);
+  while (source)
+    {
+      if ((n_ready > 0) && (source->priority > max_priority))
+       {
+         SOURCE_UNREF (source, context);
+         break;
+       }
+      if (SOURCE_BLOCKED (source))
+       goto next;
+
+      if (!(source->flags & G_SOURCE_READY))
+       {
+         gboolean result;
+         gboolean (*check) (GSource  *source);
+
+         check = source->source_funcs->check;
+         
+         context->in_check_or_prepare++;
+         UNLOCK_CONTEXT (context);
+         
+         result = (*check) (source);
+         
+         LOCK_CONTEXT (context);
+         context->in_check_or_prepare--;
+         
+         if (result)
+           source->flags |= G_SOURCE_READY;
+       }
+
+      if (source->flags & G_SOURCE_READY)
+       {
+         source->ref_count++;
+         g_ptr_array_add (context->pending_dispatches, source);
+
+         n_ready++;
+
+          /* never dispatch sources with less priority than the first
+           * one we choose to dispatch
+           */
+          max_priority = source->priority;
+       }
+
+    next:
+      source = next_valid_source (context, source);
+    }
+
+  UNLOCK_CONTEXT (context);
+
+  return n_ready > 0;
+}
+
+/**
+ * g_main_context_dispatch:
+ * @context: a #GMainContext
+ * 
+ * Dispatches all pending sources.
+ **/
+void
+g_main_context_dispatch (GMainContext *context)
+{
+  LOCK_CONTEXT (context);
+
+  if (context->pending_dispatches->len > 0)
+    {
+      g_main_dispatch (context);
+    }
+
+  UNLOCK_CONTEXT (context);
+}
+
+/* HOLDS context lock */
+static gboolean
+g_main_context_iterate (GMainContext *context,
+                       gboolean      block,
+                       gboolean      dispatch,
+                       GThread      *self)
+{
+  gint max_priority;
+  gint timeout;
+  gboolean some_ready;
+  gint nfds, allocated_nfds;
+  GPollFD *fds = NULL;
+
+  UNLOCK_CONTEXT (context);
+
+#ifdef G_THREADS_ENABLED
+  if (!g_main_context_acquire (context))
+    {
+      gboolean got_ownership;
+
+      LOCK_CONTEXT (context);
+
+      g_return_val_if_fail (g_thread_supported (), FALSE);
+
+      if (!block)
+       return FALSE;
+
+      if (!context->cond)
+       context->cond = g_cond_new ();
+
+      got_ownership = g_main_context_wait (context,
+                                          context->cond,
+                                          g_static_mutex_get_mutex (&context->mutex));
+
+      if (!got_ownership)
+       return FALSE;
+    }
+  else
+    LOCK_CONTEXT (context);
+#endif /* G_THREADS_ENABLED */
+  
+  if (!context->cached_poll_array)
+    {
+      context->cached_poll_array_size = context->n_poll_records;
+      context->cached_poll_array = g_new (GPollFD, context->n_poll_records);
+    }
+
+  allocated_nfds = context->cached_poll_array_size;
+  fds = context->cached_poll_array;
+  
+  UNLOCK_CONTEXT (context);
+
+  g_main_context_prepare (context, &max_priority); 
+  
+  while ((nfds = g_main_context_query (context, max_priority, &timeout, fds, 
+                                      allocated_nfds)) > allocated_nfds)
+    {
+      LOCK_CONTEXT (context);
+      g_free (fds);
+      context->cached_poll_array_size = allocated_nfds = nfds;
+      context->cached_poll_array = fds = g_new (GPollFD, nfds);
+      UNLOCK_CONTEXT (context);
+    }
+
+  if (!block)
+    timeout = 0;
+  
+  g_main_context_poll (context, timeout, max_priority, fds, nfds);
+  
+  some_ready = g_main_context_check (context, max_priority, fds, nfds);
+  
+  if (dispatch)
+    g_main_context_dispatch (context);
+  
+#ifdef G_THREADS_ENABLED
+  g_main_context_release (context);
+#endif /* G_THREADS_ENABLED */    
+
+  LOCK_CONTEXT (context);
+
+  return some_ready;
+}
+
+/**
+ * g_main_context_pending:
+ * @context: a #GMainContext (if %NULL, the default context will be used)
+ *
+ * Checks if any sources have pending events for the given context.
+ * 
+ * Return value: %TRUE if events are pending.
+ **/
+gboolean 
+g_main_context_pending (GMainContext *context)
+{
+  gboolean retval;
+
+  if (!context)
+    context = g_main_context_default();
+
+  LOCK_CONTEXT (context);
+  retval = g_main_context_iterate (context, FALSE, FALSE, G_THREAD_SELF);
+  UNLOCK_CONTEXT (context);
+  
+  return retval;
+}
+
+/**
+ * g_main_context_iteration:
+ * @context: a #GMainContext (if %NULL, the default context will be used) 
+ * @may_block: whether the call may block.
+ * 
+ * Runs a single iteration for the given main loop. This involves
+ * checking to see if any event sources are ready to be processed,
+ * then if no events sources are ready and @may_block is %TRUE, waiting
+ * for a source to become ready, then dispatching the highest priority
+ * events sources that are ready. Otherwise, if @may_block is %FALSE 
+ * sources are not waited to become ready, only those highest priority 
+ * events sources will be dispatched (if any), that are ready at this 
+ * given moment without further waiting.
+ *
+ * Note that even when @may_block is %TRUE, it is still possible for 
+ * g_main_context_iteration() to return %FALSE, since the the wait may 
+ * be interrupted for other reasons than an event source becoming ready.
+ * 
+ * Return value: %TRUE if events were dispatched.
+ **/
+gboolean
+g_main_context_iteration (GMainContext *context, gboolean may_block)
+{
+  gboolean retval;
+
+  if (!context)
+    context = g_main_context_default();
+  
+  LOCK_CONTEXT (context);
+  retval = g_main_context_iterate (context, may_block, TRUE, G_THREAD_SELF);
+  UNLOCK_CONTEXT (context);
+  
+  return retval;
+}
+
+/**
+ * g_main_loop_new:
+ * @context: a #GMainContext  (if %NULL, the default context will be used).
+ * @is_running: set to %TRUE to indicate that the loop is running. This
+ * is not very important since calling g_main_loop_run() will set this to
+ * %TRUE anyway.
+ * 
+ * Creates a new #GMainLoop structure.
+ * 
+ * Return value: a new #GMainLoop.
+ **/
+GMainLoop *
+g_main_loop_new (GMainContext *context,
+                gboolean      is_running)
+{
+  GMainLoop *loop;
+
+  if (!context)
+    context = g_main_context_default();
+  
+  g_main_context_ref (context);
+
+  loop = g_new0 (GMainLoop, 1);
+  loop->context = context;
+  loop->is_running = is_running != FALSE;
+  loop->ref_count = 1;
+  
+  return loop;
+}
+
+/**
+ * g_main_loop_ref:
+ * @loop: a #GMainLoop
+ * 
+ * Increases the reference count on a #GMainLoop object by one.
+ * 
+ * Return value: @loop
+ **/
+GMainLoop *
+g_main_loop_ref (GMainLoop *loop)
+{
+  g_return_val_if_fail (loop != NULL, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL);
+
+  g_atomic_int_inc (&loop->ref_count);
+
+  return loop;
+}
+
+/**
+ * g_main_loop_unref:
+ * @loop: a #GMainLoop
+ * 
+ * Decreases the reference count on a #GMainLoop object by one. If
+ * the result is zero, free the loop and free all associated memory.
+ **/
+void
+g_main_loop_unref (GMainLoop *loop)
+{
+  g_return_if_fail (loop != NULL);
+  g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
+
+  if (!g_atomic_int_dec_and_test (&loop->ref_count))
+    return;
+
+  g_main_context_unref (loop->context);
+  g_free (loop);
+}
+
+/**
+ * g_main_loop_run:
+ * @loop: a #GMainLoop
+ * 
+ * Runs a main loop until g_main_loop_quit() is called on the loop.
+ * If this is called for the thread of the loop's #GMainContext,
+ * it will process events from the loop, otherwise it will
+ * simply wait.
+ **/
+void 
+g_main_loop_run (GMainLoop *loop)
+{
+  GThread *self = G_THREAD_SELF;
+
+  g_return_if_fail (loop != NULL);
+  g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
+
+#ifdef G_THREADS_ENABLED
+  if (!g_main_context_acquire (loop->context))
+    {
+      gboolean got_ownership = FALSE;
+      
+      /* Another thread owns this context */
+      if (!g_thread_supported ())
+       {
+         g_warning ("g_main_loop_run() was called from second thread but "
+                    "g_thread_init() was never called.");
+         return;
+       }
+      
+      LOCK_CONTEXT (loop->context);
+
+      g_atomic_int_inc (&loop->ref_count);
+
+      if (!loop->is_running)
+       loop->is_running = TRUE;
+
+      if (!loop->context->cond)
+       loop->context->cond = g_cond_new ();
+          
+      while (loop->is_running && !got_ownership)
+       got_ownership = g_main_context_wait (loop->context,
+                                            loop->context->cond,
+                                            g_static_mutex_get_mutex (&loop->context->mutex));
+      
+      if (!loop->is_running)
+       {
+         UNLOCK_CONTEXT (loop->context);
+         if (got_ownership)
+           g_main_context_release (loop->context);
+         g_main_loop_unref (loop);
+         return;
+       }
+
+      g_assert (got_ownership);
+    }
+  else
+    LOCK_CONTEXT (loop->context);
+#endif /* G_THREADS_ENABLED */ 
+
+  if (loop->context->in_check_or_prepare)
+    {
+      g_warning ("g_main_loop_run(): called recursively from within a source's "
+                "check() or prepare() member, iteration not possible.");
+      return;
+    }
+
+  g_atomic_int_inc (&loop->ref_count);
+  loop->is_running = TRUE;
+  while (loop->is_running)
+    g_main_context_iterate (loop->context, TRUE, TRUE, self);
+
+  UNLOCK_CONTEXT (loop->context);
+  
+#ifdef G_THREADS_ENABLED
+  g_main_context_release (loop->context);
+#endif /* G_THREADS_ENABLED */    
+  
+  g_main_loop_unref (loop);
+}
+
+/**
+ * g_main_loop_quit:
+ * @loop: a #GMainLoop
+ * 
+ * Stops a #GMainLoop from running. Any calls to g_main_loop_run()
+ * for the loop will return. 
+ *
+ * Note that sources that have already been dispatched when 
+ * g_main_loop_quit() is called will still be executed.
+ **/
+void 
+g_main_loop_quit (GMainLoop *loop)
+{
+  g_return_if_fail (loop != NULL);
+  g_return_if_fail (g_atomic_int_get (&loop->ref_count) > 0);
+
+  LOCK_CONTEXT (loop->context);
+  loop->is_running = FALSE;
+  g_main_context_wakeup_unlocked (loop->context);
+
+#ifdef G_THREADS_ENABLED
+  if (loop->context->cond)
+    g_cond_broadcast (loop->context->cond);
+#endif /* G_THREADS_ENABLED */
+
+  UNLOCK_CONTEXT (loop->context);
+}
+
+/**
+ * g_main_loop_is_running:
+ * @loop: a #GMainLoop.
+ * 
+ * Checks to see if the main loop is currently being run via g_main_loop_run().
+ * 
+ * Return value: %TRUE if the mainloop is currently being run.
+ **/
+gboolean
+g_main_loop_is_running (GMainLoop *loop)
+{
+  g_return_val_if_fail (loop != NULL, FALSE);
+  g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, FALSE);
+
+  return loop->is_running;
+}
+
+/**
+ * g_main_loop_get_context:
+ * @loop: a #GMainLoop.
+ * 
+ * Returns the #GMainContext of @loop.
+ * 
+ * Return value: the #GMainContext of @loop
+ **/
+GMainContext *
+g_main_loop_get_context (GMainLoop *loop)
+{
+  g_return_val_if_fail (loop != NULL, NULL);
+  g_return_val_if_fail (g_atomic_int_get (&loop->ref_count) > 0, NULL);
+  return loop->context;
+}
+
+/* HOLDS: context's lock */
+static void
+g_main_context_poll (GMainContext *context,
+                    gint          timeout,
+                    gint          priority,
+                    GPollFD      *fds,
+                    gint          n_fds)
+{
+#ifdef  G_MAIN_POLL_DEBUG
+  GTimer *poll_timer;
+  GPollRec *pollrec;
+  gint i;
+#endif
+
+  GPollFunc poll_func;
+
+  if (n_fds || timeout != 0)
+    {
+#ifdef G_MAIN_POLL_DEBUG
+      if (_g_main_poll_debug)
+       {
+         g_print ("polling context=%p n=%d timeout=%d\n",
+                  context, n_fds, timeout);
+         poll_timer = g_timer_new ();
+       }
+#endif
+
+      LOCK_CONTEXT (context);
+
+      poll_func = context->poll_func;
+      
+      UNLOCK_CONTEXT (context);
+      if ((*poll_func) (fds, n_fds, timeout) < 0 && errno != EINTR)
+       {
+#ifndef G_OS_WIN32
+         g_warning ("poll(2) failed due to: %s.",
+                    g_strerror (errno));
+#else
+         /* If g_poll () returns -1, it has already called g_warning() */
+#endif
+       }
+      
+#ifdef G_MAIN_POLL_DEBUG
+      if (_g_main_poll_debug)
+       {
+         LOCK_CONTEXT (context);
+
+         g_print ("g_main_poll(%d) timeout: %d - elapsed %12.10f seconds",
+                  n_fds,
+                  timeout,
+                  g_timer_elapsed (poll_timer, NULL));
+         g_timer_destroy (poll_timer);
+         pollrec = context->poll_records;
+
+         while (pollrec != NULL)
+           {
+             i = 0;
+             while (i < n_fds)
+               {
+                 if (fds[i].fd == pollrec->fd->fd &&
+                     pollrec->fd->events &&
+                     fds[i].revents)
+                   {
+                     g_print (" [" G_POLLFD_FORMAT " :", fds[i].fd);
+                     if (fds[i].revents & G_IO_IN)
+                       g_print ("i");
+                     if (fds[i].revents & G_IO_OUT)
+                       g_print ("o");
+                     if (fds[i].revents & G_IO_PRI)
+                       g_print ("p");
+                     if (fds[i].revents & G_IO_ERR)
+                       g_print ("e");
+                     if (fds[i].revents & G_IO_HUP)
+                       g_print ("h");
+                     if (fds[i].revents & G_IO_NVAL)
+                       g_print ("n");
+                     g_print ("]");
+                   }
+                 i++;
+               }
+             pollrec = pollrec->next;
+           }
+         g_print ("\n");
+
+         UNLOCK_CONTEXT (context);
+       }
+#endif
+    } /* if (n_fds || timeout != 0) */
+}
+
+/**
+ * g_main_context_add_poll:
+ * @context: a #GMainContext (or %NULL for the default context)
+ * @fd: a #GPollFD structure holding information about a file
+ *      descriptor to watch.
+ * @priority: the priority for this file descriptor which should be
+ *      the same as the priority used for g_source_attach() to ensure that the
+ *      file descriptor is polled whenever the results may be needed.
+ * 
+ * Adds a file descriptor to the set of file descriptors polled for
+ * this context. This will very seldomly be used directly. Instead
+ * a typical event source will use g_source_add_poll() instead.
+ **/
+void
+g_main_context_add_poll (GMainContext *context,
+                        GPollFD      *fd,
+                        gint          priority)
+{
+  if (!context)
+    context = g_main_context_default ();
+  
+  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
+  g_return_if_fail (fd);
+
+  LOCK_CONTEXT (context);
+  g_main_context_add_poll_unlocked (context, priority, fd);
+  UNLOCK_CONTEXT (context);
+}
+
+/* HOLDS: main_loop_lock */
+static void 
+g_main_context_add_poll_unlocked (GMainContext *context,
+                                 gint          priority,
+                                 GPollFD      *fd)
+{
+  GPollRec *lastrec, *pollrec;
+  GPollRec *newrec = g_slice_new (GPollRec);
+
+  /* This file descriptor may be checked before we ever poll */
+  fd->revents = 0;
+  newrec->fd = fd;
+  newrec->priority = priority;
+
+  lastrec = NULL;
+  pollrec = context->poll_records;
+  while (pollrec && priority >= pollrec->priority)
+    {
+      lastrec = pollrec;
+      pollrec = pollrec->next;
+    }
+  
+  if (lastrec)
+    lastrec->next = newrec;
+  else
+    context->poll_records = newrec;
+
+  newrec->next = pollrec;
+
+  context->n_poll_records++;
+
+#ifdef G_THREADS_ENABLED
+  context->poll_changed = TRUE;
+
+  /* Now wake up the main loop if it is waiting in the poll() */
+  g_main_context_wakeup_unlocked (context);
+#endif
+}
+
+/**
+ * g_main_context_remove_poll:
+ * @context:a #GMainContext 
+ * @fd: a #GPollFD descriptor previously added with g_main_context_add_poll()
+ * 
+ * Removes file descriptor from the set of file descriptors to be
+ * polled for a particular context.
+ **/
+void
+g_main_context_remove_poll (GMainContext *context,
+                           GPollFD      *fd)
+{
+  if (!context)
+    context = g_main_context_default ();
+  
+  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
+  g_return_if_fail (fd);
+
+  LOCK_CONTEXT (context);
+  g_main_context_remove_poll_unlocked (context, fd);
+  UNLOCK_CONTEXT (context);
+}
+
+static void
+g_main_context_remove_poll_unlocked (GMainContext *context,
+                                    GPollFD      *fd)
+{
+  GPollRec *pollrec, *lastrec;
+
+  lastrec = NULL;
+  pollrec = context->poll_records;
+
+  while (pollrec)
+    {
+      if (pollrec->fd == fd)
+       {
+         if (lastrec != NULL)
+           lastrec->next = pollrec->next;
+         else
+           context->poll_records = pollrec->next;
+
+         g_slice_free (GPollRec, pollrec);
+
+         context->n_poll_records--;
+         break;
+       }
+      lastrec = pollrec;
+      pollrec = pollrec->next;
+    }
+
+#ifdef G_THREADS_ENABLED
+  context->poll_changed = TRUE;
+  
+  /* Now wake up the main loop if it is waiting in the poll() */
+  g_main_context_wakeup_unlocked (context);
+#endif
+}
+
+/**
+ * g_source_get_current_time:
+ * @source:  a #GSource
+ * @timeval: #GTimeVal structure in which to store current time.
+ * 
+ * Gets the "current time" to be used when checking 
+ * this source. The advantage of calling this function over
+ * calling g_get_current_time() directly is that when 
+ * checking multiple sources, GLib can cache a single value
+ * instead of having to repeatedly get the system time.
+ **/
+void
+g_source_get_current_time (GSource  *source,
+                          GTimeVal *timeval)
+{
+  GMainContext *context;
+  
+  g_return_if_fail (source->context != NULL);
+  context = source->context;
+
+  LOCK_CONTEXT (context);
+
+  if (!context->time_is_current)
+    {
+      g_get_current_time (&context->current_time);
+      context->time_is_current = TRUE;
+    }
+  
+  *timeval = context->current_time;
+  
+  UNLOCK_CONTEXT (context);
+}
+
+/**
+ * g_main_context_set_poll_func:
+ * @context: a #GMainContext
+ * @func: the function to call to poll all file descriptors
+ * 
+ * Sets the function to use to handle polling of file descriptors. It
+ * will be used instead of the poll() system call 
+ * (or GLib's replacement function, which is used where 
+ * poll() isn't available).
+ *
+ * This function could possibly be used to integrate the GLib event
+ * loop with an external event loop.
+ **/
+void
+g_main_context_set_poll_func (GMainContext *context,
+                             GPollFunc     func)
+{
+  if (!context)
+    context = g_main_context_default ();
+  
+  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
+
+  LOCK_CONTEXT (context);
+  
+  if (func)
+    context->poll_func = func;
+  else
+    context->poll_func = g_poll;
+
+  UNLOCK_CONTEXT (context);
+}
+
+/**
+ * g_main_context_get_poll_func:
+ * @context: a #GMainContext
+ * 
+ * Gets the poll function set by g_main_context_set_poll_func().
+ * 
+ * Return value: the poll function
+ **/
+GPollFunc
+g_main_context_get_poll_func (GMainContext *context)
+{
+  GPollFunc result;
+  
+  if (!context)
+    context = g_main_context_default ();
+  
+  g_return_val_if_fail (g_atomic_int_get (&context->ref_count) > 0, NULL);
+
+  LOCK_CONTEXT (context);
+  result = context->poll_func;
+  UNLOCK_CONTEXT (context);
+
+  return result;
+}
+
+/* HOLDS: context's lock */
+/* Wake the main loop up from a poll() */
+static void
+g_main_context_wakeup_unlocked (GMainContext *context)
+{
+#ifdef G_THREADS_ENABLED
+  if (g_thread_supported() && context->poll_waiting)
+    {
+      context->poll_waiting = FALSE;
+#ifndef G_OS_WIN32
+      write (context->wake_up_pipe[1], "A", 1);
+#else
+      ReleaseSemaphore (context->wake_up_semaphore, 1, NULL);
+#endif
+    }
+#endif
+}
+
+/**
+ * g_main_context_wakeup:
+ * @context: a #GMainContext
+ * 
+ * If @context is currently waiting in a poll(), interrupt
+ * the poll(), and continue the iteration process.
+ **/
+void
+g_main_context_wakeup (GMainContext *context)
+{
+  if (!context)
+    context = g_main_context_default ();
+  
+  g_return_if_fail (g_atomic_int_get (&context->ref_count) > 0);
+
+  LOCK_CONTEXT (context);
+  g_main_context_wakeup_unlocked (context);
+  UNLOCK_CONTEXT (context);
+}
+
+/**
+ * g_main_context_is_owner:
+ * @context: a #GMainContext
+ * 
+ * Determines whether this thread holds the (recursive)
+ * ownership of this #GMaincontext. This is useful to
+ * know before waiting on another thread that may be
+ * blocking to get ownership of @context.
+ *
+ * Returns: %TRUE if current thread is owner of @context.
+ *
+ * Since: 2.10
+ **/
+gboolean
+g_main_context_is_owner (GMainContext *context)
+{
+  gboolean is_owner;
+
+  if (!context)
+    context = g_main_context_default ();
+
+#ifdef G_THREADS_ENABLED
+  LOCK_CONTEXT (context);
+  is_owner = context->owner == G_THREAD_SELF;
+  UNLOCK_CONTEXT (context);
+#else
+  is_owner = TRUE;
+#endif
+
+  return is_owner;
+}
+
+/* Timeouts */
+
+static void
+g_timeout_set_expiration (GTimeoutSource *timeout_source,
+                         GTimeVal       *current_time)
+{
+  guint seconds = timeout_source->interval / 1000;
+  guint msecs = timeout_source->interval - seconds * 1000;
+
+  timeout_source->expiration.tv_sec = current_time->tv_sec + seconds;
+  timeout_source->expiration.tv_usec = current_time->tv_usec + msecs * 1000;
+  if (timeout_source->expiration.tv_usec >= 1000000)
+    {
+      timeout_source->expiration.tv_usec -= 1000000;
+      timeout_source->expiration.tv_sec++;
+    }
+  if (timer_perturb==-1)
+    {
+      /*
+       * we want a per machine/session unique 'random' value; try the dbus
+       * address first, that has a UUID in it. If there is no dbus, use the
+       * hostname for hashing.
+       */
+      const char *session_bus_address = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
+      if (!session_bus_address)
+        session_bus_address = g_getenv ("HOSTNAME");
+      if (session_bus_address)
+        timer_perturb = ABS ((gint) g_str_hash (session_bus_address));
+      else
+        timer_perturb = 0;
+    }
+  if (timeout_source->granularity)
+    {
+      gint remainder;
+      gint gran; /* in usecs */
+      gint perturb;
+
+      gran = timeout_source->granularity * 1000;
+      perturb = timer_perturb % gran;
+      /*
+       * We want to give each machine a per machine pertubation;
+       * shift time back first, and forward later after the rounding
+       */
+
+      timeout_source->expiration.tv_usec -= perturb;
+      if (timeout_source->expiration.tv_usec < 0)
+        {
+          timeout_source->expiration.tv_usec += 1000000;
+          timeout_source->expiration.tv_sec--;
+        }
+
+      remainder = timeout_source->expiration.tv_usec % gran;
+      if (remainder >= gran/4) /* round up */
+        timeout_source->expiration.tv_usec += gran;
+      timeout_source->expiration.tv_usec -= remainder;
+      /* shift back */
+      timeout_source->expiration.tv_usec += perturb;
+
+      /* the rounding may have overflown tv_usec */
+      while (timeout_source->expiration.tv_usec > 1000000)
+        {
+          timeout_source->expiration.tv_usec -= 1000000;
+          timeout_source->expiration.tv_sec++;
+        }
+    }
+}
+
+static gboolean
+g_timeout_prepare (GSource *source,
+                  gint    *timeout)
+{
+  glong sec;
+  glong msec;
+  GTimeVal current_time;
+  
+  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
+
+  g_source_get_current_time (source, &current_time);
+
+  sec = timeout_source->expiration.tv_sec - current_time.tv_sec;
+  msec = (timeout_source->expiration.tv_usec - current_time.tv_usec) / 1000;
+
+  /* We do the following in a rather convoluted fashion to deal with
+   * the fact that we don't have an integral type big enough to hold
+   * the difference of two timevals in millseconds.
+   */
+  if (sec < 0 || (sec == 0 && msec < 0))
+    msec = 0;
+  else
+    {
+      glong interval_sec = timeout_source->interval / 1000;
+      glong interval_msec = timeout_source->interval % 1000;
+
+      if (msec < 0)
+       {
+         msec += 1000;
+         sec -= 1;
+       }
+      
+      if (sec > interval_sec ||
+         (sec == interval_sec && msec > interval_msec))
+       {
+         /* The system time has been set backwards, so we
+          * reset the expiration time to now + timeout_source->interval;
+          * this at least avoids hanging for long periods of time.
+          */
+         g_timeout_set_expiration (timeout_source, &current_time);
+         msec = MIN (G_MAXINT, timeout_source->interval);
+       }
+      else
+       {
+         msec = MIN (G_MAXINT, (guint)msec + 1000 * (guint)sec);
+       }
+    }
+
+  *timeout = (gint)msec;
+  
+  return msec == 0;
+}
+
+static gboolean 
+g_timeout_check (GSource *source)
+{
+  GTimeVal current_time;
+  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
+
+  g_source_get_current_time (source, &current_time);
+  
+  return ((timeout_source->expiration.tv_sec < current_time.tv_sec) ||
+         ((timeout_source->expiration.tv_sec == current_time.tv_sec) &&
+          (timeout_source->expiration.tv_usec <= current_time.tv_usec)));
+}
+
+static gboolean
+g_timeout_dispatch (GSource     *source,
+                   GSourceFunc  callback,
+                   gpointer     user_data)
+{
+  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
+
+  if (!callback)
+    {
+      g_warning ("Timeout source dispatched without callback\n"
+                "You must call g_source_set_callback().");
+      return FALSE;
+    }
+  if (callback (user_data))
+    {
+      GTimeVal current_time;
+
+      g_source_get_current_time (source, &current_time);
+      g_timeout_set_expiration (timeout_source, &current_time);
+
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+/**
+ * g_timeout_source_new:
+ * @interval: the timeout interval in milliseconds.
+ * 
+ * Creates a new timeout source.
+ *
+ * The source will not initially be associated with any #GMainContext
+ * and must be added to one with g_source_attach() before it will be
+ * executed.
+ * 
+ * Return value: the newly-created timeout source
+ **/
+GSource *
+g_timeout_source_new (guint interval)
+{
+  GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
+  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
+  GTimeVal current_time;
+
+  timeout_source->interval = interval;
+
+  g_get_current_time (&current_time);
+  g_timeout_set_expiration (timeout_source, &current_time);
+  
+  return source;
+}
+
+/**
+ * g_timeout_source_new_seconds:
+ * @interval: the timeout interval in seconds
+ *
+ * Creates a new timeout source.
+ *
+ * The source will not initially be associated with any #GMainContext
+ * and must be added to one with g_source_attach() before it will be
+ * executed.
+ *
+ * The scheduling granularity/accuracy of this timeout source will be
+ * in seconds.
+ *
+ * Return value: the newly-created timeout source
+ *
+ * Since: 2.14 
+ **/
+GSource *
+g_timeout_source_new_seconds (guint interval)
+{
+  GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
+  GTimeoutSource *timeout_source = (GTimeoutSource *)source;
+  GTimeVal current_time;
+
+  timeout_source->interval = 1000*interval;
+  timeout_source->granularity = 1000;
+
+  g_get_current_time (&current_time);
+  g_timeout_set_expiration (timeout_source, &current_time);
+
+  return source;
+}
+
+
+/**
+ * g_timeout_add_full:
+ * @priority: the priority of the timeout source. Typically this will be in
+ *            the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH.
+ * @interval: the time between calls to the function, in milliseconds
+ *             (1/1000ths of a second)
+ * @function: function to call
+ * @data:     data to pass to @function
+ * @notify:   function to call when the timeout is removed, or %NULL
+ * 
+ * Sets a function to be called at regular intervals, with the given
+ * priority.  The function is called repeatedly until it returns
+ * %FALSE, at which point the timeout is automatically destroyed and
+ * the function will not be called again.  The @notify function is
+ * called when the timeout is destroyed.  The first call to the
+ * function will be at the end of the first @interval.
+ *
+ * Note that timeout functions may be delayed, due to the processing of other
+ * event sources. Thus they should not be relied on for precise timing.
+ * After each call to the timeout function, the time of the next
+ * timeout is recalculated based on the current time and the given interval
+ * (it does not try to 'catch up' time lost in delays).
+ *
+ * This internally creates a main loop source using g_timeout_source_new()
+ * and attaches it to the main loop context using g_source_attach(). You can
+ * do these steps manually if you need greater control.
+ * 
+ * Return value: the ID (greater than 0) of the event source.
+ **/
+guint
+g_timeout_add_full (gint           priority,
+                   guint          interval,
+                   GSourceFunc    function,
+                   gpointer       data,
+                   GDestroyNotify notify)
+{
+  GSource *source;
+  guint id;
+  
+  g_return_val_if_fail (function != NULL, 0);
+
+  source = g_timeout_source_new (interval);
+
+  if (priority != G_PRIORITY_DEFAULT)
+    g_source_set_priority (source, priority);
+
+  g_source_set_callback (source, function, data, notify);
+  id = g_source_attach (source, NULL);
+  g_source_unref (source);
+
+  return id;
+}
+
+/**
+ * g_timeout_add:
+ * @interval: the time between calls to the function, in milliseconds
+ *             (1/1000ths of a second)
+ * @function: function to call
+ * @data:     data to pass to @function
+ * 
+ * Sets a function to be called at regular intervals, with the default
+ * priority, #G_PRIORITY_DEFAULT.  The function is called repeatedly
+ * until it returns %FALSE, at which point the timeout is automatically
+ * destroyed and the function will not be called again.  The first call
+ * to the function will be at the end of the first @interval.
+ *
+ * Note that timeout functions may be delayed, due to the processing of other
+ * event sources. Thus they should not be relied on for precise timing.
+ * After each call to the timeout function, the time of the next
+ * timeout is recalculated based on the current time and the given interval
+ * (it does not try to 'catch up' time lost in delays).
+ *
+ * If you want to have a timer in the "seconds" range and do not care
+ * about the exact time of the first call of the timer, use the
+ * g_timeout_add_seconds() function; this function allows for more
+ * optimizations and more efficient system power usage.
+ *
+ * This internally creates a main loop source using g_timeout_source_new()
+ * and attaches it to the main loop context using g_source_attach(). You can
+ * do these steps manually if you need greater control.
+ * 
+ * Return value: the ID (greater than 0) of the event source.
+ **/
+guint
+g_timeout_add (guint32        interval,
+              GSourceFunc    function,
+              gpointer       data)
+{
+  return g_timeout_add_full (G_PRIORITY_DEFAULT, 
+                            interval, function, data, NULL);
+}
+
+/**
+ * g_timeout_add_seconds_full:
+ * @priority: the priority of the timeout source. Typically this will be in
+ *            the range between #G_PRIORITY_DEFAULT and #G_PRIORITY_HIGH.
+ * @interval: the time between calls to the function, in seconds
+ * @function: function to call
+ * @data:     data to pass to @function
+ * @notify:   function to call when the timeout is removed, or %NULL
+ *
+ * Sets a function to be called at regular intervals, with @priority.
+ * The function is called repeatedly until it returns %FALSE, at which
+ * point the timeout is automatically destroyed and the function will
+ * not be called again.
+ *
+ * Unlike g_timeout_add(), this function operates at whole second granularity.
+ * The initial starting point of the timer is determined by the implementation
+ * and the implementation is expected to group multiple timers together so that
+ * they fire all at the same time.
+ * To allow this grouping, the @interval to the first timer is rounded
+ * and can deviate up to one second from the specified interval.
+ * Subsequent timer iterations will generally run at the specified interval.
+ *
+ * Note that timeout functions may be delayed, due to the processing of other
+ * event sources. Thus they should not be relied on for precise timing.
+ * After each call to the timeout function, the time of the next
+ * timeout is recalculated based on the current time and the given @interval
+ *
+ * If you want timing more precise than whole seconds, use g_timeout_add()
+ * instead.
+ *
+ * The grouping of timers to fire at the same time results in a more power
+ * and CPU efficient behavior so if your timer is in multiples of seconds
+ * and you don't require the first timer exactly one second from now, the
+ * use of g_timeout_add_seconds() is preferred over g_timeout_add().
+ *
+ * This internally creates a main loop source using 
+ * g_timeout_source_new_seconds() and attaches it to the main loop context 
+ * using g_source_attach(). You can do these steps manually if you need 
+ * greater control.
+ * 
+ * Return value: the ID (greater than 0) of the event source.
+ *
+ * Since: 2.14
+ **/
+guint
+g_timeout_add_seconds_full (gint           priority,
+                            guint32        interval,
+                            GSourceFunc    function,
+                            gpointer       data,
+                            GDestroyNotify notify)
+{
+  GSource *source;
+  guint id;
+
+  g_return_val_if_fail (function != NULL, 0);
+
+  source = g_timeout_source_new_seconds (interval);
+
+  if (priority != G_PRIORITY_DEFAULT)
+    g_source_set_priority (source, priority);
+
+  g_source_set_callback (source, function, data, notify);
+  id = g_source_attach (source, NULL);
+  g_source_unref (source);
+
+  return id;
+}
+
+/**
+ * g_timeout_add_seconds:
+ * @interval: the time between calls to the function, in seconds
+ * @function: function to call
+ * @data: data to pass to @function
+ *
+ * Sets a function to be called at regular intervals with the default
+ * priority, #G_PRIORITY_DEFAULT. The function is called repeatedly until
+ * it returns %FALSE, at which point the timeout is automatically destroyed
+ * and the function will not be called again.
+ *
+ * This internally creates a main loop source using 
+ * g_timeout_source_new_seconds() and attaches it to the main loop context 
+ * using g_source_attach(). You can do these steps manually if you need 
+ * greater control. Also see g_timout_add_seconds_full().
+ * 
+ * Return value: the ID (greater than 0) of the event source.
+ *
+ * Since: 2.14
+ **/
+guint
+g_timeout_add_seconds (guint       interval,
+                       GSourceFunc function,
+                       gpointer    data)
+{
+  g_return_val_if_fail (function != NULL, 0);
+
+  return g_timeout_add_seconds_full (G_PRIORITY_DEFAULT, interval, function, data, NULL);
+}
+
+/* Child watch functions */
+
+#ifdef G_OS_WIN32
+
+static gboolean
+g_child_watch_prepare (GSource *source,
+                      gint    *timeout)
+{
+  *timeout = -1;
+  return FALSE;
+}
+
+
+static gboolean 
+g_child_watch_check (GSource  *source)
+{
+  GChildWatchSource *child_watch_source;
+  gboolean child_exited;
+
+  child_watch_source = (GChildWatchSource *) source;
+
+  child_exited = child_watch_source->poll.revents & G_IO_IN;
+
+  if (child_exited)
+    {
+      DWORD child_status;
+
+      /*
+       * Note: We do _not_ check for the special value of STILL_ACTIVE
+       * since we know that the process has exited and doing so runs into
+       * problems if the child process "happens to return STILL_ACTIVE(259)"
+       * as Microsoft's Platform SDK puts it.
+       */
+      if (!GetExitCodeProcess (child_watch_source->pid, &child_status))
+        {
+         gchar *emsg = g_win32_error_message (GetLastError ());
+         g_warning (G_STRLOC ": GetExitCodeProcess() failed: %s", emsg);
+         g_free (emsg);
+
+         child_watch_source->child_status = -1;
+       }
+      else
+       child_watch_source->child_status = child_status;
+    }
+
+  return child_exited;
+}
+
+#else /* G_OS_WIN32 */
+
+static gboolean
+check_for_child_exited (GSource *source)
+{
+  GChildWatchSource *child_watch_source;
+  gint count;
+
+  /* protect against another SIGCHLD in the middle of this call */
+  count = child_watch_count;
+
+  child_watch_source = (GChildWatchSource *) source;
+
+  if (child_watch_source->child_exited)
+    return TRUE;
+
+  if (child_watch_source->count < count)
+    {
+      gint child_status;
+
+      if (waitpid (child_watch_source->pid, &child_status, WNOHANG) > 0)
+       {
+         child_watch_source->child_status = child_status;
+         child_watch_source->child_exited = TRUE;
+       }
+      child_watch_source->count = count;
+    }
+
+  return child_watch_source->child_exited;
+}
+
+static gboolean
+g_child_watch_prepare (GSource *source,
+                      gint    *timeout)
+{
+  *timeout = -1;
+
+  return check_for_child_exited (source);
+}
+
+
+static gboolean 
+g_child_watch_check (GSource  *source)
+{
+  return check_for_child_exited (source);
+}
+
+#endif /* G_OS_WIN32 */
+
+static gboolean
+g_child_watch_dispatch (GSource    *source, 
+                       GSourceFunc callback,
+                       gpointer    user_data)
+{
+  GChildWatchSource *child_watch_source;
+  GChildWatchFunc child_watch_callback = (GChildWatchFunc) callback;
+
+  child_watch_source = (GChildWatchSource *) source;
+
+  if (!callback)
+    {
+      g_warning ("Child watch source dispatched without callback\n"
+                "You must call g_source_set_callback().");
+      return FALSE;
+    }
+
+  (child_watch_callback) (child_watch_source->pid, child_watch_source->child_status, user_data);
+
+  /* We never keep a child watch source around as the child is gone */
+  return FALSE;
+}
+
+#ifndef G_OS_WIN32
+
+static void
+g_child_watch_signal_handler (int signum)
+{
+  child_watch_count ++;
+
+  if (child_watch_init_state == CHILD_WATCH_INITIALIZED_THREADED)
+    {
+      write (child_watch_wake_up_pipe[1], "B", 1);
+    }
+  else
+    {
+      /* We count on the signal interrupting the poll in the same thread.
+       */
+    }
+}
+static void
+g_child_watch_source_init_single (void)
+{
+  struct sigaction action;
+
+  g_assert (! g_thread_supported());
+  g_assert (child_watch_init_state == CHILD_WATCH_UNINITIALIZED);
+
+  child_watch_init_state = CHILD_WATCH_INITIALIZED_SINGLE;
+
+  action.sa_handler = g_child_watch_signal_handler;
+  sigemptyset (&action.sa_mask);
+  action.sa_flags = SA_NOCLDSTOP;
+  sigaction (SIGCHLD, &action, NULL);
+}
+
+G_GNUC_NORETURN static gpointer
+child_watch_helper_thread (gpointer data) 
+{
+  while (1)
+    {
+      gchar b[20];
+      GSList *list;
+
+      read (child_watch_wake_up_pipe[0], b, 20);
+
+      /* We were woken up.  Wake up all other contexts in all other threads */
+      G_LOCK (main_context_list);
+      for (list = main_context_list; list; list = list->next)
+       {
+         GMainContext *context;
+
+         context = list->data;
+         if (g_atomic_int_get (&context->ref_count) > 0)
+           /* Due to racing conditions we can find ref_count == 0, in
+            * that case, however, the context is still not destroyed
+            * and no poll can be active, otherwise the ref_count
+            * wouldn't be 0 */
+           g_main_context_wakeup (context);
+       }
+      G_UNLOCK (main_context_list);
+    }
+}
+
+static void
+g_child_watch_source_init_multi_threaded (void)
+{
+  GError *error = NULL;
+  struct sigaction action;
+
+  g_assert (g_thread_supported());
+
+  if (pipe (child_watch_wake_up_pipe) < 0)
+    g_error ("Cannot create wake up pipe: %s\n", g_strerror (errno));
+  fcntl (child_watch_wake_up_pipe[1], F_SETFL, O_NONBLOCK | fcntl (child_watch_wake_up_pipe[1], F_GETFL));
+
+  /* We create a helper thread that polls on the wakeup pipe indefinitely */
+  /* FIXME: Think this through for races */
+  if (g_thread_create (child_watch_helper_thread, NULL, FALSE, &error) == NULL)
+    g_error ("Cannot create a thread to monitor child exit status: %s\n", error->message);
+  child_watch_init_state = CHILD_WATCH_INITIALIZED_THREADED;
+  action.sa_handler = g_child_watch_signal_handler;
+  sigemptyset (&action.sa_mask);
+  action.sa_flags = SA_RESTART | SA_NOCLDSTOP;
+  sigaction (SIGCHLD, &action, NULL);
+}
+
+static void
+g_child_watch_source_init_promote_single_to_threaded (void)
+{
+  g_child_watch_source_init_multi_threaded ();
+}
+
+static void
+g_child_watch_source_init (void)
+{
+  if (g_thread_supported())
+    {
+      if (child_watch_init_state == CHILD_WATCH_UNINITIALIZED)
+       g_child_watch_source_init_multi_threaded ();
+      else if (child_watch_init_state == CHILD_WATCH_INITIALIZED_SINGLE)
+       g_child_watch_source_init_promote_single_to_threaded ();
+    }
+  else
+    {
+      if (child_watch_init_state == CHILD_WATCH_UNINITIALIZED)
+       g_child_watch_source_init_single ();
+    }
+}
+
+#endif /* !G_OS_WIN32 */
+
+/**
+ * g_child_watch_source_new:
+ * @pid: process to watch. On POSIX the pid of a child process. On
+ * Windows a handle for a process (which doesn't have to be a child).
+ * 
+ * Creates a new child_watch source.
+ *
+ * The source will not initially be associated with any #GMainContext
+ * and must be added to one with g_source_attach() before it will be
+ * executed.
+ * 
+ * Note that child watch sources can only be used in conjunction with
+ * <literal>g_spawn...</literal> when the %G_SPAWN_DO_NOT_REAP_CHILD
+ * flag is used.
+ *
+ * Note that on platforms where #GPid must be explicitly closed
+ * (see g_spawn_close_pid()) @pid must not be closed while the
+ * source is still active. Typically, you will want to call
+ * g_spawn_close_pid() in the callback function for the source.
+ *
+ * Note further that using g_child_watch_source_new() is not 
+ * compatible with calling <literal>waitpid(-1)</literal> in 
+ * the application. Calling waitpid() for individual pids will
+ * still work fine. 
+ * 
+ * Return value: the newly-created child watch source
+ *
+ * Since: 2.4
+ **/
+GSource *
+g_child_watch_source_new (GPid pid)
+{
+  GSource *source = g_source_new (&g_child_watch_funcs, sizeof (GChildWatchSource));
+  GChildWatchSource *child_watch_source = (GChildWatchSource *)source;
+
+#ifdef G_OS_WIN32
+  child_watch_source->poll.fd = (gintptr) pid;
+  child_watch_source->poll.events = G_IO_IN;
+
+  g_source_add_poll (source, &child_watch_source->poll);
+#else /* G_OS_WIN32 */
+  g_child_watch_source_init ();
+#endif /* G_OS_WIN32 */
+
+  child_watch_source->pid = pid;
+
+  return source;
+}
+
+/**
+ * g_child_watch_add_full:
+ * @priority: the priority of the idle source. Typically this will be in the
+ *            range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
+ * @pid:      process to watch. On POSIX the pid of a child process. On
+ * Windows a handle for a process (which doesn't have to be a child).
+ * @function: function to call
+ * @data:     data to pass to @function
+ * @notify:   function to call when the idle is removed, or %NULL
+ * 
+ * Sets a function to be called when the child indicated by @pid 
+ * exits, at the priority @priority.
+ *
+ * If you obtain @pid from g_spawn_async() or g_spawn_async_with_pipes() 
+ * you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to 
+ * the spawn function for the child watching to work.
+ * 
+ * Note that on platforms where #GPid must be explicitly closed
+ * (see g_spawn_close_pid()) @pid must not be closed while the
+ * source is still active. Typically, you will want to call
+ * g_spawn_close_pid() in the callback function for the source.
+ * 
+ * GLib supports only a single callback per process id.
+ *
+ * This internally creates a main loop source using 
+ * g_child_watch_source_new() and attaches it to the main loop context 
+ * using g_source_attach(). You can do these steps manually if you 
+ * need greater control.
+ *
+ * Return value: the ID (greater than 0) of the event source.
+ *
+ * Since: 2.4
+ **/
+guint
+g_child_watch_add_full (gint            priority,
+                       GPid            pid,
+                       GChildWatchFunc function,
+                       gpointer        data,
+                       GDestroyNotify  notify)
+{
+  GSource *source;
+  guint id;
+  
+  g_return_val_if_fail (function != NULL, 0);
+
+  source = g_child_watch_source_new (pid);
+
+  if (priority != G_PRIORITY_DEFAULT)
+    g_source_set_priority (source, priority);
+
+  g_source_set_callback (source, (GSourceFunc) function, data, notify);
+  id = g_source_attach (source, NULL);
+  g_source_unref (source);
+
+  return id;
+}
+
+/**
+ * g_child_watch_add:
+ * @pid:      process id to watch. On POSIX the pid of a child process. On
+ * Windows a handle for a process (which doesn't have to be a child).
+ * @function: function to call
+ * @data:     data to pass to @function
+ * 
+ * Sets a function to be called when the child indicated by @pid 
+ * exits, at a default priority, #G_PRIORITY_DEFAULT.
+ * 
+ * If you obtain @pid from g_spawn_async() or g_spawn_async_with_pipes() 
+ * you will need to pass #G_SPAWN_DO_NOT_REAP_CHILD as flag to 
+ * the spawn function for the child watching to work.
+ * 
+ * Note that on platforms where #GPid must be explicitly closed
+ * (see g_spawn_close_pid()) @pid must not be closed while the
+ * source is still active. Typically, you will want to call
+ * g_spawn_close_pid() in the callback function for the source.
+ *
+ * GLib supports only a single callback per process id.
+ *
+ * This internally creates a main loop source using 
+ * g_child_watch_source_new() and attaches it to the main loop context 
+ * using g_source_attach(). You can do these steps manually if you 
+ * need greater control.
+ *
+ * Return value: the ID (greater than 0) of the event source.
+ *
+ * Since: 2.4
+ **/
+guint 
+g_child_watch_add (GPid            pid,
+                  GChildWatchFunc function,
+                  gpointer        data)
+{
+  return g_child_watch_add_full (G_PRIORITY_DEFAULT, pid, function, data, NULL);
+}
+
+
+/* Idle functions */
+
+static gboolean 
+g_idle_prepare  (GSource  *source,
+                gint     *timeout)
+{
+  *timeout = 0;
+
+  return TRUE;
+}
+
+static gboolean 
+g_idle_check    (GSource  *source)
+{
+  return TRUE;
+}
+
+static gboolean
+g_idle_dispatch (GSource    *source, 
+                GSourceFunc callback,
+                gpointer    user_data)
+{
+  if (!callback)
+    {
+      g_warning ("Idle source dispatched without callback\n"
+                "You must call g_source_set_callback().");
+      return FALSE;
+    }
+  
+  return callback (user_data);
+}
+
+/**
+ * g_idle_source_new:
+ * 
+ * Creates a new idle source.
+ *
+ * The source will not initially be associated with any #GMainContext
+ * and must be added to one with g_source_attach() before it will be
+ * executed. Note that the default priority for idle sources is
+ * %G_PRIORITY_DEFAULT_IDLE, as compared to other sources which
+ * have a default priority of %G_PRIORITY_DEFAULT.
+ * 
+ * Return value: the newly-created idle source
+ **/
+GSource *
+g_idle_source_new (void)
+{
+  GSource *source;
+
+  source = g_source_new (&g_idle_funcs, sizeof (GSource));
+  g_source_set_priority (source, G_PRIORITY_DEFAULT_IDLE);
+
+  return source;
+}
+
+/**
+ * g_idle_add_full:
+ * @priority: the priority of the idle source. Typically this will be in the
+ *            range between #G_PRIORITY_DEFAULT_IDLE and #G_PRIORITY_HIGH_IDLE.
+ * @function: function to call
+ * @data:     data to pass to @function
+ * @notify:   function to call when the idle is removed, or %NULL
+ * 
+ * Adds a function to be called whenever there are no higher priority
+ * events pending.  If the function returns %FALSE it is automatically
+ * removed from the list of event sources and will not be called again.
+ * 
+ * This internally creates a main loop source using g_idle_source_new()
+ * and attaches it to the main loop context using g_source_attach(). 
+ * You can do these steps manually if you need greater control.
+ * 
+ * Return value: the ID (greater than 0) of the event source.
+ **/
+guint 
+g_idle_add_full (gint           priority,
+                GSourceFunc    function,
+                gpointer       data,
+                GDestroyNotify notify)
+{
+  GSource *source;
+  guint id;
+  
+  g_return_val_if_fail (function != NULL, 0);
+
+  source = g_idle_source_new ();
+
+  if (priority != G_PRIORITY_DEFAULT_IDLE)
+    g_source_set_priority (source, priority);
+
+  g_source_set_callback (source, function, data, notify);
+  id = g_source_attach (source, NULL);
+  g_source_unref (source);
+
+  return id;
+}
+
+/**
+ * g_idle_add:
+ * @function: function to call 
+ * @data: data to pass to @function.
+ * 
+ * Adds a function to be called whenever there are no higher priority
+ * events pending to the default main loop. The function is given the
+ * default idle priority, #G_PRIORITY_DEFAULT_IDLE.  If the function
+ * returns %FALSE it is automatically removed from the list of event
+ * sources and will not be called again.
+ * 
+ * This internally creates a main loop source using g_idle_source_new()
+ * and attaches it to the main loop context using g_source_attach(). 
+ * You can do these steps manually if you need greater control.
+ * 
+ * Return value: the ID (greater than 0) of the event source.
+ **/
+guint 
+g_idle_add (GSourceFunc    function,
+           gpointer       data)
+{
+  return g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, function, data, NULL);
+}
+
+/**
+ * g_idle_remove_by_data:
+ * @data: the data for the idle source's callback.
+ * 
+ * Removes the idle function with the given data.
+ * 
+ * Return value: %TRUE if an idle source was found and removed.
+ **/
+gboolean
+g_idle_remove_by_data (gpointer data)
+{
+  return g_source_remove_by_funcs_user_data (&g_idle_funcs, data);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gmain.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gmain.h
new file mode 100644 (file)
index 0000000..24c6171
--- /dev/null
@@ -0,0 +1,531 @@
+/* gmain.h - the GLib Main loop
+ * Copyright (C) 1998-2000 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_MAIN_H__
+#define __G_MAIN_H__
+
+#include <glib/gpoll.h>
+#include <glib/gslist.h>
+#include <glib/gthread.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GMainContext:
+ *
+ * The <structname>GMainContext</structname> struct is an opaque data
+ * type representing a set of sources to be handled in a main loop.
+ */
+typedef struct _GMainContext            GMainContext;
+
+/**
+ * GMainLoop:
+ *
+ * The <structname>GMainLoop</structname> struct is an opaque data type
+ * representing the main event loop of a GLib or GTK+ application.
+ */
+typedef struct _GMainLoop               GMainLoop;
+
+/**
+ * GSource:
+ *
+ * The <structname>GSource</structname> struct is an opaque data type
+ * representing an event source.
+ */
+typedef struct _GSource                 GSource;
+
+/**
+ * GSourceCallbackFuncs:
+ * @ref: Called when a reference is added to the callback object
+ * @unref: Called when a reference to the callback object is dropped
+ * @get: Called to extract the callback function and data from the
+ *     callback object.
+
+ * The <structname>GSourceCallbackFuncs</structname> struct contains
+ * functions for managing callback objects.
+ */
+typedef struct _GSourceCallbackFuncs    GSourceCallbackFuncs;
+
+/**
+ * GSourceFuncs:
+ * @prepare: Called before all the file descriptors are polled. If the
+ *     source can determine that it is ready here (without waiting for the
+ *     results of the poll() call) it should return %TRUE. It can also return
+ *     a @timeout_ value which should be the maximum timeout (in milliseconds)
+ *     which should be passed to the poll() call. The actual timeout used will
+ *     be -1 if all sources returned -1, or it will be the minimum of all the
+ *     @timeout_ values returned which were >= 0.
+ * @check: Called after all the file descriptors are polled. The source
+ *     should return %TRUE if it is ready to be dispatched. Note that some
+ *     time may have passed since the previous prepare function was called,
+ *     so the source should be checked again here.
+ * @dispatch: Called to dispatch the event source, after it has returned
+ *     %TRUE in either its @prepare or its @check function. The @dispatch
+ *     function is passed in a callback function and data. The callback
+ *     function may be %NULL if the source was never connected to a callback
+ *     using g_source_set_callback(). The @dispatch function should call the
+ *     callback function with @user_data and whatever additional parameters
+ *     are needed for this type of event source.
+ * @finalize: Called when the source is finalized.
+ * @closure_callback:
+ * @closure_marshal:
+ *
+ * The <structname>GSourceFuncs</structname> struct contains a table of
+ * functions used to handle event sources in a generic manner.
+ *
+ * For idle sources, the prepare and check functions always return %TRUE
+ * to indicate that the source is always ready to be processed. The prepare
+ * function also returns a timeout value of 0 to ensure that the poll() call
+ * doesn't block (since that would be time wasted which could have been spent
+ * running the idle function).
+ *
+ * For timeout sources, the prepare and check functions both return %TRUE
+ * if the timeout interval has expired. The prepare function also returns
+ * a timeout value to ensure that the poll() call doesn't block too long
+ * and miss the next timeout.
+ *
+ * For file descriptor sources, the prepare function typically returns %FALSE,
+ * since it must wait until poll() has been called before it knows whether
+ * any events need to be processed. It sets the returned timeout to -1 to
+ * indicate that it doesn't mind how long the poll() call blocks. In the
+ * check function, it tests the results of the poll() call to see if the
+ * required condition has been met, and returns %TRUE if so.
+ */
+typedef struct _GSourceFuncs            GSourceFuncs;
+
+/**
+ * GPid:
+ *
+ * A type which is used to hold a process identification.
+ *
+ * On UNIX, processes are identified by a process id (an integer),
+ * while Windows uses process handles (which are pointers).
+ */
+
+typedef gboolean (*GSourceFunc)       (gpointer data);
+
+/**
+ * GChildWatchFunc:
+ * @pid: the process id of the child process
+ * @status: Status information about the child process,
+ *     see waitpid(2) for more information about this field
+ * @data: user data passed to g_child_watch_add()
+ *
+ * The type of functions to be called when a child exists.
+ */
+typedef void     (*GChildWatchFunc)   (GPid     pid,
+                                       gint     status,
+                                       gpointer data);
+struct _GSource
+{
+  /*< private >*/
+  gpointer callback_data;
+  GSourceCallbackFuncs *callback_funcs;
+
+  GSourceFuncs *source_funcs;
+  guint ref_count;
+
+  GMainContext *context;
+
+  gint priority;
+  guint flags;
+  guint source_id;
+
+  GSList *poll_fds;
+  
+  GSource *prev;
+  GSource *next;
+
+  char    *name;
+  gpointer reserved2;
+};
+
+struct _GSourceCallbackFuncs
+{
+  void (*ref)   (gpointer     cb_data);
+  void (*unref) (gpointer     cb_data);
+  void (*get)   (gpointer     cb_data,
+                 GSource     *source, 
+                 GSourceFunc *func,
+                 gpointer    *data);
+};
+
+typedef void (*GSourceDummyMarshal) (void);
+
+struct _GSourceFuncs
+{
+  gboolean (*prepare)  (GSource    *source,
+                        gint       *timeout_);
+  gboolean (*check)    (GSource    *source);
+  gboolean (*dispatch) (GSource    *source,
+                        GSourceFunc callback,
+                        gpointer    user_data);
+  void     (*finalize) (GSource    *source); /* Can be NULL */
+
+  /* For use by g_source_set_closure */
+  GSourceFunc     closure_callback;        
+  GSourceDummyMarshal closure_marshal; /* Really is of type GClosureMarshal */
+};
+
+/* Standard priorities */
+
+/**
+ * G_PRIORITY_HIGH:
+ *
+ * Use this for high priority event sources.
+ *
+ * It is not used within GLib or GTK+.
+ */
+#define G_PRIORITY_HIGH            -100
+
+/**
+ * G_PRIORITY_DEFAULT:
+ *
+ * Use this for default priority event sources.
+ *
+ * In GLib this priority is used when adding timeout functions
+ * with g_timeout_add(). In GDK this priority is used for events
+ * from the X server.
+ */
+#define G_PRIORITY_DEFAULT          0
+
+/**
+ * G_PRIORITY_HIGH_IDLE:
+ *
+ * Use this for high priority idle functions.
+ *
+ * GTK+ uses #G_PRIORITY_HIGH_IDLE + 10 for resizing operations,
+ * and #G_PRIORITY_HIGH_IDLE + 20 for redrawing operations. (This is
+ * done to ensure that any pending resizes are processed before any
+ * pending redraws, so that widgets are not redrawn twice unnecessarily.)
+ */
+#define G_PRIORITY_HIGH_IDLE        100
+
+/**
+ * G_PRIORITY_DEFAULT_IDLE:
+ *
+ * Use this for default priority idle functions.
+ *
+ * In GLib this priority is used when adding idle functions with
+ * g_idle_add().
+ */
+#define G_PRIORITY_DEFAULT_IDLE     200
+
+/**
+ * G_PRIORITY_LOW:
+ *
+ * Use this for very low priority background tasks.
+ *
+ * It is not used within GLib or GTK+.
+ */
+#define G_PRIORITY_LOW              300
+
+/* GMainContext: */
+
+GMainContext *g_main_context_new       (void);
+GMainContext *g_main_context_ref       (GMainContext *context);
+void          g_main_context_unref     (GMainContext *context);
+GMainContext *g_main_context_default   (void);
+
+gboolean      g_main_context_iteration (GMainContext *context,
+                                        gboolean      may_block);
+gboolean      g_main_context_pending   (GMainContext *context);
+
+/* For implementation of legacy interfaces
+ */
+GSource      *g_main_context_find_source_by_id              (GMainContext *context,
+                                                             guint         source_id);
+GSource      *g_main_context_find_source_by_user_data       (GMainContext *context,
+                                                             gpointer      user_data);
+GSource      *g_main_context_find_source_by_funcs_user_data (GMainContext *context,
+                                                             GSourceFuncs *funcs,
+                                                             gpointer      user_data);
+
+/* Low level functions for implementing custom main loops.
+ */
+void     g_main_context_wakeup  (GMainContext *context);
+gboolean g_main_context_acquire (GMainContext *context);
+void     g_main_context_release (GMainContext *context);
+gboolean g_main_context_is_owner (GMainContext *context);
+gboolean g_main_context_wait    (GMainContext *context,
+                                 GCond        *cond,
+                                 GMutex       *mutex);
+
+gboolean g_main_context_prepare  (GMainContext *context,
+                                  gint         *priority);
+gint     g_main_context_query    (GMainContext *context,
+                                  gint          max_priority,
+                                  gint         *timeout_,
+                                  GPollFD      *fds,
+                                  gint          n_fds);
+gint     g_main_context_check    (GMainContext *context,
+                                  gint          max_priority,
+                                  GPollFD      *fds,
+                                  gint          n_fds);
+void     g_main_context_dispatch (GMainContext *context);
+
+void     g_main_context_set_poll_func (GMainContext *context,
+                                       GPollFunc     func);
+GPollFunc g_main_context_get_poll_func (GMainContext *context);
+
+/* Low level functions for use by source implementations
+ */
+void     g_main_context_add_poll    (GMainContext *context,
+                                     GPollFD      *fd,
+                                     gint          priority);
+void     g_main_context_remove_poll (GMainContext *context,
+                                     GPollFD      *fd);
+
+gint     g_main_depth               (void);
+GSource *g_main_current_source      (void);
+
+/* GMainContexts for other threads
+ */
+void          g_main_context_push_thread_default (GMainContext *context);
+void          g_main_context_pop_thread_default  (GMainContext *context);
+GMainContext *g_main_context_get_thread_default  (void);
+
+/* GMainLoop: */
+
+GMainLoop *g_main_loop_new        (GMainContext *context,
+                                   gboolean      is_running);
+void       g_main_loop_run        (GMainLoop    *loop);
+void       g_main_loop_quit       (GMainLoop    *loop);
+GMainLoop *g_main_loop_ref        (GMainLoop    *loop);
+void       g_main_loop_unref      (GMainLoop    *loop);
+gboolean   g_main_loop_is_running (GMainLoop    *loop);
+GMainContext *g_main_loop_get_context (GMainLoop    *loop);
+
+/* GSource: */
+
+GSource *g_source_new             (GSourceFuncs   *source_funcs,
+                                   guint           struct_size);
+GSource *g_source_ref             (GSource        *source);
+void     g_source_unref           (GSource        *source);
+
+guint    g_source_attach          (GSource        *source,
+                                   GMainContext   *context);
+void     g_source_destroy         (GSource        *source);
+
+void     g_source_set_priority    (GSource        *source,
+                                   gint            priority);
+gint     g_source_get_priority    (GSource        *source);
+void     g_source_set_can_recurse (GSource        *source,
+                                   gboolean        can_recurse);
+gboolean g_source_get_can_recurse (GSource        *source);
+guint    g_source_get_id          (GSource        *source);
+
+GMainContext *g_source_get_context (GSource       *source);
+
+void     g_source_set_callback    (GSource        *source,
+                                   GSourceFunc     func,
+                                   gpointer        data,
+                                   GDestroyNotify  notify);
+
+void     g_source_set_funcs       (GSource        *source,
+                                   GSourceFuncs   *funcs);
+gboolean g_source_is_destroyed    (GSource        *source);
+
+void                 g_source_set_name       (GSource        *source,
+                                              const char     *name);
+G_CONST_RETURN char* g_source_get_name       (GSource        *source);
+void                 g_source_set_name_by_id (guint           tag,
+                                              const char     *name);
+
+
+/* Used to implement g_source_connect_closure and internally*/
+void g_source_set_callback_indirect (GSource              *source,
+                                     gpointer              callback_data,
+                                     GSourceCallbackFuncs *callback_funcs);
+
+void     g_source_add_poll         (GSource        *source,
+                                    GPollFD        *fd);
+void     g_source_remove_poll      (GSource        *source,
+                                    GPollFD        *fd);
+
+void     g_source_get_current_time (GSource        *source,
+                                    GTimeVal       *timeval);
+
+ /* void g_source_connect_closure (GSource        *source,
+                                  GClosure       *closure);
+ */
+
+/* Specific source types
+ */
+GSource *g_idle_source_new        (void);
+GSource *g_child_watch_source_new (GPid pid);
+GSource *g_timeout_source_new     (guint interval);
+GSource *g_timeout_source_new_seconds (guint interval);
+
+/* Miscellaneous functions
+ */
+void g_get_current_time                 (GTimeVal       *result);
+
+/* ============== Compat main loop stuff ================== */
+
+#ifndef G_DISABLE_DEPRECATED
+
+/**
+ * g_main_new:
+ * @is_running: set to %TRUE to indicate that the loop is running. This
+ *     is not very important since calling g_main_run() will set this
+ *     to %TRUE anyway.
+ *
+ * Creates a new #GMainLoop for th default main context.
+ *
+ * Returns: a new #GMainLoop
+ *
+ * Deprecated: 2.2: Use g_main_loop_new() instead
+ */
+#define         g_main_new(is_running)  g_main_loop_new (NULL, is_running)
+
+/**
+ * g_main_run:
+ * @loop: a #GMainLoop
+ *
+ * Runs a main loop until it stops running.
+ *
+ * Deprecated: 2.2: Use g_main_loop_run() instead
+ */
+#define         g_main_run(loop)        g_main_loop_run(loop)
+
+/**
+ * g_main_quit:
+ * @loop: a #GMainLoop
+ *
+ * Stops the #GMainLoop.
+ * If g_main_run() was called to run the #GMainLoop, it will now return.
+ *
+ * Deprecated: 2.2: Use g_main_loop_quit() instead
+ */
+#define g_main_quit(loop)       g_main_loop_quit(loop)
+
+/**
+ * g_main_destroy:
+ * @loop: a #GMainLoop
+ *
+ * Frees the memory allocated for the #GMainLoop.
+ *
+ * Deprecated: 2.2: Use g_main_loop_unref() instead
+ */
+#define g_main_destroy(loop)    g_main_loop_unref(loop)
+
+/**
+ * g_main_is_running:
+ * @loop: a #GMainLoop
+ *
+ * Checks if the main loop is running.
+ *
+ * Returns: %TRUE if the main loop is running
+ *
+ * Deprecated: 2.2: Use g_main_loop_is_running() instead
+ */
+#define g_main_is_running(loop) g_main_loop_is_running(loop)
+
+/**
+ * g_main_iteration:
+ * @may_block: set to %TRUE if it should block (i.e. wait) until an event
+ *     source becomes ready. It will return after an event source has been
+ *     processed. If set to %FALSE it will return immediately if no event
+ *     source is ready to be processed.
+ *
+ * Runs a single iteration for the default #GMainContext.
+ *
+ * Returns: %TRUE if more events are pending.
+ *
+ * Deprecated: 2.2: Use g_main_context_iteration() instead.
+ */
+#define g_main_iteration(may_block) g_main_context_iteration (NULL, may_block)
+
+/**
+ * g_main_pending:
+ *
+ * Checks if any events are pending for the default #GMainContext
+ * (i.e. ready to be processed).
+ *
+ * Returns: %TRUE if any events are pending.
+ *
+ * Deprected: 2.2: Use g_main_context_pending() instead.
+ */
+#define g_main_pending()            g_main_context_pending (NULL)
+
+/**
+ * g_main_set_poll_func:
+ * @func: the function to call to poll all file descriptors
+ *
+ * Sets the function to use for the handle polling of file descriptors
+ * for the default main context.
+ *
+ * Deprecated: 2.2: Use g_main_context_set_poll_func() again
+ */
+#define g_main_set_poll_func(func)  g_main_context_set_poll_func (NULL, func)
+
+#endif /* G_DISABLE_DEPRECATED */
+
+/* Source manipulation by ID */
+gboolean g_source_remove                     (guint          tag);
+gboolean g_source_remove_by_user_data        (gpointer       user_data);
+gboolean g_source_remove_by_funcs_user_data  (GSourceFuncs  *funcs,
+                                              gpointer       user_data);
+
+/* Idles, child watchers and timeouts */
+guint    g_timeout_add_full         (gint            priority,
+                                     guint           interval,
+                                     GSourceFunc     function,
+                                     gpointer        data,
+                                     GDestroyNotify  notify);
+guint    g_timeout_add              (guint           interval,
+                                     GSourceFunc     function,
+                                     gpointer        data);
+guint    g_timeout_add_seconds_full (gint            priority,
+                                     guint           interval,
+                                     GSourceFunc     function,
+                                     gpointer        data,
+                                     GDestroyNotify  notify);
+guint    g_timeout_add_seconds      (guint           interval,
+                                     GSourceFunc     function,
+                                     gpointer        data);
+guint    g_child_watch_add_full     (gint            priority,
+                                     GPid            pid,
+                                     GChildWatchFunc function,
+                                     gpointer        data,
+                                     GDestroyNotify  notify);
+guint    g_child_watch_add          (GPid            pid,
+                                     GChildWatchFunc function,
+                                     gpointer        data);
+guint    g_idle_add                 (GSourceFunc     function,
+                                     gpointer        data);
+guint    g_idle_add_full            (gint            priority,
+                                     GSourceFunc     function,
+                                     gpointer        data,
+                                     GDestroyNotify  notify);
+gboolean g_idle_remove_by_data      (gpointer        data);
+
+/* Hook for GClosure / GSource integration. Don't touch */
+GLIB_VAR GSourceFuncs g_timeout_funcs;
+GLIB_VAR GSourceFuncs g_child_watch_funcs;
+GLIB_VAR GSourceFuncs g_idle_funcs;
+
+G_END_DECLS
+
+#endif /* __G_MAIN_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gmappedfile.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gmappedfile.c
new file mode 100644 (file)
index 0000000..2af6630
--- /dev/null
@@ -0,0 +1,344 @@
+/* GLIB - Library of useful routines for C programming
+ * gmappedfile.c: Simplified wrapper around the mmap() function.
+ *
+ * Copyright 2005 Matthias Clasen
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <sys/types.h> 
+#include <sys/stat.h> 
+#include <fcntl.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef HAVE_MMAP
+#include <sys/mman.h>
+#endif
+
+#include "glibconfig.h"
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include <io.h>
+
+#define fstat(a,b) _fstati64(a,b)
+#define stat _stati64
+
+#endif
+
+#include "gconvert.h"
+#include "gerror.h"
+#include "gfileutils.h"
+#include "gmappedfile.h"
+#include "gmem.h"
+#include "gmessages.h"
+#include "gstdio.h"
+#include "gstrfuncs.h"
+#include "gatomic.h"
+#include "gbuffer.h"
+
+#include "glibintl.h"
+
+
+#ifndef _O_BINARY
+#define _O_BINARY 0
+#endif
+
+#ifndef MAP_FAILED
+#define MAP_FAILED ((void *) -1)
+#endif
+
+struct _GMappedFile 
+{
+  gchar *contents;
+  gsize  length;
+  gpointer free_func;
+  int    ref_count;
+#ifdef G_OS_WIN32
+  HANDLE mapping;
+#endif
+};
+
+/* Make sure the layout of GMappedFile is the same as GBuffer's */
+G_STATIC_ASSERT (G_STRUCT_OFFSET (GMappedFile, contents) ==
+                 G_STRUCT_OFFSET (GBuffer, data));
+G_STATIC_ASSERT (G_STRUCT_OFFSET (GMappedFile, length) ==
+                 G_STRUCT_OFFSET (GBuffer, size));
+G_STATIC_ASSERT (G_STRUCT_OFFSET (GMappedFile, ref_count) ==
+                 G_STRUCT_OFFSET (GBuffer, ref_count));
+G_STATIC_ASSERT (G_STRUCT_OFFSET (GMappedFile, free_func) ==
+                 G_STRUCT_OFFSET (GBuffer, free_func));
+
+static void
+g_mapped_file_destroy (GMappedFile *file)
+{
+  if (file->length)
+    {
+#ifdef HAVE_MMAP
+      munmap (file->contents, file->length);
+#endif
+#ifdef G_OS_WIN32
+      UnmapViewOfFile (file->contents);
+      CloseHandle (file->mapping);
+#endif
+    }
+
+  g_slice_free (GMappedFile, file);
+}
+
+/**
+ * g_mapped_file_new:
+ * @filename: The path of the file to load, in the GLib filename encoding
+ * @writable: whether the mapping should be writable
+ * @error: return location for a #GError, or %NULL
+ *
+ * Maps a file into memory. On UNIX, this is using the mmap() function.
+ *
+ * If @writable is %TRUE, the mapped buffer may be modified, otherwise
+ * it is an error to modify the mapped buffer. Modifications to the buffer 
+ * are not visible to other processes mapping the same file, and are not 
+ * written back to the file.
+ *
+ * Note that modifications of the underlying file might affect the contents
+ * of the #GMappedFile. Therefore, mapping should only be used if the file 
+ * will not be modified, or if all modifications of the file are done
+ * atomically (e.g. using g_file_set_contents()). 
+ *
+ * Return value: a newly allocated #GMappedFile which must be unref'd
+ *    with g_mapped_file_unref(), or %NULL if the mapping failed.
+ *
+ * Since: 2.8
+ */
+GMappedFile *
+g_mapped_file_new (const gchar  *filename,
+                  gboolean      writable,
+                  GError      **error)
+{
+  GMappedFile *file;
+  int fd;
+  struct stat st;
+
+  g_return_val_if_fail (filename != NULL, NULL);
+  g_return_val_if_fail (!error || *error == NULL, NULL);
+
+  fd = g_open (filename, (writable ? O_RDWR : O_RDONLY) | _O_BINARY, 0);
+  if (fd == -1)
+    {
+      int save_errno = errno;
+      gchar *display_filename = g_filename_display_name (filename);
+      
+      g_set_error (error,
+                   G_FILE_ERROR,
+                   g_file_error_from_errno (save_errno),
+                   _("Failed to open file '%s': open() failed: %s"),
+                   display_filename, 
+                  g_strerror (save_errno));
+      g_free (display_filename);
+      return NULL;
+    }
+
+  file = g_slice_new0 (GMappedFile);
+  file->ref_count = 1;
+  file->free_func = g_mapped_file_destroy;
+
+  if (fstat (fd, &st) == -1)
+    {
+      int save_errno = errno;
+      gchar *display_filename = g_filename_display_name (filename);
+
+      g_set_error (error,
+                   G_FILE_ERROR,
+                   g_file_error_from_errno (save_errno),
+                   _("Failed to get attributes of file '%s': fstat() failed: %s"),
+                   display_filename, 
+                  g_strerror (save_errno));
+      g_free (display_filename);
+      goto out;
+    }
+
+  if (st.st_size == 0)
+    {
+      file->length = 0;
+      file->contents = NULL;
+      close (fd);
+      return file;
+    }
+
+  file->contents = MAP_FAILED;
+
+#ifdef HAVE_MMAP
+  if (st.st_size > G_MAXSIZE)
+    {
+      errno = EINVAL;
+    }
+  else
+    {      
+      file->length = (gsize) st.st_size;
+      file->contents = (gchar *) mmap (NULL,  file->length,
+                                      writable ? PROT_READ|PROT_WRITE : PROT_READ,
+                                      MAP_PRIVATE, fd, 0);
+    }
+#endif
+#ifdef G_OS_WIN32
+  file->length = st.st_size;
+  file->mapping = CreateFileMapping ((HANDLE) _get_osfhandle (fd), NULL,
+                                    writable ? PAGE_WRITECOPY : PAGE_READONLY,
+                                    0, 0,
+                                    NULL);
+  if (file->mapping != NULL)
+    {
+      file->contents = MapViewOfFile (file->mapping,
+                                     writable ? FILE_MAP_COPY : FILE_MAP_READ,
+                                     0, 0,
+                                     0);
+      if (file->contents == NULL)
+       {
+         file->contents = MAP_FAILED;
+         CloseHandle (file->mapping);
+         file->mapping = NULL;
+       }
+    }
+#endif
+
+  
+  if (file->contents == MAP_FAILED)
+    {
+      int save_errno = errno;
+      gchar *display_filename = g_filename_display_name (filename);
+      
+      g_set_error (error,
+                  G_FILE_ERROR,
+                  g_file_error_from_errno (save_errno),
+                  _("Failed to map file '%s': mmap() failed: %s"),
+                  display_filename,
+                  g_strerror (save_errno));
+      g_free (display_filename);
+      goto out;
+    }
+
+  close (fd);
+  return file;
+
+ out:
+  close (fd);
+  g_slice_free (GMappedFile, file);
+
+  return NULL;
+}
+
+/**
+ * g_mapped_file_get_length:
+ * @file: a #GMappedFile
+ *
+ * Returns the length of the contents of a #GMappedFile.
+ *
+ * Returns: the length of the contents of @file.
+ *
+ * Since: 2.8
+ */
+gsize
+g_mapped_file_get_length (GMappedFile *file)
+{
+  g_return_val_if_fail (file != NULL, 0);
+
+  return file->length;
+}
+
+/**
+ * g_mapped_file_get_contents:
+ * @file: a #GMappedFile
+ *
+ * Returns the contents of a #GMappedFile. 
+ *
+ * Note that the contents may not be zero-terminated,
+ * even if the #GMappedFile is backed by a text file.
+ *
+ * If the file is empty then %NULL is returned.
+ *
+ * Returns: the contents of @file, or %NULL.
+ *
+ * Since: 2.8
+ */
+gchar *
+g_mapped_file_get_contents (GMappedFile *file)
+{
+  g_return_val_if_fail (file != NULL, NULL);
+
+  return file->contents;
+}
+
+/**
+ * g_mapped_file_free:
+ * @file: a #GMappedFile
+ *
+ * This call existed before #GMappedFile had refcounting and is currently
+ * exactly the same as g_mapped_file_unref().
+ *
+ * Since: 2.8
+ * Deprecated:2.22: Use g_mapped_file_unref() instead.
+ */
+void
+g_mapped_file_free (GMappedFile *file)
+{
+  g_mapped_file_unref (file);
+}
+
+/**
+ * g_mapped_file_ref:
+ * @file: a #GMappedFile
+ *
+ * Increments the reference count of @file by one.  It is safe to call
+ * this function from any thread.
+ *
+ * Return value: the passed in #GMappedFile.
+ *
+ * Since: 2.22
+ **/
+GMappedFile *
+g_mapped_file_ref (GMappedFile *file)
+{
+  g_return_val_if_fail (file != NULL, NULL);
+  g_return_val_if_fail (file->ref_count > 0, file);
+
+  g_atomic_int_inc (&file->ref_count);
+
+  return file;
+}
+
+/**
+ * g_mapped_file_unref:
+ * @file: a #GMappedFile
+ *
+ * Decrements the reference count of @file by one.  If the reference count
+ * drops to 0, unmaps the buffer of @file and frees it.
+ *
+ * It is safe to call this function from any thread.
+ *
+ * Since 2.22
+ **/
+void
+g_mapped_file_unref (GMappedFile *file)
+{
+  g_return_if_fail (file != NULL);
+  g_return_if_fail (file->ref_count > 0);
+
+  if (g_atomic_int_dec_and_test (&file->ref_count))
+    g_mapped_file_destroy (file);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gmappedfile.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gmappedfile.h
new file mode 100644 (file)
index 0000000..dbb3f89
--- /dev/null
@@ -0,0 +1,49 @@
+/* GLIB - Library of useful routines for C programming
+ * gmappedfile.h: Simplified wrapper around the mmap function
+ *
+ * Copyright 2005 Matthias Clasen
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_MAPPED_FILE_H__
+#define __G_MAPPED_FILE_H__
+
+#include <glib/gerror.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GMappedFile GMappedFile;
+
+GMappedFile *g_mapped_file_new          (const gchar  *filename,
+                                        gboolean      writable,
+                                        GError      **error) G_GNUC_MALLOC;
+gsize        g_mapped_file_get_length   (GMappedFile  *file);
+gchar       *g_mapped_file_get_contents (GMappedFile  *file);
+GMappedFile *g_mapped_file_ref          (GMappedFile  *file);
+void         g_mapped_file_unref        (GMappedFile  *file);
+
+#ifndef G_DISABLE_DEPRECATED
+void         g_mapped_file_free         (GMappedFile  *file);
+#endif
+
+G_END_DECLS
+
+#endif /* __G_MAPPED_FILE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gmarkup.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gmarkup.c
new file mode 100644 (file)
index 0000000..b9e8c31
--- /dev/null
@@ -0,0 +1,2785 @@
+/* gmarkup.c - Simple XML-like parser
+ *
+ *  Copyright 2000, 2003 Red Hat, Inc.
+ *  Copyright 2007, 2008 Ryan Lortie <desrt@desrt.ca>
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *   Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <errno.h>
+
+#include "gmarkup.h"
+
+#include "galloca.h"
+#include "gstrfuncs.h"
+#include "gstring.h"
+#include "gtestutils.h"
+#include "glibintl.h"
+
+GQuark
+g_markup_error_quark (void)
+{
+  return g_quark_from_static_string ("g-markup-error-quark");
+}
+
+typedef enum
+{
+  STATE_START,
+  STATE_AFTER_OPEN_ANGLE,
+  STATE_AFTER_CLOSE_ANGLE,
+  STATE_AFTER_ELISION_SLASH, /* the slash that obviates need for end element */
+  STATE_INSIDE_OPEN_TAG_NAME,
+  STATE_INSIDE_ATTRIBUTE_NAME,
+  STATE_AFTER_ATTRIBUTE_NAME,
+  STATE_BETWEEN_ATTRIBUTES,
+  STATE_AFTER_ATTRIBUTE_EQUALS_SIGN,
+  STATE_INSIDE_ATTRIBUTE_VALUE_SQ,
+  STATE_INSIDE_ATTRIBUTE_VALUE_DQ,
+  STATE_INSIDE_TEXT,
+  STATE_AFTER_CLOSE_TAG_SLASH,
+  STATE_INSIDE_CLOSE_TAG_NAME,
+  STATE_AFTER_CLOSE_TAG_NAME,
+  STATE_INSIDE_PASSTHROUGH,
+  STATE_ERROR
+} GMarkupParseState;
+
+typedef struct
+{
+  const char *prev_element;
+  const GMarkupParser *prev_parser;
+  gpointer prev_user_data;
+} GMarkupRecursionTracker;
+
+struct _GMarkupParseContext
+{
+  const GMarkupParser *parser;
+
+  GMarkupParseFlags flags;
+
+  gint line_number;
+  gint char_number;
+
+  gpointer user_data;
+  GDestroyNotify dnotify;
+
+  /* A piece of character data or an element that
+   * hasn't "ended" yet so we haven't yet called
+   * the callback for it.
+   */
+  GString *partial_chunk;
+  GSList *spare_chunks;
+
+  GMarkupParseState state;
+  GSList *tag_stack;
+  GSList *tag_stack_gstr;
+  GSList *spare_list_nodes;
+
+  GString **attr_names;
+  GString **attr_values;
+  gint cur_attr;
+  gint alloc_attrs;
+
+  const gchar *current_text;
+  gssize       current_text_len;      
+  const gchar *current_text_end;
+
+  /* used to save the start of the last interesting thingy */
+  const gchar *start;
+
+  const gchar *iter;
+
+  guint document_empty : 1;
+  guint parsing : 1;
+  guint awaiting_pop : 1;
+  gint balance;
+
+  /* subparser support */
+  GSList *subparser_stack; /* (GMarkupRecursionTracker *) */
+  const char *subparser_element;
+  gpointer held_user_data;
+};
+
+/*
+ * Helpers to reduce our allocation overhead, we have
+ * a well defined allocation lifecycle.
+ */
+static GSList *
+get_list_node (GMarkupParseContext *context, gpointer data)
+{
+  GSList *node;
+  if (context->spare_list_nodes != NULL)
+    {
+      node = context->spare_list_nodes;
+      context->spare_list_nodes = g_slist_remove_link (context->spare_list_nodes, node);
+    }
+  else
+    node = g_slist_alloc();
+  node->data = data;
+  return node;
+}
+
+static void
+free_list_node (GMarkupParseContext *context, GSList *node)
+{
+  node->data = NULL;
+  context->spare_list_nodes = g_slist_concat (node, context->spare_list_nodes);
+}
+
+static inline void
+string_blank (GString *string)
+{
+  string->str[0] = '\0';
+  string->len = 0;
+}
+
+/**
+ * g_markup_parse_context_new:
+ * @parser: a #GMarkupParser
+ * @flags: one or more #GMarkupParseFlags
+ * @user_data: user data to pass to #GMarkupParser functions
+ * @user_data_dnotify: user data destroy notifier called when the parse context is freed
+ * 
+ * Creates a new parse context. A parse context is used to parse
+ * marked-up documents. You can feed any number of documents into
+ * a context, as long as no errors occur; once an error occurs,
+ * the parse context can't continue to parse text (you have to free it
+ * and create a new parse context).
+ * 
+ * Return value: a new #GMarkupParseContext
+ **/
+GMarkupParseContext *
+g_markup_parse_context_new (const GMarkupParser *parser,
+                            GMarkupParseFlags    flags,
+                            gpointer             user_data,
+                            GDestroyNotify       user_data_dnotify)
+{
+  GMarkupParseContext *context;
+
+  g_return_val_if_fail (parser != NULL, NULL);
+
+  context = g_new (GMarkupParseContext, 1);
+
+  context->parser = parser;
+  context->flags = flags;
+  context->user_data = user_data;
+  context->dnotify = user_data_dnotify;
+
+  context->line_number = 1;
+  context->char_number = 1;
+
+  context->partial_chunk = NULL;
+  context->spare_chunks = NULL;
+  context->spare_list_nodes = NULL;
+
+  context->state = STATE_START;
+  context->tag_stack = NULL;
+  context->tag_stack_gstr = NULL;
+  context->attr_names = NULL;
+  context->attr_values = NULL;
+  context->cur_attr = -1;
+  context->alloc_attrs = 0;
+
+  context->current_text = NULL;
+  context->current_text_len = -1;
+  context->current_text_end = NULL;
+
+  context->start = NULL;
+  context->iter = NULL;
+
+  context->document_empty = TRUE;
+  context->parsing = FALSE;
+
+  context->awaiting_pop = FALSE;
+  context->subparser_stack = NULL;
+  context->subparser_element = NULL;
+
+  /* this is only looked at if awaiting_pop = TRUE.  initialise anyway. */
+  context->held_user_data = NULL;
+
+  context->balance = 0;
+
+  return context;
+}
+
+static void
+string_full_free (gpointer ptr, gpointer user_data)
+{
+  g_string_free (ptr, TRUE);
+}
+
+static void clear_attributes (GMarkupParseContext *context);
+
+/**
+ * g_markup_parse_context_free:
+ * @context: a #GMarkupParseContext
+ * 
+ * Frees a #GMarkupParseContext. Can't be called from inside
+ * one of the #GMarkupParser functions. Can't be called while
+ * a subparser is pushed.
+ **/
+void
+g_markup_parse_context_free (GMarkupParseContext *context)
+{
+  g_return_if_fail (context != NULL);
+  g_return_if_fail (!context->parsing);
+  g_return_if_fail (!context->subparser_stack);
+  g_return_if_fail (!context->awaiting_pop);
+
+  if (context->dnotify)
+    (* context->dnotify) (context->user_data);
+
+  clear_attributes (context);
+  g_free (context->attr_names);
+  g_free (context->attr_values);
+
+  g_slist_foreach (context->tag_stack_gstr, string_full_free, NULL);
+  g_slist_free (context->tag_stack_gstr);
+  g_slist_free (context->tag_stack);
+
+  g_slist_foreach (context->spare_chunks, string_full_free, NULL);
+  g_slist_free (context->spare_chunks);
+  g_slist_free (context->spare_list_nodes);
+
+  if (context->partial_chunk)
+    g_string_free (context->partial_chunk, TRUE);
+
+  g_free (context);
+}
+
+static void pop_subparser_stack (GMarkupParseContext *context);
+
+static void
+mark_error (GMarkupParseContext *context,
+            GError              *error)
+{
+  context->state = STATE_ERROR;
+
+  if (context->parser->error)
+    (*context->parser->error) (context, error, context->user_data);
+
+  /* report the error all the way up to free all the user-data */
+  while (context->subparser_stack)
+    {
+      pop_subparser_stack (context);
+      context->awaiting_pop = FALSE; /* already been freed */
+
+      if (context->parser->error)
+        (*context->parser->error) (context, error, context->user_data);
+    }
+}
+
+static void set_error (GMarkupParseContext *context,
+                      GError             **error,
+                      GMarkupError         code,
+                      const gchar         *format,
+                      ...) G_GNUC_PRINTF (4, 5);
+
+static void
+set_error_literal (GMarkupParseContext *context,
+                   GError             **error,
+                   GMarkupError         code,
+                   const gchar         *message)
+{
+  GError *tmp_error;
+
+  tmp_error = g_error_new_literal (G_MARKUP_ERROR, code, message);
+
+  g_prefix_error (&tmp_error,
+                  _("Error on line %d char %d: "),
+                  context->line_number,
+                  context->char_number);
+
+  mark_error (context, tmp_error);
+
+  g_propagate_error (error, tmp_error);
+}
+
+static void
+set_error (GMarkupParseContext *context,
+           GError             **error,
+           GMarkupError         code,
+           const gchar         *format,
+           ...)
+{
+  gchar *s;
+  gchar *s_valid;
+  va_list args;
+
+  va_start (args, format);
+  s = g_strdup_vprintf (format, args);
+  va_end (args);
+
+  /* Make sure that the GError message is valid UTF-8 even if it is
+   * complaining about invalid UTF-8 in the markup: */
+  s_valid = _g_utf8_make_valid (s);
+  set_error_literal (context, error, code, s);
+
+  g_free (s);
+  g_free (s_valid);
+}
+
+static void
+propagate_error (GMarkupParseContext  *context,
+                 GError              **dest,
+                 GError               *src)
+{
+  if (context->flags & G_MARKUP_PREFIX_ERROR_POSITION)
+    g_prefix_error (&src,
+                    _("Error on line %d char %d: "),
+                    context->line_number,
+                    context->char_number);
+
+  mark_error (context, src);
+
+  g_propagate_error (dest, src);
+}
+
+#define IS_COMMON_NAME_END_CHAR(c) \
+  ((c) == '=' || (c) == '/' || (c) == '>' || (c) == ' ')
+
+static gboolean
+slow_name_validate (GMarkupParseContext *context, const char *name, GError **error)
+{
+  const char *p = name;
+
+  if (!g_utf8_validate (name, strlen (name), NULL))
+    {
+      set_error (context, error, G_MARKUP_ERROR_BAD_UTF8,
+                _("Invalid UTF-8 encoded text in name - not valid '%s'"), name);
+      return FALSE;
+    }
+
+  if (!(g_ascii_isalpha (*p) ||
+       (!IS_COMMON_NAME_END_CHAR (*p) &&
+        (*p == '_' || 
+         *p == ':' ||
+         g_unichar_isalpha (g_utf8_get_char (p))))))
+    {
+      set_error (context, error, G_MARKUP_ERROR_PARSE,
+                _("'%s' is not a valid name "), name);
+      return FALSE;
+    }
+
+  for (p = g_utf8_next_char (name); *p != '\0'; p = g_utf8_next_char (p))
+    {
+      /* is_name_char */
+      if (!(g_ascii_isalnum (*p) ||
+           (!IS_COMMON_NAME_END_CHAR (*p) &&
+            (*p == '.' || 
+             *p == '-' ||
+             *p == '_' ||
+             *p == ':' ||
+             g_unichar_isalpha (g_utf8_get_char (p))))))
+       {
+         set_error (context, error, G_MARKUP_ERROR_PARSE,
+                    _("'%s' is not a valid name: '%c' "), name, *p);
+         return FALSE;
+       }
+    }
+  return TRUE;
+}
+
+/* 
+ * Use me for elements, attributes etc.
+ */
+static gboolean
+name_validate (GMarkupParseContext *context, const char *name, GError **error)
+{
+  char mask;
+  const char *p;
+
+  /* name start char */
+  p = name;
+  if (G_UNLIKELY (IS_COMMON_NAME_END_CHAR (*p) ||
+                 !(g_ascii_isalpha (*p) || *p == '_' || *p == ':')))
+    goto slow_validate;
+  
+  for (mask = *p++; *p != '\0'; p++)
+    {
+      mask |= *p;
+
+      /* is_name_char */
+      if (G_UNLIKELY (!(g_ascii_isalnum (*p) ||
+                       (!IS_COMMON_NAME_END_CHAR (*p) &&
+                        (*p == '.' || 
+                         *p == '-' ||
+                         *p == '_' ||
+                         *p == ':')))))
+       goto slow_validate;
+    }
+
+  if (mask & 0x80) /* un-common / non-ascii */
+    goto slow_validate;
+
+  return TRUE;
+
+ slow_validate:
+  return slow_name_validate (context, name, error);
+}
+
+static gboolean
+text_validate (GMarkupParseContext *context, const char *p, int len, GError **error)
+{
+  if (!g_utf8_validate (p, len, NULL))
+    {
+      set_error (context, error, G_MARKUP_ERROR_BAD_UTF8,
+                _("Invalid UTF-8 encoded text in name - not valid '%s'"), p);
+      return FALSE;
+    }
+  else
+    return TRUE;
+}
+
+static gchar*
+char_str (gunichar c,
+          gchar   *buf)
+{
+  memset (buf, 0, 8);
+  g_unichar_to_utf8 (c, buf);
+  return buf;
+}
+
+static gchar*
+utf8_str (const gchar *utf8,
+          gchar       *buf)
+{
+  char_str (g_utf8_get_char (utf8), buf);
+  return buf;
+}
+
+static void
+set_unescape_error (GMarkupParseContext *context,
+                    GError             **error,
+                    const gchar         *remaining_text,
+                    GMarkupError         code,
+                    const gchar         *format,
+                    ...)
+{
+  GError *tmp_error;
+  gchar *s;
+  va_list args;
+  gint remaining_newlines;
+  const gchar *p;
+
+  remaining_newlines = 0;
+  p = remaining_text;
+  while (*p != '\0')
+    {
+      if (*p == '\n')
+        ++remaining_newlines;
+      ++p;
+    }
+
+  va_start (args, format);
+  s = g_strdup_vprintf (format, args);
+  va_end (args);
+
+  tmp_error = g_error_new (G_MARKUP_ERROR,
+                           code,
+                           _("Error on line %d: %s"),
+                           context->line_number - remaining_newlines,
+                           s);
+
+  g_free (s);
+
+  mark_error (context, tmp_error);
+
+  g_propagate_error (error, tmp_error);
+}
+
+/*
+ * re-write the GString in-place, unescaping anything that escaped.
+ * most XML does not contain entities, or escaping.
+ */
+static gboolean
+unescape_gstring_inplace (GMarkupParseContext *context,
+                         GString             *string,
+                         gboolean            *is_ascii,
+                         GError             **error)
+{
+  char mask, *to;
+  int line_num = 1;
+  const char *from;
+  gboolean normalize_attribute;
+
+  *is_ascii = FALSE;
+
+  /* are we unescaping an attribute or not ? */
+  if (context->state == STATE_INSIDE_ATTRIBUTE_VALUE_SQ ||
+      context->state == STATE_INSIDE_ATTRIBUTE_VALUE_DQ)
+    normalize_attribute = TRUE;
+  else
+    normalize_attribute = FALSE;
+
+  /*
+   * Meeks' theorum: unescaping can only shrink text.
+   * for &lt; etc. this is obvious, for &#xffff; more
+   * thought is required, but this is patently so.
+   */
+  mask = 0;
+  for (from = to = string->str; *from != '\0'; from++, to++) 
+    {
+      *to = *from;
+
+      mask |= *to;
+      if (*to == '\n')
+       line_num++;
+      if (normalize_attribute && (*to == '\t' || *to == '\n'))
+       *to = ' ';
+      if (*to == '\r')
+       {
+         *to = normalize_attribute ? ' ' : '\n';
+         if (from[1] == '\n')
+           from++;
+       }
+      if (*from == '&')
+       {
+         from++;
+         if (*from == '#')
+           {
+             gboolean is_hex = FALSE;
+             gulong l;
+             gchar *end = NULL;
+
+             from++;
+
+             if (*from == 'x')
+               {
+                 is_hex = TRUE;
+                 from++;
+               }
+
+             /* digit is between start and p */
+             errno = 0;
+             if (is_hex)
+               l = strtoul (from, &end, 16);
+             else
+               l = strtoul (from, &end, 10);
+             
+             if (end == from || errno != 0)
+               {
+                 set_unescape_error (context, error,
+                                     from, G_MARKUP_ERROR_PARSE,
+                                     _("Failed to parse '%-.*s', which "
+                                       "should have been a digit "
+                                       "inside a character reference "
+                                       "(&#234; for example) - perhaps "
+                                       "the digit is too large"),
+                                     end - from, from);
+                 return FALSE;
+               }
+             else if (*end != ';')
+               {
+                 set_unescape_error (context, error,
+                                     from, G_MARKUP_ERROR_PARSE,
+                                     _("Character reference did not end with a "
+                                       "semicolon; "
+                                       "most likely you used an ampersand "
+                                       "character without intending to start "
+                                       "an entity - escape ampersand as &amp;"));
+                 return FALSE;
+               }
+             else
+               {
+                 /* characters XML 1.1 permits */
+                 if ((0 < l && l <= 0xD7FF) ||
+                     (0xE000 <= l && l <= 0xFFFD) ||
+                     (0x10000 <= l && l <= 0x10FFFF))
+                   {
+                     gchar buf[8];
+                     char_str (l, buf);
+                     strcpy (to, buf);
+                     to += strlen (buf) - 1;
+                     from = end;
+                     if (l >= 0x80) /* not ascii */
+                       mask |= 0x80;
+                   }
+                 else
+                   {
+                     set_unescape_error (context, error,
+                                         from, G_MARKUP_ERROR_PARSE,
+                                         _("Character reference '%-.*s' does not "
+                                           "encode a permitted character"),
+                                         end - from, from);
+                     return FALSE;
+                   }
+               }
+            }
+
+          else if (strncmp (from, "lt;", 3) == 0)
+           {
+             *to = '<';
+             from += 2;
+           }
+          else if (strncmp (from, "gt;", 3) == 0)
+           {
+             *to = '>';
+             from += 2;
+           }
+          else if (strncmp (from, "amp;", 4) == 0)
+           {
+             *to = '&';
+             from += 3;
+           }
+          else if (strncmp (from, "quot;", 5) == 0)
+           {
+             *to = '"';
+             from += 4;
+           }
+         else if (strncmp (from, "apos;", 5) == 0)
+           {
+             *to = '\'';
+             from += 4;
+           }
+         else
+           {
+             if (*from == ';')
+               set_unescape_error (context, error,
+                                   from, G_MARKUP_ERROR_PARSE,
+                                   _("Empty entity '&;' seen; valid "
+                                     "entities are: &amp; &quot; &lt; &gt; &apos;"));
+             else
+               {
+                 const char *end = strchr (from, ';');
+                 if (end)
+                   set_unescape_error (context, error,
+                                       from, G_MARKUP_ERROR_PARSE,
+                                       _("Entity name '%-.*s' is not known"),
+                                       end-from, from);
+                 else
+                   set_unescape_error (context, error,
+                                       from, G_MARKUP_ERROR_PARSE,
+                                       _("Entity did not end with a semicolon; "
+                                         "most likely you used an ampersand "
+                                         "character without intending to start "
+                                         "an entity - escape ampersand as &amp;"));
+               }
+             return FALSE;
+           }
+       }
+    }
+
+  g_assert (to - string->str <= string->len);
+  if (to - string->str != string->len)
+    g_string_truncate (string, to - string->str);
+
+  *is_ascii = !(mask & 0x80);
+
+  return TRUE;
+}
+
+static inline gboolean
+advance_char (GMarkupParseContext *context)
+{  
+  context->iter++;
+  context->char_number++;
+
+  if (G_UNLIKELY (context->iter == context->current_text_end))
+      return FALSE;
+
+  else if (G_UNLIKELY (*context->iter == '\n'))
+    {
+      context->line_number++;
+      context->char_number = 1;
+    }
+  
+  return TRUE;
+}
+
+static inline gboolean
+xml_isspace (char c)
+{
+  return c == ' ' || c == '\t' || c == '\n' || c == '\r';
+}
+
+static void
+skip_spaces (GMarkupParseContext *context)
+{
+  do
+    {
+      if (!xml_isspace (*context->iter))
+        return;
+    }
+  while (advance_char (context));
+}
+
+static void
+advance_to_name_end (GMarkupParseContext *context)
+{
+  do
+    {
+      if (IS_COMMON_NAME_END_CHAR (*(context->iter)))
+        return;
+      if (xml_isspace (*(context->iter)))
+       return;
+    }
+  while (advance_char (context));
+}
+
+static void
+release_chunk (GMarkupParseContext *context, GString *str)
+{
+  GSList *node;
+  if (!str)
+    return;
+  if (str->allocated_len > 256)
+    { /* large strings are unusual and worth freeing */
+      g_string_free (str, TRUE);
+      return;
+    }
+  string_blank (str);
+  node = get_list_node (context, str);
+  context->spare_chunks = g_slist_concat (node, context->spare_chunks);
+}
+
+static void
+add_to_partial (GMarkupParseContext *context,
+                const gchar         *text_start,
+                const gchar         *text_end)
+{
+  if (context->partial_chunk == NULL)
+    { /* allocate a new chunk to parse into */
+
+      if (context->spare_chunks != NULL)
+       {
+         GSList *node = context->spare_chunks;
+         context->spare_chunks = g_slist_remove_link (context->spare_chunks, node);
+         context->partial_chunk = node->data;
+         free_list_node (context, node);
+       }
+      else
+       context->partial_chunk = g_string_sized_new (MAX (28, text_end - text_start));
+    }
+
+  if (text_start != text_end)
+    g_string_insert_len (context->partial_chunk, -1,
+                        text_start, text_end - text_start);
+}
+
+static inline void
+truncate_partial (GMarkupParseContext *context)
+{
+  if (context->partial_chunk != NULL)
+    string_blank (context->partial_chunk);
+}
+
+static inline const gchar*
+current_element (GMarkupParseContext *context)
+{
+  return context->tag_stack->data;
+}
+
+static void
+pop_subparser_stack (GMarkupParseContext *context)
+{
+  GMarkupRecursionTracker *tracker;
+
+  g_assert (context->subparser_stack);
+
+  tracker = context->subparser_stack->data;
+
+  context->awaiting_pop = TRUE;
+  context->held_user_data = context->user_data;
+
+  context->user_data = tracker->prev_user_data;
+  context->parser = tracker->prev_parser;
+  context->subparser_element = tracker->prev_element;
+  g_slice_free (GMarkupRecursionTracker, tracker);
+
+  context->subparser_stack = g_slist_delete_link (context->subparser_stack,
+                                                  context->subparser_stack);
+}
+
+static void
+push_partial_as_tag (GMarkupParseContext *context)
+{
+  GString *str = context->partial_chunk;
+  /* sadly, this is exported by gmarkup_get_element_stack as-is */
+  context->tag_stack = g_slist_concat (get_list_node (context, str->str), context->tag_stack);
+  context->tag_stack_gstr = g_slist_concat (get_list_node (context, str), context->tag_stack_gstr);
+  context->partial_chunk = NULL;
+}
+
+static void
+pop_tag (GMarkupParseContext *context)
+{
+  GSList *nodea, *nodeb;
+
+  nodea = context->tag_stack;
+  nodeb = context->tag_stack_gstr;
+  release_chunk (context, nodeb->data);
+  context->tag_stack = g_slist_remove_link (context->tag_stack, nodea);
+  context->tag_stack_gstr = g_slist_remove_link (context->tag_stack_gstr, nodeb);
+  free_list_node (context, nodea);
+  free_list_node (context, nodeb);
+}
+
+static void
+possibly_finish_subparser (GMarkupParseContext *context)
+{
+  if (current_element (context) == context->subparser_element)
+    pop_subparser_stack (context);
+}
+
+static void
+ensure_no_outstanding_subparser (GMarkupParseContext *context)
+{
+  if (context->awaiting_pop)
+    g_critical ("During the first end_element call after invoking a "
+               "subparser you must pop the subparser stack and handle "
+               "the freeing of the subparser user_data.  This can be "
+               "done by calling the end function of the subparser.  "
+               "Very probably, your program just leaked memory.");
+
+  /* let valgrind watch the pointer disappear... */
+  context->held_user_data = NULL;
+  context->awaiting_pop = FALSE;
+}
+
+static const gchar*
+current_attribute (GMarkupParseContext *context)
+{
+  g_assert (context->cur_attr >= 0);
+  return context->attr_names[context->cur_attr]->str;
+}
+
+static void
+add_attribute (GMarkupParseContext *context, GString *str)
+{
+  if (context->cur_attr + 2 >= context->alloc_attrs)
+    {
+      context->alloc_attrs += 5; /* silly magic number */
+      context->attr_names = g_realloc (context->attr_names, sizeof(GString*)*context->alloc_attrs);
+      context->attr_values = g_realloc (context->attr_values, sizeof(GString*)*context->alloc_attrs);
+    }
+  context->cur_attr++;
+  context->attr_names[context->cur_attr] = str;
+  context->attr_values[context->cur_attr] = NULL;
+  context->attr_names[context->cur_attr+1] = NULL;
+  context->attr_values[context->cur_attr+1] = NULL;
+}
+
+static void
+clear_attributes (GMarkupParseContext *context)
+{
+  /* Go ahead and free the attributes. */
+  for (; context->cur_attr >= 0; context->cur_attr--)
+    {
+      int pos = context->cur_attr;
+      release_chunk (context, context->attr_names[pos]);
+      release_chunk (context, context->attr_values[pos]);
+      context->attr_names[pos] = context->attr_values[pos] = NULL;
+    }
+  g_assert (context->cur_attr == -1);
+  g_assert (context->attr_names == NULL ||
+           context->attr_names[0] == NULL);
+  g_assert (context->attr_values == NULL ||
+           context->attr_values[0] == NULL);
+}
+
+/* This has to be a separate function to ensure the alloca's
+   are unwound on exit - otherwise we grow & blow the stack
+   with large documents */
+static inline void
+emit_start_element (GMarkupParseContext *context, GError **error)
+{
+  int i;
+  const gchar *start_name;
+  const gchar **attr_names;
+  const gchar **attr_values;
+  GError *tmp_error;
+  
+  attr_names = g_newa (const gchar *, context->cur_attr + 2);
+  attr_values = g_newa (const gchar *, context->cur_attr + 2);
+  for (i = 0; i < context->cur_attr + 1; i++)
+    {
+      attr_names[i] = context->attr_names[i]->str;
+      attr_values[i] = context->attr_values[i]->str;
+    }
+  attr_names[i] = NULL;
+  attr_values[i] = NULL;
+  
+  /* Call user callback for element start */
+  tmp_error = NULL;
+  start_name = current_element (context);
+  
+  if (context->parser->start_element &&
+      name_validate (context, start_name, error))
+    (* context->parser->start_element) (context,
+                                       start_name,
+                                       (const gchar **)attr_names,
+                                       (const gchar **)attr_values,
+                                       context->user_data,
+                                       &tmp_error);
+  clear_attributes (context);
+  
+  if (tmp_error != NULL)
+    propagate_error (context, error, tmp_error);
+}
+
+/**
+ * g_markup_parse_context_parse:
+ * @context: a #GMarkupParseContext
+ * @text: chunk of text to parse
+ * @text_len: length of @text in bytes
+ * @error: return location for a #GError
+ * 
+ * Feed some data to the #GMarkupParseContext. The data need not
+ * be valid UTF-8; an error will be signaled if it's invalid.
+ * The data need not be an entire document; you can feed a document
+ * into the parser incrementally, via multiple calls to this function.
+ * Typically, as you receive data from a network connection or file,
+ * you feed each received chunk of data into this function, aborting
+ * the process if an error occurs. Once an error is reported, no further
+ * data may be fed to the #GMarkupParseContext; all errors are fatal.
+ * 
+ * Return value: %FALSE if an error occurred, %TRUE on success
+ **/
+gboolean
+g_markup_parse_context_parse (GMarkupParseContext *context,
+                              const gchar         *text,
+                              gssize               text_len,
+                              GError             **error)
+{
+  g_return_val_if_fail (context != NULL, FALSE);
+  g_return_val_if_fail (text != NULL, FALSE);
+  g_return_val_if_fail (context->state != STATE_ERROR, FALSE);
+  g_return_val_if_fail (!context->parsing, FALSE);
+  
+  if (text_len < 0)
+    text_len = strlen (text);
+
+  if (text_len == 0)
+    return TRUE;
+  
+  context->parsing = TRUE;
+  
+
+  context->current_text = text;
+  context->current_text_len = text_len;
+  context->current_text_end = context->current_text + text_len;
+  context->iter = context->current_text;
+  context->start = context->iter;
+
+  if (context->current_text_len == 0)
+    goto finished;
+
+  while (context->iter != context->current_text_end)
+    {
+      switch (context->state)
+        {
+        case STATE_START:
+          /* Possible next state: AFTER_OPEN_ANGLE */
+
+          g_assert (context->tag_stack == NULL);
+
+          /* whitespace is ignored outside of any elements */
+          skip_spaces (context);
+
+          if (context->iter != context->current_text_end)
+            {
+              if (*context->iter == '<')
+                {
+                  /* Move after the open angle */
+                  advance_char (context);
+
+                  context->state = STATE_AFTER_OPEN_ANGLE;
+
+                  /* this could start a passthrough */
+                  context->start = context->iter;
+
+                  /* document is now non-empty */
+                  context->document_empty = FALSE;
+                }
+              else
+                {
+                  set_error_literal (context,
+                                     error,
+                                     G_MARKUP_ERROR_PARSE,
+                                     _("Document must begin with an element (e.g. <book>)"));
+                }
+            }
+          break;
+
+        case STATE_AFTER_OPEN_ANGLE:
+          /* Possible next states: INSIDE_OPEN_TAG_NAME,
+           *  AFTER_CLOSE_TAG_SLASH, INSIDE_PASSTHROUGH
+           */
+          if (*context->iter == '?' ||
+              *context->iter == '!')
+            {
+              /* include < in the passthrough */
+              const gchar *openangle = "<";
+              add_to_partial (context, openangle, openangle + 1);
+              context->start = context->iter;
+             context->balance = 1;
+              context->state = STATE_INSIDE_PASSTHROUGH;
+            }
+          else if (*context->iter == '/')
+            {
+              /* move after it */
+              advance_char (context);
+
+              context->state = STATE_AFTER_CLOSE_TAG_SLASH;
+            }
+          else if (!IS_COMMON_NAME_END_CHAR (*(context->iter)))
+            {
+              context->state = STATE_INSIDE_OPEN_TAG_NAME;
+
+              /* start of tag name */
+              context->start = context->iter;
+            }
+          else
+            {
+              gchar buf[8];
+
+              set_error (context,
+                         error,
+                         G_MARKUP_ERROR_PARSE,
+                         _("'%s' is not a valid character following "
+                           "a '<' character; it may not begin an "
+                           "element name"),
+                         utf8_str (context->iter, buf));
+            }
+          break;
+
+          /* The AFTER_CLOSE_ANGLE state is actually sort of
+           * broken, because it doesn't correspond to a range
+           * of characters in the input stream as the others do,
+           * and thus makes things harder to conceptualize
+           */
+        case STATE_AFTER_CLOSE_ANGLE:
+          /* Possible next states: INSIDE_TEXT, STATE_START */
+          if (context->tag_stack == NULL)
+            {
+              context->start = NULL;
+              context->state = STATE_START;
+            }
+          else
+            {
+              context->start = context->iter;
+              context->state = STATE_INSIDE_TEXT;
+            }
+          break;
+
+        case STATE_AFTER_ELISION_SLASH:
+          /* Possible next state: AFTER_CLOSE_ANGLE */
+
+          {
+            /* We need to pop the tag stack and call the end_element
+             * function, since this is the close tag
+             */
+            GError *tmp_error = NULL;
+          
+            g_assert (context->tag_stack != NULL);
+
+            possibly_finish_subparser (context);
+
+            tmp_error = NULL;
+            if (context->parser->end_element)
+              (* context->parser->end_element) (context,
+                                               current_element (context),
+                                                context->user_data,
+                                                &tmp_error);
+
+            ensure_no_outstanding_subparser (context);
+          
+            if (tmp_error)
+              {
+                mark_error (context, tmp_error);
+                g_propagate_error (error, tmp_error);
+              }          
+            else
+              {
+                if (*context->iter == '>')
+                  {
+                    /* move after the close angle */
+                    advance_char (context);
+                    context->state = STATE_AFTER_CLOSE_ANGLE;
+                  }
+                else
+                  {
+                    gchar buf[8];
+
+                    set_error (context,
+                               error,
+                               G_MARKUP_ERROR_PARSE,
+                               _("Odd character '%s', expected a '>' character "
+                                 "to end the empty-element tag '%s'"),
+                               utf8_str (context->iter, buf),
+                               current_element (context));
+                  }
+              }
+           pop_tag (context);
+          }
+          break;
+
+        case STATE_INSIDE_OPEN_TAG_NAME:
+          /* Possible next states: BETWEEN_ATTRIBUTES */
+
+          /* if there's a partial chunk then it's the first part of the
+           * tag name. If there's a context->start then it's the start
+           * of the tag name in current_text, the partial chunk goes
+           * before that start though.
+           */
+          advance_to_name_end (context);
+
+          if (context->iter == context->current_text_end)
+            {
+              /* The name hasn't necessarily ended. Merge with
+               * partial chunk, leave state unchanged.
+               */
+              add_to_partial (context, context->start, context->iter);
+            }
+          else
+            {
+              /* The name has ended. Combine it with the partial chunk
+               * if any; push it on the stack; enter next state.
+               */
+              add_to_partial (context, context->start, context->iter);
+             push_partial_as_tag (context);
+
+              context->state = STATE_BETWEEN_ATTRIBUTES;
+              context->start = NULL;
+            }
+          break;
+
+        case STATE_INSIDE_ATTRIBUTE_NAME:
+          /* Possible next states: AFTER_ATTRIBUTE_NAME */
+
+          advance_to_name_end (context);
+         add_to_partial (context, context->start, context->iter);
+
+          /* read the full name, if we enter the equals sign state
+           * then add the attribute to the list (without the value),
+           * otherwise store a partial chunk to be prepended later.
+           */
+          if (context->iter != context->current_text_end)
+           context->state = STATE_AFTER_ATTRIBUTE_NAME;
+         break;
+
+       case STATE_AFTER_ATTRIBUTE_NAME:
+          /* Possible next states: AFTER_ATTRIBUTE_EQUALS_SIGN */
+
+         skip_spaces (context);
+
+         if (context->iter != context->current_text_end)
+           {
+             /* The name has ended. Combine it with the partial chunk
+              * if any; push it on the stack; enter next state.
+              */
+             if (!name_validate (context, context->partial_chunk->str, error))
+               break;
+
+             add_attribute (context, context->partial_chunk);
+             
+              context->partial_chunk = NULL;
+              context->start = NULL;
+             
+              if (*context->iter == '=')
+                {
+                  advance_char (context);
+                  context->state = STATE_AFTER_ATTRIBUTE_EQUALS_SIGN;
+                }
+              else
+                {
+                  gchar buf[8];
+
+                  set_error (context,
+                             error,
+                             G_MARKUP_ERROR_PARSE,
+                             _("Odd character '%s', expected a '=' after "
+                               "attribute name '%s' of element '%s'"),
+                             utf8_str (context->iter, buf),
+                             current_attribute (context),
+                             current_element (context));
+                 
+                }
+            }
+          break;
+
+        case STATE_BETWEEN_ATTRIBUTES:
+          /* Possible next states: AFTER_CLOSE_ANGLE,
+           * AFTER_ELISION_SLASH, INSIDE_ATTRIBUTE_NAME
+           */
+          skip_spaces (context);
+
+          if (context->iter != context->current_text_end)
+            {
+              if (*context->iter == '/')
+                {
+                  advance_char (context);
+                  context->state = STATE_AFTER_ELISION_SLASH;
+                }
+              else if (*context->iter == '>')
+                {
+                  advance_char (context);
+                  context->state = STATE_AFTER_CLOSE_ANGLE;
+                }
+              else if (!IS_COMMON_NAME_END_CHAR (*(context->iter)))
+                {
+                  context->state = STATE_INSIDE_ATTRIBUTE_NAME;
+                  /* start of attribute name */
+                  context->start = context->iter;
+                }
+              else
+                {
+                  gchar buf[8];
+
+                  set_error (context,
+                             error,
+                             G_MARKUP_ERROR_PARSE,
+                             _("Odd character '%s', expected a '>' or '/' "
+                               "character to end the start tag of "
+                               "element '%s', or optionally an attribute; "
+                               "perhaps you used an invalid character in "
+                               "an attribute name"),
+                             utf8_str (context->iter, buf),
+                             current_element (context));
+                }
+
+              /* If we're done with attributes, invoke
+               * the start_element callback
+               */
+              if (context->state == STATE_AFTER_ELISION_SLASH ||
+                  context->state == STATE_AFTER_CLOSE_ANGLE)
+               emit_start_element (context, error);
+            }
+          break;
+
+        case STATE_AFTER_ATTRIBUTE_EQUALS_SIGN:
+          /* Possible next state: INSIDE_ATTRIBUTE_VALUE_[SQ/DQ] */
+
+         skip_spaces (context);
+
+         if (context->iter != context->current_text_end)
+           {
+             if (*context->iter == '"')
+               {
+                 advance_char (context);
+                 context->state = STATE_INSIDE_ATTRIBUTE_VALUE_DQ;
+                 context->start = context->iter;
+               }
+             else if (*context->iter == '\'')
+               {
+                 advance_char (context);
+                 context->state = STATE_INSIDE_ATTRIBUTE_VALUE_SQ;
+                 context->start = context->iter;
+               }
+             else
+               {
+                 gchar buf[8];
+                 
+                 set_error (context,
+                            error,
+                            G_MARKUP_ERROR_PARSE,
+                            _("Odd character '%s', expected an open quote mark "
+                              "after the equals sign when giving value for "
+                              "attribute '%s' of element '%s'"),
+                            utf8_str (context->iter, buf),
+                            current_attribute (context),
+                            current_element (context));
+               }
+           }
+          break;
+
+        case STATE_INSIDE_ATTRIBUTE_VALUE_SQ:
+        case STATE_INSIDE_ATTRIBUTE_VALUE_DQ:
+          /* Possible next states: BETWEEN_ATTRIBUTES */
+         {
+           gchar delim;
+
+           if (context->state == STATE_INSIDE_ATTRIBUTE_VALUE_SQ) 
+             {
+               delim = '\'';
+             }
+           else 
+             {
+               delim = '"';
+             }
+
+           do
+             {
+               if (*context->iter == delim)
+                 break;
+             }
+           while (advance_char (context));
+         }
+          if (context->iter == context->current_text_end)
+            {
+              /* The value hasn't necessarily ended. Merge with
+               * partial chunk, leave state unchanged.
+               */
+              add_to_partial (context, context->start, context->iter);
+            }
+          else
+            {
+             gboolean is_ascii;
+              /* The value has ended at the quote mark. Combine it
+               * with the partial chunk if any; set it for the current
+               * attribute.
+               */
+              add_to_partial (context, context->start, context->iter);
+
+              g_assert (context->cur_attr >= 0);
+              
+              if (unescape_gstring_inplace (context, context->partial_chunk, &is_ascii, error) &&
+                 (is_ascii || text_validate (context, context->partial_chunk->str,
+                                             context->partial_chunk->len, error)))
+                {
+                  /* success, advance past quote and set state. */
+                  context->attr_values[context->cur_attr] = context->partial_chunk;
+                 context->partial_chunk = NULL;
+                  advance_char (context);
+                  context->state = STATE_BETWEEN_ATTRIBUTES;
+                  context->start = NULL;
+                }
+              
+              truncate_partial (context);
+            }
+          break;
+
+        case STATE_INSIDE_TEXT:
+          /* Possible next states: AFTER_OPEN_ANGLE */
+          do
+            {
+              if (*context->iter == '<')
+                break;
+            }
+          while (advance_char (context));
+
+          /* The text hasn't necessarily ended. Merge with
+           * partial chunk, leave state unchanged.
+           */
+
+          add_to_partial (context, context->start, context->iter);
+
+          if (context->iter != context->current_text_end)
+            {
+             gboolean is_ascii;
+
+              /* The text has ended at the open angle. Call the text
+               * callback.
+               */
+              
+              if (unescape_gstring_inplace (context, context->partial_chunk, &is_ascii, error) &&
+                 (is_ascii || text_validate (context, context->partial_chunk->str,
+                                             context->partial_chunk->len, error)))
+                {
+                  GError *tmp_error = NULL;
+
+                  if (context->parser->text)
+                    (*context->parser->text) (context,
+                                             context->partial_chunk->str,
+                                             context->partial_chunk->len,
+                                              context->user_data,
+                                              &tmp_error);
+                  
+                  if (tmp_error == NULL)
+                    {
+                      /* advance past open angle and set state. */
+                      advance_char (context);
+                      context->state = STATE_AFTER_OPEN_ANGLE;
+                      /* could begin a passthrough */
+                      context->start = context->iter;
+                    }
+                  else
+                    propagate_error (context, error, tmp_error);
+                }
+
+              truncate_partial (context);
+            }
+          break;
+
+        case STATE_AFTER_CLOSE_TAG_SLASH:
+          /* Possible next state: INSIDE_CLOSE_TAG_NAME */
+          if (!IS_COMMON_NAME_END_CHAR (*(context->iter)))
+            {
+              context->state = STATE_INSIDE_CLOSE_TAG_NAME;
+
+              /* start of tag name */
+              context->start = context->iter;
+            }
+          else
+            {
+              gchar buf[8];
+
+              set_error (context,
+                         error,
+                         G_MARKUP_ERROR_PARSE,
+                         _("'%s' is not a valid character following "
+                           "the characters '</'; '%s' may not begin an "
+                           "element name"),
+                         utf8_str (context->iter, buf),
+                         utf8_str (context->iter, buf));
+            }
+          break;
+
+        case STATE_INSIDE_CLOSE_TAG_NAME:
+          /* Possible next state: AFTER_CLOSE_TAG_NAME */
+          advance_to_name_end (context);
+         add_to_partial (context, context->start, context->iter);
+
+          if (context->iter != context->current_text_end)
+           context->state = STATE_AFTER_CLOSE_TAG_NAME;
+         break;
+
+       case STATE_AFTER_CLOSE_TAG_NAME:
+          /* Possible next state: AFTER_CLOSE_TAG_SLASH */
+
+         skip_spaces (context);
+         
+         if (context->iter != context->current_text_end)
+           {
+             GString *close_name;
+
+             close_name = context->partial_chunk;
+             context->partial_chunk = NULL;
+              
+             if (*context->iter != '>')
+               {
+                 gchar buf[8];
+
+                 set_error (context,
+                            error,
+                            G_MARKUP_ERROR_PARSE,
+                            _("'%s' is not a valid character following "
+                              "the close element name '%s'; the allowed "
+                              "character is '>'"),
+                            utf8_str (context->iter, buf),
+                            close_name->str);
+               }
+             else if (context->tag_stack == NULL)
+               {
+                 set_error (context,
+                            error,
+                            G_MARKUP_ERROR_PARSE,
+                            _("Element '%s' was closed, no element "
+                              "is currently open"),
+                            close_name->str);
+               }
+             else if (strcmp (close_name->str, current_element (context)) != 0)
+               {
+                 set_error (context,
+                            error,
+                            G_MARKUP_ERROR_PARSE,
+                            _("Element '%s' was closed, but the currently "
+                              "open element is '%s'"),
+                            close_name->str,
+                            current_element (context));
+               }
+             else
+               {
+                 GError *tmp_error;
+                 advance_char (context);
+                 context->state = STATE_AFTER_CLOSE_ANGLE;
+                 context->start = NULL;
+                 
+                  possibly_finish_subparser (context);
+
+                 /* call the end_element callback */
+                 tmp_error = NULL;
+                 if (context->parser->end_element)
+                   (* context->parser->end_element) (context,
+                                                     close_name->str,
+                                                     context->user_data,
+                                                     &tmp_error);
+                 
+                  ensure_no_outstanding_subparser (context);
+                 pop_tag (context);
+                 
+                 if (tmp_error)
+                    propagate_error (context, error, tmp_error);
+                }
+             context->partial_chunk = close_name;
+             truncate_partial (context);
+            }
+          break;
+         
+        case STATE_INSIDE_PASSTHROUGH:
+          /* Possible next state: AFTER_CLOSE_ANGLE */
+          do
+            {
+             if (*context->iter == '<') 
+               context->balance++;
+              if (*context->iter == '>') 
+               {                               
+                 gchar *str;
+                 gsize len;
+
+                 context->balance--;
+                 add_to_partial (context, context->start, context->iter);
+                 context->start = context->iter;
+
+                 str = context->partial_chunk->str;
+                 len = context->partial_chunk->len;
+
+                 if (str[1] == '?' && str[len - 1] == '?')
+                   break;
+                 if (strncmp (str, "<!--", 4) == 0 && 
+                     strcmp (str + len - 2, "--") == 0)
+                   break;
+                 if (strncmp (str, "<![CDATA[", 9) == 0 && 
+                     strcmp (str + len - 2, "]]") == 0)
+                   break;
+                 if (strncmp (str, "<!DOCTYPE", 9) == 0 &&
+                     context->balance == 0)
+                   break;
+               }
+            }
+          while (advance_char (context));
+
+          if (context->iter == context->current_text_end)
+            {
+              /* The passthrough hasn't necessarily ended. Merge with
+               * partial chunk, leave state unchanged.
+               */
+               add_to_partial (context, context->start, context->iter);
+            }
+          else
+            {
+              /* The passthrough has ended at the close angle. Combine
+               * it with the partial chunk if any. Call the passthrough
+               * callback. Note that the open/close angles are
+               * included in the text of the passthrough.
+               */
+              GError *tmp_error = NULL;
+
+              advance_char (context); /* advance past close angle */
+              add_to_partial (context, context->start, context->iter);
+
+             if (context->flags & G_MARKUP_TREAT_CDATA_AS_TEXT &&
+                 strncmp (context->partial_chunk->str, "<![CDATA[", 9) == 0)
+               {
+                 if (context->parser->text &&
+                     text_validate (context,
+                                    context->partial_chunk->str + 9,
+                                    context->partial_chunk->len - 12,
+                                    error))
+                   (*context->parser->text) (context,
+                                             context->partial_chunk->str + 9,
+                                             context->partial_chunk->len - 12,
+                                             context->user_data,
+                                             &tmp_error);
+               }
+             else if (context->parser->passthrough &&
+                      text_validate (context,
+                                     context->partial_chunk->str,
+                                     context->partial_chunk->len,
+                                     error))
+                (*context->parser->passthrough) (context,
+                                                 context->partial_chunk->str,
+                                                 context->partial_chunk->len,
+                                                 context->user_data,
+                                                 &tmp_error);
+                  
+              truncate_partial (context);
+
+              if (tmp_error == NULL)
+                {
+                  context->state = STATE_AFTER_CLOSE_ANGLE;
+                  context->start = context->iter; /* could begin text */
+                }
+              else
+                propagate_error (context, error, tmp_error);
+            }
+          break;
+
+        case STATE_ERROR:
+          goto finished;
+          break;
+
+        default:
+          g_assert_not_reached ();
+          break;
+        }
+    }
+
+ finished:
+  context->parsing = FALSE;
+
+  return context->state != STATE_ERROR;
+}
+
+/**
+ * g_markup_parse_context_end_parse:
+ * @context: a #GMarkupParseContext
+ * @error: return location for a #GError
+ * 
+ * Signals to the #GMarkupParseContext that all data has been
+ * fed into the parse context with g_markup_parse_context_parse().
+ * This function reports an error if the document isn't complete,
+ * for example if elements are still open.
+ * 
+ * Return value: %TRUE on success, %FALSE if an error was set
+ **/
+gboolean
+g_markup_parse_context_end_parse (GMarkupParseContext *context,
+                                  GError             **error)
+{
+  g_return_val_if_fail (context != NULL, FALSE);
+  g_return_val_if_fail (!context->parsing, FALSE);
+  g_return_val_if_fail (context->state != STATE_ERROR, FALSE);
+
+  if (context->partial_chunk != NULL)
+    {
+      g_string_free (context->partial_chunk, TRUE);
+      context->partial_chunk = NULL;
+    }
+
+  if (context->document_empty)
+    {
+      set_error_literal (context, error, G_MARKUP_ERROR_EMPTY,
+                         _("Document was empty or contained only whitespace"));
+      return FALSE;
+    }
+  
+  context->parsing = TRUE;
+  
+  switch (context->state)
+    {
+    case STATE_START:
+      /* Nothing to do */
+      break;
+
+    case STATE_AFTER_OPEN_ANGLE:
+      set_error_literal (context, error, G_MARKUP_ERROR_PARSE,
+                         _("Document ended unexpectedly just after an open angle bracket '<'"));
+      break;
+
+    case STATE_AFTER_CLOSE_ANGLE:
+      if (context->tag_stack != NULL)
+        {
+          /* Error message the same as for INSIDE_TEXT */
+          set_error (context, error, G_MARKUP_ERROR_PARSE,
+                     _("Document ended unexpectedly with elements still open - "
+                       "'%s' was the last element opened"),
+                     current_element (context));
+        }
+      break;
+      
+    case STATE_AFTER_ELISION_SLASH:
+      set_error (context, error, G_MARKUP_ERROR_PARSE,
+                 _("Document ended unexpectedly, expected to see a close angle "
+                   "bracket ending the tag <%s/>"), current_element (context));
+      break;
+
+    case STATE_INSIDE_OPEN_TAG_NAME:
+      set_error_literal (context, error, G_MARKUP_ERROR_PARSE,
+                         _("Document ended unexpectedly inside an element name"));
+      break;
+
+    case STATE_INSIDE_ATTRIBUTE_NAME:
+    case STATE_AFTER_ATTRIBUTE_NAME:
+      set_error_literal (context, error, G_MARKUP_ERROR_PARSE,
+                         _("Document ended unexpectedly inside an attribute name"));
+      break;
+
+    case STATE_BETWEEN_ATTRIBUTES:
+      set_error_literal (context, error, G_MARKUP_ERROR_PARSE,
+                         _("Document ended unexpectedly inside an element-opening "
+                           "tag."));
+      break;
+
+    case STATE_AFTER_ATTRIBUTE_EQUALS_SIGN:
+      set_error_literal (context, error, G_MARKUP_ERROR_PARSE,
+                         _("Document ended unexpectedly after the equals sign "
+                           "following an attribute name; no attribute value"));
+      break;
+
+    case STATE_INSIDE_ATTRIBUTE_VALUE_SQ:
+    case STATE_INSIDE_ATTRIBUTE_VALUE_DQ:
+      set_error_literal (context, error, G_MARKUP_ERROR_PARSE,
+                         _("Document ended unexpectedly while inside an attribute "
+                           "value"));
+      break;
+
+    case STATE_INSIDE_TEXT:
+      g_assert (context->tag_stack != NULL);
+      set_error (context, error, G_MARKUP_ERROR_PARSE,
+                 _("Document ended unexpectedly with elements still open - "
+                   "'%s' was the last element opened"),
+                 current_element (context));
+      break;
+
+    case STATE_AFTER_CLOSE_TAG_SLASH:
+    case STATE_INSIDE_CLOSE_TAG_NAME:
+    case STATE_AFTER_CLOSE_TAG_NAME:
+      set_error (context, error, G_MARKUP_ERROR_PARSE,
+                 _("Document ended unexpectedly inside the close tag for "
+                   "element '%s'"), current_element (context));
+      break;
+
+    case STATE_INSIDE_PASSTHROUGH:
+      set_error_literal (context, error, G_MARKUP_ERROR_PARSE,
+                         _("Document ended unexpectedly inside a comment or "
+                           "processing instruction"));
+      break;
+
+    case STATE_ERROR:
+    default:
+      g_assert_not_reached ();
+      break;
+    }
+
+  context->parsing = FALSE;
+
+  return context->state != STATE_ERROR;
+}
+
+/**
+ * g_markup_parse_context_get_element:
+ * @context: a #GMarkupParseContext
+ * @returns: the name of the currently open element, or %NULL
+ *
+ * Retrieves the name of the currently open element.
+ *
+ * If called from the start_element or end_element handlers this will
+ * give the element_name as passed to those functions. For the parent
+ * elements, see g_markup_parse_context_get_element_stack().
+ *
+ * Since: 2.2
+ **/
+G_CONST_RETURN gchar *
+g_markup_parse_context_get_element (GMarkupParseContext *context)
+{
+  g_return_val_if_fail (context != NULL, NULL);
+
+  if (context->tag_stack == NULL) 
+    return NULL;
+  else
+    return current_element (context);
+} 
+
+/**
+ * g_markup_parse_context_get_element_stack:
+ * @context: a #GMarkupParseContext
+ *
+ * Retrieves the element stack from the internal state of the parser.
+ * The returned #GSList is a list of strings where the first item is
+ * the currently open tag (as would be returned by
+ * g_markup_parse_context_get_element()) and the next item is its
+ * immediate parent.
+ *
+ * This function is intended to be used in the start_element and
+ * end_element handlers where g_markup_parse_context_get_element()
+ * would merely return the name of the element that is being
+ * processed.
+ *
+ * Returns: the element stack, which must not be modified
+ *
+ * Since: 2.16
+ **/
+G_CONST_RETURN GSList *
+g_markup_parse_context_get_element_stack (GMarkupParseContext *context)
+{
+  g_return_val_if_fail (context != NULL, NULL);
+  return context->tag_stack;
+}
+
+/**
+ * g_markup_parse_context_get_position:
+ * @context: a #GMarkupParseContext
+ * @line_number: return location for a line number, or %NULL
+ * @char_number: return location for a char-on-line number, or %NULL
+ *
+ * Retrieves the current line number and the number of the character on
+ * that line. Intended for use in error messages; there are no strict
+ * semantics for what constitutes the "current" line number other than
+ * "the best number we could come up with for error messages."
+ * 
+ **/
+void
+g_markup_parse_context_get_position (GMarkupParseContext *context,
+                                     gint                *line_number,
+                                     gint                *char_number)
+{
+  g_return_if_fail (context != NULL);
+
+  if (line_number)
+    *line_number = context->line_number;
+
+  if (char_number)
+    *char_number = context->char_number;
+}
+
+/**
+ * g_markup_parse_context_get_user_data:
+ * @context: a #GMarkupParseContext
+ *
+ * Returns the user_data associated with @context.  This will either
+ * be the user_data that was provided to g_markup_parse_context_new()
+ * or to the most recent call of g_markup_parse_context_push().
+ *
+ * Returns: the provided user_data. The returned data belongs to
+ *     the markup context and will be freed when g_markup_context_free()
+ *     is called.
+ *
+ * Since: 2.18
+ **/
+gpointer
+g_markup_parse_context_get_user_data (GMarkupParseContext *context)
+{
+  return context->user_data;
+}
+
+/**
+ * g_markup_parse_context_push:
+ * @context: a #GMarkupParseContext
+ * @parser: a #GMarkupParser
+ * @user_data: user data to pass to #GMarkupParser functions
+ *
+ * Temporarily redirects markup data to a sub-parser.
+ *
+ * This function may only be called from the start_element handler of
+ * a #GMarkupParser.  It must be matched with a corresponding call to
+ * g_markup_parse_context_pop() in the matching end_element handler
+ * (except in the case that the parser aborts due to an error).
+ *
+ * All tags, text and other data between the matching tags is
+ * redirected to the subparser given by @parser.  @user_data is used
+ * as the user_data for that parser.  @user_data is also passed to the
+ * error callback in the event that an error occurs.  This includes
+ * errors that occur in subparsers of the subparser.
+ *
+ * The end tag matching the start tag for which this call was made is
+ * handled by the previous parser (which is given its own user_data)
+ * which is why g_markup_parse_context_pop() is provided to allow "one
+ * last access" to the @user_data provided to this function.  In the
+ * case of error, the @user_data provided here is passed directly to
+ * the error callback of the subparser and g_markup_parse_context()
+ * should not be called.  In either case, if @user_data was allocated
+ * then it ought to be freed from both of these locations.
+ *
+ * This function is not intended to be directly called by users
+ * interested in invoking subparsers.  Instead, it is intended to be
+ * used by the subparsers themselves to implement a higher-level
+ * interface.
+ *
+ * As an example, see the following implementation of a simple
+ * parser that counts the number of tags encountered.
+ *
+ * |[
+ * typedef struct
+ * {
+ *   gint tag_count;
+ * } CounterData;
+ * 
+ * static void
+ * counter_start_element (GMarkupParseContext  *context,
+ *                        const gchar          *element_name,
+ *                        const gchar         **attribute_names,
+ *                        const gchar         **attribute_values,
+ *                        gpointer              user_data,
+ *                        GError              **error)
+ * {
+ *   CounterData *data = user_data;
+ * 
+ *   data->tag_count++;
+ * }
+ * 
+ * static void
+ * counter_error (GMarkupParseContext *context,
+ *                GError              *error,
+ *                gpointer             user_data)
+ * {
+ *   CounterData *data = user_data;
+ * 
+ *   g_slice_free (CounterData, data);
+ * }
+ * 
+ * static GMarkupParser counter_subparser =
+ * {
+ *   counter_start_element,
+ *   NULL,
+ *   NULL,
+ *   NULL,
+ *   counter_error
+ * };
+ * ]|
+ *
+ * In order to allow this parser to be easily used as a subparser, the
+ * following interface is provided:
+ *
+ * |[
+ * void
+ * start_counting (GMarkupParseContext *context)
+ * {
+ *   CounterData *data = g_slice_new (CounterData);
+ * 
+ *   data->tag_count = 0;
+ *   g_markup_parse_context_push (context, &counter_subparser, data);
+ * }
+ * 
+ * gint
+ * end_counting (GMarkupParseContext *context)
+ * {
+ *   CounterData *data = g_markup_parse_context_pop (context);
+ *   int result;
+ * 
+ *   result = data->tag_count;
+ *   g_slice_free (CounterData, data);
+ * 
+ *   return result;
+ * }
+ * ]|
+ *
+ * The subparser would then be used as follows:
+ *
+ * |[
+ * static void start_element (context, element_name, ...)
+ * {
+ *   if (strcmp (element_name, "count-these") == 0)
+ *     start_counting (context);
+ * 
+ *   /&ast; else, handle other tags... &ast;/
+ * }
+ * 
+ * static void end_element (context, element_name, ...)
+ * {
+ *   if (strcmp (element_name, "count-these") == 0)
+ *     g_print ("Counted %d tags\n", end_counting (context));
+ * 
+ *   /&ast; else, handle other tags... &ast;/
+ * }
+ * ]|
+ *
+ * Since: 2.18
+ **/
+void
+g_markup_parse_context_push (GMarkupParseContext *context,
+                             const GMarkupParser *parser,
+                             gpointer             user_data)
+{
+  GMarkupRecursionTracker *tracker;
+
+  tracker = g_slice_new (GMarkupRecursionTracker);
+  tracker->prev_element = context->subparser_element;
+  tracker->prev_parser = context->parser;
+  tracker->prev_user_data = context->user_data;
+
+  context->subparser_element = current_element (context);
+  context->parser = parser;
+  context->user_data = user_data;
+
+  context->subparser_stack = g_slist_prepend (context->subparser_stack,
+                                              tracker);
+}
+
+/**
+ * g_markup_parse_context_pop:
+ * @context: a #GMarkupParseContext
+ *
+ * Completes the process of a temporary sub-parser redirection.
+ *
+ * This function exists to collect the user_data allocated by a
+ * matching call to g_markup_parse_context_push().  It must be called
+ * in the end_element handler corresponding to the start_element
+ * handler during which g_markup_parse_context_push() was called.  You
+ * must not call this function from the error callback -- the
+ * @user_data is provided directly to the callback in that case.
+ *
+ * This function is not intended to be directly called by users
+ * interested in invoking subparsers.  Instead, it is intended to be
+ * used by the subparsers themselves to implement a higher-level
+ * interface.
+ *
+ * Returns: the user_data passed to g_markup_parse_context_push().
+ *
+ * Since: 2.18
+ **/
+gpointer
+g_markup_parse_context_pop (GMarkupParseContext *context)
+{
+  gpointer user_data;
+
+  if (!context->awaiting_pop)
+    possibly_finish_subparser (context);
+
+  g_assert (context->awaiting_pop);
+
+  context->awaiting_pop = FALSE;
+  
+  /* valgrind friendliness */
+  user_data = context->held_user_data;
+  context->held_user_data = NULL;
+
+  return user_data;
+}
+
+static void
+append_escaped_text (GString     *str,
+                     const gchar *text,
+                     gssize       length)    
+{
+  const gchar *p;
+  const gchar *end;
+  gunichar c;
+
+  p = text;
+  end = text + length;
+
+  while (p != end)
+    {
+      const gchar *next;
+      next = g_utf8_next_char (p);
+
+      switch (*p)
+        {
+        case '&':
+          g_string_append (str, "&amp;");
+          break;
+
+        case '<':
+          g_string_append (str, "&lt;");
+          break;
+
+        case '>':
+          g_string_append (str, "&gt;");
+          break;
+
+        case '\'':
+          g_string_append (str, "&apos;");
+          break;
+
+        case '"':
+          g_string_append (str, "&quot;");
+          break;
+
+        default:
+          c = g_utf8_get_char (p);
+          if ((0x1 <= c && c <= 0x8) ||
+              (0xb <= c && c  <= 0xc) ||
+              (0xe <= c && c <= 0x1f) ||
+              (0x7f <= c && c <= 0x84) ||
+              (0x86 <= c && c <= 0x9f))
+            g_string_append_printf (str, "&#x%x;", c);
+          else
+            g_string_append_len (str, p, next - p);
+          break;
+        }
+
+      p = next;
+    }
+}
+
+/**
+ * g_markup_escape_text:
+ * @text: some valid UTF-8 text
+ * @length: length of @text in bytes, or -1 if the text is nul-terminated
+ * 
+ * Escapes text so that the markup parser will parse it verbatim.
+ * Less than, greater than, ampersand, etc. are replaced with the
+ * corresponding entities. This function would typically be used
+ * when writing out a file to be parsed with the markup parser.
+ * 
+ * Note that this function doesn't protect whitespace and line endings
+ * from being processed according to the XML rules for normalization
+ * of line endings and attribute values.
+ *
+ * Note also that this function will produce character references in
+ * the range of &amp;#x1; ... &amp;#x1f; for all control sequences
+ * except for tabstop, newline and carriage return.  The character
+ * references in this range are not valid XML 1.0, but they are
+ * valid XML 1.1 and will be accepted by the GMarkup parser.
+ * 
+ * Return value: a newly allocated string with the escaped text
+ **/
+gchar*
+g_markup_escape_text (const gchar *text,
+                      gssize       length)  
+{
+  GString *str;
+
+  g_return_val_if_fail (text != NULL, NULL);
+
+  if (length < 0)
+    length = strlen (text);
+
+  /* prealloc at least as long as original text */
+  str = g_string_sized_new (length);
+  append_escaped_text (str, text, length);
+
+  return g_string_free (str, FALSE);
+}
+
+/**
+ * find_conversion:
+ * @format: a printf-style format string
+ * @after: location to store a pointer to the character after
+ *   the returned conversion. On a %NULL return, returns the
+ *   pointer to the trailing NUL in the string
+ * 
+ * Find the next conversion in a printf-style format string.
+ * Partially based on code from printf-parser.c,
+ * Copyright (C) 1999-2000, 2002-2003 Free Software Foundation, Inc.
+ * 
+ * Return value: pointer to the next conversion in @format,
+ *  or %NULL, if none.
+ **/
+static const char *
+find_conversion (const char  *format,
+                const char **after)
+{
+  const char *start = format;
+  const char *cp;
+  
+  while (*start != '\0' && *start != '%')
+    start++;
+
+  if (*start == '\0')
+    {
+      *after = start;
+      return NULL;
+    }
+
+  cp = start + 1;
+
+  if (*cp == '\0')
+    {
+      *after = cp;
+      return NULL;
+    }
+  
+  /* Test for positional argument.  */
+  if (*cp >= '0' && *cp <= '9')
+    {
+      const char *np;
+      
+      for (np = cp; *np >= '0' && *np <= '9'; np++)
+       ;
+      if (*np == '$')
+       cp = np + 1;
+    }
+
+  /* Skip the flags.  */
+  for (;;)
+    {
+      if (*cp == '\'' ||
+         *cp == '-' ||
+         *cp == '+' ||
+         *cp == ' ' ||
+         *cp == '#' ||
+         *cp == '0')
+       cp++;
+      else
+       break;
+    }
+
+  /* Skip the field width.  */
+  if (*cp == '*')
+    {
+      cp++;
+
+      /* Test for positional argument.  */
+      if (*cp >= '0' && *cp <= '9')
+       {
+         const char *np;
+
+         for (np = cp; *np >= '0' && *np <= '9'; np++)
+           ;
+         if (*np == '$')
+           cp = np + 1;
+       }
+    }
+  else
+    {
+      for (; *cp >= '0' && *cp <= '9'; cp++)
+       ;
+    }
+
+  /* Skip the precision.  */
+  if (*cp == '.')
+    {
+      cp++;
+      if (*cp == '*')
+       {
+         /* Test for positional argument.  */
+         if (*cp >= '0' && *cp <= '9')
+           {
+             const char *np;
+
+             for (np = cp; *np >= '0' && *np <= '9'; np++)
+               ;
+             if (*np == '$')
+               cp = np + 1;
+           }
+       }
+      else
+       {
+         for (; *cp >= '0' && *cp <= '9'; cp++)
+           ;
+       }
+    }
+
+  /* Skip argument type/size specifiers.  */
+  while (*cp == 'h' ||
+        *cp == 'L' ||
+        *cp == 'l' ||
+        *cp == 'j' ||
+        *cp == 'z' ||
+        *cp == 'Z' ||
+        *cp == 't')
+    cp++;
+         
+  /* Skip the conversion character.  */
+  cp++;
+
+  *after = cp;
+  return start;
+}
+
+/**
+ * g_markup_vprintf_escaped:
+ * @format: printf() style format string
+ * @args: variable argument list, similar to vprintf()
+ * 
+ * Formats the data in @args according to @format, escaping
+ * all string and character arguments in the fashion
+ * of g_markup_escape_text(). See g_markup_printf_escaped().
+ * 
+ * Return value: newly allocated result from formatting
+ *  operation. Free with g_free().
+ *
+ * Since: 2.4
+ **/
+char *
+g_markup_vprintf_escaped (const char *format,
+                         va_list     args)
+{
+  GString *format1;
+  GString *format2;
+  GString *result = NULL;
+  gchar *output1 = NULL;
+  gchar *output2 = NULL;
+  const char *p, *op1, *op2;
+  va_list args2;
+
+  /* The technique here, is that we make two format strings that
+   * have the identical conversions in the identical order to the
+   * original strings, but differ in the text in-between. We
+   * then use the normal g_strdup_vprintf() to format the arguments
+   * with the two new format strings. By comparing the results,
+   * we can figure out what segments of the output come from
+   * the the original format string, and what from the arguments,
+   * and thus know what portions of the string to escape.
+   *
+   * For instance, for:
+   *
+   *  g_markup_printf_escaped ("%s ate %d apples", "Susan & Fred", 5);
+   *
+   * We form the two format strings "%sX%dX" and %sY%sY". The results
+   * of formatting with those two strings are
+   *
+   * "%sX%dX" => "Susan & FredX5X"
+   * "%sY%dY" => "Susan & FredY5Y"
+   *
+   * To find the span of the first argument, we find the first position
+   * where the two arguments differ, which tells us that the first
+   * argument formatted to "Susan & Fred". We then escape that
+   * to "Susan &amp; Fred" and join up with the intermediate portions
+   * of the format string and the second argument to get
+   * "Susan &amp; Fred ate 5 apples".
+   */
+
+  /* Create the two modified format strings
+   */
+  format1 = g_string_new (NULL);
+  format2 = g_string_new (NULL);
+  p = format;
+  while (TRUE)
+    {
+      const char *after;
+      const char *conv = find_conversion (p, &after);
+      if (!conv)
+       break;
+
+      g_string_append_len (format1, conv, after - conv);
+      g_string_append_c (format1, 'X');
+      g_string_append_len (format2, conv, after - conv);
+      g_string_append_c (format2, 'Y');
+
+      p = after;
+    }
+
+  /* Use them to format the arguments
+   */
+  G_VA_COPY (args2, args);
+  
+  output1 = g_strdup_vprintf (format1->str, args);
+  if (!output1)
+    {
+      va_end (args2);
+      goto cleanup;
+    }
+  
+  output2 = g_strdup_vprintf (format2->str, args2);
+  va_end (args2);
+  if (!output2)
+    goto cleanup;
+
+  result = g_string_new (NULL);
+
+  /* Iterate through the original format string again,
+   * copying the non-conversion portions and the escaped
+   * converted arguments to the output string.
+   */
+  op1 = output1;
+  op2 = output2;
+  p = format;
+  while (TRUE)
+    {
+      const char *after;
+      const char *output_start;
+      const char *conv = find_conversion (p, &after);
+      char *escaped;
+      
+      if (!conv)       /* The end, after points to the trailing \0 */
+       {
+         g_string_append_len (result, p, after - p);
+         break;
+       }
+
+      g_string_append_len (result, p, conv - p);
+      output_start = op1;
+      while (*op1 == *op2)
+       {
+         op1++;
+         op2++;
+       }
+      
+      escaped = g_markup_escape_text (output_start, op1 - output_start);
+      g_string_append (result, escaped);
+      g_free (escaped);
+      
+      p = after;
+      op1++;
+      op2++;
+    }
+
+ cleanup:
+  g_string_free (format1, TRUE);
+  g_string_free (format2, TRUE);
+  g_free (output1);
+  g_free (output2);
+
+  if (result)
+    return g_string_free (result, FALSE);
+  else
+    return NULL;
+}
+
+/**
+ * g_markup_printf_escaped:
+ * @format: printf() style format string
+ * @Varargs: the arguments to insert in the format string
+ * 
+ * Formats arguments according to @format, escaping
+ * all string and character arguments in the fashion
+ * of g_markup_escape_text(). This is useful when you
+ * want to insert literal strings into XML-style markup
+ * output, without having to worry that the strings
+ * might themselves contain markup.
+ *
+ * |[
+ * const char *store = "Fortnum &amp; Mason";
+ * const char *item = "Tea";
+ * char *output;
+ * &nbsp;
+ * output = g_markup_printf_escaped ("&lt;purchase&gt;"
+ *                                   "&lt;store&gt;&percnt;s&lt;/store&gt;"
+ *                                   "&lt;item&gt;&percnt;s&lt;/item&gt;"
+ *                                   "&lt;/purchase&gt;",
+ *                                   store, item);
+ * ]|
+ * 
+ * Return value: newly allocated result from formatting
+ *  operation. Free with g_free().
+ *
+ * Since: 2.4
+ **/
+char *
+g_markup_printf_escaped (const char *format, ...)
+{
+  char *result;
+  va_list args;
+  
+  va_start (args, format);
+  result = g_markup_vprintf_escaped (format, args);
+  va_end (args);
+
+  return result;
+}
+
+static gboolean
+g_markup_parse_boolean (const char  *string,
+                        gboolean    *value)
+{
+  char const * const falses[] = { "false", "f", "no", "n", "0" };
+  char const * const trues[] = { "true", "t", "yes", "y", "1" };
+  int i;
+
+  for (i = 0; i < G_N_ELEMENTS (falses); i++)
+    {
+      if (g_ascii_strcasecmp (string, falses[i]) == 0)
+        {
+          if (value != NULL)
+            *value = FALSE;
+
+          return TRUE;
+        }
+    }
+
+  for (i = 0; i < G_N_ELEMENTS (trues); i++)
+    {
+      if (g_ascii_strcasecmp (string, trues[i]) == 0)
+        {
+          if (value != NULL)
+            *value = TRUE;
+
+          return TRUE;
+        }
+    }
+
+  return FALSE;
+}
+
+/**
+ * GMarkupCollectType:
+ * @G_MARKUP_COLLECT_INVALID: used to terminate the list of attributes
+ *                            to collect.
+ * @G_MARKUP_COLLECT_STRING: collect the string pointer directly from
+ *                           the attribute_values[] array.  Expects a
+ *                           parameter of type (const char **).  If
+ *                           %G_MARKUP_COLLECT_OPTIONAL is specified
+ *                           and the attribute isn't present then the
+ *                           pointer will be set to %NULL.
+ * @G_MARKUP_COLLECT_STRDUP: as with %G_MARKUP_COLLECT_STRING, but
+ *                           expects a parameter of type (char **) and
+ *                           g_strdup()s the returned pointer.  The
+ *                           pointer must be freed with g_free().
+ * @G_MARKUP_COLLECT_BOOLEAN: expects a parameter of type (gboolean *)
+ *                            and parses the attribute value as a
+ *                            boolean.  Sets %FALSE if the attribute
+ *                            isn't present.  Valid boolean values
+ *                            consist of (case insensitive) "false",
+ *                            "f", "no", "n", "0" and "true", "t",
+ *                            "yes", "y", "1".
+ * @G_MARKUP_COLLECT_TRISTATE: as with %G_MARKUP_COLLECT_BOOLEAN, but
+ *                             in the case of a missing attribute a
+ *                             value is set that compares equal to
+ *                             neither %FALSE nor %TRUE.
+ *                             G_MARKUP_COLLECT_OPTIONAL is implied.
+ * @G_MARKUP_COLLECT_OPTIONAL: can be bitwise ORed with the other
+ *                             fields.  If present, allows the
+ *                             attribute not to appear.  A default
+ *                             value is set depending on what value
+ *                             type is used.
+ *
+ * A mixed enumerated type and flags field.  You must specify one type
+ * (string, strdup, boolean, tristate).  Additionally, you may
+ * optionally bitwise OR the type with the flag
+ * %G_MARKUP_COLLECT_OPTIONAL.
+ *
+ * It is likely that this enum will be extended in the future to
+ * support other types.
+ **/
+
+/**
+ * g_markup_collect_attributes:
+ * @element_name: the current tag name
+ * @attribute_names: the attribute names
+ * @attribute_values: the attribute values
+ * @error: a pointer to a #GError or %NULL
+ * @first_type: the #GMarkupCollectType of the
+ *              first attribute
+ * @first_attr: the name of the first attribute
+ * @...: a pointer to the storage location of the
+ *       first attribute (or %NULL), followed by
+ *       more types names and pointers, ending
+ *       with %G_MARKUP_COLLECT_INVALID.
+ * 
+ * Collects the attributes of the element from the
+ * data passed to the #GMarkupParser start_element
+ * function, dealing with common error conditions
+ * and supporting boolean values.
+ *
+ * This utility function is not required to write
+ * a parser but can save a lot of typing.
+ *
+ * The @element_name, @attribute_names,
+ * @attribute_values and @error parameters passed
+ * to the start_element callback should be passed
+ * unmodified to this function.
+ *
+ * Following these arguments is a list of
+ * "supported" attributes to collect.  It is an
+ * error to specify multiple attributes with the
+ * same name.  If any attribute not in the list
+ * appears in the @attribute_names array then an
+ * unknown attribute error will result.
+ *
+ * The #GMarkupCollectType field allows specifying
+ * the type of collection to perform and if a
+ * given attribute must appear or is optional.
+ *
+ * The attribute name is simply the name of the
+ * attribute to collect.
+ *
+ * The pointer should be of the appropriate type
+ * (see the descriptions under
+ * #GMarkupCollectType) and may be %NULL in case a
+ * particular attribute is to be allowed but
+ * ignored.
+ *
+ * This function deals with issuing errors for missing attributes 
+ * (of type %G_MARKUP_ERROR_MISSING_ATTRIBUTE), unknown attributes 
+ * (of type %G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE) and duplicate 
+ * attributes (of type %G_MARKUP_ERROR_INVALID_CONTENT) as well 
+ * as parse errors for boolean-valued attributes (again of type
+ * %G_MARKUP_ERROR_INVALID_CONTENT). In all of these cases %FALSE 
+ * will be returned and @error will be set as appropriate.
+ *
+ * Return value: %TRUE if successful
+ *
+ * Since: 2.16
+ **/
+gboolean
+g_markup_collect_attributes (const gchar         *element_name,
+                             const gchar        **attribute_names,
+                             const gchar        **attribute_values,
+                             GError             **error,
+                             GMarkupCollectType   first_type,
+                             const gchar         *first_attr,
+                             ...)
+{
+  GMarkupCollectType type;
+  const gchar *attr;
+  guint64 collected;
+  int written;
+  va_list ap;
+  int i;
+
+  type = first_type;
+  attr = first_attr;
+  collected = 0;
+  written = 0;
+
+  va_start (ap, first_attr);
+  while (type != G_MARKUP_COLLECT_INVALID)
+    {
+      gboolean mandatory;
+      const gchar *value;
+
+      mandatory = !(type & G_MARKUP_COLLECT_OPTIONAL);
+      type &= (G_MARKUP_COLLECT_OPTIONAL - 1);
+
+      /* tristate records a value != TRUE and != FALSE
+       * for the case where the attribute is missing
+       */
+      if (type == G_MARKUP_COLLECT_TRISTATE)
+        mandatory = FALSE;
+
+      for (i = 0; attribute_names[i]; i++)
+        if (i >= 40 || !(collected & (G_GUINT64_CONSTANT(1) << i)))
+          if (!strcmp (attribute_names[i], attr))
+            break;
+
+      /* ISO C99 only promises that the user can pass up to 127 arguments.
+       * Subtracting the first 4 arguments plus the final NULL and dividing
+       * by 3 arguments per collected attribute, we are left with a maximum
+       * number of supported attributes of (127 - 5) / 3 = 40.
+       *
+       * In reality, nobody is ever going to call us with anywhere close to
+       * 40 attributes to collect, so it is safe to assume that if i > 40
+       * then the user has given some invalid or repeated arguments.  These
+       * problems will be caught and reported at the end of the function.
+       *
+       * We know at this point that we have an error, but we don't know
+       * what error it is, so just continue...
+       */
+      if (i < 40)
+        collected |= (G_GUINT64_CONSTANT(1) << i);
+
+      value = attribute_values[i];
+
+      if (value == NULL && mandatory)
+        {
+          g_set_error (error, G_MARKUP_ERROR,
+                       G_MARKUP_ERROR_MISSING_ATTRIBUTE,
+                       "element '%s' requires attribute '%s'",
+                       element_name, attr);
+
+          va_end (ap);
+          goto failure;
+        }
+
+      switch (type)
+        {
+        case G_MARKUP_COLLECT_STRING:
+          {
+            const char **str_ptr;
+
+            str_ptr = va_arg (ap, const char **);
+
+            if (str_ptr != NULL)
+              *str_ptr = value;
+          }
+          break;
+
+        case G_MARKUP_COLLECT_STRDUP:
+          {
+            char **str_ptr;
+
+            str_ptr = va_arg (ap, char **);
+
+            if (str_ptr != NULL)
+              *str_ptr = g_strdup (value);
+          }
+          break;
+
+        case G_MARKUP_COLLECT_BOOLEAN:
+        case G_MARKUP_COLLECT_TRISTATE:
+          if (value == NULL)
+            {
+              gboolean *bool_ptr;
+
+              bool_ptr = va_arg (ap, gboolean *);
+
+              if (bool_ptr != NULL)
+                {
+                  if (type == G_MARKUP_COLLECT_TRISTATE)
+                    /* constructivists rejoice!
+                     * neither false nor true...
+                     */
+                    *bool_ptr = -1;
+
+                  else /* G_MARKUP_COLLECT_BOOLEAN */
+                    *bool_ptr = FALSE;
+                }
+            }
+          else
+            {
+              if (!g_markup_parse_boolean (value, va_arg (ap, gboolean *)))
+                {
+                  g_set_error (error, G_MARKUP_ERROR,
+                               G_MARKUP_ERROR_INVALID_CONTENT,
+                               "element '%s', attribute '%s', value '%s' "
+                               "cannot be parsed as a boolean value",
+                               element_name, attr, value);
+
+                  va_end (ap);
+                  goto failure;
+                }
+            }
+
+          break;
+
+        default:
+          g_assert_not_reached ();
+        }
+
+      type = va_arg (ap, GMarkupCollectType);
+      attr = va_arg (ap, const char *);
+      written++;
+    }
+  va_end (ap);
+
+  /* ensure we collected all the arguments */
+  for (i = 0; attribute_names[i]; i++)
+    if ((collected & (G_GUINT64_CONSTANT(1) << i)) == 0)
+      {
+        /* attribute not collected:  could be caused by two things.
+         *
+         * 1) it doesn't exist in our list of attributes
+         * 2) it existed but was matched by a duplicate attribute earlier
+         *
+         * find out.
+         */
+        int j;
+
+        for (j = 0; j < i; j++)
+          if (strcmp (attribute_names[i], attribute_names[j]) == 0)
+            /* duplicate! */
+            break;
+
+        /* j is now the first occurrence of attribute_names[i] */
+        if (i == j)
+          g_set_error (error, G_MARKUP_ERROR,
+                       G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
+                       "attribute '%s' invalid for element '%s'",
+                       attribute_names[i], element_name);
+        else
+          g_set_error (error, G_MARKUP_ERROR,
+                       G_MARKUP_ERROR_INVALID_CONTENT,
+                       "attribute '%s' given multiple times for element '%s'",
+                       attribute_names[i], element_name);
+
+        goto failure;
+      }
+
+  return TRUE;
+
+failure:
+  /* replay the above to free allocations */
+  type = first_type;
+  attr = first_attr;
+
+  va_start (ap, first_attr);
+  while (type != G_MARKUP_COLLECT_INVALID)
+    {
+      gpointer ptr;
+
+      ptr = va_arg (ap, gpointer);
+
+      if (ptr == NULL)
+        continue;
+
+      switch (type & (G_MARKUP_COLLECT_OPTIONAL - 1))
+        {
+        case G_MARKUP_COLLECT_STRDUP:
+          if (written)
+            g_free (*(char **) ptr);
+
+        case G_MARKUP_COLLECT_STRING:
+          *(char **) ptr = NULL;
+          break;
+
+        case G_MARKUP_COLLECT_BOOLEAN:
+          *(gboolean *) ptr = FALSE;
+          break;
+
+        case G_MARKUP_COLLECT_TRISTATE:
+          *(gboolean *) ptr = -1;
+          break;
+        }
+
+      type = va_arg (ap, GMarkupCollectType);
+      attr = va_arg (ap, const char *);
+
+      if (written)
+        written--;
+    }
+  va_end (ap);
+
+  return FALSE;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gmarkup.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gmarkup.h
new file mode 100644 (file)
index 0000000..7bfc086
--- /dev/null
@@ -0,0 +1,163 @@
+/* gmarkup.h - Simple XML-like string parser/writer
+ *
+ *  Copyright 2000 Red Hat, Inc.
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *   Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_MARKUP_H__
+#define __G_MARKUP_H__
+
+#include <stdarg.h>
+
+#include <glib/gerror.h>
+#include <glib/gslist.h>
+
+G_BEGIN_DECLS
+
+typedef enum
+{
+  G_MARKUP_ERROR_BAD_UTF8,
+  G_MARKUP_ERROR_EMPTY,
+  G_MARKUP_ERROR_PARSE,
+  /* The following are primarily intended for specific GMarkupParser
+   * implementations to set.
+   */
+  G_MARKUP_ERROR_UNKNOWN_ELEMENT,
+  G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE,
+  G_MARKUP_ERROR_INVALID_CONTENT,
+  G_MARKUP_ERROR_MISSING_ATTRIBUTE
+} GMarkupError;
+
+#define G_MARKUP_ERROR g_markup_error_quark ()
+
+GQuark g_markup_error_quark (void);
+
+typedef enum
+{
+  G_MARKUP_DO_NOT_USE_THIS_UNSUPPORTED_FLAG = 1 << 0,
+  G_MARKUP_TREAT_CDATA_AS_TEXT              = 1 << 1,
+  G_MARKUP_PREFIX_ERROR_POSITION            = 1 << 2
+} GMarkupParseFlags;
+
+typedef struct _GMarkupParseContext GMarkupParseContext;
+typedef struct _GMarkupParser GMarkupParser;
+
+struct _GMarkupParser
+{
+  /* Called for open tags <foo bar="baz"> */
+  void (*start_element)  (GMarkupParseContext *context,
+                          const gchar         *element_name,
+                          const gchar        **attribute_names,
+                          const gchar        **attribute_values,
+                          gpointer             user_data,
+                          GError             **error);
+
+  /* Called for close tags </foo> */
+  void (*end_element)    (GMarkupParseContext *context,
+                          const gchar         *element_name,
+                          gpointer             user_data,
+                          GError             **error);
+
+  /* Called for character data */
+  /* text is not nul-terminated */
+  void (*text)           (GMarkupParseContext *context,
+                          const gchar         *text,
+                          gsize                text_len,  
+                          gpointer             user_data,
+                          GError             **error);
+
+  /* Called for strings that should be re-saved verbatim in this same
+   * position, but are not otherwise interpretable.  At the moment
+   * this includes comments and processing instructions.
+   */
+  /* text is not nul-terminated. */
+  void (*passthrough)    (GMarkupParseContext *context,
+                          const gchar         *passthrough_text,
+                          gsize                text_len,  
+                          gpointer             user_data,
+                          GError             **error);
+
+  /* Called on error, including one set by other
+   * methods in the vtable. The GError should not be freed.
+   */
+  void (*error)          (GMarkupParseContext *context,
+                          GError              *error,
+                          gpointer             user_data);
+};
+
+GMarkupParseContext *g_markup_parse_context_new   (const GMarkupParser *parser,
+                                                   GMarkupParseFlags    flags,
+                                                   gpointer             user_data,
+                                                   GDestroyNotify       user_data_dnotify);
+void                 g_markup_parse_context_free  (GMarkupParseContext *context);
+gboolean             g_markup_parse_context_parse (GMarkupParseContext *context,
+                                                   const gchar         *text,
+                                                   gssize               text_len,  
+                                                   GError             **error);
+void                 g_markup_parse_context_push  (GMarkupParseContext *context,
+                                                   const GMarkupParser *parser,
+                                                   gpointer             user_data);
+gpointer             g_markup_parse_context_pop   (GMarkupParseContext *context);
+                                                   
+gboolean             g_markup_parse_context_end_parse (GMarkupParseContext *context,
+                                                       GError             **error);
+G_CONST_RETURN gchar *g_markup_parse_context_get_element (GMarkupParseContext *context);
+G_CONST_RETURN GSList *g_markup_parse_context_get_element_stack (GMarkupParseContext *context);
+
+/* For user-constructed error messages, has no precise semantics */
+void                 g_markup_parse_context_get_position (GMarkupParseContext *context,
+                                                          gint                *line_number,
+                                                          gint                *char_number);
+gpointer             g_markup_parse_context_get_user_data (GMarkupParseContext *context);
+
+/* useful when saving */
+gchar* g_markup_escape_text (const gchar *text,
+                             gssize       length);  
+
+gchar *g_markup_printf_escaped (const char *format,
+                               ...) G_GNUC_PRINTF (1, 2);
+gchar *g_markup_vprintf_escaped (const char *format,
+                                va_list     args);
+
+typedef enum
+{
+  G_MARKUP_COLLECT_INVALID,
+  G_MARKUP_COLLECT_STRING,
+  G_MARKUP_COLLECT_STRDUP,
+  G_MARKUP_COLLECT_BOOLEAN,
+  G_MARKUP_COLLECT_TRISTATE,
+
+  G_MARKUP_COLLECT_OPTIONAL = (1 << 16)
+} GMarkupCollectType;
+
+
+/* useful from start_element */
+gboolean   g_markup_collect_attributes (const gchar         *element_name,
+                                        const gchar        **attribute_names,
+                                        const gchar        **attribute_values,
+                                        GError             **error,
+                                        GMarkupCollectType   first_type,
+                                        const gchar         *first_attr,
+                                        ...);
+
+G_END_DECLS
+
+#endif /* __G_MARKUP_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gmem.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gmem.c
new file mode 100644 (file)
index 0000000..7212ae4
--- /dev/null
@@ -0,0 +1,1397 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/* 
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "gmem.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <signal.h>
+
+#include "gbacktrace.h"
+#include "gtestutils.h"
+#include "gthread.h"
+#include "glib_trace.h"
+
+
+#define MEM_PROFILE_TABLE_SIZE 4096
+
+
+/* notes on macros:
+ * having G_DISABLE_CHECKS defined disables use of glib_mem_profiler_table and
+ * g_mem_profile().
+ * REALLOC_0_WORKS is defined if g_realloc (NULL, x) works.
+ * SANE_MALLOC_PROTOS is defined if the systems malloc() and friends functions
+ * match the corresponding GLib prototypes, keep configure.ac and gmem.h in sync here.
+ * g_mem_gc_friendly is TRUE, freed memory should be 0-wiped.
+ */
+
+/* --- prototypes --- */
+static gboolean g_mem_initialized = FALSE;
+static void     g_mem_init_nomessage (void);
+
+
+/* --- malloc wrappers --- */
+#ifndef        REALLOC_0_WORKS
+static gpointer
+standard_realloc (gpointer mem,
+                 gsize    n_bytes)
+{
+  if (!mem)
+    return malloc (n_bytes);
+  else
+    return realloc (mem, n_bytes);
+}
+#endif /* !REALLOC_0_WORKS */
+
+#ifdef SANE_MALLOC_PROTOS
+#  define standard_malloc      malloc
+#  ifdef REALLOC_0_WORKS
+#    define standard_realloc   realloc
+#  endif /* REALLOC_0_WORKS */
+#  define standard_free                free
+#  define standard_calloc      calloc
+#  define standard_try_malloc  malloc
+#  define standard_try_realloc realloc
+#else  /* !SANE_MALLOC_PROTOS */
+static gpointer
+standard_malloc (gsize n_bytes)
+{
+  return malloc (n_bytes);
+}
+#  ifdef REALLOC_0_WORKS
+static gpointer
+standard_realloc (gpointer mem,
+                 gsize    n_bytes)
+{
+  return realloc (mem, n_bytes);
+}
+#  endif /* REALLOC_0_WORKS */
+static void
+standard_free (gpointer mem)
+{
+  free (mem);
+}
+static gpointer
+standard_calloc (gsize n_blocks,
+                gsize n_bytes)
+{
+  return calloc (n_blocks, n_bytes);
+}
+#define        standard_try_malloc     standard_malloc
+#define        standard_try_realloc    standard_realloc
+#endif /* !SANE_MALLOC_PROTOS */
+
+
+/* --- variables --- */
+static GMemVTable glib_mem_vtable = {
+  standard_malloc,
+  standard_realloc,
+  standard_free,
+  standard_calloc,
+  standard_try_malloc,
+  standard_try_realloc,
+};
+
+/**
+ * SECTION:memory
+ * @Short_Description: general memory-handling
+ * @Title: Memory Allocation
+ * 
+ * These functions provide support for allocating and freeing memory.
+ * 
+ * <note>
+ * If any call to allocate memory fails, the application is terminated.
+ * This also means that there is no need to check if the call succeeded.
+ * </note>
+ * 
+ * <note>
+ * It's important to match g_malloc() with g_free(), plain malloc() with free(),
+ * and (if you're using C++) new with delete and new[] with delete[]. Otherwise
+ * bad things can happen, since these allocators may use different memory
+ * pools (and new/delete call constructors and destructors). See also
+ * g_mem_set_vtable().
+ * </note>
+ */
+
+/* --- functions --- */
+/**
+ * g_malloc:
+ * @n_bytes: the number of bytes to allocate
+ * 
+ * Allocates @n_bytes bytes of memory.
+ * If @n_bytes is 0 it returns %NULL.
+ * 
+ * Returns: a pointer to the allocated memory
+ */
+gpointer
+g_malloc (gsize n_bytes)
+{
+  if (G_UNLIKELY (!g_mem_initialized))
+    g_mem_init_nomessage();
+  if (G_LIKELY (n_bytes))
+    {
+      gpointer mem;
+
+      mem = glib_mem_vtable.malloc (n_bytes);
+      TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 0));
+      if (mem)
+       return mem;
+
+      g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
+               G_STRLOC, n_bytes);
+    }
+
+  TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 0, 0));
+
+  return NULL;
+}
+
+/**
+ * g_malloc0:
+ * @n_bytes: the number of bytes to allocate
+ * 
+ * Allocates @n_bytes bytes of memory, initialized to 0's.
+ * If @n_bytes is 0 it returns %NULL.
+ * 
+ * Returns: a pointer to the allocated memory
+ */
+gpointer
+g_malloc0 (gsize n_bytes)
+{
+  if (G_UNLIKELY (!g_mem_initialized))
+    g_mem_init_nomessage();
+  if (G_LIKELY (n_bytes))
+    {
+      gpointer mem;
+
+      mem = glib_mem_vtable.calloc (1, n_bytes);
+      TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 1, 0));
+      if (mem)
+       return mem;
+
+      g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
+               G_STRLOC, n_bytes);
+    }
+
+  TRACE(GLIB_MEM_ALLOC((void*) NULL, (int) n_bytes, 1, 0));
+
+  return NULL;
+}
+
+/**
+ * g_realloc:
+ * @mem: the memory to reallocate
+ * @n_bytes: new size of the memory in bytes
+ * 
+ * Reallocates the memory pointed to by @mem, so that it now has space for
+ * @n_bytes bytes of memory. It returns the new address of the memory, which may
+ * have been moved. @mem may be %NULL, in which case it's considered to
+ * have zero-length. @n_bytes may be 0, in which case %NULL will be returned
+ * and @mem will be freed unless it is %NULL.
+ * 
+ * Returns: the new address of the allocated memory
+ */
+gpointer
+g_realloc (gpointer mem,
+          gsize    n_bytes)
+{
+  gpointer newmem;
+
+  if (G_UNLIKELY (!g_mem_initialized))
+    g_mem_init_nomessage();
+  if (G_LIKELY (n_bytes))
+    {
+      newmem = glib_mem_vtable.realloc (mem, n_bytes);
+      TRACE (GLIB_MEM_REALLOC((void*) newmem, (void*)mem, (unsigned int) n_bytes, 0));
+      if (newmem)
+       return newmem;
+
+      g_error ("%s: failed to allocate %"G_GSIZE_FORMAT" bytes",
+               G_STRLOC, n_bytes);
+    }
+
+  if (mem)
+    glib_mem_vtable.free (mem);
+
+  TRACE (GLIB_MEM_REALLOC((void*) NULL, (void*)mem, 0, 0));
+
+  return NULL;
+}
+
+/**
+ * g_free:
+ * @mem: the memory to free
+ * 
+ * Frees the memory pointed to by @mem.
+ * If @mem is %NULL it simply returns.
+ */
+void
+g_free (gpointer mem)
+{
+  if (G_UNLIKELY (!g_mem_initialized))
+    g_mem_init_nomessage();
+  if (G_LIKELY (mem))
+    glib_mem_vtable.free (mem);
+  TRACE(GLIB_MEM_FREE((void*) mem));
+}
+
+/**
+ * g_try_malloc:
+ * @n_bytes: number of bytes to allocate.
+ * 
+ * Attempts to allocate @n_bytes, and returns %NULL on failure.
+ * Contrast with g_malloc(), which aborts the program on failure.
+ * 
+ * Returns: the allocated memory, or %NULL.
+ */
+gpointer
+g_try_malloc (gsize n_bytes)
+{
+  gpointer mem;
+
+  if (G_UNLIKELY (!g_mem_initialized))
+    g_mem_init_nomessage();
+  if (G_LIKELY (n_bytes))
+    mem = glib_mem_vtable.try_malloc (n_bytes);
+  else
+    mem = NULL;
+
+  TRACE (GLIB_MEM_ALLOC((void*) mem, (unsigned int) n_bytes, 0, 1));
+
+  return mem;
+}
+
+/**
+ * g_try_malloc0:
+ * @n_bytes: number of bytes to allocate
+ * 
+ * Attempts to allocate @n_bytes, initialized to 0's, and returns %NULL on
+ * failure. Contrast with g_malloc0(), which aborts the program on failure.
+ * 
+ * Since: 2.8
+ * Returns: the allocated memory, or %NULL
+ */
+gpointer
+g_try_malloc0 (gsize n_bytes)
+{
+  gpointer mem;
+
+  if (G_UNLIKELY (!g_mem_initialized))
+    g_mem_init_nomessage();
+  if (G_LIKELY (n_bytes))
+    mem = glib_mem_vtable.try_malloc (n_bytes);
+  else
+    mem = NULL;
+
+  if (mem)
+    memset (mem, 0, n_bytes);
+
+  return mem;
+}
+
+/**
+ * g_try_realloc:
+ * @mem: previously-allocated memory, or %NULL.
+ * @n_bytes: number of bytes to allocate.
+ * 
+ * Attempts to realloc @mem to a new size, @n_bytes, and returns %NULL
+ * on failure. Contrast with g_realloc(), which aborts the program
+ * on failure. If @mem is %NULL, behaves the same as g_try_malloc().
+ * 
+ * Returns: the allocated memory, or %NULL.
+ */
+gpointer
+g_try_realloc (gpointer mem,
+              gsize    n_bytes)
+{
+  gpointer newmem;
+
+  if (G_UNLIKELY (!g_mem_initialized))
+    g_mem_init_nomessage();
+  if (G_LIKELY (n_bytes))
+    newmem = glib_mem_vtable.try_realloc (mem, n_bytes);
+  else
+    {
+      newmem = NULL;
+      if (mem)
+       glib_mem_vtable.free (mem);
+    }
+
+  TRACE (GLIB_MEM_REALLOC((void*) newmem, (void*)mem, (unsigned int) n_bytes, 1));
+
+  return newmem;
+}
+
+
+#define SIZE_OVERFLOWS(a,b) (G_UNLIKELY ((b) > 0 && (a) > G_MAXSIZE / (b)))
+
+/**
+ * g_malloc_n:
+ * @n_blocks: the number of blocks to allocate
+ * @n_block_bytes: the size of each block in bytes
+ * 
+ * This function is similar to g_malloc(), allocating (@n_blocks * @n_block_bytes) bytes,
+ * but care is taken to detect possible overflow during multiplication.
+ * 
+ * Since: 2.24
+ * Returns: a pointer to the allocated memory
+ */
+gpointer
+g_malloc_n (gsize n_blocks,
+           gsize n_block_bytes)
+{
+  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
+    {
+      if (G_UNLIKELY (!g_mem_initialized))
+       g_mem_init_nomessage();
+
+      g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
+               G_STRLOC, n_blocks, n_block_bytes);
+    }
+
+  return g_malloc (n_blocks * n_block_bytes);
+}
+
+/**
+ * g_malloc0_n:
+ * @n_blocks: the number of blocks to allocate
+ * @n_block_bytes: the size of each block in bytes
+ * 
+ * This function is similar to g_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes,
+ * but care is taken to detect possible overflow during multiplication.
+ * 
+ * Since: 2.24
+ * Returns: a pointer to the allocated memory
+ */
+gpointer
+g_malloc0_n (gsize n_blocks,
+            gsize n_block_bytes)
+{
+  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
+    {
+      if (G_UNLIKELY (!g_mem_initialized))
+       g_mem_init_nomessage();
+
+      g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
+               G_STRLOC, n_blocks, n_block_bytes);
+    }
+
+  return g_malloc0 (n_blocks * n_block_bytes);
+}
+
+/**
+ * g_realloc_n:
+ * @mem: the memory to reallocate
+ * @n_blocks: the number of blocks to allocate
+ * @n_block_bytes: the size of each block in bytes
+ * 
+ * This function is similar to g_realloc(), allocating (@n_blocks * @n_block_bytes) bytes,
+ * but care is taken to detect possible overflow during multiplication.
+ * 
+ * Since: 2.24
+ * Returns: the new address of the allocated memory
+ */
+gpointer
+g_realloc_n (gpointer mem,
+            gsize    n_blocks,
+            gsize    n_block_bytes)
+{
+  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
+    {
+      if (G_UNLIKELY (!g_mem_initialized))
+       g_mem_init_nomessage();
+
+      g_error ("%s: overflow allocating %"G_GSIZE_FORMAT"*%"G_GSIZE_FORMAT" bytes",
+               G_STRLOC, n_blocks, n_block_bytes);
+    }
+
+  return g_realloc (mem, n_blocks * n_block_bytes);
+}
+
+/**
+ * g_try_malloc_n:
+ * @n_blocks: the number of blocks to allocate
+ * @n_block_bytes: the size of each block in bytes
+ * 
+ * This function is similar to g_try_malloc(), allocating (@n_blocks * @n_block_bytes) bytes,
+ * but care is taken to detect possible overflow during multiplication.
+ * 
+ * Since: 2.24
+ * Returns: the allocated memory, or %NULL.
+ */
+gpointer
+g_try_malloc_n (gsize n_blocks,
+               gsize n_block_bytes)
+{
+  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
+    return NULL;
+
+  return g_try_malloc (n_blocks * n_block_bytes);
+}
+
+/**
+ * g_try_malloc0_n:
+ * @n_blocks: the number of blocks to allocate
+ * @n_block_bytes: the size of each block in bytes
+ * 
+ * This function is similar to g_try_malloc0(), allocating (@n_blocks * @n_block_bytes) bytes,
+ * but care is taken to detect possible overflow during multiplication.
+ * 
+ * Since: 2.24
+ * Returns: the allocated memory, or %NULL
+ */
+gpointer
+g_try_malloc0_n (gsize n_blocks,
+                gsize n_block_bytes)
+{
+  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
+    return NULL;
+
+  return g_try_malloc0 (n_blocks * n_block_bytes);
+}
+
+/**
+ * g_try_realloc_n:
+ * @mem: previously-allocated memory, or %NULL.
+ * @n_blocks: the number of blocks to allocate
+ * @n_block_bytes: the size of each block in bytes
+ * 
+ * This function is similar to g_try_realloc(), allocating (@n_blocks * @n_block_bytes) bytes,
+ * but care is taken to detect possible overflow during multiplication.
+ * 
+ * Since: 2.24
+ * Returns: the allocated memory, or %NULL.
+ */
+gpointer
+g_try_realloc_n (gpointer mem,
+                gsize    n_blocks,
+                gsize    n_block_bytes)
+{
+  if (SIZE_OVERFLOWS (n_blocks, n_block_bytes))
+    return NULL;
+
+  return g_try_realloc (mem, n_blocks * n_block_bytes);
+}
+
+
+
+static gpointer
+fallback_calloc (gsize n_blocks,
+                gsize n_block_bytes)
+{
+  gsize l = n_blocks * n_block_bytes;
+  gpointer mem = glib_mem_vtable.malloc (l);
+
+  if (mem)
+    memset (mem, 0, l);
+
+  return mem;
+}
+
+static gboolean vtable_set = FALSE;
+
+/**
+ * g_mem_is_system_malloc
+ * 
+ * Checks whether the allocator used by g_malloc() is the system's
+ * malloc implementation. If it returns %TRUE memory allocated with
+ * malloc() can be used interchangeable with memory allocated using g_malloc().
+ * This function is useful for avoiding an extra copy of allocated memory returned
+ * by a non-GLib-based API.
+ *
+ * A different allocator can be set using g_mem_set_vtable().
+ *
+ * Return value: if %TRUE, malloc() and g_malloc() can be mixed.
+ **/
+gboolean
+g_mem_is_system_malloc (void)
+{
+  return !vtable_set;
+}
+
+/**
+ * g_mem_set_vtable:
+ * @vtable: table of memory allocation routines.
+ * 
+ * Sets the #GMemVTable to use for memory allocation. You can use this to provide
+ * custom memory allocation routines. <emphasis>This function must be called
+ * before using any other GLib functions.</emphasis> The @vtable only needs to
+ * provide malloc(), realloc(), and free() functions; GLib can provide default
+ * implementations of the others. The malloc() and realloc() implementations
+ * should return %NULL on failure, GLib will handle error-checking for you.
+ * @vtable is copied, so need not persist after this function has been called.
+ */
+void
+g_mem_set_vtable (GMemVTable *vtable)
+{
+  if (!vtable_set)
+    {
+      if (vtable->malloc && vtable->realloc && vtable->free)
+       {
+         glib_mem_vtable.malloc = vtable->malloc;
+         glib_mem_vtable.realloc = vtable->realloc;
+         glib_mem_vtable.free = vtable->free;
+         glib_mem_vtable.calloc = vtable->calloc ? vtable->calloc : fallback_calloc;
+         glib_mem_vtable.try_malloc = vtable->try_malloc ? vtable->try_malloc : glib_mem_vtable.malloc;
+         glib_mem_vtable.try_realloc = vtable->try_realloc ? vtable->try_realloc : glib_mem_vtable.realloc;
+         vtable_set = TRUE;
+       }
+      else
+       g_warning (G_STRLOC ": memory allocation vtable lacks one of malloc(), realloc() or free()");
+    }
+  else
+    g_warning (G_STRLOC ": memory allocation vtable can only be set once at startup");
+}
+
+
+/* --- memory profiling and checking --- */
+#ifdef G_DISABLE_CHECKS
+/**
+ * glib_mem_profiler_table:
+ * 
+ * A #GMemVTable containing profiling variants of the memory
+ * allocation functions. Use them together with g_mem_profile()
+ * in order to get information about the memory allocation pattern
+ * of your program.
+ */
+GMemVTable *glib_mem_profiler_table = &glib_mem_vtable;
+void
+g_mem_profile (void)
+{
+}
+#else  /* !G_DISABLE_CHECKS */
+typedef enum {
+  PROFILER_FREE                = 0,
+  PROFILER_ALLOC       = 1,
+  PROFILER_RELOC       = 2,
+  PROFILER_ZINIT       = 4
+} ProfilerJob;
+static guint *profile_data = NULL;
+static gsize profile_allocs = 0;
+static gsize profile_zinit = 0;
+static gsize profile_frees = 0;
+static GMutex *gmem_profile_mutex = NULL;
+#ifdef  G_ENABLE_DEBUG
+static volatile gsize g_trap_free_size = 0;
+static volatile gsize g_trap_realloc_size = 0;
+static volatile gsize g_trap_malloc_size = 0;
+#endif  /* G_ENABLE_DEBUG */
+
+#define        PROFILE_TABLE(f1,f2,f3)   ( ( ((f3) << 2) | ((f2) << 1) | (f1) ) * (MEM_PROFILE_TABLE_SIZE + 1))
+
+static void
+profiler_log (ProfilerJob job,
+             gsize       n_bytes,
+             gboolean    success)
+{
+  g_mutex_lock (gmem_profile_mutex);
+  if (!profile_data)
+    {
+      profile_data = standard_calloc ((MEM_PROFILE_TABLE_SIZE + 1) * 8, 
+                                      sizeof (profile_data[0]));
+      if (!profile_data)       /* memory system kiddin' me, eh? */
+       {
+         g_mutex_unlock (gmem_profile_mutex);
+         return;
+       }
+    }
+
+  if (n_bytes < MEM_PROFILE_TABLE_SIZE)
+    profile_data[n_bytes + PROFILE_TABLE ((job & PROFILER_ALLOC) != 0,
+                                          (job & PROFILER_RELOC) != 0,
+                                          success != 0)] += 1;
+  else
+    profile_data[MEM_PROFILE_TABLE_SIZE + PROFILE_TABLE ((job & PROFILER_ALLOC) != 0,
+                                                         (job & PROFILER_RELOC) != 0,
+                                                         success != 0)] += 1;
+  if (success)
+    {
+      if (job & PROFILER_ALLOC)
+        {
+          profile_allocs += n_bytes;
+          if (job & PROFILER_ZINIT)
+            profile_zinit += n_bytes;
+        }
+      else
+        profile_frees += n_bytes;
+    }
+  g_mutex_unlock (gmem_profile_mutex);
+}
+
+static void
+profile_print_locked (guint   *local_data,
+                     gboolean success)
+{
+  gboolean need_header = TRUE;
+  guint i;
+
+  for (i = 0; i <= MEM_PROFILE_TABLE_SIZE; i++)
+    {
+      glong t_malloc = local_data[i + PROFILE_TABLE (1, 0, success)];
+      glong t_realloc = local_data[i + PROFILE_TABLE (1, 1, success)];
+      glong t_free = local_data[i + PROFILE_TABLE (0, 0, success)];
+      glong t_refree = local_data[i + PROFILE_TABLE (0, 1, success)];
+      
+      if (!t_malloc && !t_realloc && !t_free && !t_refree)
+       continue;
+      else if (need_header)
+       {
+         need_header = FALSE;
+         g_print (" blocks of | allocated  | freed      | allocated  | freed      | n_bytes   \n");
+         g_print ("  n_bytes  | n_times by | n_times by | n_times by | n_times by | remaining \n");
+         g_print ("           | malloc()   | free()     | realloc()  | realloc()  |           \n");
+         g_print ("===========|============|============|============|============|===========\n");
+       }
+      if (i < MEM_PROFILE_TABLE_SIZE)
+       g_print ("%10u | %10ld | %10ld | %10ld | %10ld |%+11ld\n",
+                i, t_malloc, t_free, t_realloc, t_refree,
+                (t_malloc - t_free + t_realloc - t_refree) * i);
+      else if (i >= MEM_PROFILE_TABLE_SIZE)
+       g_print ("   >%6u | %10ld | %10ld | %10ld | %10ld |        ***\n",
+                i, t_malloc, t_free, t_realloc, t_refree);
+    }
+  if (need_header)
+    g_print (" --- none ---\n");
+}
+
+/**
+ * g_mem_profile:
+ * @void:
+ * 
+ * Outputs a summary of memory usage.
+ * 
+ * It outputs the frequency of allocations of different sizes,
+ * the total number of bytes which have been allocated,
+ * the total number of bytes which have been freed,
+ * and the difference between the previous two values, i.e. the number of bytes
+ * still in use.
+ * 
+ * Note that this function will not output anything unless you have
+ * previously installed the #glib_mem_profiler_table with g_mem_set_vtable().
+ */
+
+void
+g_mem_profile (void)
+{
+  guint local_data[(MEM_PROFILE_TABLE_SIZE + 1) * 8 * sizeof (profile_data[0])];
+  gsize local_allocs;
+  gsize local_zinit;
+  gsize local_frees;
+
+  if (G_UNLIKELY (!g_mem_initialized))
+    g_mem_init_nomessage();
+
+  g_mutex_lock (gmem_profile_mutex);
+
+  local_allocs = profile_allocs;
+  local_zinit = profile_zinit;
+  local_frees = profile_frees;
+
+  if (!profile_data)
+    {
+      g_mutex_unlock (gmem_profile_mutex);
+      return;
+    }
+
+  memcpy (local_data, profile_data, 
+         (MEM_PROFILE_TABLE_SIZE + 1) * 8 * sizeof (profile_data[0]));
+  
+  g_mutex_unlock (gmem_profile_mutex);
+
+  g_print ("GLib Memory statistics (successful operations):\n");
+  profile_print_locked (local_data, TRUE);
+  g_print ("GLib Memory statistics (failing operations):\n");
+  profile_print_locked (local_data, FALSE);
+  g_print ("Total bytes: allocated=%"G_GSIZE_FORMAT", "
+           "zero-initialized=%"G_GSIZE_FORMAT" (%.2f%%), "
+           "freed=%"G_GSIZE_FORMAT" (%.2f%%), "
+           "remaining=%"G_GSIZE_FORMAT"\n",
+          local_allocs,
+          local_zinit,
+          ((gdouble) local_zinit) / local_allocs * 100.0,
+          local_frees,
+          ((gdouble) local_frees) / local_allocs * 100.0,
+          local_allocs - local_frees);
+}
+
+static gpointer
+profiler_try_malloc (gsize n_bytes)
+{
+  gsize *p;
+
+#ifdef  G_ENABLE_DEBUG
+  if (g_trap_malloc_size == n_bytes)
+    G_BREAKPOINT ();
+#endif  /* G_ENABLE_DEBUG */
+
+  p = standard_malloc (sizeof (gsize) * 2 + n_bytes);
+
+  if (p)
+    {
+      p[0] = 0;                /* free count */
+      p[1] = n_bytes;  /* length */
+      profiler_log (PROFILER_ALLOC, n_bytes, TRUE);
+      p += 2;
+    }
+  else
+    profiler_log (PROFILER_ALLOC, n_bytes, FALSE);
+  
+  return p;
+}
+
+static gpointer
+profiler_malloc (gsize n_bytes)
+{
+  gpointer mem = profiler_try_malloc (n_bytes);
+
+  if (!mem)
+    g_mem_profile ();
+
+  return mem;
+}
+
+static gpointer
+profiler_calloc (gsize n_blocks,
+                gsize n_block_bytes)
+{
+  gsize l = n_blocks * n_block_bytes;
+  gsize *p;
+
+#ifdef  G_ENABLE_DEBUG
+  if (g_trap_malloc_size == l)
+    G_BREAKPOINT ();
+#endif  /* G_ENABLE_DEBUG */
+  
+  p = standard_calloc (1, sizeof (gsize) * 2 + l);
+
+  if (p)
+    {
+      p[0] = 0;                /* free count */
+      p[1] = l;                /* length */
+      profiler_log (PROFILER_ALLOC | PROFILER_ZINIT, l, TRUE);
+      p += 2;
+    }
+  else
+    {
+      profiler_log (PROFILER_ALLOC | PROFILER_ZINIT, l, FALSE);
+      g_mem_profile ();
+    }
+
+  return p;
+}
+
+static void
+profiler_free (gpointer mem)
+{
+  gsize *p = mem;
+
+  p -= 2;
+  if (p[0])    /* free count */
+    {
+      g_warning ("free(%p): memory has been freed %"G_GSIZE_FORMAT" times already",
+                 p + 2, p[0]);
+      profiler_log (PROFILER_FREE,
+                   p[1],       /* length */
+                   FALSE);
+    }
+  else
+    {
+#ifdef  G_ENABLE_DEBUG
+      if (g_trap_free_size == p[1])
+       G_BREAKPOINT ();
+#endif  /* G_ENABLE_DEBUG */
+
+      profiler_log (PROFILER_FREE,
+                   p[1],       /* length */
+                   TRUE);
+      memset (p + 2, 0xaa, p[1]);
+
+      /* for all those that miss standard_free (p); in this place, yes,
+       * we do leak all memory when profiling, and that is intentional
+       * to catch double frees. patch submissions are futile.
+       */
+    }
+  p[0] += 1;
+}
+
+static gpointer
+profiler_try_realloc (gpointer mem,
+                     gsize    n_bytes)
+{
+  gsize *p = mem;
+
+  p -= 2;
+
+#ifdef  G_ENABLE_DEBUG
+  if (g_trap_realloc_size == n_bytes)
+    G_BREAKPOINT ();
+#endif  /* G_ENABLE_DEBUG */
+  
+  if (mem && p[0])     /* free count */
+    {
+      g_warning ("realloc(%p, %"G_GSIZE_FORMAT"): "
+                 "memory has been freed %"G_GSIZE_FORMAT" times already",
+                 p + 2, (gsize) n_bytes, p[0]);
+      profiler_log (PROFILER_ALLOC | PROFILER_RELOC, n_bytes, FALSE);
+
+      return NULL;
+    }
+  else
+    {
+      p = standard_realloc (mem ? p : NULL, sizeof (gsize) * 2 + n_bytes);
+
+      if (p)
+       {
+         if (mem)
+           profiler_log (PROFILER_FREE | PROFILER_RELOC, p[1], TRUE);
+         p[0] = 0;
+         p[1] = n_bytes;
+         profiler_log (PROFILER_ALLOC | PROFILER_RELOC, p[1], TRUE);
+         p += 2;
+       }
+      else
+       profiler_log (PROFILER_ALLOC | PROFILER_RELOC, n_bytes, FALSE);
+
+      return p;
+    }
+}
+
+static gpointer
+profiler_realloc (gpointer mem,
+                 gsize    n_bytes)
+{
+  mem = profiler_try_realloc (mem, n_bytes);
+
+  if (!mem)
+    g_mem_profile ();
+
+  return mem;
+}
+
+static GMemVTable profiler_table = {
+  profiler_malloc,
+  profiler_realloc,
+  profiler_free,
+  profiler_calloc,
+  profiler_try_malloc,
+  profiler_try_realloc,
+};
+GMemVTable *glib_mem_profiler_table = &profiler_table;
+
+#endif /* !G_DISABLE_CHECKS */
+
+/* --- MemChunks --- */
+/**
+ * SECTION: allocators
+ * @title: Memory Allocators
+ * @short_description: deprecated way to allocate chunks of memory for
+ *                     GList, GSList and GNode
+ *
+ * Prior to 2.10, #GAllocator was used as an efficient way to allocate
+ * small pieces of memory for use with the #GList, #GSList and #GNode
+ * data structures. Since 2.10, it has been completely replaced by the
+ * <link linkend="glib-Memory-Slices">slice allocator</link> and
+ * deprecated.
+ **/
+
+/**
+ * SECTION: memory_chunks
+ * @title: Memory Chunks
+ * @short_description: deprecated way to allocate groups of equal-sized
+ *                     chunks of memory
+ *
+ * Memory chunks provide an space-efficient way to allocate equal-sized
+ * pieces of memory, called atoms. However, due to the administrative
+ * overhead (in particular for #G_ALLOC_AND_FREE, and when used from
+ * multiple threads), they are in practise often slower than direct use
+ * of g_malloc(). Therefore, memory chunks have been deprecated in
+ * favor of the <link linkend="glib-Memory-Slices">slice
+ * allocator</link>, which has been added in 2.10. All internal uses of
+ * memory chunks in GLib have been converted to the
+ * <literal>g_slice</literal> API.
+ *
+ * There are two types of memory chunks, #G_ALLOC_ONLY, and
+ * #G_ALLOC_AND_FREE. <itemizedlist> <listitem><para> #G_ALLOC_ONLY
+ * chunks only allow allocation of atoms. The atoms can never be freed
+ * individually. The memory chunk can only be free in its entirety.
+ * </para></listitem> <listitem><para> #G_ALLOC_AND_FREE chunks do
+ * allow atoms to be freed individually. The disadvantage of this is
+ * that the memory chunk has to keep track of which atoms have been
+ * freed. This results in more memory being used and a slight
+ * degradation in performance. </para></listitem> </itemizedlist>
+ *
+ * To create a memory chunk use g_mem_chunk_new() or the convenience
+ * macro g_mem_chunk_create().
+ *
+ * To allocate a new atom use g_mem_chunk_alloc(),
+ * g_mem_chunk_alloc0(), or the convenience macros g_chunk_new() or
+ * g_chunk_new0().
+ *
+ * To free an atom use g_mem_chunk_free(), or the convenience macro
+ * g_chunk_free(). (Atoms can only be freed if the memory chunk is
+ * created with the type set to #G_ALLOC_AND_FREE.)
+ *
+ * To free any blocks of memory which are no longer being used, use
+ * g_mem_chunk_clean(). To clean all memory chunks, use g_blow_chunks().
+ *
+ * To reset the memory chunk, freeing all of the atoms, use
+ * g_mem_chunk_reset().
+ *
+ * To destroy a memory chunk, use g_mem_chunk_destroy().
+ *
+ * To help debug memory chunks, use g_mem_chunk_info() and
+ * g_mem_chunk_print().
+ *
+ * <example>
+ *  <title>Using a #GMemChunk</title>
+ *  <programlisting>
+ *   GMemChunk *mem_chunk;
+ *   gchar *mem[10000];
+ *   gint i;
+ *
+ *   /<!-- -->* Create a GMemChunk with atoms 50 bytes long, and memory
+ *      blocks holding 100 bytes. Note that this means that only 2 atoms
+ *      fit into each memory block and so isn't very efficient. *<!-- -->/
+ *   mem_chunk = g_mem_chunk_new ("test mem chunk", 50, 100, G_ALLOC_AND_FREE);
+ *   /<!-- -->* Now allocate 10000 atoms. *<!-- -->/
+ *   for (i = 0; i &lt; 10000; i++)
+ *     {
+ *       mem[i] = g_chunk_new (gchar, mem_chunk);
+ *       /<!-- -->* Fill in the atom memory with some junk. *<!-- -->/
+ *       for (j = 0; j &lt; 50; j++)
+ *         mem[i][j] = i * j;
+ *     }
+ *   /<!-- -->* Now free all of the atoms. Note that since we are going to
+ *      destroy the GMemChunk, this wouldn't normally be used. *<!-- -->/
+ *   for (i = 0; i &lt; 10000; i++)
+ *     {
+ *       g_mem_chunk_free (mem_chunk, mem[i]);
+ *     }
+ *   /<!-- -->* We are finished with the GMemChunk, so we destroy it. *<!-- -->/
+ *   g_mem_chunk_destroy (mem_chunk);
+ *  </programlisting>
+ * </example>
+ *
+ * <example>
+ *  <title>Using a #GMemChunk with data structures</title>
+ *  <programlisting>
+ *    GMemChunk *array_mem_chunk;
+ *    GRealArray *array;
+ *    /<!-- -->* Create a GMemChunk to hold GRealArray structures, using
+ *       the g_mem_chunk_create(<!-- -->) convenience macro. We want 1024 atoms in each
+ *       memory block, and we want to be able to free individual atoms. *<!-- -->/
+ *    array_mem_chunk = g_mem_chunk_create (GRealArray, 1024, G_ALLOC_AND_FREE);
+ *    /<!-- -->* Allocate one atom, using the g_chunk_new(<!-- -->) convenience macro. *<!-- -->/
+ *    array = g_chunk_new (GRealArray, array_mem_chunk);
+ *    /<!-- -->* We can now use array just like a normal pointer to a structure. *<!-- -->/
+ *    array->data            = NULL;
+ *    array->len             = 0;
+ *    array->alloc           = 0;
+ *    array->zero_terminated = (zero_terminated ? 1 : 0);
+ *    array->clear           = (clear ? 1 : 0);
+ *    array->elt_size        = elt_size;
+ *    /<!-- -->* We can free the element, so it can be reused. *<!-- -->/
+ *    g_chunk_free (array, array_mem_chunk);
+ *    /<!-- -->* We destroy the GMemChunk when we are finished with it. *<!-- -->/
+ *    g_mem_chunk_destroy (array_mem_chunk);
+ *  </programlisting>
+ * </example>
+ **/
+
+#ifndef G_ALLOC_AND_FREE
+
+/**
+ * GAllocator:
+ *
+ * The #GAllocator struct contains private data. and should only be
+ * accessed using the following functions.
+ **/
+typedef struct _GAllocator GAllocator;
+
+/**
+ * GMemChunk:
+ *
+ * The #GMemChunk struct is an opaque data structure representing a
+ * memory chunk. It should be accessed only through the use of the
+ * following functions.
+ **/
+typedef struct _GMemChunk  GMemChunk;
+
+/**
+ * G_ALLOC_ONLY:
+ *
+ * Specifies the type of a #GMemChunk. Used in g_mem_chunk_new() and
+ * g_mem_chunk_create() to specify that atoms will never be freed
+ * individually.
+ **/
+#define G_ALLOC_ONLY     1
+
+/**
+ * G_ALLOC_AND_FREE:
+ *
+ * Specifies the type of a #GMemChunk. Used in g_mem_chunk_new() and
+ * g_mem_chunk_create() to specify that atoms will be freed
+ * individually.
+ **/
+#define G_ALLOC_AND_FREE  2
+#endif
+
+struct _GMemChunk {
+  guint alloc_size;           /* the size of an atom */
+};
+
+/**
+ * g_mem_chunk_new:
+ * @name: a string to identify the #GMemChunk. It is not copied so it
+ *        should be valid for the lifetime of the #GMemChunk. It is
+ *        only used in g_mem_chunk_print(), which is used for debugging.
+ * @atom_size: the size, in bytes, of each element in the #GMemChunk.
+ * @area_size: the size, in bytes, of each block of memory allocated to
+ *             contain the atoms.
+ * @type: the type of the #GMemChunk.  #G_ALLOC_AND_FREE is used if the
+ *        atoms will be freed individually.  #G_ALLOC_ONLY should be
+ *        used if atoms will never be freed individually.
+ *        #G_ALLOC_ONLY is quicker, since it does not need to track
+ *        free atoms, but it obviously wastes memory if you no longer
+ *        need many of the atoms.
+ * @Returns: the new #GMemChunk.
+ *
+ * Creates a new #GMemChunk.
+ *
+ * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link> instead
+ **/
+GMemChunk*
+g_mem_chunk_new (const gchar  *name,
+                gint          atom_size,
+                gsize         area_size,
+                gint          type)
+{
+  GMemChunk *mem_chunk;
+  g_return_val_if_fail (atom_size > 0, NULL);
+
+  mem_chunk = g_slice_new (GMemChunk);
+  mem_chunk->alloc_size = atom_size;
+  return mem_chunk;
+}
+
+/**
+ * g_mem_chunk_destroy:
+ * @mem_chunk: a #GMemChunk.
+ *
+ * Frees all of the memory allocated for a #GMemChunk.
+ *
+ * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link> instead
+ **/
+void
+g_mem_chunk_destroy (GMemChunk *mem_chunk)
+{
+  g_return_if_fail (mem_chunk != NULL);
+  
+  g_slice_free (GMemChunk, mem_chunk);
+}
+
+/**
+ * g_mem_chunk_alloc:
+ * @mem_chunk: a #GMemChunk.
+ * @Returns: a pointer to the allocated atom.
+ *
+ * Allocates an atom of memory from a #GMemChunk.
+ *
+ * Deprecated:2.10: Use g_slice_alloc() instead
+ **/
+gpointer
+g_mem_chunk_alloc (GMemChunk *mem_chunk)
+{
+  g_return_val_if_fail (mem_chunk != NULL, NULL);
+  
+  return g_slice_alloc (mem_chunk->alloc_size);
+}
+
+/**
+ * g_mem_chunk_alloc0:
+ * @mem_chunk: a #GMemChunk.
+ * @Returns: a pointer to the allocated atom.
+ *
+ * Allocates an atom of memory from a #GMemChunk, setting the memory to
+ * 0.
+ *
+ * Deprecated:2.10: Use g_slice_alloc0() instead
+ **/
+gpointer
+g_mem_chunk_alloc0 (GMemChunk *mem_chunk)
+{
+  g_return_val_if_fail (mem_chunk != NULL, NULL);
+  
+  return g_slice_alloc0 (mem_chunk->alloc_size);
+}
+
+/**
+ * g_mem_chunk_free:
+ * @mem_chunk: a #GMemChunk.
+ * @mem: a pointer to the atom to free.
+ *
+ * Frees an atom in a #GMemChunk. This should only be called if the
+ * #GMemChunk was created with #G_ALLOC_AND_FREE. Otherwise it will
+ * simply return.
+ *
+ * Deprecated:2.10: Use g_slice_free1() instead
+ **/
+void
+g_mem_chunk_free (GMemChunk *mem_chunk,
+                 gpointer   mem)
+{
+  g_return_if_fail (mem_chunk != NULL);
+  
+  g_slice_free1 (mem_chunk->alloc_size, mem);
+}
+
+/**
+ * g_mem_chunk_clean:
+ * @mem_chunk: a #GMemChunk.
+ *
+ * Frees any blocks in a #GMemChunk which are no longer being used.
+ *
+ * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link> instead
+ **/
+void   g_mem_chunk_clean       (GMemChunk *mem_chunk)  {}
+
+/**
+ * g_mem_chunk_reset:
+ * @mem_chunk: a #GMemChunk.
+ *
+ * Resets a GMemChunk to its initial state. It frees all of the
+ * currently allocated blocks of memory.
+ *
+ * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link> instead
+ **/
+void   g_mem_chunk_reset       (GMemChunk *mem_chunk)  {}
+
+
+/**
+ * g_mem_chunk_print:
+ * @mem_chunk: a #GMemChunk.
+ *
+ * Outputs debugging information for a #GMemChunk. It outputs the name
+ * of the #GMemChunk (set with g_mem_chunk_new()), the number of bytes
+ * used, and the number of blocks of memory allocated.
+ *
+ * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link> instead
+ **/
+void   g_mem_chunk_print       (GMemChunk *mem_chunk)  {}
+
+
+/**
+ * g_mem_chunk_info:
+ *
+ * Outputs debugging information for all #GMemChunk objects currently
+ * in use. It outputs the number of #GMemChunk objects currently
+ * allocated, and calls g_mem_chunk_print() to output information on
+ * each one.
+ *
+ * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link> instead
+ **/
+void   g_mem_chunk_info        (void)                  {}
+
+/**
+ * g_blow_chunks:
+ *
+ * Calls g_mem_chunk_clean() on all #GMemChunk objects.
+ *
+ * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link> instead
+ **/
+void   g_blow_chunks           (void)                  {}
+
+/**
+ * g_chunk_new0:
+ * @type: the type of the #GMemChunk atoms, typically a structure name.
+ * @chunk: a #GMemChunk.
+ * @Returns: a pointer to the allocated atom, cast to a pointer to
+ *           @type.
+ *
+ * A convenience macro to allocate an atom of memory from a #GMemChunk.
+ * It calls g_mem_chunk_alloc0() and casts the returned atom to a
+ * pointer to the given type, avoiding a type cast in the source code.
+ *
+ * Deprecated:2.10: Use g_slice_new0() instead
+ **/
+
+/**
+ * g_chunk_free:
+ * @mem: a pointer to the atom to be freed.
+ * @mem_chunk: a #GMemChunk.
+ *
+ * A convenience macro to free an atom of memory from a #GMemChunk. It
+ * simply switches the arguments and calls g_mem_chunk_free() It is
+ * included simply to complement the other convenience macros,
+ * g_chunk_new() and g_chunk_new0().
+ *
+ * Deprecated:2.10: Use g_slice_free() instead
+ **/
+
+/**
+ * g_chunk_new:
+ * @type: the type of the #GMemChunk atoms, typically a structure name.
+ * @chunk: a #GMemChunk.
+ * @Returns: a pointer to the allocated atom, cast to a pointer to
+ *           @type.
+ *
+ * A convenience macro to allocate an atom of memory from a #GMemChunk.
+ * It calls g_mem_chunk_alloc() and casts the returned atom to a
+ * pointer to the given type, avoiding a type cast in the source code.
+ *
+ * Deprecated:2.10: Use g_slice_new() instead
+ **/
+
+/**
+ * g_mem_chunk_create:
+ * @type: the type of the atoms, typically a structure name.
+ * @pre_alloc: the number of atoms to store in each block of memory.
+ * @alloc_type: the type of the #GMemChunk.  #G_ALLOC_AND_FREE is used
+ *              if the atoms will be freed individually.  #G_ALLOC_ONLY
+ *              should be used if atoms will never be freed
+ *              individually.  #G_ALLOC_ONLY is quicker, since it does
+ *              not need to track free atoms, but it obviously wastes
+ *              memory if you no longer need many of the atoms.
+ * @Returns: the new #GMemChunk.
+ *
+ * A convenience macro for creating a new #GMemChunk. It calls
+ * g_mem_chunk_new(), using the given type to create the #GMemChunk
+ * name. The atom size is determined using
+ * <function>sizeof()</function>, and the area size is calculated by
+ * multiplying the @pre_alloc parameter with the atom size.
+ *
+ * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link> instead
+ **/
+
+
+/**
+ * g_allocator_new:
+ * @name: the name of the #GAllocator. This name is used to set the
+ *        name of the #GMemChunk used by the #GAllocator, and is only
+ *        used for debugging.
+ * @n_preallocs: the number of elements in each block of memory
+ *               allocated.  Larger blocks mean less calls to
+ *               g_malloc(), but some memory may be wasted.  (GLib uses
+ *               128 elements per block by default.) The value must be
+ *               between 1 and 65535.
+ * @Returns: a new #GAllocator.
+ *
+ * Creates a new #GAllocator.
+ *
+ * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link> instead
+ **/
+GAllocator*
+g_allocator_new (const gchar *name,
+                guint        n_preallocs)
+{
+  static struct _GAllocator {
+    gchar      *name;
+    guint16     n_preallocs;
+    guint       is_unused : 1;
+    guint       type : 4;
+    GAllocator *last;
+    GMemChunk  *mem_chunk;
+    gpointer    free_list;
+  } dummy = {
+    "GAllocator is deprecated", 1, TRUE, 0, NULL, NULL, NULL,
+  };
+  /* some (broken) GAllocator uses depend on non-NULL allocators */
+  return (void*) &dummy;
+}
+
+/**
+ * g_allocator_free:
+ * @allocator: a #GAllocator.
+ *
+ * Frees all of the memory allocated by the #GAllocator.
+ *
+ * Deprecated:2.10: Use the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link> instead
+ **/
+void
+g_allocator_free (GAllocator *allocator)
+{
+}
+
+#ifdef ENABLE_GC_FRIENDLY_DEFAULT
+gboolean g_mem_gc_friendly = TRUE;
+#else
+/**
+ * g_mem_gc_friendly:
+ * 
+ * This variable is %TRUE if the <envar>G_DEBUG</envar> environment variable
+ * includes the key <link linkend="G_DEBUG">gc-friendly</link>.
+ */
+gboolean g_mem_gc_friendly = FALSE;
+#endif
+
+static void
+g_mem_init_nomessage (void)
+{
+  gchar buffer[1024];
+  const gchar *val;
+  const GDebugKey keys[] = {
+    { "gc-friendly", 1 },
+  };
+  gint flags;
+  if (g_mem_initialized)
+    return;
+  /* don't use g_malloc/g_message here */
+  val = _g_getenv_nomalloc ("G_DEBUG", buffer);
+  flags = !val ? 0 : g_parse_debug_string (val, keys, G_N_ELEMENTS (keys));
+  if (flags & 1)        /* gc-friendly */
+    {
+      g_mem_gc_friendly = TRUE;
+    }
+  g_mem_initialized = TRUE;
+}
+
+void
+_g_mem_thread_init_noprivate_nomessage (void)
+{
+  /* we may only create mutexes here, locking/
+   * unlocking a mutex does not yet work.
+   */
+  g_mem_init_nomessage();
+#ifndef G_DISABLE_CHECKS
+  gmem_profile_mutex = g_mutex_new ();
+#endif
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gmem.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gmem.h
new file mode 100644 (file)
index 0000000..01d953e
--- /dev/null
@@ -0,0 +1,309 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_MEM_H__
+#define __G_MEM_H__
+
+#include <glib/gslice.h>
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GMemVTable:
+ * @malloc: function to use for allocating memory.
+ * @realloc: function to use for reallocating memory.
+ * @free: function to use to free memory.
+ * @calloc: function to use for allocating zero-filled memory.
+ * @try_malloc: function to use for allocating memory without a default error handler.
+ * @try_realloc: function to use for reallocating memory without a default error handler.
+ * 
+ * A set of functions used to perform memory allocation. The same #GMemVTable must
+ * be used for all allocations in the same program; a call to g_mem_set_vtable(),
+ * if it exists, should be prior to any use of GLib.
+ */
+typedef struct _GMemVTable GMemVTable;
+
+
+#if GLIB_SIZEOF_VOID_P > GLIB_SIZEOF_LONG
+/**
+ * G_MEM_ALIGN:
+ * 
+ * Indicates the number of bytes to which memory will be aligned on the
+ * current platform.
+ */
+#  define G_MEM_ALIGN  GLIB_SIZEOF_VOID_P
+#else  /* GLIB_SIZEOF_VOID_P <= GLIB_SIZEOF_LONG */
+#  define G_MEM_ALIGN  GLIB_SIZEOF_LONG
+#endif /* GLIB_SIZEOF_VOID_P <= GLIB_SIZEOF_LONG */
+
+
+/* Memory allocation functions
+ */
+
+void    g_free           (gpointer      mem);
+
+gpointer g_malloc         (gsize        n_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1);
+gpointer g_malloc0        (gsize        n_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1);
+gpointer g_realloc        (gpointer     mem,
+                          gsize         n_bytes) G_GNUC_WARN_UNUSED_RESULT;
+gpointer g_try_malloc     (gsize        n_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1);
+gpointer g_try_malloc0    (gsize        n_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1);
+gpointer g_try_realloc    (gpointer     mem,
+                          gsize         n_bytes) G_GNUC_WARN_UNUSED_RESULT;
+
+gpointer g_malloc_n       (gsize        n_blocks,
+                          gsize         n_block_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE2(1,2);
+gpointer g_malloc0_n      (gsize        n_blocks,
+                          gsize         n_block_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE2(1,2);
+gpointer g_realloc_n      (gpointer     mem,
+                          gsize         n_blocks,
+                          gsize         n_block_bytes) G_GNUC_WARN_UNUSED_RESULT;
+gpointer g_try_malloc_n   (gsize        n_blocks,
+                          gsize         n_block_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE2(1,2);
+gpointer g_try_malloc0_n  (gsize        n_blocks,
+                          gsize         n_block_bytes) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE2(1,2);
+gpointer g_try_realloc_n  (gpointer     mem,
+                          gsize         n_blocks,
+                          gsize         n_block_bytes) G_GNUC_WARN_UNUSED_RESULT;
+
+
+/* Optimise: avoid the call to the (slower) _n function if we can
+ * determine at compile-time that no overflow happens.
+ */
+#if defined (__GNUC__) && (__GNUC__ >= 2) && defined (__OPTIMIZE__)
+#  define _G_NEW(struct_type, n_structs, func) \
+       (struct_type *) (__extension__ ({                       \
+         gsize __n = (gsize) (n_structs);                      \
+         gsize __s = sizeof (struct_type);                     \
+         gpointer __p;                                         \
+         if (__s == 1)                                         \
+           __p = g_##func (__n);                               \
+         else if (__builtin_constant_p (__n) &&                \
+                  (__s == 0 || __n <= G_MAXSIZE / __s))        \
+           __p = g_##func (__n * __s);                         \
+         else                                                  \
+           __p = g_##func##_n (__n, __s);                      \
+         __p;                                                  \
+       }))
+#  define _G_RENEW(struct_type, mem, n_structs, func) \
+       (struct_type *) (__extension__ ({                       \
+         gsize __n = (gsize) (n_structs);                      \
+         gsize __s = sizeof (struct_type);                     \
+         gpointer __p = (gpointer) (mem);                      \
+         if (__s == 1)                                         \
+           __p = g_##func (__p, __n);                          \
+         else if (__builtin_constant_p (__n) &&                \
+                  (__s == 0 || __n <= G_MAXSIZE / __s))        \
+           __p = g_##func (__p, __n * __s);                    \
+         else                                                  \
+           __p = g_##func##_n (__p, __n, __s);                 \
+         __p;                                                  \
+       }))
+
+#else
+
+/* Unoptimised version: always call the _n() function. */
+
+#define _G_NEW(struct_type, n_structs, func) \
+        ((struct_type *) g_##func##_n ((n_structs), sizeof (struct_type)))
+#define _G_RENEW(struct_type, mem, n_structs, func) \
+        ((struct_type *) g_##func##_n (mem, (n_structs), sizeof (struct_type)))
+
+#endif
+
+/**
+ * g_new:
+ * @struct_type: the type of the elements to allocate
+ * @n_structs: the number of elements to allocate
+ * 
+ * Allocates @n_structs elements of type @struct_type.
+ * The returned pointer is cast to a pointer to the given type.
+ * If @n_structs is 0 it returns %NULL.
+ * Care is taken to avoid overflow when calculating the size of the allocated block.
+ * 
+ * Since the returned pointer is already casted to the right type,
+ * it is normally unnecessary to cast it explicitly, and doing
+ * so might hide memory allocation errors.
+ * 
+ * Returns: a pointer to the allocated memory, cast to a pointer to @struct_type
+ */
+#define g_new(struct_type, n_structs)                  _G_NEW (struct_type, n_structs, malloc)
+/**
+ * g_new0:
+ * @struct_type: the type of the elements to allocate.
+ * @n_structs: the number of elements to allocate.
+ * 
+ * Allocates @n_structs elements of type @struct_type, initialized to 0's.
+ * The returned pointer is cast to a pointer to the given type.
+ * If @n_structs is 0 it returns %NULL.
+ * Care is taken to avoid overflow when calculating the size of the allocated block.
+ * 
+ * Since the returned pointer is already casted to the right type,
+ * it is normally unnecessary to cast it explicitly, and doing
+ * so might hide memory allocation errors.
+ * 
+ * Returns: a pointer to the allocated memory, cast to a pointer to @struct_type.
+ */
+#define g_new0(struct_type, n_structs)                 _G_NEW (struct_type, n_structs, malloc0)
+/**
+ * g_renew:
+ * @struct_type: the type of the elements to allocate
+ * @mem: the currently allocated memory
+ * @n_structs: the number of elements to allocate
+ * 
+ * Reallocates the memory pointed to by @mem, so that it now has space for
+ * @n_structs elements of type @struct_type. It returns the new address of
+ * the memory, which may have been moved.
+ * Care is taken to avoid overflow when calculating the size of the allocated block.
+ * 
+ * Returns: a pointer to the new allocated memory, cast to a pointer to @struct_type
+ */
+#define g_renew(struct_type, mem, n_structs)           _G_RENEW (struct_type, mem, n_structs, realloc)
+/**
+ * g_try_new:
+ * @struct_type: the type of the elements to allocate
+ * @n_structs: the number of elements to allocate
+ * 
+ * Attempts to allocate @n_structs elements of type @struct_type, and returns
+ * %NULL on failure. Contrast with g_new(), which aborts the program on failure.
+ * The returned pointer is cast to a pointer to the given type.
+ * The function returns %NULL when @n_structs is 0 of if an overflow occurs.
+ * 
+ * Since: 2.8
+ * Returns: a pointer to the allocated memory, cast to a pointer to @struct_type
+ */
+#define g_try_new(struct_type, n_structs)              _G_NEW (struct_type, n_structs, try_malloc)
+/**
+ * g_try_new0:
+ * @struct_type: the type of the elements to allocate
+ * @n_structs: the number of elements to allocate
+ * 
+ * Attempts to allocate @n_structs elements of type @struct_type, initialized
+ * to 0's, and returns %NULL on failure. Contrast with g_new0(), which aborts
+ * the program on failure.
+ * The returned pointer is cast to a pointer to the given type.
+ * The function returns %NULL when @n_structs is 0 of if an overflow occurs.
+ * 
+ * Since: 2.8
+ * Returns: a pointer to the allocated memory, cast to a pointer to @struct_type
+ */
+#define g_try_new0(struct_type, n_structs)             _G_NEW (struct_type, n_structs, try_malloc0)
+/**
+ * g_try_renew:
+ * @struct_type: the type of the elements to allocate
+ * @mem: the currently allocated memory
+ * @n_structs: the number of elements to allocate
+ * 
+ * Attempts to reallocate the memory pointed to by @mem, so that it now has
+ * space for @n_structs elements of type @struct_type, and returns %NULL on
+ * failure. Contrast with g_renew(), which aborts the program on failure.
+ * It returns the new address of the memory, which may have been moved.
+ * The function returns %NULL if an overflow occurs.
+ * 
+ * Since: 2.8
+ * Returns: a pointer to the new allocated memory, cast to a pointer to @struct_type
+ */
+#define g_try_renew(struct_type, mem, n_structs)       _G_RENEW (struct_type, mem, n_structs, try_realloc)
+
+
+/* Memory allocation virtualization for debugging purposes
+ * g_mem_set_vtable() has to be the very first GLib function called
+ * if being used
+ */
+struct _GMemVTable {
+  gpointer (*malloc)      (gsize    n_bytes);
+  gpointer (*realloc)     (gpointer mem,
+                          gsize    n_bytes);
+  void     (*free)        (gpointer mem);
+  /* optional; set to NULL if not used ! */
+  gpointer (*calloc)      (gsize    n_blocks,
+                          gsize    n_block_bytes);
+  gpointer (*try_malloc)  (gsize    n_bytes);
+  gpointer (*try_realloc) (gpointer mem,
+                          gsize    n_bytes);
+};
+void    g_mem_set_vtable (GMemVTable   *vtable);
+gboolean g_mem_is_system_malloc (void);
+
+GLIB_VAR gboolean g_mem_gc_friendly;
+
+/* Memory profiler and checker, has to be enabled via g_mem_set_vtable()
+ */
+GLIB_VAR GMemVTable    *glib_mem_profiler_table;
+void   g_mem_profile   (void);
+
+
+/* deprecated memchunks and allocators */
+#if !defined (G_DISABLE_DEPRECATED) || defined (GTK_COMPILATION) || defined (GDK_COMPILATION)
+typedef struct _GAllocator GAllocator;
+typedef struct _GMemChunk  GMemChunk;
+#define g_mem_chunk_create(type, pre_alloc, alloc_type)        ( \
+  g_mem_chunk_new (#type " mem chunks (" #pre_alloc ")", \
+                  sizeof (type), \
+                  sizeof (type) * (pre_alloc), \
+                  (alloc_type)) \
+)
+#define g_chunk_new(type, chunk)       ( \
+  (type *) g_mem_chunk_alloc (chunk) \
+)
+#define g_chunk_new0(type, chunk)      ( \
+  (type *) g_mem_chunk_alloc0 (chunk) \
+)
+#define g_chunk_free(mem, mem_chunk)   G_STMT_START { \
+  g_mem_chunk_free ((mem_chunk), (mem)); \
+} G_STMT_END
+#define G_ALLOC_ONLY     1
+#define G_ALLOC_AND_FREE  2
+GMemChunk* g_mem_chunk_new     (const gchar *name,
+                               gint         atom_size,
+                               gsize        area_size,
+                               gint         type);
+void       g_mem_chunk_destroy (GMemChunk   *mem_chunk);
+gpointer   g_mem_chunk_alloc   (GMemChunk   *mem_chunk);
+gpointer   g_mem_chunk_alloc0  (GMemChunk   *mem_chunk);
+void       g_mem_chunk_free    (GMemChunk   *mem_chunk,
+                               gpointer     mem);
+void       g_mem_chunk_clean   (GMemChunk   *mem_chunk);
+void       g_mem_chunk_reset   (GMemChunk   *mem_chunk);
+void       g_mem_chunk_print   (GMemChunk   *mem_chunk);
+void       g_mem_chunk_info    (void);
+void      g_blow_chunks       (void);
+GAllocator*g_allocator_new     (const gchar  *name,
+                               guint         n_preallocs);
+void       g_allocator_free    (GAllocator   *allocator);
+#define        G_ALLOCATOR_LIST       (1)
+#define        G_ALLOCATOR_SLIST      (2)
+#define        G_ALLOCATOR_NODE       (3)
+#endif /* G_DISABLE_DEPRECATED */
+
+G_END_DECLS
+
+#endif /* __G_MEM_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gmessages.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gmessages.c
new file mode 100644 (file)
index 0000000..3c18b95
--- /dev/null
@@ -0,0 +1,1183 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdio.h>
+#include <string.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <signal.h>
+#include <locale.h>
+#include <errno.h>
+
+#ifdef G_OS_WIN32
+#include <process.h>           /* For getpid() */
+#include <io.h>
+#  define STRICT               /* Strict typing, please */
+#  define _WIN32_WINDOWS 0x0401 /* to get IsDebuggerPresent */
+#  include <windows.h>
+#  undef STRICT
+#endif
+
+#include "gmessages.h"
+
+#include "gbacktrace.h"
+#include "gconvert.h"
+#include "gdebug.h"
+#include "gmem.h"
+#include "gprintfint.h"
+#include "gtestutils.h"
+#include "gthread.h"
+#include "gthreadprivate.h"
+#include "gstrfuncs.h"
+#include "gstring.h"
+
+
+/* --- structures --- */
+typedef struct _GLogDomain     GLogDomain;
+typedef struct _GLogHandler    GLogHandler;
+struct _GLogDomain
+{
+  gchar                *log_domain;
+  GLogLevelFlags fatal_mask;
+  GLogHandler  *handlers;
+  GLogDomain   *next;
+};
+struct _GLogHandler
+{
+  guint                 id;
+  GLogLevelFlags log_level;
+  GLogFunc      log_func;
+  gpointer      data;
+  GLogHandler  *next;
+};
+
+
+/* --- variables --- */
+static GMutex        *g_messages_lock = NULL;
+static GLogDomain    *g_log_domains = NULL;
+static GLogLevelFlags g_log_always_fatal = G_LOG_FATAL_MASK;
+static GPrintFunc     glib_print_func = NULL;
+static GPrintFunc     glib_printerr_func = NULL;
+static GPrivate             *g_log_depth = NULL;
+static GLogLevelFlags g_log_msg_prefix = G_LOG_LEVEL_ERROR | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_DEBUG;
+static GLogFunc       default_log_func = g_log_default_handler;
+static gpointer       default_log_data = NULL;
+static GTestLogFatalFunc fatal_log_func = NULL;
+static gpointer          fatal_log_data;
+
+/* --- functions --- */
+#ifdef G_OS_WIN32
+#  define STRICT
+#  include <windows.h>
+#  undef STRICT
+static gboolean win32_keep_fatal_message = FALSE;
+
+/* This default message will usually be overwritten. */
+/* Yes, a fixed size buffer is bad. So sue me. But g_error() is never
+ * called with huge strings, is it?
+ */
+static gchar  fatal_msg_buf[1000] = "Unspecified fatal error encountered, aborting.";
+static gchar *fatal_msg_ptr = fatal_msg_buf;
+
+#undef write
+static inline int
+dowrite (int          fd,
+        const void  *buf,
+        unsigned int len)
+{
+  if (win32_keep_fatal_message)
+    {
+      memcpy (fatal_msg_ptr, buf, len);
+      fatal_msg_ptr += len;
+      *fatal_msg_ptr = 0;
+      return len;
+    }
+
+  write (fd, buf, len);
+
+  return len;
+}
+#define write(fd, buf, len) dowrite(fd, buf, len)
+
+#endif
+
+static void
+write_string (int          fd,
+             const gchar *string)
+{
+  write (fd, string, strlen (string));
+}
+
+static void
+g_messages_prefixed_init (void)
+{
+  static gboolean initialized = FALSE;
+
+  if (!initialized)
+    {
+      const gchar *val;
+
+      initialized = TRUE;
+      val = g_getenv ("G_MESSAGES_PREFIXED");
+      
+      if (val)
+       {
+         const GDebugKey keys[] = {
+           { "error", G_LOG_LEVEL_ERROR },
+           { "critical", G_LOG_LEVEL_CRITICAL },
+           { "warning", G_LOG_LEVEL_WARNING },
+           { "message", G_LOG_LEVEL_MESSAGE },
+           { "info", G_LOG_LEVEL_INFO },
+           { "debug", G_LOG_LEVEL_DEBUG }
+         };
+         
+         g_log_msg_prefix = g_parse_debug_string (val, keys, G_N_ELEMENTS (keys));
+       }
+    }
+}
+
+static GLogDomain*
+g_log_find_domain_L (const gchar *log_domain)
+{
+  register GLogDomain *domain;
+  
+  domain = g_log_domains;
+  while (domain)
+    {
+      if (strcmp (domain->log_domain, log_domain) == 0)
+       return domain;
+      domain = domain->next;
+    }
+  return NULL;
+}
+
+static GLogDomain*
+g_log_domain_new_L (const gchar *log_domain)
+{
+  register GLogDomain *domain;
+
+  domain = g_new (GLogDomain, 1);
+  domain->log_domain = g_strdup (log_domain);
+  domain->fatal_mask = G_LOG_FATAL_MASK;
+  domain->handlers = NULL;
+  
+  domain->next = g_log_domains;
+  g_log_domains = domain;
+  
+  return domain;
+}
+
+static void
+g_log_domain_check_free_L (GLogDomain *domain)
+{
+  if (domain->fatal_mask == G_LOG_FATAL_MASK &&
+      domain->handlers == NULL)
+    {
+      register GLogDomain *last, *work;
+      
+      last = NULL;  
+
+      work = g_log_domains;
+      while (work)
+       {
+         if (work == domain)
+           {
+             if (last)
+               last->next = domain->next;
+             else
+               g_log_domains = domain->next;
+             g_free (domain->log_domain);
+             g_free (domain);
+             break;
+           }
+         last = work;
+         work = last->next;
+       }  
+    }
+}
+
+static GLogFunc
+g_log_domain_get_handler_L (GLogDomain *domain,
+                           GLogLevelFlags log_level,
+                           gpointer    *data)
+{
+  if (domain && log_level)
+    {
+      register GLogHandler *handler;
+      
+      handler = domain->handlers;
+      while (handler)
+       {
+         if ((handler->log_level & log_level) == log_level)
+           {
+             *data = handler->data;
+             return handler->log_func;
+           }
+         handler = handler->next;
+       }
+    }
+
+  *data = default_log_data;
+  return default_log_func;
+}
+
+GLogLevelFlags
+g_log_set_always_fatal (GLogLevelFlags fatal_mask)
+{
+  GLogLevelFlags old_mask;
+
+  /* restrict the global mask to levels that are known to glib
+   * since this setting applies to all domains
+   */
+  fatal_mask &= (1 << G_LOG_LEVEL_USER_SHIFT) - 1;
+  /* force errors to be fatal */
+  fatal_mask |= G_LOG_LEVEL_ERROR;
+  /* remove bogus flag */
+  fatal_mask &= ~G_LOG_FLAG_FATAL;
+
+  g_mutex_lock (g_messages_lock);
+  old_mask = g_log_always_fatal;
+  g_log_always_fatal = fatal_mask;
+  g_mutex_unlock (g_messages_lock);
+
+  return old_mask;
+}
+
+GLogLevelFlags
+g_log_set_fatal_mask (const gchar   *log_domain,
+                     GLogLevelFlags fatal_mask)
+{
+  GLogLevelFlags old_flags;
+  register GLogDomain *domain;
+  
+  if (!log_domain)
+    log_domain = "";
+  
+  /* force errors to be fatal */
+  fatal_mask |= G_LOG_LEVEL_ERROR;
+  /* remove bogus flag */
+  fatal_mask &= ~G_LOG_FLAG_FATAL;
+  
+  g_mutex_lock (g_messages_lock);
+
+  domain = g_log_find_domain_L (log_domain);
+  if (!domain)
+    domain = g_log_domain_new_L (log_domain);
+  old_flags = domain->fatal_mask;
+  
+  domain->fatal_mask = fatal_mask;
+  g_log_domain_check_free_L (domain);
+
+  g_mutex_unlock (g_messages_lock);
+
+  return old_flags;
+}
+
+guint
+g_log_set_handler (const gchar  *log_domain,
+                  GLogLevelFlags log_levels,
+                  GLogFunc       log_func,
+                  gpointer       user_data)
+{
+  static guint handler_id = 0;
+  GLogDomain *domain;
+  GLogHandler *handler;
+  
+  g_return_val_if_fail ((log_levels & G_LOG_LEVEL_MASK) != 0, 0);
+  g_return_val_if_fail (log_func != NULL, 0);
+  
+  if (!log_domain)
+    log_domain = "";
+
+  handler = g_new (GLogHandler, 1);
+
+  g_mutex_lock (g_messages_lock);
+
+  domain = g_log_find_domain_L (log_domain);
+  if (!domain)
+    domain = g_log_domain_new_L (log_domain);
+  
+  handler->id = ++handler_id;
+  handler->log_level = log_levels;
+  handler->log_func = log_func;
+  handler->data = user_data;
+  handler->next = domain->handlers;
+  domain->handlers = handler;
+
+  g_mutex_unlock (g_messages_lock);
+  
+  return handler_id;
+}
+
+GLogFunc
+g_log_set_default_handler (GLogFunc log_func,
+                          gpointer user_data)
+{
+  GLogFunc old_log_func;
+  
+  g_mutex_lock (g_messages_lock);
+  old_log_func = default_log_func;
+  default_log_func = log_func;
+  default_log_data = user_data;
+  g_mutex_unlock (g_messages_lock);
+  
+  return old_log_func;
+}
+
+/**
+ * g_test_log_set_fatal_handler:
+ * @log_func: the log handler function.
+ * @user_data: data passed to the log handler.
+ *
+ * Installs a non-error fatal log handler which can be
+ * used to decide whether log messages which are counted
+ * as fatal abort the program.
+ *
+ * The use case here is that you are running a test case
+ * that depends on particular libraries or circumstances
+ * and cannot prevent certain known critical or warning
+ * messages. So you install a handler that compares the
+ * domain and message to precisely not abort in such a case.
+ *
+ * Note that the handler is reset at the beginning of
+ * any test case, so you have to set it inside each test
+ * function which needs the special behavior.
+ *
+ * This handler has no effect on g_error messages.
+ *
+ * Since: 2.22
+ **/
+void
+g_test_log_set_fatal_handler (GTestLogFatalFunc log_func,
+                              gpointer          user_data)
+{
+  g_mutex_lock (g_messages_lock);
+  fatal_log_func = log_func;
+  fatal_log_data = user_data;
+  g_mutex_unlock (g_messages_lock);
+}
+
+void
+g_log_remove_handler (const gchar *log_domain,
+                     guint        handler_id)
+{
+  register GLogDomain *domain;
+  
+  g_return_if_fail (handler_id > 0);
+  
+  if (!log_domain)
+    log_domain = "";
+  
+  g_mutex_lock (g_messages_lock);
+  domain = g_log_find_domain_L (log_domain);
+  if (domain)
+    {
+      GLogHandler *work, *last;
+      
+      last = NULL;
+      work = domain->handlers;
+      while (work)
+       {
+         if (work->id == handler_id)
+           {
+             if (last)
+               last->next = work->next;
+             else
+               domain->handlers = work->next;
+             g_log_domain_check_free_L (domain); 
+             g_mutex_unlock (g_messages_lock);
+             g_free (work);
+             return;
+           }
+         last = work;
+         work = last->next;
+       }
+    } 
+  g_mutex_unlock (g_messages_lock);
+  g_warning ("%s: could not find handler with id `%d' for domain \"%s\"",
+            G_STRLOC, handler_id, log_domain);
+}
+
+void
+g_logv (const gchar   *log_domain,
+       GLogLevelFlags log_level,
+       const gchar   *format,
+       va_list        args1)
+{
+  gboolean was_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
+  gboolean was_recursion = (log_level & G_LOG_FLAG_RECURSION) != 0;
+  gint i;
+
+  log_level &= G_LOG_LEVEL_MASK;
+  if (!log_level)
+    return;
+
+  for (i = g_bit_nth_msf (log_level, -1); i >= 0; i = g_bit_nth_msf (log_level, i))
+    {
+      register GLogLevelFlags test_level;
+
+      test_level = 1 << i;
+      if (log_level & test_level)
+       {
+         guint depth = GPOINTER_TO_UINT (g_private_get (g_log_depth));
+         GLogDomain *domain;
+         GLogFunc log_func;
+         GLogLevelFlags domain_fatal_mask;
+         gpointer data = NULL;
+          gboolean masquerade_fatal = FALSE;
+
+         if (was_fatal)
+           test_level |= G_LOG_FLAG_FATAL;
+         if (was_recursion)
+           test_level |= G_LOG_FLAG_RECURSION;
+
+         /* check recursion and lookup handler */
+         g_mutex_lock (g_messages_lock);
+         domain = g_log_find_domain_L (log_domain ? log_domain : "");
+         if (depth)
+           test_level |= G_LOG_FLAG_RECURSION;
+         depth++;
+         domain_fatal_mask = domain ? domain->fatal_mask : G_LOG_FATAL_MASK;
+         if ((domain_fatal_mask | g_log_always_fatal) & test_level)
+           test_level |= G_LOG_FLAG_FATAL;
+         if (test_level & G_LOG_FLAG_RECURSION)
+           log_func = _g_log_fallback_handler;
+         else
+           log_func = g_log_domain_get_handler_L (domain, test_level, &data);
+         domain = NULL;
+         g_mutex_unlock (g_messages_lock);
+
+         g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
+
+         /* had to defer debug initialization until we can keep track of recursion */
+         if (!(test_level & G_LOG_FLAG_RECURSION) && !_g_debug_initialized)
+           {
+             GLogLevelFlags orig_test_level = test_level;
+
+             _g_debug_init ();
+             if ((domain_fatal_mask | g_log_always_fatal) & test_level)
+               test_level |= G_LOG_FLAG_FATAL;
+             if (test_level != orig_test_level)
+               {
+                 /* need a relookup, not nice, but not too bad either */
+                 g_mutex_lock (g_messages_lock);
+                 domain = g_log_find_domain_L (log_domain ? log_domain : "");
+                 log_func = g_log_domain_get_handler_L (domain, test_level, &data);
+                 domain = NULL;
+                 g_mutex_unlock (g_messages_lock);
+               }
+           }
+
+         if (test_level & G_LOG_FLAG_RECURSION)
+           {
+             /* we use a stack buffer of fixed size, since we're likely
+              * in an out-of-memory situation
+              */
+             gchar buffer[1025];
+              gsize size;
+              va_list args2;
+
+              G_VA_COPY (args2, args1);
+             size = _g_vsnprintf (buffer, 1024, format, args2);
+              va_end (args2);
+
+             log_func (log_domain, test_level, buffer, data);
+           }
+         else
+           {
+             gchar *msg;
+              va_list args2;
+
+              G_VA_COPY (args2, args1);
+              msg = g_strdup_vprintf (format, args2);
+              va_end (args2);
+
+             log_func (log_domain, test_level, msg, data);
+
+              if ((test_level & G_LOG_FLAG_FATAL)
+                && !(test_level & G_LOG_LEVEL_ERROR))
+                {
+                  masquerade_fatal = fatal_log_func
+                    && !fatal_log_func (log_domain, test_level, msg, data);
+                }
+
+             g_free (msg);
+           }
+
+         if ((test_level & G_LOG_FLAG_FATAL) && !masquerade_fatal)
+            {
+#ifdef G_OS_WIN32
+             gchar *locale_msg = g_locale_from_utf8 (fatal_msg_buf, -1, NULL, NULL, NULL);
+             
+             MessageBox (NULL, locale_msg, NULL,
+                         MB_ICONERROR|MB_SETFOREGROUND);
+             if (IsDebuggerPresent () && !(test_level & G_LOG_FLAG_RECURSION))
+               G_BREAKPOINT ();
+             else
+               abort ();
+#else
+#if defined (G_ENABLE_DEBUG) && defined (SIGTRAP)
+             if (!(test_level & G_LOG_FLAG_RECURSION))
+               G_BREAKPOINT ();
+             else
+               abort ();
+#else /* !G_ENABLE_DEBUG || !SIGTRAP */
+             abort ();
+#endif /* !G_ENABLE_DEBUG || !SIGTRAP */
+#endif /* !G_OS_WIN32 */
+           }
+         
+         depth--;
+         g_private_set (g_log_depth, GUINT_TO_POINTER (depth));
+       }
+    }
+}
+
+void
+g_log (const gchar   *log_domain,
+       GLogLevelFlags log_level,
+       const gchar   *format,
+       ...)
+{
+  va_list args;
+  
+  va_start (args, format);
+  g_logv (log_domain, log_level, format, args);
+  va_end (args);
+}
+
+void
+g_return_if_fail_warning (const char *log_domain,
+                         const char *pretty_function,
+                         const char *expression)
+{
+  g_log (log_domain,
+        G_LOG_LEVEL_CRITICAL,
+        "%s: assertion `%s' failed",
+        pretty_function,
+        expression);
+}
+
+void
+g_warn_message (const char     *domain,
+                const char     *file,
+                int             line,
+                const char     *func,
+                const char     *warnexpr)
+{
+  char *s, lstr[32];
+  g_snprintf (lstr, 32, "%d", line);
+  if (warnexpr)
+    s = g_strconcat ("(", file, ":", lstr, "):",
+                     func, func[0] ? ":" : "",
+                     " runtime check failed: (", warnexpr, ")", NULL);
+  else
+    s = g_strconcat ("(", file, ":", lstr, "):",
+                     func, func[0] ? ":" : "",
+                     " ", "code should not be reached", NULL);
+  g_log (domain, G_LOG_LEVEL_WARNING, "%s", s);
+  g_free (s);
+}
+
+void
+g_assert_warning (const char *log_domain,
+                 const char *file,
+                 const int   line,
+                 const char *pretty_function,
+                 const char *expression)
+{
+  g_log (log_domain,
+        G_LOG_LEVEL_ERROR,
+        expression 
+        ? "file %s: line %d (%s): assertion failed: (%s)"
+        : "file %s: line %d (%s): should not be reached",
+        file, 
+        line, 
+        pretty_function,
+        expression);
+  abort ();
+}
+
+#define CHAR_IS_SAFE(wc) (!((wc < 0x20 && wc != '\t' && wc != '\n' && wc != '\r') || \
+                           (wc == 0x7f) || \
+                           (wc >= 0x80 && wc < 0xa0)))
+     
+static gchar*
+strdup_convert (const gchar *string,
+               const gchar *charset)
+{
+  if (!g_utf8_validate (string, -1, NULL))
+    {
+      GString *gstring = g_string_new ("[Invalid UTF-8] ");
+      guchar *p;
+
+      for (p = (guchar *)string; *p; p++)
+       {
+         if (CHAR_IS_SAFE(*p) &&
+             !(*p == '\r' && *(p + 1) != '\n') &&
+             *p < 0x80)
+           g_string_append_c (gstring, *p);
+         else
+           g_string_append_printf (gstring, "\\x%02x", (guint)(guchar)*p);
+       }
+      
+      return g_string_free (gstring, FALSE);
+    }
+  else
+    {
+      GError *err = NULL;
+      
+      gchar *result = g_convert_with_fallback (string, -1, charset, "UTF-8", "?", NULL, NULL, &err);
+      if (result)
+       return result;
+      else
+       {
+         /* Not thread-safe, but doesn't matter if we print the warning twice
+          */
+         static gboolean warned = FALSE; 
+         if (!warned)
+           {
+             warned = TRUE;
+             _g_fprintf (stderr, "GLib: Cannot convert message: %s\n", err->message);
+           }
+         g_error_free (err);
+         
+         return g_strdup (string);
+       }
+    }
+}
+
+/* For a radix of 8 we need at most 3 output bytes for 1 input
+ * byte. Additionally we might need up to 2 output bytes for the
+ * readix prefix and 1 byte for the trailing NULL.
+ */
+#define FORMAT_UNSIGNED_BUFSIZE ((GLIB_SIZEOF_LONG * 3) + 3)
+
+static void
+format_unsigned (gchar  *buf,
+                gulong  num,
+                guint   radix)
+{
+  gulong tmp;
+  gchar c;
+  gint i, n;
+
+  /* we may not call _any_ GLib functions here (or macros like g_return_if_fail()) */
+
+  if (radix != 8 && radix != 10 && radix != 16)
+    {
+      *buf = '\000';
+      return;
+    }
+  
+  if (!num)
+    {
+      *buf++ = '0';
+      *buf = '\000';
+      return;
+    } 
+  
+  if (radix == 16)
+    {
+      *buf++ = '0';
+      *buf++ = 'x';
+    }
+  else if (radix == 8)
+    {
+      *buf++ = '0';
+    }
+       
+  n = 0;
+  tmp = num;
+  while (tmp)
+    {
+      tmp /= radix;
+      n++;
+    }
+
+  i = n;
+
+  /* Again we can't use g_assert; actually this check should _never_ fail. */
+  if (n > FORMAT_UNSIGNED_BUFSIZE - 3)
+    {
+      *buf = '\000';
+      return;
+    }
+
+  while (num)
+    {
+      i--;
+      c = (num % radix);
+      if (c < 10)
+       buf[i] = c + '0';
+      else
+       buf[i] = c + 'a' - 10;
+      num /= radix;
+    }
+  
+  buf[n] = '\000';
+}
+
+/* string size big enough to hold level prefix */
+#define        STRING_BUFFER_SIZE      (FORMAT_UNSIGNED_BUFSIZE + 32)
+
+#define        ALERT_LEVELS            (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL | G_LOG_LEVEL_WARNING)
+
+static int
+mklevel_prefix (gchar          level_prefix[STRING_BUFFER_SIZE],
+               GLogLevelFlags log_level)
+{
+  gboolean to_stdout = TRUE;
+
+  /* we may not call _any_ GLib functions here */
+
+  switch (log_level & G_LOG_LEVEL_MASK)
+    {
+    case G_LOG_LEVEL_ERROR:
+      strcpy (level_prefix, "ERROR");
+      to_stdout = FALSE;
+      break;
+    case G_LOG_LEVEL_CRITICAL:
+      strcpy (level_prefix, "CRITICAL");
+      to_stdout = FALSE;
+      break;
+    case G_LOG_LEVEL_WARNING:
+      strcpy (level_prefix, "WARNING");
+      to_stdout = FALSE;
+      break;
+    case G_LOG_LEVEL_MESSAGE:
+      strcpy (level_prefix, "Message");
+      to_stdout = FALSE;
+      break;
+    case G_LOG_LEVEL_INFO:
+      strcpy (level_prefix, "INFO");
+      break;
+    case G_LOG_LEVEL_DEBUG:
+      strcpy (level_prefix, "DEBUG");
+      break;
+    default:
+      if (log_level)
+       {
+         strcpy (level_prefix, "LOG-");
+         format_unsigned (level_prefix + 4, log_level & G_LOG_LEVEL_MASK, 16);
+       }
+      else
+       strcpy (level_prefix, "LOG");
+      break;
+    }
+  if (log_level & G_LOG_FLAG_RECURSION)
+    strcat (level_prefix, " (recursed)");
+  if (log_level & ALERT_LEVELS)
+    strcat (level_prefix, " **");
+
+#ifdef G_OS_WIN32
+  win32_keep_fatal_message = (log_level & G_LOG_FLAG_FATAL) != 0;
+#endif
+  return to_stdout ? 1 : 2;
+}
+
+void
+_g_log_fallback_handler (const gchar   *log_domain,
+                        GLogLevelFlags log_level,
+                        const gchar   *message,
+                        gpointer       unused_data)
+{
+  gchar level_prefix[STRING_BUFFER_SIZE];
+#ifndef G_OS_WIN32
+  gchar pid_string[FORMAT_UNSIGNED_BUFSIZE];
+#endif
+  gboolean is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
+  int fd;
+
+  /* we can not call _any_ GLib functions in this fallback handler,
+   * which is why we skip UTF-8 conversion, etc.
+   * since we either recursed or ran out of memory, we're in a pretty
+   * pathologic situation anyways, what we can do is giving the
+   * the process ID unconditionally however.
+   */
+
+  fd = mklevel_prefix (level_prefix, log_level);
+  if (!message)
+    message = "(NULL) message";
+
+#ifndef G_OS_WIN32
+  format_unsigned (pid_string, getpid (), 10);
+#endif
+
+  if (log_domain)
+    write_string (fd, "\n");
+  else
+    write_string (fd, "\n** ");
+
+#ifndef G_OS_WIN32
+  write_string (fd, "(process:");
+  write_string (fd, pid_string);
+  write_string (fd, "): ");
+#endif
+
+  if (log_domain)
+    {
+      write_string (fd, log_domain);
+      write_string (fd, "-");
+    }
+  write_string (fd, level_prefix);
+  write_string (fd, ": ");
+  write_string (fd, message);
+  if (is_fatal)
+    write_string (fd, "\naborting...\n");
+  else
+    write_string (fd, "\n");
+}
+
+static void
+escape_string (GString *string)
+{
+  const char *p = string->str;
+  gunichar wc;
+
+  while (p < string->str + string->len)
+    {
+      gboolean safe;
+           
+      wc = g_utf8_get_char_validated (p, -1);
+      if (wc == (gunichar)-1 || wc == (gunichar)-2)  
+       {
+         gchar *tmp;
+         guint pos;
+
+         pos = p - string->str;
+
+         /* Emit invalid UTF-8 as hex escapes 
+           */
+         tmp = g_strdup_printf ("\\x%02x", (guint)(guchar)*p);
+         g_string_erase (string, pos, 1);
+         g_string_insert (string, pos, tmp);
+
+         p = string->str + (pos + 4); /* Skip over escape sequence */
+
+         g_free (tmp);
+         continue;
+       }
+      if (wc == '\r')
+       {
+         safe = *(p + 1) == '\n';
+       }
+      else
+       {
+         safe = CHAR_IS_SAFE (wc);
+       }
+      
+      if (!safe)
+       {
+         gchar *tmp;
+         guint pos;
+
+         pos = p - string->str;
+         
+         /* Largest char we escape is 0x0a, so we don't have to worry
+          * about 8-digit \Uxxxxyyyy
+          */
+         tmp = g_strdup_printf ("\\u%04x", wc); 
+         g_string_erase (string, pos, g_utf8_next_char (p) - p);
+         g_string_insert (string, pos, tmp);
+         g_free (tmp);
+
+         p = string->str + (pos + 6); /* Skip over escape sequence */
+       }
+      else
+       p = g_utf8_next_char (p);
+    }
+}
+
+#ifdef BUILD_WITH_ANDROID
+#include <android/log.h>
+void g_log_default_handler (const gchar   *log_domain,
+                      GLogLevelFlags log_level,
+                      const gchar   *message,
+                      gpointer       unused_data)
+{
+  gint pri = ANDROID_LOG_UNKNOWN;
+
+  if (log_level & G_LOG_FLAG_FATAL)
+    pri = ANDROID_LOG_FATAL;
+  else if (log_level & (G_LOG_LEVEL_ERROR | G_LOG_LEVEL_CRITICAL))
+    pri = ANDROID_LOG_ERROR;
+  else if (log_level & G_LOG_LEVEL_WARNING)
+    pri = ANDROID_LOG_WARN;
+  else if (log_level & (G_LOG_LEVEL_MESSAGE | G_LOG_LEVEL_INFO))
+    pri = ANDROID_LOG_INFO;
+  else if (log_level & G_LOG_LEVEL_DEBUG)
+    pri = ANDROID_LOG_DEBUG;
+
+  __android_log_print (pri, log_domain == NULL ? "GLib-NULL" : log_domain, message);
+}
+#else
+void
+g_log_default_handler (const gchar   *log_domain,
+                      GLogLevelFlags log_level,
+                      const gchar   *message,
+                      gpointer       unused_data)
+{
+  gboolean is_fatal = (log_level & G_LOG_FLAG_FATAL) != 0;
+  gchar level_prefix[STRING_BUFFER_SIZE], *string;
+  GString *gstring;
+  int fd;
+
+  /* we can be called externally with recursion for whatever reason */
+  if (log_level & G_LOG_FLAG_RECURSION)
+    {
+      _g_log_fallback_handler (log_domain, log_level, message, unused_data);
+      return;
+    }
+
+  g_messages_prefixed_init ();
+
+  fd = mklevel_prefix (level_prefix, log_level);
+
+  gstring = g_string_new (NULL);
+  if (log_level & ALERT_LEVELS)
+    g_string_append (gstring, "\n");
+  if (!log_domain)
+    g_string_append (gstring, "** ");
+
+  if ((g_log_msg_prefix & log_level) == log_level)
+    {
+      const gchar *prg_name = g_get_prgname ();
+      
+      if (!prg_name)
+       g_string_append_printf (gstring, "(process:%lu): ", (gulong)getpid ());
+      else
+       g_string_append_printf (gstring, "(%s:%lu): ", prg_name, (gulong)getpid ());
+    }
+
+  if (log_domain)
+    {
+      g_string_append (gstring, log_domain);
+      g_string_append_c (gstring, '-');
+    }
+  g_string_append (gstring, level_prefix);
+
+  g_string_append (gstring, ": ");
+  if (!message)
+    g_string_append (gstring, "(NULL) message");
+  else
+    {
+      GString *msg;
+      const gchar *charset;
+
+      msg = g_string_new (message);
+      escape_string (msg);
+
+      if (g_get_charset (&charset))
+       g_string_append (gstring, msg->str);    /* charset is UTF-8 already */
+      else
+       {
+         string = strdup_convert (msg->str, charset);
+         g_string_append (gstring, string);
+         g_free (string);
+       }
+
+      g_string_free (msg, TRUE);
+    }
+  if (is_fatal)
+    g_string_append (gstring, "\naborting...\n");
+  else
+    g_string_append (gstring, "\n");
+
+  string = g_string_free (gstring, FALSE);
+
+  write_string (fd, string);
+  g_free (string);
+}
+#endif
+
+GPrintFunc
+g_set_print_handler (GPrintFunc func)
+{
+  GPrintFunc old_print_func;
+  
+  g_mutex_lock (g_messages_lock);
+  old_print_func = glib_print_func;
+  glib_print_func = func;
+  g_mutex_unlock (g_messages_lock);
+  
+  return old_print_func;
+}
+
+void
+g_print (const gchar *format,
+        ...)
+{
+  va_list args;
+  gchar *string;
+  GPrintFunc local_glib_print_func;
+  
+  g_return_if_fail (format != NULL);
+  
+  va_start (args, format);
+  string = g_strdup_vprintf (format, args);
+  va_end (args);
+  
+  g_mutex_lock (g_messages_lock);
+  local_glib_print_func = glib_print_func;
+  g_mutex_unlock (g_messages_lock);
+  
+  if (local_glib_print_func)
+    local_glib_print_func (string);
+  else
+    {
+      const gchar *charset;
+
+      if (g_get_charset (&charset))
+       fputs (string, stdout); /* charset is UTF-8 already */
+      else
+       {
+         gchar *lstring = strdup_convert (string, charset);
+
+         fputs (lstring, stdout);
+         g_free (lstring);
+       }
+      fflush (stdout);
+    }
+  g_free (string);
+}
+
+GPrintFunc
+g_set_printerr_handler (GPrintFunc func)
+{
+  GPrintFunc old_printerr_func;
+  
+  g_mutex_lock (g_messages_lock);
+  old_printerr_func = glib_printerr_func;
+  glib_printerr_func = func;
+  g_mutex_unlock (g_messages_lock);
+  
+  return old_printerr_func;
+}
+
+void
+g_printerr (const gchar *format,
+           ...)
+{
+  va_list args;
+  gchar *string;
+  GPrintFunc local_glib_printerr_func;
+  
+  g_return_if_fail (format != NULL);
+  
+  va_start (args, format);
+  string = g_strdup_vprintf (format, args);
+  va_end (args);
+  
+  g_mutex_lock (g_messages_lock);
+  local_glib_printerr_func = glib_printerr_func;
+  g_mutex_unlock (g_messages_lock);
+  
+  if (local_glib_printerr_func)
+    local_glib_printerr_func (string);
+  else
+    {
+      const gchar *charset;
+
+      if (g_get_charset (&charset))
+       fputs (string, stderr); /* charset is UTF-8 already */
+      else
+       {
+         gchar *lstring = strdup_convert (string, charset);
+
+         fputs (lstring, stderr);
+         g_free (lstring);
+       }
+      fflush (stderr);
+    }
+  g_free (string);
+}
+
+gsize
+g_printf_string_upper_bound (const gchar *format,
+                            va_list      args)
+{
+  gchar c;
+  return _g_vsnprintf (&c, 1, format, args) + 1;
+}
+
+void
+_g_messages_thread_init_nomessage (void)
+{
+  g_messages_lock = g_mutex_new ();
+  g_log_depth = g_private_new (NULL);
+  g_messages_prefixed_init ();
+  _g_debug_init ();
+}
+
+gboolean _g_debug_initialized = FALSE;
+guint _g_debug_flags = 0;
+
+void
+_g_debug_init (void) 
+{
+  const gchar *val;
+  
+  _g_debug_initialized = TRUE;
+  
+  val = g_getenv ("G_DEBUG");
+  if (val != NULL)
+    {
+      const GDebugKey keys[] = {
+       {"fatal_warnings", G_DEBUG_FATAL_WARNINGS},
+       {"fatal_criticals", G_DEBUG_FATAL_CRITICALS}
+      };
+      
+      _g_debug_flags = g_parse_debug_string (val, keys, G_N_ELEMENTS (keys));
+    }
+  
+  if (_g_debug_flags & G_DEBUG_FATAL_WARNINGS) 
+    {
+      GLogLevelFlags fatal_mask;
+      
+      fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
+      fatal_mask |= G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL;
+      g_log_set_always_fatal (fatal_mask);
+    }
+  
+  if (_g_debug_flags & G_DEBUG_FATAL_CRITICALS) 
+    {
+      GLogLevelFlags fatal_mask;
+      
+      fatal_mask = g_log_set_always_fatal (G_LOG_FATAL_MASK);
+      fatal_mask |= G_LOG_LEVEL_CRITICAL;
+      g_log_set_always_fatal (fatal_mask);
+    }
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gmessages.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gmessages.h
new file mode 100644 (file)
index 0000000..9acaec6
--- /dev/null
@@ -0,0 +1,343 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_MESSAGES_H__
+#define __G_MESSAGES_H__
+
+#include <stdarg.h>
+#include <glib/gtypes.h>
+#include <glib/gmacros.h>
+
+/* Suppress warnings when GCC is in -pedantic mode and not -std=c99
+ */
+#if (__GNUC__ >= 3 || (__GNUC__ == 2 && __GNUC_MINOR__ >= 96))
+#pragma GCC system_header
+#endif
+
+G_BEGIN_DECLS
+
+/* calculate a string size, guaranteed to fit format + args.
+ */
+gsize  g_printf_string_upper_bound (const gchar* format,
+                                    va_list      args);
+
+/* Log level shift offset for user defined
+ * log levels (0-7 are used by GLib).
+ */
+#define G_LOG_LEVEL_USER_SHIFT  (8)
+
+/* Glib log levels and flags.
+ */
+typedef enum
+{
+  /* log flags */
+  G_LOG_FLAG_RECURSION          = 1 << 0,
+  G_LOG_FLAG_FATAL              = 1 << 1,
+
+  /* GLib log levels */
+  G_LOG_LEVEL_ERROR             = 1 << 2,       /* always fatal */
+  G_LOG_LEVEL_CRITICAL          = 1 << 3,
+  G_LOG_LEVEL_WARNING           = 1 << 4,
+  G_LOG_LEVEL_MESSAGE           = 1 << 5,
+  G_LOG_LEVEL_INFO              = 1 << 6,
+  G_LOG_LEVEL_DEBUG             = 1 << 7,
+
+  G_LOG_LEVEL_MASK              = ~(G_LOG_FLAG_RECURSION | G_LOG_FLAG_FATAL)
+} GLogLevelFlags;
+
+/* GLib log levels that are considered fatal by default */
+#define G_LOG_FATAL_MASK        (G_LOG_FLAG_RECURSION | G_LOG_LEVEL_ERROR)
+
+typedef void            (*GLogFunc)             (const gchar   *log_domain,
+                                                 GLogLevelFlags log_level,
+                                                 const gchar   *message,
+                                                 gpointer       user_data);
+
+/* Logging mechanism
+ */
+guint           g_log_set_handler       (const gchar    *log_domain,
+                                         GLogLevelFlags  log_levels,
+                                         GLogFunc        log_func,
+                                         gpointer        user_data);
+void            g_log_remove_handler    (const gchar    *log_domain,
+                                         guint           handler_id);
+void            g_log_default_handler   (const gchar    *log_domain,
+                                         GLogLevelFlags  log_level,
+                                         const gchar    *message,
+                                         gpointer        unused_data);
+GLogFunc        g_log_set_default_handler (GLogFunc      log_func,
+                                          gpointer      user_data);
+void            g_log                   (const gchar    *log_domain,
+                                         GLogLevelFlags  log_level,
+                                         const gchar    *format,
+                                         ...) G_GNUC_PRINTF (3, 4);
+void            g_logv                  (const gchar    *log_domain,
+                                         GLogLevelFlags  log_level,
+                                         const gchar    *format,
+                                         va_list         args);
+GLogLevelFlags  g_log_set_fatal_mask    (const gchar    *log_domain,
+                                         GLogLevelFlags  fatal_mask);
+GLogLevelFlags  g_log_set_always_fatal  (GLogLevelFlags  fatal_mask);
+
+/* internal */
+G_GNUC_INTERNAL void   _g_log_fallback_handler (const gchar   *log_domain,
+                                                GLogLevelFlags log_level,
+                                                const gchar   *message,
+                                                gpointer       unused_data);
+
+/* Internal functions, used to implement the following macros */
+void g_return_if_fail_warning (const char *log_domain,
+                              const char *pretty_function,
+                              const char *expression);
+void g_warn_message           (const char     *domain,
+                               const char     *file,
+                               int             line,
+                               const char     *func,
+                               const char     *warnexpr);
+#ifndef G_DISABLE_DEPRECATED
+void g_assert_warning         (const char *log_domain,
+                              const char *file,
+                              const int   line,
+                              const char *pretty_function,
+                              const char *expression) G_GNUC_NORETURN;
+#endif /* !G_DISABLE_DEPRECATED */
+
+
+#ifndef G_LOG_DOMAIN
+#define G_LOG_DOMAIN    ((gchar*) 0)
+#endif  /* G_LOG_DOMAIN */
+#ifdef G_HAVE_ISO_VARARGS
+/* for(;;) ; so that GCC knows that control doesn't go past g_error().
+ * Put space before ending semicolon to avoid C++ build warnings.
+ */
+#define g_error(...)  G_STMT_START {                 \
+                        g_log (G_LOG_DOMAIN,         \
+                               G_LOG_LEVEL_ERROR,    \
+                               __VA_ARGS__);         \
+                        for (;;) ;                   \
+                      } G_STMT_END
+                        
+#define g_message(...)  g_log (G_LOG_DOMAIN,         \
+                               G_LOG_LEVEL_MESSAGE,  \
+                               __VA_ARGS__)
+#define g_critical(...) g_log (G_LOG_DOMAIN,         \
+                               G_LOG_LEVEL_CRITICAL, \
+                               __VA_ARGS__)
+#define g_warning(...)  g_log (G_LOG_DOMAIN,         \
+                               G_LOG_LEVEL_WARNING,  \
+                               __VA_ARGS__)
+#define g_debug(...)    g_log (G_LOG_DOMAIN,         \
+                               G_LOG_LEVEL_DEBUG,    \
+                               __VA_ARGS__)
+#elif defined(G_HAVE_GNUC_VARARGS)
+#define g_error(format...)    G_STMT_START {                 \
+                                g_log (G_LOG_DOMAIN,         \
+                                       G_LOG_LEVEL_ERROR,    \
+                                       format);              \
+                                for (;;) ;                   \
+                              } G_STMT_END
+                              
+#define g_message(format...)    g_log (G_LOG_DOMAIN,         \
+                                       G_LOG_LEVEL_MESSAGE,  \
+                                       format)
+#define g_critical(format...)   g_log (G_LOG_DOMAIN,         \
+                                       G_LOG_LEVEL_CRITICAL, \
+                                       format)
+#define g_warning(format...)    g_log (G_LOG_DOMAIN,         \
+                                       G_LOG_LEVEL_WARNING,  \
+                                       format)
+#define g_debug(format...)      g_log (G_LOG_DOMAIN,         \
+                                       G_LOG_LEVEL_DEBUG,    \
+                                       format)
+#else   /* no varargs macros */
+static void
+g_error (const gchar *format,
+         ...)
+{
+  va_list args;
+  va_start (args, format);
+  g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_ERROR, format, args);
+  va_end (args);
+
+  for(;;) ;
+}
+static void
+g_message (const gchar *format,
+           ...)
+{
+  va_list args;
+  va_start (args, format);
+  g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_MESSAGE, format, args);
+  va_end (args);
+}
+static void
+g_critical (const gchar *format,
+            ...)
+{
+  va_list args;
+  va_start (args, format);
+  g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_CRITICAL, format, args);
+  va_end (args);
+}
+static void
+g_warning (const gchar *format,
+           ...)
+{
+  va_list args;
+  va_start (args, format);
+  g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_WARNING, format, args);
+  va_end (args);
+}
+static void
+g_debug (const gchar *format,
+         ...)
+{
+  va_list args;
+  va_start (args, format);
+  g_logv (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG, format, args);
+  va_end (args);
+}
+#endif  /* !__GNUC__ */
+
+typedef void    (*GPrintFunc)           (const gchar    *string);
+void            g_print                 (const gchar    *format,
+                                         ...) G_GNUC_PRINTF (1, 2);
+GPrintFunc      g_set_print_handler     (GPrintFunc      func);
+void            g_printerr              (const gchar    *format,
+                                         ...) G_GNUC_PRINTF (1, 2);
+GPrintFunc      g_set_printerr_handler  (GPrintFunc      func);
+
+
+/* Provide macros for graceful error handling.
+ * The "return" macros will return from the current function.
+ * Two different definitions are given for the macros in
+ * order to support gcc's __PRETTY_FUNCTION__ capability.
+ */
+
+#define g_warn_if_reached()     do { g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, NULL); } while (0)
+#define g_warn_if_fail(expr)    do { if G_LIKELY (expr) ; else \
+                                       g_warn_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, #expr); } while (0)
+
+#ifdef G_DISABLE_CHECKS
+
+#define g_return_if_fail(expr)                 G_STMT_START{ (void)0; }G_STMT_END
+#define g_return_val_if_fail(expr,val)         G_STMT_START{ (void)0; }G_STMT_END
+#define g_return_if_reached()                  G_STMT_START{ return; }G_STMT_END
+#define g_return_val_if_reached(val)           G_STMT_START{ return (val); }G_STMT_END
+
+#else /* !G_DISABLE_CHECKS */
+
+#ifdef __GNUC__
+
+#define g_return_if_fail(expr)         G_STMT_START{                   \
+     if G_LIKELY(expr) { } else                                        \
+       {                                                               \
+        g_return_if_fail_warning (G_LOG_DOMAIN,                        \
+                                  __PRETTY_FUNCTION__,                 \
+                                  #expr);                              \
+        return;                                                        \
+       };                              }G_STMT_END
+
+#define g_return_val_if_fail(expr,val) G_STMT_START{                   \
+     if G_LIKELY(expr) { } else                                                \
+       {                                                               \
+        g_return_if_fail_warning (G_LOG_DOMAIN,                        \
+                                  __PRETTY_FUNCTION__,                 \
+                                  #expr);                              \
+        return (val);                                                  \
+       };                              }G_STMT_END
+
+#define g_return_if_reached()          G_STMT_START{                   \
+     g_log (G_LOG_DOMAIN,                                              \
+           G_LOG_LEVEL_CRITICAL,                                       \
+           "file %s: line %d (%s): should not be reached",             \
+           __FILE__,                                                   \
+           __LINE__,                                                   \
+           __PRETTY_FUNCTION__);                                       \
+     return;                           }G_STMT_END
+
+#define g_return_val_if_reached(val)   G_STMT_START{                   \
+     g_log (G_LOG_DOMAIN,                                              \
+           G_LOG_LEVEL_CRITICAL,                                       \
+           "file %s: line %d (%s): should not be reached",             \
+           __FILE__,                                                   \
+           __LINE__,                                                   \
+           __PRETTY_FUNCTION__);                                       \
+     return (val);                     }G_STMT_END
+
+#else /* !__GNUC__ */
+
+#define g_return_if_fail(expr)         G_STMT_START{           \
+     if (expr) { } else                                                \
+       {                                                       \
+        g_log (G_LOG_DOMAIN,                                   \
+               G_LOG_LEVEL_CRITICAL,                           \
+               "file %s: line %d: assertion `%s' failed",      \
+               __FILE__,                                       \
+               __LINE__,                                       \
+               #expr);                                         \
+        return;                                                \
+       };                              }G_STMT_END
+
+#define g_return_val_if_fail(expr, val)        G_STMT_START{           \
+     if (expr) { } else                                                \
+       {                                                       \
+        g_log (G_LOG_DOMAIN,                                   \
+               G_LOG_LEVEL_CRITICAL,                           \
+               "file %s: line %d: assertion `%s' failed",      \
+               __FILE__,                                       \
+               __LINE__,                                       \
+               #expr);                                         \
+        return (val);                                          \
+       };                              }G_STMT_END
+
+#define g_return_if_reached()          G_STMT_START{           \
+     g_log (G_LOG_DOMAIN,                                      \
+           G_LOG_LEVEL_CRITICAL,                               \
+           "file %s: line %d: should not be reached",          \
+           __FILE__,                                           \
+           __LINE__);                                          \
+     return;                           }G_STMT_END
+
+#define g_return_val_if_reached(val)   G_STMT_START{           \
+     g_log (G_LOG_DOMAIN,                                      \
+           G_LOG_LEVEL_CRITICAL,                               \
+           "file %s: line %d: should not be reached",          \
+           __FILE__,                                           \
+           __LINE__);                                          \
+     return (val);                     }G_STMT_END
+
+#endif /* !__GNUC__ */
+
+#endif /* !G_DISABLE_CHECKS */
+
+G_END_DECLS
+
+#endif /* __G_MESSAGES_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gmirroringtable.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gmirroringtable.h
new file mode 100644 (file)
index 0000000..dd8f18a
--- /dev/null
@@ -0,0 +1,901 @@
+/* gmirroringtable.h
+ * generated by gen-mirroring-tab 
+ * from the file BidiMirroring.txt of */
+
+#define PACKTAB_UINT8 guint8
+#define PACKTAB_UINT16 guint16
+#define PACKTAB_UINT32 guint32
+
+/*
+  generated by packtab.c version 3
+
+  use GLIB_GET_MIRRORING_DELTA(key) to access your table
+
+  assumed sizeof(gint16): 2
+  required memory: 1008
+  lookups: 4
+  partition shape: Mir[256][16][4][4]
+  different table entries: 1 14 56 38
+*/
+
+/* *INDENT-OFF* */
+
+static const gint16 MirLev3[4*38] = {
+#define MirLev3_0000 0x0
+  0,0,0,0,
+#define MirLev3_0028 0x4
+  1,-1,0,0,
+#define MirLev3_003C 0x8
+  2,0,-2,0,
+#define MirLev3_0058 0xC
+  0,0,0,2,
+#define MirLev3_005C 0x10
+  0,-2,0,0,
+#define MirLev3_00A8 0x14
+  0,0,0,16,
+#define MirLev3_00B8 0x18
+  0,0,0,-16,
+#define MirLev3_0F38 0x1C
+  0,0,1,-1,
+#define MirLev3_1698 0x20
+  0,0,0,1,
+#define MirLev3_169C 0x24
+  -1,0,0,0,
+#define MirLev3_2038 0x28
+  0,1,-1,0,
+#define MirLev3_2208 0x2C
+  3,3,3,-3,
+#define MirLev3_220C 0x30
+  -3,-3,0,0,
+#define MirLev3_2214 0x34
+  0,2016,0,0,
+#define MirLev3_2240 0x38
+  0,0,0,138,
+#define MirLev3_2264 0x3C
+  1,-1,1,-1,
+#define MirLev3_2290 0x40
+  -1,1,-1,0,
+#define MirLev3_2298 0x44
+  1824,0,0,0,
+#define MirLev3_22A4 0x48
+  0,0,2104,0,
+#define MirLev3_22A8 0x4C
+  2108,2106,0,2106,
+#define MirLev3_22C8 0x50
+  0,1,-1,1,
+#define MirLev3_22CC 0x54
+  -1,-138,0,0,
+#define MirLev3_22F0 0x58
+  1,-1,8,8,
+#define MirLev3_22F4 0x5C
+  8,0,7,7,
+#define MirLev3_22F8 0x60
+  0,0,-8,-8,
+#define MirLev3_22FC 0x64
+  -8,-7,-7,0,
+#define MirLev3_2984 0x68
+  -1,1,-1,1,
+#define MirLev3_298C 0x6C
+  -1,3,1,-1,
+#define MirLev3_2990 0x70
+  -3,1,-1,1,
+#define MirLev3_29B8 0x74
+  -1824,0,0,0,
+#define MirLev3_29F4 0x78
+  0,-2016,0,0,
+#define MirLev3_2AAC 0x7C
+  1,-1,0,1,
+#define MirLev3_2AB0 0x80
+  -1,0,0,1,
+#define MirLev3_2ADC 0x84
+  0,0,-2104,0,
+#define MirLev3_2AE0 0x88
+  0,0,0,-2106,
+#define MirLev3_2AE4 0x8C
+  -2108,-2106,0,0,
+#define MirLev3_FF5C 0x90
+  0,-2,0,1,
+#define MirLev3_FF60 0x94
+  -1,0,1,-1,
+};
+
+static const PACKTAB_UINT8 MirLev2[4*56] = {
+#define MirLev2_0000 0x0
+  MirLev3_0000,  /* 0000..0003 */
+  MirLev3_0000,  /* 0004..0007 */
+  MirLev3_0000,  /* 0008..000B */
+  MirLev3_0000,  /* 000C..000F */
+#define MirLev2_0020 0x4
+  MirLev3_0000,  /* 0020..0023 */
+  MirLev3_0000,  /* 0024..0027 */
+  MirLev3_0028,  /* 0028..002B */
+  MirLev3_0000,  /* 002C..002F */
+#define MirLev2_0030 0x8
+  MirLev3_0000,  /* 0030..0033 */
+  MirLev3_0000,  /* 0034..0037 */
+  MirLev3_0000,  /* 0038..003B */
+  MirLev3_003C,  /* 003C..003F */
+#define MirLev2_0050 0xC
+  MirLev3_0000,  /* 0050..0053 */
+  MirLev3_0000,  /* 0054..0057 */
+  MirLev3_0058,  /* 0058..005B */
+  MirLev3_005C,  /* 005C..005F */
+#define MirLev2_00A0 0x10
+  MirLev3_0000,  /* 00A0..00A3 */
+  MirLev3_0000,  /* 00A4..00A7 */
+  MirLev3_00A8,  /* 00A8..00AB */
+  MirLev3_0000,  /* 00AC..00AF */
+#define MirLev2_00B0 0x14
+  MirLev3_0000,  /* 00B0..00B3 */
+  MirLev3_0000,  /* 00B4..00B7 */
+  MirLev3_00B8,  /* 00B8..00BB */
+  MirLev3_0000,  /* 00BC..00BF */
+#define MirLev2_0F30 0x18
+  MirLev3_0000,  /* 0F30..0F33 */
+  MirLev3_0000,  /* 0F34..0F37 */
+  MirLev3_0F38,  /* 0F38..0F3B */
+  MirLev3_0028,  /* 0F3C..0F3F */
+#define MirLev2_1690 0x1C
+  MirLev3_0000,  /* 1690..1693 */
+  MirLev3_0000,  /* 1694..1697 */
+  MirLev3_1698,  /* 1698..169B */
+  MirLev3_169C,  /* 169C..169F */
+#define MirLev2_2030 0x20
+  MirLev3_0000,  /* 2030..2033 */
+  MirLev3_0000,  /* 2034..2037 */
+  MirLev3_2038,  /* 2038..203B */
+  MirLev3_0000,  /* 203C..203F */
+#define MirLev2_2040 0x24
+  MirLev3_0000,  /* 2040..2043 */
+  MirLev3_2038,  /* 2044..2047 */
+  MirLev3_0000,  /* 2048..204B */
+  MirLev3_0000,  /* 204C..204F */
+#define MirLev2_2070 0x28
+  MirLev3_0000,  /* 2070..2073 */
+  MirLev3_0000,  /* 2074..2077 */
+  MirLev3_0000,  /* 2078..207B */
+  MirLev3_2038,  /* 207C..207F */
+#define MirLev2_2200 0x2C
+  MirLev3_0000,  /* 2200..2203 */
+  MirLev3_0000,  /* 2204..2207 */
+  MirLev3_2208,  /* 2208..220B */
+  MirLev3_220C,  /* 220C..220F */
+#define MirLev2_2210 0x30
+  MirLev3_0000,  /* 2210..2213 */
+  MirLev3_2214,  /* 2214..2217 */
+  MirLev3_0000,  /* 2218..221B */
+  MirLev3_0000,  /* 221C..221F */
+#define MirLev2_2230 0x34
+  MirLev3_0000,  /* 2230..2233 */
+  MirLev3_0000,  /* 2234..2237 */
+  MirLev3_0000,  /* 2238..223B */
+  MirLev3_0028,  /* 223C..223F */
+#define MirLev2_2240 0x38
+  MirLev3_2240,  /* 2240..2243 */
+  MirLev3_0000,  /* 2244..2247 */
+  MirLev3_0000,  /* 2248..224B */
+  MirLev3_0000,  /* 224C..224F */
+#define MirLev2_2250 0x3C
+  MirLev3_0F38,  /* 2250..2253 */
+  MirLev3_0028,  /* 2254..2257 */
+  MirLev3_0000,  /* 2258..225B */
+  MirLev3_0000,  /* 225C..225F */
+#define MirLev2_2260 0x40
+  MirLev3_0000,  /* 2260..2263 */
+  MirLev3_2264,  /* 2264..2267 */
+  MirLev3_2264,  /* 2268..226B */
+  MirLev3_0F38,  /* 226C..226F */
+#define MirLev2_2270 0x44
+  MirLev3_2264,  /* 2270..2273 */
+  MirLev3_2264,  /* 2274..2277 */
+  MirLev3_2264,  /* 2278..227B */
+  MirLev3_2264,  /* 227C..227F */
+#define MirLev2_2280 0x48
+  MirLev3_2264,  /* 2280..2283 */
+  MirLev3_2264,  /* 2284..2287 */
+  MirLev3_2264,  /* 2288..228B */
+  MirLev3_1698,  /* 228C..228F */
+#define MirLev2_2290 0x4C
+  MirLev3_2290,  /* 2290..2293 */
+  MirLev3_0000,  /* 2294..2297 */
+  MirLev3_2298,  /* 2298..229B */
+  MirLev3_0000,  /* 229C..229F */
+#define MirLev2_22A0 0x50
+  MirLev3_0F38,  /* 22A0..22A3 */
+  MirLev3_22A4,  /* 22A4..22A7 */
+  MirLev3_22A8,  /* 22A8..22AB */
+  MirLev3_0000,  /* 22AC..22AF */
+#define MirLev2_22B0 0x54
+  MirLev3_2264,  /* 22B0..22B3 */
+  MirLev3_2264,  /* 22B4..22B7 */
+  MirLev3_0000,  /* 22B8..22BB */
+  MirLev3_0000,  /* 22BC..22BF */
+#define MirLev2_22C0 0x58
+  MirLev3_0000,  /* 22C0..22C3 */
+  MirLev3_0000,  /* 22C4..22C7 */
+  MirLev3_22C8,  /* 22C8..22CB */
+  MirLev3_22CC,  /* 22CC..22CF */
+#define MirLev2_22D0 0x5C
+  MirLev3_0028,  /* 22D0..22D3 */
+  MirLev3_0F38,  /* 22D4..22D7 */
+  MirLev3_2264,  /* 22D8..22DB */
+  MirLev3_2264,  /* 22DC..22DF */
+#define MirLev2_22E0 0x60
+  MirLev3_2264,  /* 22E0..22E3 */
+  MirLev3_2264,  /* 22E4..22E7 */
+  MirLev3_2264,  /* 22E8..22EB */
+  MirLev3_0028,  /* 22EC..22EF */
+#define MirLev2_22F0 0x64
+  MirLev3_22F0,  /* 22F0..22F3 */
+  MirLev3_22F4,  /* 22F4..22F7 */
+  MirLev3_22F8,  /* 22F8..22FB */
+  MirLev3_22FC,  /* 22FC..22FF */
+#define MirLev2_2300 0x68
+  MirLev3_0000,  /* 2300..2303 */
+  MirLev3_0000,  /* 2304..2307 */
+  MirLev3_2264,  /* 2308..230B */
+  MirLev3_0000,  /* 230C..230F */
+#define MirLev2_2760 0x6C
+  MirLev3_0000,  /* 2760..2763 */
+  MirLev3_0000,  /* 2764..2767 */
+  MirLev3_2264,  /* 2768..276B */
+  MirLev3_2264,  /* 276C..276F */
+#define MirLev2_2770 0x70
+  MirLev3_2264,  /* 2770..2773 */
+  MirLev3_0028,  /* 2774..2777 */
+  MirLev3_0000,  /* 2778..277B */
+  MirLev3_0000,  /* 277C..277F */
+#define MirLev2_27C0 0x74
+  MirLev3_1698,  /* 27C0..27C3 */
+  MirLev3_2290,  /* 27C4..27C7 */
+  MirLev3_0028,  /* 27C8..27CB */
+  MirLev3_0000,  /* 27CC..27CF */
+#define MirLev2_27D0 0x78
+  MirLev3_0000,  /* 27D0..27D3 */
+  MirLev3_2038,  /* 27D4..27D7 */
+  MirLev3_0000,  /* 27D8..27DB */
+  MirLev3_2038,  /* 27DC..27DF */
+#define MirLev2_27E0 0x7C
+  MirLev3_0F38,  /* 27E0..27E3 */
+  MirLev3_2264,  /* 27E4..27E7 */
+  MirLev3_2264,  /* 27E8..27EB */
+  MirLev3_2264,  /* 27EC..27EF */
+#define MirLev2_2980 0x80
+  MirLev3_1698,  /* 2980..2983 */
+  MirLev3_2984,  /* 2984..2987 */
+  MirLev3_2984,  /* 2988..298B */
+  MirLev3_298C,  /* 298C..298F */
+#define MirLev2_2990 0x84
+  MirLev3_2990,  /* 2990..2993 */
+  MirLev3_2984,  /* 2994..2997 */
+  MirLev3_169C,  /* 2998..299B */
+  MirLev3_0000,  /* 299C..299F */
+#define MirLev2_29B0 0x88
+  MirLev3_0000,  /* 29B0..29B3 */
+  MirLev3_0000,  /* 29B4..29B7 */
+  MirLev3_29B8,  /* 29B8..29BB */
+  MirLev3_0000,  /* 29BC..29BF */
+#define MirLev2_29C0 0x8C
+  MirLev3_0028,  /* 29C0..29C3 */
+  MirLev3_0028,  /* 29C4..29C7 */
+  MirLev3_0000,  /* 29C8..29CB */
+  MirLev3_1698,  /* 29CC..29CF */
+#define MirLev2_29D0 0x90
+  MirLev3_2290,  /* 29D0..29D3 */
+  MirLev3_0028,  /* 29D4..29D7 */
+  MirLev3_2264,  /* 29D8..29DB */
+  MirLev3_0000,  /* 29DC..29DF */
+#define MirLev2_29F0 0x94
+  MirLev3_0000,  /* 29F0..29F3 */
+  MirLev3_29F4,  /* 29F4..29F7 */
+  MirLev3_0028,  /* 29F8..29FB */
+  MirLev3_0028,  /* 29FC..29FF */
+#define MirLev2_2A20 0x98
+  MirLev3_0000,  /* 2A20..2A23 */
+  MirLev3_0000,  /* 2A24..2A27 */
+  MirLev3_1698,  /* 2A28..2A2B */
+  MirLev3_2290,  /* 2A2C..2A2F */
+#define MirLev2_2A30 0x9C
+  MirLev3_0000,  /* 2A30..2A33 */
+  MirLev3_0028,  /* 2A34..2A37 */
+  MirLev3_0000,  /* 2A38..2A3B */
+  MirLev3_0028,  /* 2A3C..2A3F */
+#define MirLev2_2A60 0xA0
+  MirLev3_0000,  /* 2A60..2A63 */
+  MirLev3_0028,  /* 2A64..2A67 */
+  MirLev3_0000,  /* 2A68..2A6B */
+  MirLev3_0000,  /* 2A6C..2A6F */
+#define MirLev2_2A70 0xA4
+  MirLev3_0000,  /* 2A70..2A73 */
+  MirLev3_0000,  /* 2A74..2A77 */
+  MirLev3_2038,  /* 2A78..2A7B */
+  MirLev3_22C8,  /* 2A7C..2A7F */
+#define MirLev2_2A80 0xA8
+  MirLev3_2984,  /* 2A80..2A83 */
+  MirLev3_169C,  /* 2A84..2A87 */
+  MirLev3_1698,  /* 2A88..2A8B */
+  MirLev3_169C,  /* 2A8C..2A8F */
+#define MirLev2_2A90 0xAC
+  MirLev3_22C8,  /* 2A90..2A93 */
+  MirLev3_2984,  /* 2A94..2A97 */
+  MirLev3_2984,  /* 2A98..2A9B */
+  MirLev3_169C,  /* 2A9C..2A9F */
+#define MirLev2_2AA0 0xB0
+  MirLev3_2038,  /* 2AA0..2AA3 */
+  MirLev3_0F38,  /* 2AA4..2AA7 */
+  MirLev3_2264,  /* 2AA8..2AAB */
+  MirLev3_2AAC,  /* 2AAC..2AAF */
+#define MirLev2_2AB0 0xB4
+  MirLev3_2AB0,  /* 2AB0..2AB3 */
+  MirLev3_169C,  /* 2AB4..2AB7 */
+  MirLev3_1698,  /* 2AB8..2ABB */
+  MirLev3_2984,  /* 2ABC..2ABF */
+#define MirLev2_2AC0 0xB8
+  MirLev3_2984,  /* 2AC0..2AC3 */
+  MirLev3_2290,  /* 2AC4..2AC7 */
+  MirLev3_0000,  /* 2AC8..2ACB */
+  MirLev3_22C8,  /* 2ACC..2ACF */
+#define MirLev2_2AD0 0xBC
+  MirLev3_2984,  /* 2AD0..2AD3 */
+  MirLev3_2290,  /* 2AD4..2AD7 */
+  MirLev3_0000,  /* 2AD8..2ADB */
+  MirLev3_2ADC,  /* 2ADC..2ADF */
+#define MirLev2_2AE0 0xC0
+  MirLev3_2AE0,  /* 2AE0..2AE3 */
+  MirLev3_2AE4,  /* 2AE4..2AE7 */
+  MirLev3_0000,  /* 2AE8..2AEB */
+  MirLev3_0028,  /* 2AEC..2AEF */
+#define MirLev2_2AF0 0xC4
+  MirLev3_0000,  /* 2AF0..2AF3 */
+  MirLev3_1698,  /* 2AF4..2AF7 */
+  MirLev3_2290,  /* 2AF8..2AFB */
+  MirLev3_0000,  /* 2AFC..2AFF */
+#define MirLev2_2E00 0xC8
+  MirLev3_0F38,  /* 2E00..2E03 */
+  MirLev3_0028,  /* 2E04..2E07 */
+  MirLev3_2038,  /* 2E08..2E0B */
+  MirLev3_0028,  /* 2E0C..2E0F */
+#define MirLev2_2E20 0xCC
+  MirLev3_2264,  /* 2E20..2E23 */
+  MirLev3_2264,  /* 2E24..2E27 */
+  MirLev3_0028,  /* 2E28..2E2B */
+  MirLev3_0000,  /* 2E2C..2E2F */
+#define MirLev2_3010 0xD0
+  MirLev3_0028,  /* 3010..3013 */
+  MirLev3_2264,  /* 3014..3017 */
+  MirLev3_2264,  /* 3018..301B */
+  MirLev3_0000,  /* 301C..301F */
+#define MirLev2_FE50 0xD4
+  MirLev3_0000,  /* FE50..FE53 */
+  MirLev3_0000,  /* FE54..FE57 */
+  MirLev3_22C8,  /* FE58..FE5B */
+  MirLev3_2290,  /* FE5C..FE5F */
+#define MirLev2_FF50 0xD8
+  MirLev3_0000,  /* FF50..FF53 */
+  MirLev3_0000,  /* FF54..FF57 */
+  MirLev3_0058,  /* FF58..FF5B */
+  MirLev3_FF5C,  /* FF5C..FF5F */
+#define MirLev2_FF60 0xDC
+  MirLev3_FF60,  /* FF60..FF63 */
+  MirLev3_0000,  /* FF64..FF67 */
+  MirLev3_0000,  /* FF68..FF6B */
+  MirLev3_0000,  /* FF6C..FF6F */
+};
+
+static const PACKTAB_UINT8 MirLev1[16*14] = {
+#define MirLev1_0000 0x0
+  MirLev2_0000,  /* 0000..000F */
+  MirLev2_0000,  /* 0010..001F */
+  MirLev2_0020,  /* 0020..002F */
+  MirLev2_0030,  /* 0030..003F */
+  MirLev2_0000,  /* 0040..004F */
+  MirLev2_0050,  /* 0050..005F */
+  MirLev2_0000,  /* 0060..006F */
+  MirLev2_0050,  /* 0070..007F */
+  MirLev2_0000,  /* 0080..008F */
+  MirLev2_0000,  /* 0090..009F */
+  MirLev2_00A0,  /* 00A0..00AF */
+  MirLev2_00B0,  /* 00B0..00BF */
+  MirLev2_0000,  /* 00C0..00CF */
+  MirLev2_0000,  /* 00D0..00DF */
+  MirLev2_0000,  /* 00E0..00EF */
+  MirLev2_0000,  /* 00F0..00FF */
+#define MirLev1_0100 0x10
+  MirLev2_0000,  /* 0100..010F */
+  MirLev2_0000,  /* 0110..011F */
+  MirLev2_0000,  /* 0120..012F */
+  MirLev2_0000,  /* 0130..013F */
+  MirLev2_0000,  /* 0140..014F */
+  MirLev2_0000,  /* 0150..015F */
+  MirLev2_0000,  /* 0160..016F */
+  MirLev2_0000,  /* 0170..017F */
+  MirLev2_0000,  /* 0180..018F */
+  MirLev2_0000,  /* 0190..019F */
+  MirLev2_0000,  /* 01A0..01AF */
+  MirLev2_0000,  /* 01B0..01BF */
+  MirLev2_0000,  /* 01C0..01CF */
+  MirLev2_0000,  /* 01D0..01DF */
+  MirLev2_0000,  /* 01E0..01EF */
+  MirLev2_0000,  /* 01F0..01FF */
+#define MirLev1_0F00 0x20
+  MirLev2_0000,  /* 0F00..0F0F */
+  MirLev2_0000,  /* 0F10..0F1F */
+  MirLev2_0000,  /* 0F20..0F2F */
+  MirLev2_0F30,  /* 0F30..0F3F */
+  MirLev2_0000,  /* 0F40..0F4F */
+  MirLev2_0000,  /* 0F50..0F5F */
+  MirLev2_0000,  /* 0F60..0F6F */
+  MirLev2_0000,  /* 0F70..0F7F */
+  MirLev2_0000,  /* 0F80..0F8F */
+  MirLev2_0000,  /* 0F90..0F9F */
+  MirLev2_0000,  /* 0FA0..0FAF */
+  MirLev2_0000,  /* 0FB0..0FBF */
+  MirLev2_0000,  /* 0FC0..0FCF */
+  MirLev2_0000,  /* 0FD0..0FDF */
+  MirLev2_0000,  /* 0FE0..0FEF */
+  MirLev2_0000,  /* 0FF0..0FFF */
+#define MirLev1_1600 0x30
+  MirLev2_0000,  /* 1600..160F */
+  MirLev2_0000,  /* 1610..161F */
+  MirLev2_0000,  /* 1620..162F */
+  MirLev2_0000,  /* 1630..163F */
+  MirLev2_0000,  /* 1640..164F */
+  MirLev2_0000,  /* 1650..165F */
+  MirLev2_0000,  /* 1660..166F */
+  MirLev2_0000,  /* 1670..167F */
+  MirLev2_0000,  /* 1680..168F */
+  MirLev2_1690,  /* 1690..169F */
+  MirLev2_0000,  /* 16A0..16AF */
+  MirLev2_0000,  /* 16B0..16BF */
+  MirLev2_0000,  /* 16C0..16CF */
+  MirLev2_0000,  /* 16D0..16DF */
+  MirLev2_0000,  /* 16E0..16EF */
+  MirLev2_0000,  /* 16F0..16FF */
+#define MirLev1_2000 0x40
+  MirLev2_0000,  /* 2000..200F */
+  MirLev2_0000,  /* 2010..201F */
+  MirLev2_0000,  /* 2020..202F */
+  MirLev2_2030,  /* 2030..203F */
+  MirLev2_2040,  /* 2040..204F */
+  MirLev2_0000,  /* 2050..205F */
+  MirLev2_0000,  /* 2060..206F */
+  MirLev2_2070,  /* 2070..207F */
+  MirLev2_2070,  /* 2080..208F */
+  MirLev2_0000,  /* 2090..209F */
+  MirLev2_0000,  /* 20A0..20AF */
+  MirLev2_0000,  /* 20B0..20BF */
+  MirLev2_0000,  /* 20C0..20CF */
+  MirLev2_0000,  /* 20D0..20DF */
+  MirLev2_0000,  /* 20E0..20EF */
+  MirLev2_0000,  /* 20F0..20FF */
+#define MirLev1_2200 0x50
+  MirLev2_2200,  /* 2200..220F */
+  MirLev2_2210,  /* 2210..221F */
+  MirLev2_0000,  /* 2220..222F */
+  MirLev2_2230,  /* 2230..223F */
+  MirLev2_2240,  /* 2240..224F */
+  MirLev2_2250,  /* 2250..225F */
+  MirLev2_2260,  /* 2260..226F */
+  MirLev2_2270,  /* 2270..227F */
+  MirLev2_2280,  /* 2280..228F */
+  MirLev2_2290,  /* 2290..229F */
+  MirLev2_22A0,  /* 22A0..22AF */
+  MirLev2_22B0,  /* 22B0..22BF */
+  MirLev2_22C0,  /* 22C0..22CF */
+  MirLev2_22D0,  /* 22D0..22DF */
+  MirLev2_22E0,  /* 22E0..22EF */
+  MirLev2_22F0,  /* 22F0..22FF */
+#define MirLev1_2300 0x60
+  MirLev2_2300,  /* 2300..230F */
+  MirLev2_0000,  /* 2310..231F */
+  MirLev2_2030,  /* 2320..232F */
+  MirLev2_0000,  /* 2330..233F */
+  MirLev2_0000,  /* 2340..234F */
+  MirLev2_0000,  /* 2350..235F */
+  MirLev2_0000,  /* 2360..236F */
+  MirLev2_0000,  /* 2370..237F */
+  MirLev2_0000,  /* 2380..238F */
+  MirLev2_0000,  /* 2390..239F */
+  MirLev2_0000,  /* 23A0..23AF */
+  MirLev2_0000,  /* 23B0..23BF */
+  MirLev2_0000,  /* 23C0..23CF */
+  MirLev2_0000,  /* 23D0..23DF */
+  MirLev2_0000,  /* 23E0..23EF */
+  MirLev2_0000,  /* 23F0..23FF */
+#define MirLev1_2700 0x70
+  MirLev2_0000,  /* 2700..270F */
+  MirLev2_0000,  /* 2710..271F */
+  MirLev2_0000,  /* 2720..272F */
+  MirLev2_0000,  /* 2730..273F */
+  MirLev2_0000,  /* 2740..274F */
+  MirLev2_0000,  /* 2750..275F */
+  MirLev2_2760,  /* 2760..276F */
+  MirLev2_2770,  /* 2770..277F */
+  MirLev2_0000,  /* 2780..278F */
+  MirLev2_0000,  /* 2790..279F */
+  MirLev2_0000,  /* 27A0..27AF */
+  MirLev2_0000,  /* 27B0..27BF */
+  MirLev2_27C0,  /* 27C0..27CF */
+  MirLev2_27D0,  /* 27D0..27DF */
+  MirLev2_27E0,  /* 27E0..27EF */
+  MirLev2_0000,  /* 27F0..27FF */
+#define MirLev1_2900 0x80
+  MirLev2_0000,  /* 2900..290F */
+  MirLev2_0000,  /* 2910..291F */
+  MirLev2_0000,  /* 2920..292F */
+  MirLev2_0000,  /* 2930..293F */
+  MirLev2_0000,  /* 2940..294F */
+  MirLev2_0000,  /* 2950..295F */
+  MirLev2_0000,  /* 2960..296F */
+  MirLev2_0000,  /* 2970..297F */
+  MirLev2_2980,  /* 2980..298F */
+  MirLev2_2990,  /* 2990..299F */
+  MirLev2_0000,  /* 29A0..29AF */
+  MirLev2_29B0,  /* 29B0..29BF */
+  MirLev2_29C0,  /* 29C0..29CF */
+  MirLev2_29D0,  /* 29D0..29DF */
+  MirLev2_0000,  /* 29E0..29EF */
+  MirLev2_29F0,  /* 29F0..29FF */
+#define MirLev1_2A00 0x90
+  MirLev2_0000,  /* 2A00..2A0F */
+  MirLev2_0000,  /* 2A10..2A1F */
+  MirLev2_2A20,  /* 2A20..2A2F */
+  MirLev2_2A30,  /* 2A30..2A3F */
+  MirLev2_0000,  /* 2A40..2A4F */
+  MirLev2_0000,  /* 2A50..2A5F */
+  MirLev2_2A60,  /* 2A60..2A6F */
+  MirLev2_2A70,  /* 2A70..2A7F */
+  MirLev2_2A80,  /* 2A80..2A8F */
+  MirLev2_2A90,  /* 2A90..2A9F */
+  MirLev2_2AA0,  /* 2AA0..2AAF */
+  MirLev2_2AB0,  /* 2AB0..2ABF */
+  MirLev2_2AC0,  /* 2AC0..2ACF */
+  MirLev2_2AD0,  /* 2AD0..2ADF */
+  MirLev2_2AE0,  /* 2AE0..2AEF */
+  MirLev2_2AF0,  /* 2AF0..2AFF */
+#define MirLev1_2E00 0xA0
+  MirLev2_2E00,  /* 2E00..2E0F */
+  MirLev2_2230,  /* 2E10..2E1F */
+  MirLev2_2E20,  /* 2E20..2E2F */
+  MirLev2_0000,  /* 2E30..2E3F */
+  MirLev2_0000,  /* 2E40..2E4F */
+  MirLev2_0000,  /* 2E50..2E5F */
+  MirLev2_0000,  /* 2E60..2E6F */
+  MirLev2_0000,  /* 2E70..2E7F */
+  MirLev2_0000,  /* 2E80..2E8F */
+  MirLev2_0000,  /* 2E90..2E9F */
+  MirLev2_0000,  /* 2EA0..2EAF */
+  MirLev2_0000,  /* 2EB0..2EBF */
+  MirLev2_0000,  /* 2EC0..2ECF */
+  MirLev2_0000,  /* 2ED0..2EDF */
+  MirLev2_0000,  /* 2EE0..2EEF */
+  MirLev2_0000,  /* 2EF0..2EFF */
+#define MirLev1_3000 0xB0
+  MirLev2_2760,  /* 3000..300F */
+  MirLev2_3010,  /* 3010..301F */
+  MirLev2_0000,  /* 3020..302F */
+  MirLev2_0000,  /* 3030..303F */
+  MirLev2_0000,  /* 3040..304F */
+  MirLev2_0000,  /* 3050..305F */
+  MirLev2_0000,  /* 3060..306F */
+  MirLev2_0000,  /* 3070..307F */
+  MirLev2_0000,  /* 3080..308F */
+  MirLev2_0000,  /* 3090..309F */
+  MirLev2_0000,  /* 30A0..30AF */
+  MirLev2_0000,  /* 30B0..30BF */
+  MirLev2_0000,  /* 30C0..30CF */
+  MirLev2_0000,  /* 30D0..30DF */
+  MirLev2_0000,  /* 30E0..30EF */
+  MirLev2_0000,  /* 30F0..30FF */
+#define MirLev1_FE00 0xC0
+  MirLev2_0000,  /* FE00..FE0F */
+  MirLev2_0000,  /* FE10..FE1F */
+  MirLev2_0000,  /* FE20..FE2F */
+  MirLev2_0000,  /* FE30..FE3F */
+  MirLev2_0000,  /* FE40..FE4F */
+  MirLev2_FE50,  /* FE50..FE5F */
+  MirLev2_2A60,  /* FE60..FE6F */
+  MirLev2_0000,  /* FE70..FE7F */
+  MirLev2_0000,  /* FE80..FE8F */
+  MirLev2_0000,  /* FE90..FE9F */
+  MirLev2_0000,  /* FEA0..FEAF */
+  MirLev2_0000,  /* FEB0..FEBF */
+  MirLev2_0000,  /* FEC0..FECF */
+  MirLev2_0000,  /* FED0..FEDF */
+  MirLev2_0000,  /* FEE0..FEEF */
+  MirLev2_0000,  /* FEF0..FEFF */
+#define MirLev1_FF00 0xD0
+  MirLev2_0020,  /* FF00..FF0F */
+  MirLev2_0030,  /* FF10..FF1F */
+  MirLev2_0000,  /* FF20..FF2F */
+  MirLev2_0050,  /* FF30..FF3F */
+  MirLev2_0000,  /* FF40..FF4F */
+  MirLev2_FF50,  /* FF50..FF5F */
+  MirLev2_FF60,  /* FF60..FF6F */
+  MirLev2_0000,  /* FF70..FF7F */
+  MirLev2_0000,  /* FF80..FF8F */
+  MirLev2_0000,  /* FF90..FF9F */
+  MirLev2_0000,  /* FFA0..FFAF */
+  MirLev2_0000,  /* FFB0..FFBF */
+  MirLev2_0000,  /* FFC0..FFCF */
+  MirLev2_0000,  /* FFD0..FFDF */
+  MirLev2_0000,  /* FFE0..FFEF */
+  MirLev2_0000,  /* FFF0..FFFF */
+};
+
+static const PACKTAB_UINT8 MirLev0[256*1] = {
+#define MirLev0_0000 0x0
+  MirLev1_0000,  /* 0000..00FF */
+  MirLev1_0100,  /* 0100..01FF */
+  MirLev1_0100,  /* 0200..02FF */
+  MirLev1_0100,  /* 0300..03FF */
+  MirLev1_0100,  /* 0400..04FF */
+  MirLev1_0100,  /* 0500..05FF */
+  MirLev1_0100,  /* 0600..06FF */
+  MirLev1_0100,  /* 0700..07FF */
+  MirLev1_0100,  /* 0800..08FF */
+  MirLev1_0100,  /* 0900..09FF */
+  MirLev1_0100,  /* 0A00..0AFF */
+  MirLev1_0100,  /* 0B00..0BFF */
+  MirLev1_0100,  /* 0C00..0CFF */
+  MirLev1_0100,  /* 0D00..0DFF */
+  MirLev1_0100,  /* 0E00..0EFF */
+  MirLev1_0F00,  /* 0F00..0FFF */
+  MirLev1_0100,  /* 1000..10FF */
+  MirLev1_0100,  /* 1100..11FF */
+  MirLev1_0100,  /* 1200..12FF */
+  MirLev1_0100,  /* 1300..13FF */
+  MirLev1_0100,  /* 1400..14FF */
+  MirLev1_0100,  /* 1500..15FF */
+  MirLev1_1600,  /* 1600..16FF */
+  MirLev1_0100,  /* 1700..17FF */
+  MirLev1_0100,  /* 1800..18FF */
+  MirLev1_0100,  /* 1900..19FF */
+  MirLev1_0100,  /* 1A00..1AFF */
+  MirLev1_0100,  /* 1B00..1BFF */
+  MirLev1_0100,  /* 1C00..1CFF */
+  MirLev1_0100,  /* 1D00..1DFF */
+  MirLev1_0100,  /* 1E00..1EFF */
+  MirLev1_0100,  /* 1F00..1FFF */
+  MirLev1_2000,  /* 2000..20FF */
+  MirLev1_0100,  /* 2100..21FF */
+  MirLev1_2200,  /* 2200..22FF */
+  MirLev1_2300,  /* 2300..23FF */
+  MirLev1_0100,  /* 2400..24FF */
+  MirLev1_0100,  /* 2500..25FF */
+  MirLev1_0100,  /* 2600..26FF */
+  MirLev1_2700,  /* 2700..27FF */
+  MirLev1_0100,  /* 2800..28FF */
+  MirLev1_2900,  /* 2900..29FF */
+  MirLev1_2A00,  /* 2A00..2AFF */
+  MirLev1_0100,  /* 2B00..2BFF */
+  MirLev1_0100,  /* 2C00..2CFF */
+  MirLev1_0100,  /* 2D00..2DFF */
+  MirLev1_2E00,  /* 2E00..2EFF */
+  MirLev1_0100,  /* 2F00..2FFF */
+  MirLev1_3000,  /* 3000..30FF */
+  MirLev1_0100,  /* 3100..31FF */
+  MirLev1_0100,  /* 3200..32FF */
+  MirLev1_0100,  /* 3300..33FF */
+  MirLev1_0100,  /* 3400..34FF */
+  MirLev1_0100,  /* 3500..35FF */
+  MirLev1_0100,  /* 3600..36FF */
+  MirLev1_0100,  /* 3700..37FF */
+  MirLev1_0100,  /* 3800..38FF */
+  MirLev1_0100,  /* 3900..39FF */
+  MirLev1_0100,  /* 3A00..3AFF */
+  MirLev1_0100,  /* 3B00..3BFF */
+  MirLev1_0100,  /* 3C00..3CFF */
+  MirLev1_0100,  /* 3D00..3DFF */
+  MirLev1_0100,  /* 3E00..3EFF */
+  MirLev1_0100,  /* 3F00..3FFF */
+  MirLev1_0100,  /* 4000..40FF */
+  MirLev1_0100,  /* 4100..41FF */
+  MirLev1_0100,  /* 4200..42FF */
+  MirLev1_0100,  /* 4300..43FF */
+  MirLev1_0100,  /* 4400..44FF */
+  MirLev1_0100,  /* 4500..45FF */
+  MirLev1_0100,  /* 4600..46FF */
+  MirLev1_0100,  /* 4700..47FF */
+  MirLev1_0100,  /* 4800..48FF */
+  MirLev1_0100,  /* 4900..49FF */
+  MirLev1_0100,  /* 4A00..4AFF */
+  MirLev1_0100,  /* 4B00..4BFF */
+  MirLev1_0100,  /* 4C00..4CFF */
+  MirLev1_0100,  /* 4D00..4DFF */
+  MirLev1_0100,  /* 4E00..4EFF */
+  MirLev1_0100,  /* 4F00..4FFF */
+  MirLev1_0100,  /* 5000..50FF */
+  MirLev1_0100,  /* 5100..51FF */
+  MirLev1_0100,  /* 5200..52FF */
+  MirLev1_0100,  /* 5300..53FF */
+  MirLev1_0100,  /* 5400..54FF */
+  MirLev1_0100,  /* 5500..55FF */
+  MirLev1_0100,  /* 5600..56FF */
+  MirLev1_0100,  /* 5700..57FF */
+  MirLev1_0100,  /* 5800..58FF */
+  MirLev1_0100,  /* 5900..59FF */
+  MirLev1_0100,  /* 5A00..5AFF */
+  MirLev1_0100,  /* 5B00..5BFF */
+  MirLev1_0100,  /* 5C00..5CFF */
+  MirLev1_0100,  /* 5D00..5DFF */
+  MirLev1_0100,  /* 5E00..5EFF */
+  MirLev1_0100,  /* 5F00..5FFF */
+  MirLev1_0100,  /* 6000..60FF */
+  MirLev1_0100,  /* 6100..61FF */
+  MirLev1_0100,  /* 6200..62FF */
+  MirLev1_0100,  /* 6300..63FF */
+  MirLev1_0100,  /* 6400..64FF */
+  MirLev1_0100,  /* 6500..65FF */
+  MirLev1_0100,  /* 6600..66FF */
+  MirLev1_0100,  /* 6700..67FF */
+  MirLev1_0100,  /* 6800..68FF */
+  MirLev1_0100,  /* 6900..69FF */
+  MirLev1_0100,  /* 6A00..6AFF */
+  MirLev1_0100,  /* 6B00..6BFF */
+  MirLev1_0100,  /* 6C00..6CFF */
+  MirLev1_0100,  /* 6D00..6DFF */
+  MirLev1_0100,  /* 6E00..6EFF */
+  MirLev1_0100,  /* 6F00..6FFF */
+  MirLev1_0100,  /* 7000..70FF */
+  MirLev1_0100,  /* 7100..71FF */
+  MirLev1_0100,  /* 7200..72FF */
+  MirLev1_0100,  /* 7300..73FF */
+  MirLev1_0100,  /* 7400..74FF */
+  MirLev1_0100,  /* 7500..75FF */
+  MirLev1_0100,  /* 7600..76FF */
+  MirLev1_0100,  /* 7700..77FF */
+  MirLev1_0100,  /* 7800..78FF */
+  MirLev1_0100,  /* 7900..79FF */
+  MirLev1_0100,  /* 7A00..7AFF */
+  MirLev1_0100,  /* 7B00..7BFF */
+  MirLev1_0100,  /* 7C00..7CFF */
+  MirLev1_0100,  /* 7D00..7DFF */
+  MirLev1_0100,  /* 7E00..7EFF */
+  MirLev1_0100,  /* 7F00..7FFF */
+  MirLev1_0100,  /* 8000..80FF */
+  MirLev1_0100,  /* 8100..81FF */
+  MirLev1_0100,  /* 8200..82FF */
+  MirLev1_0100,  /* 8300..83FF */
+  MirLev1_0100,  /* 8400..84FF */
+  MirLev1_0100,  /* 8500..85FF */
+  MirLev1_0100,  /* 8600..86FF */
+  MirLev1_0100,  /* 8700..87FF */
+  MirLev1_0100,  /* 8800..88FF */
+  MirLev1_0100,  /* 8900..89FF */
+  MirLev1_0100,  /* 8A00..8AFF */
+  MirLev1_0100,  /* 8B00..8BFF */
+  MirLev1_0100,  /* 8C00..8CFF */
+  MirLev1_0100,  /* 8D00..8DFF */
+  MirLev1_0100,  /* 8E00..8EFF */
+  MirLev1_0100,  /* 8F00..8FFF */
+  MirLev1_0100,  /* 9000..90FF */
+  MirLev1_0100,  /* 9100..91FF */
+  MirLev1_0100,  /* 9200..92FF */
+  MirLev1_0100,  /* 9300..93FF */
+  MirLev1_0100,  /* 9400..94FF */
+  MirLev1_0100,  /* 9500..95FF */
+  MirLev1_0100,  /* 9600..96FF */
+  MirLev1_0100,  /* 9700..97FF */
+  MirLev1_0100,  /* 9800..98FF */
+  MirLev1_0100,  /* 9900..99FF */
+  MirLev1_0100,  /* 9A00..9AFF */
+  MirLev1_0100,  /* 9B00..9BFF */
+  MirLev1_0100,  /* 9C00..9CFF */
+  MirLev1_0100,  /* 9D00..9DFF */
+  MirLev1_0100,  /* 9E00..9EFF */
+  MirLev1_0100,  /* 9F00..9FFF */
+  MirLev1_0100,  /* A000..A0FF */
+  MirLev1_0100,  /* A100..A1FF */
+  MirLev1_0100,  /* A200..A2FF */
+  MirLev1_0100,  /* A300..A3FF */
+  MirLev1_0100,  /* A400..A4FF */
+  MirLev1_0100,  /* A500..A5FF */
+  MirLev1_0100,  /* A600..A6FF */
+  MirLev1_0100,  /* A700..A7FF */
+  MirLev1_0100,  /* A800..A8FF */
+  MirLev1_0100,  /* A900..A9FF */
+  MirLev1_0100,  /* AA00..AAFF */
+  MirLev1_0100,  /* AB00..ABFF */
+  MirLev1_0100,  /* AC00..ACFF */
+  MirLev1_0100,  /* AD00..ADFF */
+  MirLev1_0100,  /* AE00..AEFF */
+  MirLev1_0100,  /* AF00..AFFF */
+  MirLev1_0100,  /* B000..B0FF */
+  MirLev1_0100,  /* B100..B1FF */
+  MirLev1_0100,  /* B200..B2FF */
+  MirLev1_0100,  /* B300..B3FF */
+  MirLev1_0100,  /* B400..B4FF */
+  MirLev1_0100,  /* B500..B5FF */
+  MirLev1_0100,  /* B600..B6FF */
+  MirLev1_0100,  /* B700..B7FF */
+  MirLev1_0100,  /* B800..B8FF */
+  MirLev1_0100,  /* B900..B9FF */
+  MirLev1_0100,  /* BA00..BAFF */
+  MirLev1_0100,  /* BB00..BBFF */
+  MirLev1_0100,  /* BC00..BCFF */
+  MirLev1_0100,  /* BD00..BDFF */
+  MirLev1_0100,  /* BE00..BEFF */
+  MirLev1_0100,  /* BF00..BFFF */
+  MirLev1_0100,  /* C000..C0FF */
+  MirLev1_0100,  /* C100..C1FF */
+  MirLev1_0100,  /* C200..C2FF */
+  MirLev1_0100,  /* C300..C3FF */
+  MirLev1_0100,  /* C400..C4FF */
+  MirLev1_0100,  /* C500..C5FF */
+  MirLev1_0100,  /* C600..C6FF */
+  MirLev1_0100,  /* C700..C7FF */
+  MirLev1_0100,  /* C800..C8FF */
+  MirLev1_0100,  /* C900..C9FF */
+  MirLev1_0100,  /* CA00..CAFF */
+  MirLev1_0100,  /* CB00..CBFF */
+  MirLev1_0100,  /* CC00..CCFF */
+  MirLev1_0100,  /* CD00..CDFF */
+  MirLev1_0100,  /* CE00..CEFF */
+  MirLev1_0100,  /* CF00..CFFF */
+  MirLev1_0100,  /* D000..D0FF */
+  MirLev1_0100,  /* D100..D1FF */
+  MirLev1_0100,  /* D200..D2FF */
+  MirLev1_0100,  /* D300..D3FF */
+  MirLev1_0100,  /* D400..D4FF */
+  MirLev1_0100,  /* D500..D5FF */
+  MirLev1_0100,  /* D600..D6FF */
+  MirLev1_0100,  /* D700..D7FF */
+  MirLev1_0100,  /* D800..D8FF */
+  MirLev1_0100,  /* D900..D9FF */
+  MirLev1_0100,  /* DA00..DAFF */
+  MirLev1_0100,  /* DB00..DBFF */
+  MirLev1_0100,  /* DC00..DCFF */
+  MirLev1_0100,  /* DD00..DDFF */
+  MirLev1_0100,  /* DE00..DEFF */
+  MirLev1_0100,  /* DF00..DFFF */
+  MirLev1_0100,  /* E000..E0FF */
+  MirLev1_0100,  /* E100..E1FF */
+  MirLev1_0100,  /* E200..E2FF */
+  MirLev1_0100,  /* E300..E3FF */
+  MirLev1_0100,  /* E400..E4FF */
+  MirLev1_0100,  /* E500..E5FF */
+  MirLev1_0100,  /* E600..E6FF */
+  MirLev1_0100,  /* E700..E7FF */
+  MirLev1_0100,  /* E800..E8FF */
+  MirLev1_0100,  /* E900..E9FF */
+  MirLev1_0100,  /* EA00..EAFF */
+  MirLev1_0100,  /* EB00..EBFF */
+  MirLev1_0100,  /* EC00..ECFF */
+  MirLev1_0100,  /* ED00..EDFF */
+  MirLev1_0100,  /* EE00..EEFF */
+  MirLev1_0100,  /* EF00..EFFF */
+  MirLev1_0100,  /* F000..F0FF */
+  MirLev1_0100,  /* F100..F1FF */
+  MirLev1_0100,  /* F200..F2FF */
+  MirLev1_0100,  /* F300..F3FF */
+  MirLev1_0100,  /* F400..F4FF */
+  MirLev1_0100,  /* F500..F5FF */
+  MirLev1_0100,  /* F600..F6FF */
+  MirLev1_0100,  /* F700..F7FF */
+  MirLev1_0100,  /* F800..F8FF */
+  MirLev1_0100,  /* F900..F9FF */
+  MirLev1_0100,  /* FA00..FAFF */
+  MirLev1_0100,  /* FB00..FBFF */
+  MirLev1_0100,  /* FC00..FCFF */
+  MirLev1_0100,  /* FD00..FDFF */
+  MirLev1_FE00,  /* FE00..FEFF */
+  MirLev1_FF00,  /* FF00..FFFF */
+};
+
+/* *INDENT-ON* */
+
+#define GLIB_GET_MIRRORING_DELTA(x) \
+       ((x) >= 0x10000 ? 0 :  \
+       MirLev3[((x) & 0x03) + \
+       MirLev2[((x) >> 2 & 0x03) + \
+       MirLev1[((x) >> 4 & 0x0f) + \
+       MirLev0[((x) >> 8)]]]])
+
+#undef PACKTAB_UINT8
+#undef PACKTAB_UINT16
+#undef PACKTAB_UINT32
+
+#define GLIB_GET_MIRRORING(x) ((x) + GLIB_GET_MIRRORING_DELTA(x))
+
+/* End of generated gmirroringtable.h */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnode.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gnode.c
new file mode 100644 (file)
index 0000000..22d1937
--- /dev/null
@@ -0,0 +1,1279 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * GNode: N-way tree implementation.
+ * Copyright (C) 1998 Tim Janik
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "gnode.h"
+
+#include "gtestutils.h"
+
+/**
+ * SECTION: trees-nary
+ * @title: N-ary Trees
+ * @short_description: trees of data with any number of branches
+ *
+ * The #GNode struct and its associated functions provide a N-ary tree
+ * data structure, where nodes in the tree can contain arbitrary data.
+ *
+ * To create a new tree use g_node_new().
+ *
+ * To insert a node into a tree use g_node_insert(),
+ * g_node_insert_before(), g_node_append() and g_node_prepend().
+ *
+ * To create a new node and insert it into a tree use
+ * g_node_insert_data(), g_node_insert_data_before(),
+ * g_node_append_data() and g_node_prepend_data().
+ *
+ * To reverse the children of a node use g_node_reverse_children().
+ *
+ * To find a node use g_node_get_root(), g_node_find(),
+ * g_node_find_child(), g_node_child_index(), g_node_child_position(),
+ * g_node_first_child(), g_node_last_child(), g_node_nth_child(),
+ * g_node_first_sibling(), g_node_prev_sibling(), g_node_next_sibling()
+ * or g_node_last_sibling().
+ *
+ * To get information about a node or tree use G_NODE_IS_LEAF(),
+ * G_NODE_IS_ROOT(), g_node_depth(), g_node_n_nodes(),
+ * g_node_n_children(), g_node_is_ancestor() or g_node_max_height().
+ *
+ * To traverse a tree, calling a function for each node visited in the
+ * traversal, use g_node_traverse() or g_node_children_foreach().
+ *
+ * To remove a node or subtree from a tree use g_node_unlink() or
+ * g_node_destroy().
+ **/
+
+/**
+ * GNode:
+ * @data: contains the actual data of the node.
+ * @next: points to the node's next sibling (a sibling is another
+ *        #GNode with the same parent).
+ * @prev: points to the node's previous sibling.
+ * @parent: points to the parent of the #GNode, or is %NULL if the
+ *          #GNode is the root of the tree.
+ * @children: points to the first child of the #GNode.  The other
+ *            children are accessed by using the @next pointer of each
+ *            child.
+ *
+ * The #GNode struct represents one node in a
+ * <link linkend="glib-N-ary-Trees">N-ary Tree</link>. fields
+ **/
+
+/**
+ * g_node_push_allocator:
+ * @dummy: the #GAllocator to use when allocating #GNode elements.
+ *
+ * Sets the allocator to use to allocate #GNode elements. Use
+ * g_node_pop_allocator() to restore the previous allocator.
+ *
+ * Note that this function is not available if GLib has been compiled
+ * with <option>--disable-mem-pools</option>
+ *
+ * Deprecated:2.10: It does nothing, since #GNode has been converted to
+ *                  the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link>
+ **/
+void g_node_push_allocator (gpointer dummy) { /* present for binary compat only */ }
+
+/**
+ * g_node_pop_allocator:
+ *
+ * Restores the previous #GAllocator, used when allocating #GNode
+ * elements.
+ *
+ * Note that this function is not available if GLib has been compiled
+ * with <option>--disable-mem-pools</option>
+ *
+ * Deprecated:2.10: It does nothing, since #GNode has been converted to
+ *                  the <link linkend="glib-Memory-Slices">slice
+ *                  allocator</link>
+ **/
+void g_node_pop_allocator  (void)           { /* present for binary compat only */ }
+
+#define g_node_alloc0()         g_slice_new0 (GNode)
+#define g_node_free(node)       g_slice_free (GNode, node)
+
+/* --- functions --- */
+/**
+ * g_node_new:
+ * @data: the data of the new node
+ *
+ * Creates a new #GNode containing the given data.
+ * Used to create the first node in a tree.
+ *
+ * Returns: a new #GNode
+ */
+GNode*
+g_node_new (gpointer data)
+{
+  GNode *node = g_node_alloc0 ();
+  node->data = data;
+  return node;
+}
+
+static void
+g_nodes_free (GNode *node)
+{
+  while (node)
+    {
+      GNode *next = node->next;
+      if (node->children)
+        g_nodes_free (node->children);
+      g_node_free (node);
+      node = next;
+    }
+}
+
+/**
+ * g_node_destroy:
+ * @root: the root of the tree/subtree to destroy
+ *
+ * Removes @root and its children from the tree, freeing any memory
+ * allocated.
+ */
+void
+g_node_destroy (GNode *root)
+{
+  g_return_if_fail (root != NULL);
+  
+  if (!G_NODE_IS_ROOT (root))
+    g_node_unlink (root);
+  
+  g_nodes_free (root);
+}
+
+/**
+ * g_node_unlink:
+ * @node: the #GNode to unlink, which becomes the root of a new tree
+ *
+ * Unlinks a #GNode from a tree, resulting in two separate trees.
+ */
+void
+g_node_unlink (GNode *node)
+{
+  g_return_if_fail (node != NULL);
+  
+  if (node->prev)
+    node->prev->next = node->next;
+  else if (node->parent)
+    node->parent->children = node->next;
+  node->parent = NULL;
+  if (node->next)
+    {
+      node->next->prev = node->prev;
+      node->next = NULL;
+    }
+  node->prev = NULL;
+}
+
+/**
+ * g_node_copy_deep:
+ * @node: a #GNode
+ * @copy_func: the function which is called to copy the data inside each node,
+ *   or %NULL to use the original data.
+ * @data: data to pass to @copy_func
+ * 
+ * Recursively copies a #GNode and its data.
+ * 
+ * Return value: a new #GNode containing copies of the data in @node.
+ *
+ * Since: 2.4
+ **/
+GNode*
+g_node_copy_deep (GNode     *node, 
+                 GCopyFunc  copy_func,
+                 gpointer   data)
+{
+  GNode *new_node = NULL;
+
+  if (copy_func == NULL)
+       return g_node_copy (node);
+
+  if (node)
+    {
+      GNode *child, *new_child;
+      
+      new_node = g_node_new (copy_func (node->data, data));
+      
+      for (child = g_node_last_child (node); child; child = child->prev) 
+       {
+         new_child = g_node_copy_deep (child, copy_func, data);
+         g_node_prepend (new_node, new_child);
+       }
+    }
+  
+  return new_node;
+}
+
+/**
+ * g_node_copy:
+ * @node: a #GNode
+ *
+ * Recursively copies a #GNode (but does not deep-copy the data inside the 
+ * nodes, see g_node_copy_deep() if you need that).
+ *
+ * Returns: a new #GNode containing the same data pointers
+ */
+GNode*
+g_node_copy (GNode *node)
+{
+  GNode *new_node = NULL;
+  
+  if (node)
+    {
+      GNode *child;
+      
+      new_node = g_node_new (node->data);
+      
+      for (child = g_node_last_child (node); child; child = child->prev)
+       g_node_prepend (new_node, g_node_copy (child));
+    }
+  
+  return new_node;
+}
+
+/**
+ * g_node_insert:
+ * @parent: the #GNode to place @node under
+ * @position: the position to place @node at, with respect to its siblings
+ *     If position is -1, @node is inserted as the last child of @parent
+ * @node: the #GNode to insert
+ *
+ * Inserts a #GNode beneath the parent at the given position.
+ *
+ * Returns: the inserted #GNode
+ */
+GNode*
+g_node_insert (GNode *parent,
+              gint   position,
+              GNode *node)
+{
+  g_return_val_if_fail (parent != NULL, node);
+  g_return_val_if_fail (node != NULL, node);
+  g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
+  
+  if (position > 0)
+    return g_node_insert_before (parent,
+                                g_node_nth_child (parent, position),
+                                node);
+  else if (position == 0)
+    return g_node_prepend (parent, node);
+  else /* if (position < 0) */
+    return g_node_append (parent, node);
+}
+
+/**
+ * g_node_insert_before:
+ * @parent: the #GNode to place @node under
+ * @sibling: the sibling #GNode to place @node before. 
+ *     If sibling is %NULL, the node is inserted as the last child of @parent.
+ * @node: the #GNode to insert
+ *
+ * Inserts a #GNode beneath the parent before the given sibling.
+ *
+ * Returns: the inserted #GNode
+ */
+GNode*
+g_node_insert_before (GNode *parent,
+                     GNode *sibling,
+                     GNode *node)
+{
+  g_return_val_if_fail (parent != NULL, node);
+  g_return_val_if_fail (node != NULL, node);
+  g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
+  if (sibling)
+    g_return_val_if_fail (sibling->parent == parent, node);
+  
+  node->parent = parent;
+  
+  if (sibling)
+    {
+      if (sibling->prev)
+       {
+         node->prev = sibling->prev;
+         node->prev->next = node;
+         node->next = sibling;
+         sibling->prev = node;
+       }
+      else
+       {
+         node->parent->children = node;
+         node->next = sibling;
+         sibling->prev = node;
+       }
+    }
+  else
+    {
+      if (parent->children)
+       {
+         sibling = parent->children;
+         while (sibling->next)
+           sibling = sibling->next;
+         node->prev = sibling;
+         sibling->next = node;
+       }
+      else
+       node->parent->children = node;
+    }
+
+  return node;
+}
+
+/**
+ * g_node_insert_after:
+ * @parent: the #GNode to place @node under
+ * @sibling: the sibling #GNode to place @node after. 
+ *     If sibling is %NULL, the node is inserted as the first child of @parent.
+ * @node: the #GNode to insert
+ *
+ * Inserts a #GNode beneath the parent after the given sibling.
+ *
+ * Returns: the inserted #GNode
+ */
+GNode*
+g_node_insert_after (GNode *parent,
+                    GNode *sibling,
+                    GNode *node)
+{
+  g_return_val_if_fail (parent != NULL, node);
+  g_return_val_if_fail (node != NULL, node);
+  g_return_val_if_fail (G_NODE_IS_ROOT (node), node);
+  if (sibling)
+    g_return_val_if_fail (sibling->parent == parent, node);
+
+  node->parent = parent;
+
+  if (sibling)
+    {
+      if (sibling->next)
+       {
+         sibling->next->prev = node;
+       }
+      node->next = sibling->next;
+      node->prev = sibling;
+      sibling->next = node;
+    }
+  else
+    {
+      if (parent->children)
+       {
+         node->next = parent->children;
+         parent->children->prev = node;
+       }
+      parent->children = node;
+    }
+
+  return node;
+}
+
+/**
+ * g_node_prepend:
+ * @parent: the #GNode to place the new #GNode under
+ * @node: the #GNode to insert
+ *
+ * Inserts a #GNode as the first child of the given parent.
+ *
+ * Returns: the inserted #GNode
+ */
+GNode*
+g_node_prepend (GNode *parent,
+               GNode *node)
+{
+  g_return_val_if_fail (parent != NULL, node);
+  
+  return g_node_insert_before (parent, parent->children, node);
+}
+
+/**
+ * g_node_get_root:
+ * @node: a #GNode
+ *
+ * Gets the root of a tree.
+ *
+ * Returns: the root of the tree
+ */
+GNode*
+g_node_get_root (GNode *node)
+{
+  g_return_val_if_fail (node != NULL, NULL);
+  
+  while (node->parent)
+    node = node->parent;
+  
+  return node;
+}
+
+/**
+ * g_node_is_ancestor:
+ * @node: a #GNode
+ * @descendant: a #GNode
+ *
+ * Returns %TRUE if @node is an ancestor of @descendant.
+ * This is true if node is the parent of @descendant, 
+ * or if node is the grandparent of @descendant etc.
+ *
+ * Returns: %TRUE if @node is an ancestor of @descendant
+ */
+gboolean
+g_node_is_ancestor (GNode *node,
+                   GNode *descendant)
+{
+  g_return_val_if_fail (node != NULL, FALSE);
+  g_return_val_if_fail (descendant != NULL, FALSE);
+  
+  while (descendant)
+    {
+      if (descendant->parent == node)
+       return TRUE;
+      
+      descendant = descendant->parent;
+    }
+  
+  return FALSE;
+}
+
+/**
+ * g_node_depth:
+ * @node: a #GNode
+ *
+ * Gets the depth of a #GNode.
+ *
+ * If @node is %NULL the depth is 0. The root node has a depth of 1.
+ * For the children of the root node the depth is 2. And so on.
+ *
+ * Returns: the depth of the #GNode
+ */
+guint
+g_node_depth (GNode *node)
+{
+  guint depth = 0;
+  
+  while (node)
+    {
+      depth++;
+      node = node->parent;
+    }
+  
+  return depth;
+}
+
+/**
+ * g_node_reverse_children:
+ * @node: a #GNode.
+ *
+ * Reverses the order of the children of a #GNode.
+ * (It doesn't change the order of the grandchildren.)
+ */
+void
+g_node_reverse_children (GNode *node)
+{
+  GNode *child;
+  GNode *last;
+  
+  g_return_if_fail (node != NULL);
+  
+  child = node->children;
+  last = NULL;
+  while (child)
+    {
+      last = child;
+      child = last->next;
+      last->next = last->prev;
+      last->prev = child;
+    }
+  node->children = last;
+}
+
+/**
+ * g_node_max_height:
+ * @root: a #GNode
+ *
+ * Gets the maximum height of all branches beneath a #GNode.
+ * This is the maximum distance from the #GNode to all leaf nodes.
+ *
+ * If @root is %NULL, 0 is returned. If @root has no children, 
+ * 1 is returned. If @root has children, 2 is returned. And so on.
+ *
+ * Returns: the maximum height of the tree beneath @root
+ */
+guint
+g_node_max_height (GNode *root)
+{
+  GNode *child;
+  guint max_height = 0;
+  
+  if (!root)
+    return 0;
+  
+  child = root->children;
+  while (child)
+    {
+      guint tmp_height;
+      
+      tmp_height = g_node_max_height (child);
+      if (tmp_height > max_height)
+       max_height = tmp_height;
+      child = child->next;
+    }
+  
+  return max_height + 1;
+}
+
+static gboolean
+g_node_traverse_pre_order (GNode           *node,
+                          GTraverseFlags    flags,
+                          GNodeTraverseFunc func,
+                          gpointer          data)
+{
+  if (node->children)
+    {
+      GNode *child;
+      
+      if ((flags & G_TRAVERSE_NON_LEAFS) &&
+         func (node, data))
+       return TRUE;
+      
+      child = node->children;
+      while (child)
+       {
+         GNode *current;
+         
+         current = child;
+         child = current->next;
+         if (g_node_traverse_pre_order (current, flags, func, data))
+           return TRUE;
+       }
+    }
+  else if ((flags & G_TRAVERSE_LEAFS) &&
+          func (node, data))
+    return TRUE;
+  
+  return FALSE;
+}
+
+static gboolean
+g_node_depth_traverse_pre_order (GNode           *node,
+                                GTraverseFlags    flags,
+                                guint             depth,
+                                GNodeTraverseFunc func,
+                                gpointer          data)
+{
+  if (node->children)
+    {
+      GNode *child;
+      
+      if ((flags & G_TRAVERSE_NON_LEAFS) &&
+         func (node, data))
+       return TRUE;
+      
+      depth--;
+      if (!depth)
+       return FALSE;
+      
+      child = node->children;
+      while (child)
+       {
+         GNode *current;
+         
+         current = child;
+         child = current->next;
+         if (g_node_depth_traverse_pre_order (current, flags, depth, func, data))
+           return TRUE;
+       }
+    }
+  else if ((flags & G_TRAVERSE_LEAFS) &&
+          func (node, data))
+    return TRUE;
+  
+  return FALSE;
+}
+
+static gboolean
+g_node_traverse_post_order (GNode           *node,
+                           GTraverseFlags    flags,
+                           GNodeTraverseFunc func,
+                           gpointer          data)
+{
+  if (node->children)
+    {
+      GNode *child;
+      
+      child = node->children;
+      while (child)
+       {
+         GNode *current;
+         
+         current = child;
+         child = current->next;
+         if (g_node_traverse_post_order (current, flags, func, data))
+           return TRUE;
+       }
+      
+      if ((flags & G_TRAVERSE_NON_LEAFS) &&
+         func (node, data))
+       return TRUE;
+      
+    }
+  else if ((flags & G_TRAVERSE_LEAFS) &&
+          func (node, data))
+    return TRUE;
+  
+  return FALSE;
+}
+
+static gboolean
+g_node_depth_traverse_post_order (GNode                   *node,
+                                 GTraverseFlags    flags,
+                                 guint             depth,
+                                 GNodeTraverseFunc func,
+                                 gpointer          data)
+{
+  if (node->children)
+    {
+      depth--;
+      if (depth)
+       {
+         GNode *child;
+         
+         child = node->children;
+         while (child)
+           {
+             GNode *current;
+             
+             current = child;
+             child = current->next;
+             if (g_node_depth_traverse_post_order (current, flags, depth, func, data))
+               return TRUE;
+           }
+       }
+      
+      if ((flags & G_TRAVERSE_NON_LEAFS) &&
+         func (node, data))
+       return TRUE;
+      
+    }
+  else if ((flags & G_TRAVERSE_LEAFS) &&
+          func (node, data))
+    return TRUE;
+  
+  return FALSE;
+}
+
+static gboolean
+g_node_traverse_in_order (GNode                   *node,
+                         GTraverseFlags    flags,
+                         GNodeTraverseFunc func,
+                         gpointer          data)
+{
+  if (node->children)
+    {
+      GNode *child;
+      GNode *current;
+      
+      child = node->children;
+      current = child;
+      child = current->next;
+      
+      if (g_node_traverse_in_order (current, flags, func, data))
+       return TRUE;
+      
+      if ((flags & G_TRAVERSE_NON_LEAFS) &&
+         func (node, data))
+       return TRUE;
+      
+      while (child)
+       {
+         current = child;
+         child = current->next;
+         if (g_node_traverse_in_order (current, flags, func, data))
+           return TRUE;
+       }
+    }
+  else if ((flags & G_TRAVERSE_LEAFS) &&
+          func (node, data))
+    return TRUE;
+  
+  return FALSE;
+}
+
+static gboolean
+g_node_depth_traverse_in_order (GNode           *node,
+                               GTraverseFlags    flags,
+                               guint             depth,
+                               GNodeTraverseFunc func,
+                               gpointer          data)
+{
+  if (node->children)
+    {
+      depth--;
+      if (depth)
+       {
+         GNode *child;
+         GNode *current;
+         
+         child = node->children;
+         current = child;
+         child = current->next;
+         
+         if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
+           return TRUE;
+         
+         if ((flags & G_TRAVERSE_NON_LEAFS) &&
+             func (node, data))
+           return TRUE;
+         
+         while (child)
+           {
+             current = child;
+             child = current->next;
+             if (g_node_depth_traverse_in_order (current, flags, depth, func, data))
+               return TRUE;
+           }
+       }
+      else if ((flags & G_TRAVERSE_NON_LEAFS) &&
+              func (node, data))
+       return TRUE;
+    }
+  else if ((flags & G_TRAVERSE_LEAFS) &&
+          func (node, data))
+    return TRUE;
+  
+  return FALSE;
+}
+
+static gboolean
+g_node_traverse_level (GNode            *node,
+                      GTraverseFlags     flags,
+                      guint              level,
+                      GNodeTraverseFunc  func,
+                      gpointer           data,
+                      gboolean          *more_levels)
+{
+  if (level == 0) 
+    {
+      if (node->children)
+       {
+         *more_levels = TRUE;
+         return (flags & G_TRAVERSE_NON_LEAFS) && func (node, data);
+       }
+      else
+       {
+         return (flags & G_TRAVERSE_LEAFS) && func (node, data);
+       }
+    }
+  else 
+    {
+      node = node->children;
+      
+      while (node)
+       {
+         if (g_node_traverse_level (node, flags, level - 1, func, data, more_levels))
+           return TRUE;
+
+         node = node->next;
+       }
+    }
+
+  return FALSE;
+}
+
+static gboolean
+g_node_depth_traverse_level (GNode             *node,
+                            GTraverseFlags     flags,
+                            guint              depth,
+                            GNodeTraverseFunc  func,
+                            gpointer           data)
+{
+  guint level;
+  gboolean more_levels;
+
+  level = 0;  
+  while (level != depth) 
+    {
+      more_levels = FALSE;
+      if (g_node_traverse_level (node, flags, level, func, data, &more_levels))
+       return TRUE;
+      if (!more_levels)
+       break;
+      level++;
+    }
+  return FALSE;
+}
+
+/**
+ * g_node_traverse:
+ * @root: the root #GNode of the tree to traverse
+ * @order: the order in which nodes are visited - %G_IN_ORDER, 
+ *     %G_PRE_ORDER, %G_POST_ORDER, or %G_LEVEL_ORDER.
+ * @flags: which types of children are to be visited, one of 
+ *     %G_TRAVERSE_ALL, %G_TRAVERSE_LEAVES and %G_TRAVERSE_NON_LEAVES
+ * @max_depth: the maximum depth of the traversal. Nodes below this
+ *     depth will not be visited. If max_depth is -1 all nodes in 
+ *     the tree are visited. If depth is 1, only the root is visited. 
+ *     If depth is 2, the root and its children are visited. And so on.
+ * @func: the function to call for each visited #GNode
+ * @data: user data to pass to the function
+ *
+ * Traverses a tree starting at the given root #GNode.
+ * It calls the given function for each node visited.
+ * The traversal can be halted at any point by returning %TRUE from @func.
+ */
+/**
+ * GTraverseFlags:
+ * @G_TRAVERSE_LEAVES: only leaf nodes should be visited. This name has
+ *                     been introduced in 2.6, for older version use
+ *                     %G_TRAVERSE_LEAFS.
+ * @G_TRAVERSE_NON_LEAVES: only non-leaf nodes should be visited. This
+ *                         name has been introduced in 2.6, for older
+ *                         version use %G_TRAVERSE_NON_LEAFS.
+ * @G_TRAVERSE_ALL: all nodes should be visited.
+ * @G_TRAVERSE_MASK: a mask of all traverse flags.
+ * @G_TRAVERSE_LEAFS: identical to %G_TRAVERSE_LEAVES.
+ * @G_TRAVERSE_NON_LEAFS: identical to %G_TRAVERSE_NON_LEAVES.
+ *
+ * Specifies which nodes are visited during several of the tree
+ * functions, including g_node_traverse() and g_node_find().
+ **/
+/**
+ * GNodeTraverseFunc:
+ * @node: a #GNode.
+ * @data: user data passed to g_node_traverse().
+ * @Returns: %TRUE to stop the traversal.
+ *
+ * Specifies the type of function passed to g_node_traverse(). The
+ * function is called with each of the nodes visited, together with the
+ * user data passed to g_node_traverse(). If the function returns
+ * %TRUE, then the traversal is stopped.
+ **/
+void
+g_node_traverse (GNode           *root,
+                GTraverseType     order,
+                GTraverseFlags    flags,
+                gint              depth,
+                GNodeTraverseFunc func,
+                gpointer          data)
+{
+  g_return_if_fail (root != NULL);
+  g_return_if_fail (func != NULL);
+  g_return_if_fail (order <= G_LEVEL_ORDER);
+  g_return_if_fail (flags <= G_TRAVERSE_MASK);
+  g_return_if_fail (depth == -1 || depth > 0);
+  
+  switch (order)
+    {
+    case G_PRE_ORDER:
+      if (depth < 0)
+       g_node_traverse_pre_order (root, flags, func, data);
+      else
+       g_node_depth_traverse_pre_order (root, flags, depth, func, data);
+      break;
+    case G_POST_ORDER:
+      if (depth < 0)
+       g_node_traverse_post_order (root, flags, func, data);
+      else
+       g_node_depth_traverse_post_order (root, flags, depth, func, data);
+      break;
+    case G_IN_ORDER:
+      if (depth < 0)
+       g_node_traverse_in_order (root, flags, func, data);
+      else
+       g_node_depth_traverse_in_order (root, flags, depth, func, data);
+      break;
+    case G_LEVEL_ORDER:
+      g_node_depth_traverse_level (root, flags, depth, func, data);
+      break;
+    }
+}
+
+static gboolean
+g_node_find_func (GNode           *node,
+                 gpointer  data)
+{
+  gpointer *d = data;
+  
+  if (*d != node->data)
+    return FALSE;
+  
+  *(++d) = node;
+  
+  return TRUE;
+}
+
+/**
+ * g_node_find:
+ * @root: the root #GNode of the tree to search
+ * @order: the order in which nodes are visited - %G_IN_ORDER, 
+ *     %G_PRE_ORDER, %G_POST_ORDER, or %G_LEVEL_ORDER
+ * @flags: which types of children are to be searched, one of 
+ *     %G_TRAVERSE_ALL, %G_TRAVERSE_LEAVES and %G_TRAVERSE_NON_LEAVES
+ * @data: the data to find
+ *
+ * Finds a #GNode in a tree.
+ *
+ * Returns: the found #GNode, or %NULL if the data is not found
+ */
+GNode*
+g_node_find (GNode         *root,
+            GTraverseType   order,
+            GTraverseFlags  flags,
+            gpointer        data)
+{
+  gpointer d[2];
+  
+  g_return_val_if_fail (root != NULL, NULL);
+  g_return_val_if_fail (order <= G_LEVEL_ORDER, NULL);
+  g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
+  
+  d[0] = data;
+  d[1] = NULL;
+  
+  g_node_traverse (root, order, flags, -1, g_node_find_func, d);
+  
+  return d[1];
+}
+
+static void
+g_node_count_func (GNode        *node,
+                  GTraverseFlags flags,
+                  guint         *n)
+{
+  if (node->children)
+    {
+      GNode *child;
+      
+      if (flags & G_TRAVERSE_NON_LEAFS)
+       (*n)++;
+      
+      child = node->children;
+      while (child)
+       {
+         g_node_count_func (child, flags, n);
+         child = child->next;
+       }
+    }
+  else if (flags & G_TRAVERSE_LEAFS)
+    (*n)++;
+}
+
+/**
+ * g_node_n_nodes:
+ * @root: a #GNode
+ * @flags: which types of children are to be counted, one of 
+ *     %G_TRAVERSE_ALL, %G_TRAVERSE_LEAVES and %G_TRAVERSE_NON_LEAVES
+ *
+ * Gets the number of nodes in a tree.
+ *
+ * Returns: the number of nodes in the tree
+ */
+guint
+g_node_n_nodes (GNode         *root,
+               GTraverseFlags  flags)
+{
+  guint n = 0;
+  
+  g_return_val_if_fail (root != NULL, 0);
+  g_return_val_if_fail (flags <= G_TRAVERSE_MASK, 0);
+  
+  g_node_count_func (root, flags, &n);
+  
+  return n;
+}
+
+/**
+ * g_node_last_child:
+ * @node: a #GNode (must not be %NULL)
+ *
+ * Gets the last child of a #GNode.
+ *
+ * Returns: the last child of @node, or %NULL if @node has no children
+ */
+GNode*
+g_node_last_child (GNode *node)
+{
+  g_return_val_if_fail (node != NULL, NULL);
+  
+  node = node->children;
+  if (node)
+    while (node->next)
+      node = node->next;
+  
+  return node;
+}
+
+/**
+ * g_node_nth_child:
+ * @node: a #GNode
+ * @n: the index of the desired child
+ *
+ * Gets a child of a #GNode, using the given index.
+ * The first child is at index 0. If the index is 
+ * too big, %NULL is returned.
+ *
+ * Returns: the child of @node at index @n
+ */
+GNode*
+g_node_nth_child (GNode *node,
+                 guint  n)
+{
+  g_return_val_if_fail (node != NULL, NULL);
+  
+  node = node->children;
+  if (node)
+    while ((n-- > 0) && node)
+      node = node->next;
+  
+  return node;
+}
+
+/**
+ * g_node_n_children:
+ * @node: a #GNode
+ *
+ * Gets the number of children of a #GNode.
+ *
+ * Returns: the number of children of @node
+ */
+guint
+g_node_n_children (GNode *node)
+{
+  guint n = 0;
+  
+  g_return_val_if_fail (node != NULL, 0);
+  
+  node = node->children;
+  while (node)
+    {
+      n++;
+      node = node->next;
+    }
+  
+  return n;
+}
+
+/**
+ * g_node_find_child:
+ * @node: a #GNode
+ * @flags: which types of children are to be searched, one of 
+ *     %G_TRAVERSE_ALL, %G_TRAVERSE_LEAVES and %G_TRAVERSE_NON_LEAVES
+ * @data: the data to find
+ *
+ * Finds the first child of a #GNode with the given data.
+ *
+ * Returns: the found child #GNode, or %NULL if the data is not found
+ */
+GNode*
+g_node_find_child (GNode         *node,
+                  GTraverseFlags  flags,
+                  gpointer        data)
+{
+  g_return_val_if_fail (node != NULL, NULL);
+  g_return_val_if_fail (flags <= G_TRAVERSE_MASK, NULL);
+  
+  node = node->children;
+  while (node)
+    {
+      if (node->data == data)
+       {
+         if (G_NODE_IS_LEAF (node))
+           {
+             if (flags & G_TRAVERSE_LEAFS)
+               return node;
+           }
+         else
+           {
+             if (flags & G_TRAVERSE_NON_LEAFS)
+               return node;
+           }
+       }
+      node = node->next;
+    }
+  
+  return NULL;
+}
+
+/**
+ * g_node_child_position:
+ * @node: a #GNode
+ * @child: a child of @node
+ *
+ * Gets the position of a #GNode with respect to its siblings.
+ * @child must be a child of @node. The first child is numbered 0, 
+ * the second 1, and so on.
+ *
+ * Returns: the position of @child with respect to its siblings
+ */
+gint
+g_node_child_position (GNode *node,
+                      GNode *child)
+{
+  guint n = 0;
+  
+  g_return_val_if_fail (node != NULL, -1);
+  g_return_val_if_fail (child != NULL, -1);
+  g_return_val_if_fail (child->parent == node, -1);
+  
+  node = node->children;
+  while (node)
+    {
+      if (node == child)
+       return n;
+      n++;
+      node = node->next;
+    }
+  
+  return -1;
+}
+
+/**
+ * g_node_child_index:
+ * @node: a #GNode
+ * @data: the data to find
+ *
+ * Gets the position of the first child of a #GNode 
+ * which contains the given data.
+ *
+ * Returns: the index of the child of @node which contains 
+ *     @data, or -1 if the data is not found
+ */
+gint
+g_node_child_index (GNode    *node,
+                   gpointer  data)
+{
+  guint n = 0;
+  
+  g_return_val_if_fail (node != NULL, -1);
+  
+  node = node->children;
+  while (node)
+    {
+      if (node->data == data)
+       return n;
+      n++;
+      node = node->next;
+    }
+  
+  return -1;
+}
+
+/**
+ * g_node_first_sibling:
+ * @node: a #GNode
+ *
+ * Gets the first sibling of a #GNode.
+ * This could possibly be the node itself.
+ *
+ * Returns: the first sibling of @node
+ */
+GNode*
+g_node_first_sibling (GNode *node)
+{
+  g_return_val_if_fail (node != NULL, NULL);
+  
+  if (node->parent)
+    return node->parent->children;
+  
+  while (node->prev)
+    node = node->prev;
+  
+  return node;
+}
+
+/**
+ * g_node_last_sibling:
+ * @node: a #GNode
+ *
+ * Gets the last sibling of a #GNode.
+ * This could possibly be the node itself.
+ *
+ * Returns: the last sibling of @node
+ */
+GNode*
+g_node_last_sibling (GNode *node)
+{
+  g_return_val_if_fail (node != NULL, NULL);
+  
+  while (node->next)
+    node = node->next;
+  
+  return node;
+}
+
+/**
+ * g_node_children_foreach:
+ * @node: a #GNode
+ * @flags: which types of children are to be visited, one of 
+ *     %G_TRAVERSE_ALL, %G_TRAVERSE_LEAVES and %G_TRAVERSE_NON_LEAVES
+ * @func: the function to call for each visited node
+ * @data: user data to pass to the function
+ *
+ * Calls a function for each of the children of a #GNode.
+ * Note that it doesn't descend beneath the child nodes.
+ */
+/**
+ * GNodeForeachFunc:
+ * @node: a #GNode.
+ * @data: user data passed to g_node_children_foreach().
+ *
+ * Specifies the type of function passed to g_node_children_foreach().
+ * The function is called with each child node, together with the user
+ * data passed to g_node_children_foreach().
+ **/
+void
+g_node_children_foreach (GNode           *node,
+                        GTraverseFlags    flags,
+                        GNodeForeachFunc  func,
+                        gpointer          data)
+{
+  g_return_if_fail (node != NULL);
+  g_return_if_fail (flags <= G_TRAVERSE_MASK);
+  g_return_if_fail (func != NULL);
+  
+  node = node->children;
+  while (node)
+    {
+      GNode *current;
+      
+      current = node;
+      node = current->next;
+      if (G_NODE_IS_LEAF (current))
+       {
+         if (flags & G_TRAVERSE_LEAFS)
+           func (current, data);
+       }
+      else
+       {
+         if (flags & G_TRAVERSE_NON_LEAFS)
+           func (current, data);
+       }
+    }
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnode.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gnode.h
new file mode 100644 (file)
index 0000000..205d47c
--- /dev/null
@@ -0,0 +1,290 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_NODE_H__
+#define __G_NODE_H__
+
+#include <glib/gmem.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GNode          GNode;
+
+/* Tree traverse flags */
+typedef enum
+{
+  G_TRAVERSE_LEAVES     = 1 << 0,
+  G_TRAVERSE_NON_LEAVES = 1 << 1,
+  G_TRAVERSE_ALL        = G_TRAVERSE_LEAVES | G_TRAVERSE_NON_LEAVES,
+  G_TRAVERSE_MASK       = 0x03,
+  G_TRAVERSE_LEAFS      = G_TRAVERSE_LEAVES,
+  G_TRAVERSE_NON_LEAFS  = G_TRAVERSE_NON_LEAVES
+} GTraverseFlags;
+
+/* Tree traverse orders */
+typedef enum
+{
+  G_IN_ORDER,
+  G_PRE_ORDER,
+  G_POST_ORDER,
+  G_LEVEL_ORDER
+} GTraverseType;
+
+typedef gboolean       (*GNodeTraverseFunc)    (GNode         *node,
+                                                gpointer       data);
+typedef void           (*GNodeForeachFunc)     (GNode         *node,
+                                                gpointer       data);
+
+/**
+ * GCopyFunc:
+ * @src: A pointer to the data which should be copied
+ * @data: Additional data
+ *
+ * A function of this signature is used to copy the node data 
+ * when doing a deep-copy of a tree.
+ *
+ * Returns: A pointer to the copy
+ *
+ * Since: 2.4
+ */
+typedef gpointer       (*GCopyFunc)            (gconstpointer  src,
+                                                 gpointer       data);
+
+/* N-way tree implementation
+ */
+struct _GNode
+{
+  gpointer data;
+  GNode          *next;
+  GNode          *prev;
+  GNode          *parent;
+  GNode          *children;
+};
+
+/**
+ * G_NODE_IS_ROOT:
+ * @node: a #GNode
+ *
+ * Returns %TRUE if a #GNode is the root of a tree.
+ *
+ * Returns: %TRUE if the #GNode is the root of a tree 
+ *     (i.e. it has no parent or siblings)
+ */
+#define         G_NODE_IS_ROOT(node)   (((GNode*) (node))->parent == NULL && \
+                                ((GNode*) (node))->prev == NULL && \
+                                ((GNode*) (node))->next == NULL)
+
+/**
+ * G_NODE_IS_LEAF:
+ * @node: a #GNode
+ *
+ * Returns %TRUE if a #GNode is a leaf node.
+ *
+ * Returns: %TRUE if the #GNode is a leaf node 
+ *     (i.e. it has no children)
+ */
+#define         G_NODE_IS_LEAF(node)   (((GNode*) (node))->children == NULL)
+
+GNode*  g_node_new             (gpointer          data);
+void    g_node_destroy         (GNode            *root);
+void    g_node_unlink          (GNode            *node);
+GNode*   g_node_copy_deep       (GNode            *node,
+                                GCopyFunc         copy_func,
+                                gpointer          data);
+GNode*   g_node_copy            (GNode            *node);
+GNode*  g_node_insert          (GNode            *parent,
+                                gint              position,
+                                GNode            *node);
+GNode*  g_node_insert_before   (GNode            *parent,
+                                GNode            *sibling,
+                                GNode            *node);
+GNode*   g_node_insert_after    (GNode            *parent,
+                                GNode            *sibling,
+                                GNode            *node); 
+GNode*  g_node_prepend         (GNode            *parent,
+                                GNode            *node);
+guint   g_node_n_nodes         (GNode            *root,
+                                GTraverseFlags    flags);
+GNode*  g_node_get_root        (GNode            *node);
+gboolean g_node_is_ancestor    (GNode            *node,
+                                GNode            *descendant);
+guint   g_node_depth           (GNode            *node);
+GNode*  g_node_find            (GNode            *root,
+                                GTraverseType     order,
+                                GTraverseFlags    flags,
+                                gpointer          data);
+
+/* convenience macros */
+/**
+ * g_node_append:
+ * @parent: the #GNode to place the new #GNode under
+ * @node: the #GNode to insert
+ *
+ * Inserts a #GNode as the last child of the given parent.
+ *
+ * Returns: the inserted #GNode
+ */
+#define g_node_append(parent, node)                            \
+     g_node_insert_before ((parent), NULL, (node))
+
+/**
+ * g_node_insert_data:
+ * @parent: the #GNode to place the new #GNode under
+ * @position: the position to place the new #GNode at. If position is -1, 
+ *     the new #GNode is inserted as the last child of @parent
+ * @data: the data for the new #GNode
+ *
+ * Inserts a new #GNode at the given position.
+ *
+ * Returns: the new #GNode
+ */
+#define        g_node_insert_data(parent, position, data)              \
+     g_node_insert ((parent), (position), g_node_new (data))
+
+/**
+ * g_node_insert_data_before:
+ * @parent: the #GNode to place the new #GNode under
+ * @sibling: the sibling #GNode to place the new #GNode before
+ * @data: the data for the new #GNode
+ *
+ * Inserts a new #GNode before the given sibling.
+ *
+ * Returns: the new #GNode
+ */
+#define        g_node_insert_data_before(parent, sibling, data)        \
+     g_node_insert_before ((parent), (sibling), g_node_new (data))
+
+/**
+ * g_node_prepend_data:
+ * @parent: the #GNode to place the new #GNode under
+ * @data: the data for the new #GNode
+ *
+ * Inserts a new #GNode as the first child of the given parent.
+ *
+ * Returns: the new #GNode
+ */
+#define        g_node_prepend_data(parent, data)                       \
+     g_node_prepend ((parent), g_node_new (data))
+
+/**
+ * g_node_append_data:
+ * @parent: the #GNode to place the new #GNode under
+ * @data: the data for the new #GNode
+ *
+ * Inserts a new #GNode as the last child of the given parent.
+ *
+ * Returns: the new #GNode
+ */
+#define        g_node_append_data(parent, data)                        \
+     g_node_insert_before ((parent), NULL, g_node_new (data))
+
+/* traversal function, assumes that `node' is root
+ * (only traverses `node' and its subtree).
+ * this function is just a high level interface to
+ * low level traversal functions, optimized for speed.
+ */
+void    g_node_traverse        (GNode            *root,
+                                GTraverseType     order,
+                                GTraverseFlags    flags,
+                                gint              max_depth,
+                                GNodeTraverseFunc func,
+                                gpointer          data);
+
+/* return the maximum tree height starting with `node', this is an expensive
+ * operation, since we need to visit all nodes. this could be shortened by
+ * adding `guint height' to struct _GNode, but then again, this is not very
+ * often needed, and would make g_node_insert() more time consuming.
+ */
+guint   g_node_max_height       (GNode *root);
+
+void    g_node_children_foreach (GNode           *node,
+                                 GTraverseFlags   flags,
+                                 GNodeForeachFunc func,
+                                 gpointer         data);
+void    g_node_reverse_children (GNode           *node);
+guint   g_node_n_children       (GNode           *node);
+GNode*  g_node_nth_child        (GNode           *node,
+                                 guint            n);
+GNode*  g_node_last_child       (GNode           *node);
+GNode*  g_node_find_child       (GNode           *node,
+                                 GTraverseFlags   flags,
+                                 gpointer         data);
+gint    g_node_child_position   (GNode           *node,
+                                 GNode           *child);
+gint    g_node_child_index      (GNode           *node,
+                                 gpointer         data);
+
+GNode*  g_node_first_sibling    (GNode           *node);
+GNode*  g_node_last_sibling     (GNode           *node);
+
+/**
+ * g_node_prev_sibling:
+ * @node: a #GNode
+ *
+ * Gets the previous sibling of a #GNode.
+ *
+ * Returns: the previous sibling of @node, or %NULL if @node is the first
+ *     node or %NULL
+ */
+#define         g_node_prev_sibling(node)      ((node) ? \
+                                        ((GNode*) (node))->prev : NULL)
+
+/**
+ * g_node_next_sibling:
+ * @node: a #GNode
+ *
+ * Gets the next sibling of a #GNode.
+ *
+ * Returns: the next sibling of @node, or %NULL if @node is the last node
+ *     or %NULL
+ */
+#define         g_node_next_sibling(node)      ((node) ? \
+                                        ((GNode*) (node))->next : NULL)
+
+/**
+ * g_node_first_child:
+ * @node: a #GNode
+ *
+ * Gets the first child of a #GNode.
+ *
+ * Returns: the first child of @node, or %NULL if @node is %NULL 
+ *     or has no children
+ */
+#define         g_node_first_child(node)       ((node) ? \
+                                        ((GNode*) (node))->children : NULL)
+
+#ifndef G_DISABLE_DEPRECATED
+void     g_node_push_allocator  (gpointer          dummy);
+void     g_node_pop_allocator   (void);
+#endif
+
+G_END_DECLS
+
+#endif /* __G_NODE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/Makefile.am b/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/Makefile.am
new file mode 100644 (file)
index 0000000..ae8283d
--- /dev/null
@@ -0,0 +1,22 @@
+## Process this file with automake to produce Makefile.in
+include $(top_srcdir)/Makefile.decl
+
+INCLUDES = $(glib_INCLUDES) -DG_LOG_DOMAIN=\"GLib\" \
+       $(GLIB_DEBUG_FLAGS) -DG_DISABLE_DEPRECATED -DGLIB_COMPILATION 
+
+noinst_LTLIBRARIES = libgnulib.la
+
+libgnulib_la_SOURCES =         \
+       asnprintf.c \
+       printf-args.c \
+       printf-args.h \
+       printf-parse.c \
+       printf-parse.h \
+       vasnprintf.c \
+       vasnprintf.h \
+       printf.c \
+       printf.h \
+       g-gnulib.h
+
+
+EXTRA_DIST += makefile.msc
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/README b/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/README
new file mode 100644 (file)
index 0000000..78e09b9
--- /dev/null
@@ -0,0 +1,44 @@
+The files
+ asnprintf.c 
+ printf-args.c
+ printf-args.h
+ printf-parse.c
+ printf-parse.h
+ vasnprintf.c
+ vasnprintf.h
+
+are taken from the vasnprintf module of the GNUlib package, which can
+be found at: 
+
+ http://www.gnu.org/software/gnulib/
+
+All files have been modified to include g-gnulib.h. 
+
+vasnprintf.c has also been modified to include support for long long 
+printing if the system printf doesn't. This code is protected by 
+#ifndef HAVE_LONG_LONG_FORMAT.
+
+Code has been added to printf-args.[ch], printf-parse.c and vasnprintf.c
+to support printing of __int64 values with the I64 format modifier. This
+is protected by #ifdef HAVE_INT64_AND_I64.
+
+The files
+
+ printf.h 
+ printf.c
+ g-gnulib.h
+
+have been written by me. printf.[hc] contain implementations of the  
+remaining functions in the printf family based on vasnprintf. 
+g-gnulib.h is included by all source files in order to move all
+exported functions to the _g_gnulib namespace, replace malloc by
+g_malloc and make sure that snprintf is only used if it implements 
+C99 return value semantics. 
+
+Matthias Clasen
+November 1, 2003
+
+
+
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/asnprintf.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/asnprintf.c
new file mode 100644 (file)
index 0000000..3863f33
--- /dev/null
@@ -0,0 +1,40 @@
+/* Formatted output to strings.
+ Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "g-gnulib.h"
+
+/* Specification.  */
+#include "vasnprintf.h"
+
+#include <stdarg.h>
+
+char *
+asnprintf(char *resultbuf, size_t *lengthp, const char *format, ...)
+{
+    va_list args;
+    char *result;
+
+    va_start(args, format);
+    result = vasnprintf(resultbuf, lengthp, format, args);
+    va_end(args);
+    return result;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/g-gnulib.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/g-gnulib.h
new file mode 100644 (file)
index 0000000..b8a0408
--- /dev/null
@@ -0,0 +1,48 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 2003  Matthias Clasen
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __G_GNULIB_H__
+
+#include "config.h"
+#include <stdlib.h>
+#include "glib/glib.h"
+
+/* Private namespace for gnulib functions */
+#define asnprintf        _g_gnulib_asnprintf
+#define vasnprintf       _g_gnulib_vasnprintf
+#define printf_parse     _g_gnulib_printf_parse
+#define printf_fetchargs _g_gnulib_printf_fetchargs
+
+/* Use GLib memory allocation */
+#undef malloc
+#undef realloc
+#undef free
+#define malloc  g_malloc
+#define realloc g_realloc
+#define free    g_free
+
+/* Ensure only C99 snprintf gets used */
+#undef HAVE_SNPRINTF
+#ifdef HAVE_C99_SNPRINTF
+#define HAVE_SNPRINTF 1
+#else
+#define HAVE_SNPRINTF 0
+#endif
+
+#endif  /* __G_GNULIB_H__ */
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/makefile.msc b/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/makefile.msc
new file mode 100644 (file)
index 0000000..da2b4cf
--- /dev/null
@@ -0,0 +1,18 @@
+TOP = ..\..\..
+!INCLUDE ..\..\build\win32\make.msc
+
+INCLUDES = -I ..\.. -I ..
+DEFINES = -DHAVE_CONFIG_H -DHAVE_LONG_LONG_FORMAT
+
+OBJECTS = \
+       asnprintf.obj \
+       printf.obj \
+       printf-args.obj \
+       printf-parse.obj \
+       vasnprintf.obj
+
+all : gnulib.lib
+
+gnulib.lib : $(OBJECTS)
+       lib -out:gnulib.lib $(OBJECTS)
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf-args.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf-args.c
new file mode 100644 (file)
index 0000000..78003af
--- /dev/null
@@ -0,0 +1,132 @@
+/* Decomposed printf argument list.
+ Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "g-gnulib.h"
+
+/* Specification.  */
+#include "printf-args.h"
+
+#ifdef STATIC
+STATIC
+#endif
+int printf_fetchargs(va_list args, arguments *a)
+{
+    unsigned int i;
+    argument *ap;
+
+    for (i = 0, ap = &a->arg[0]; i < a->count; i++, ap++)
+        switch (ap->type)
+        {
+            case TYPE_SCHAR:
+                ap->a.a_schar = va_arg (args, /*signed char*/int);
+                break;
+            case TYPE_UCHAR:
+                ap->a.a_uchar = va_arg (args, /*unsigned char*/int);
+                break;
+            case TYPE_SHORT:
+                ap->a.a_short = va_arg (args, /*short*/int);
+                break;
+            case TYPE_USHORT:
+                ap->a.a_ushort = va_arg (args, /*unsigned short*/int);
+                break;
+            case TYPE_INT:
+                ap->a.a_int = va_arg (args, int);
+                break;
+            case TYPE_UINT:
+                ap->a.a_uint = va_arg (args, unsigned int);
+                break;
+            case TYPE_LONGINT:
+                ap->a.a_longint = va_arg (args, long int);
+                break;
+            case TYPE_ULONGINT:
+                ap->a.a_ulongint = va_arg (args, unsigned long int);
+                break;
+#ifdef HAVE_LONG_LONG
+            case TYPE_LONGLONGINT:
+                ap->a.a_longlongint = va_arg (args, long long int);
+                break;
+            case TYPE_ULONGLONGINT:
+                ap->a.a_ulonglongint = va_arg (args, unsigned long long int);
+                break;
+#endif
+#ifdef HAVE_INT64_AND_I64
+                case TYPE_INT64:
+                ap->a.a_int64 = va_arg (args, __int64);
+                break;
+                case TYPE_UINT64:
+                ap->a.a_uint64 = va_arg (args, unsigned __int64);
+                break;
+#endif
+            case TYPE_DOUBLE:
+                ap->a.a_double = va_arg (args, double);
+                break;
+#ifdef HAVE_LONG_DOUBLE
+            case TYPE_LONGDOUBLE:
+                ap->a.a_longdouble = va_arg (args, long double);
+                break;
+#endif
+            case TYPE_CHAR:
+                ap->a.a_char = va_arg (args, int);
+                break;
+#ifdef HAVE_WINT_T
+                case TYPE_WIDE_CHAR:
+#ifdef _WIN32
+                ap->a.a_wide_char = va_arg (args, int);
+#else
+                ap->a.a_wide_char = va_arg (args, wint_t);
+#endif
+                break;
+#endif
+            case TYPE_STRING:
+                ap->a.a_string = va_arg (args, const char *);
+                break;
+#ifdef HAVE_WCHAR_T
+                case TYPE_WIDE_STRING:
+                ap->a.a_wide_string = va_arg (args, const wchar_t *);
+                break;
+#endif
+            case TYPE_POINTER:
+                ap->a.a_pointer = va_arg (args, void *);
+                break;
+            case TYPE_COUNT_SCHAR_POINTER:
+                ap->a.a_count_schar_pointer = va_arg (args, signed char *);
+                break;
+            case TYPE_COUNT_SHORT_POINTER:
+                ap->a.a_count_short_pointer = va_arg (args, short *);
+                break;
+            case TYPE_COUNT_INT_POINTER:
+                ap->a.a_count_int_pointer = va_arg (args, int *);
+                break;
+            case TYPE_COUNT_LONGINT_POINTER:
+                ap->a.a_count_longint_pointer = va_arg (args, long int *);
+                break;
+#ifdef HAVE_LONG_LONG
+            case TYPE_COUNT_LONGLONGINT_POINTER:
+                ap->a.a_count_longlongint_pointer = va_arg (args, long long int *);
+                break;
+#endif
+            default:
+                /* Unknown type.  */
+                return -1;
+        }
+    return 0;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf-args.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf-args.h
new file mode 100644 (file)
index 0000000..fd47ad8
--- /dev/null
@@ -0,0 +1,137 @@
+/* Decomposed printf argument list.
+ Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA.  */
+
+#ifndef _PRINTF_ARGS_H
+#define _PRINTF_ARGS_H
+
+/* Get wchar_t.  */
+#ifdef HAVE_WCHAR_T
+# include <stddef.h>
+#endif
+
+/* Get wint_t.  */
+#ifdef HAVE_WINT_T
+# include <wchar.h>
+#endif
+
+/* Get va_list.  */
+#include <stdarg.h>
+
+/* Argument types */
+typedef enum
+{
+    TYPE_NONE,
+    TYPE_SCHAR,
+    TYPE_UCHAR,
+    TYPE_SHORT,
+    TYPE_USHORT,
+    TYPE_INT,
+    TYPE_UINT,
+    TYPE_LONGINT,
+    TYPE_ULONGINT,
+#ifdef HAVE_LONG_LONG
+    TYPE_LONGLONGINT,
+    TYPE_ULONGLONGINT,
+#endif
+#ifdef HAVE_INT64_AND_I64
+    TYPE_INT64,
+    TYPE_UINT64,
+#endif
+    TYPE_DOUBLE,
+#ifdef HAVE_LONG_DOUBLE
+    TYPE_LONGDOUBLE,
+#endif
+    TYPE_CHAR,
+#ifdef HAVE_WINT_T
+    TYPE_WIDE_CHAR,
+#endif
+    TYPE_STRING,
+#ifdef HAVE_WCHAR_T
+    TYPE_WIDE_STRING,
+#endif
+    TYPE_POINTER,
+    TYPE_COUNT_SCHAR_POINTER,
+    TYPE_COUNT_SHORT_POINTER,
+    TYPE_COUNT_INT_POINTER,
+    TYPE_COUNT_LONGINT_POINTER
+#ifdef HAVE_LONG_LONG
+    , TYPE_COUNT_LONGLONGINT_POINTER
+#endif
+}    arg_type;
+
+    /* Polymorphic argument */
+typedef struct
+{
+    arg_type type;
+    union
+    {
+        signed char a_schar;
+        unsigned char a_uchar;
+        short a_short;
+        unsigned short a_ushort;
+        int a_int;
+        unsigned int a_uint;
+        long int a_longint;
+        unsigned long int a_ulongint;
+#ifdef HAVE_LONG_LONG
+        long long int a_longlongint;
+        unsigned long long int a_ulonglongint;
+#endif
+#ifdef HAVE_INT64_AND_I64
+        __int64 a_int64;
+        unsigned __int64 a_uint64;
+#endif
+        float a_float;
+        double a_double;
+#ifdef HAVE_LONG_DOUBLE
+        long double a_longdouble;
+#endif
+        int a_char;
+#ifdef HAVE_WINT_T
+        wint_t a_wide_char;
+#endif
+        const char* a_string;
+#ifdef HAVE_WCHAR_T
+        const wchar_t* a_wide_string;
+#endif
+        void* a_pointer;
+        signed char * a_count_schar_pointer;
+        short * a_count_short_pointer;
+        int * a_count_int_pointer;
+        long int * a_count_longint_pointer;
+#ifdef HAVE_LONG_LONG
+        long long int * a_count_longlongint_pointer;
+#endif
+    } a;
+} argument;
+
+typedef struct
+{
+    unsigned int count;
+    argument *arg;
+} arguments;
+
+/* Fetch the arguments, putting them into a. */
+#ifdef STATIC
+STATIC
+#else
+extern
+#endif
+int printf_fetchargs(va_list args, arguments *a);
+
+#endif /* _PRINTF_ARGS_H */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf-parse.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf-parse.c
new file mode 100644 (file)
index 0000000..15f99cf
--- /dev/null
@@ -0,0 +1,506 @@
+/* Formatted output to strings.
+ Copyright (C) 1999-2000, 2002-2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library 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.  */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "g-gnulib.h"
+
+/* Specification.  */
+#include "printf-parse.h"
+
+/* Get size_t, NULL.  */
+#include <stddef.h>
+
+/* Get intmax_t.  */
+#if HAVE_STDINT_H_WITH_UINTMAX
+# include <stdint.h>
+#endif
+#if HAVE_INTTYPES_H_WITH_UINTMAX
+# include <inttypes.h>
+#endif
+
+/* malloc(), realloc(), free().  */
+#include <stdlib.h>
+
+#ifdef STATIC
+STATIC
+#endif
+int printf_parse(const char *format, char_directives *d, arguments *a)
+{
+    const char *cp = format; /* pointer into format */
+    int arg_posn = 0; /* number of regular arguments consumed */
+    unsigned int d_allocated; /* allocated elements of d->dir */
+    unsigned int a_allocated; /* allocated elements of a->arg */
+    unsigned int max_width_length = 0;
+    unsigned int max_precision_length = 0;
+
+    d->count = 0;
+    d_allocated = 1;
+    d->dir = malloc(d_allocated * sizeof(char_directive));
+    if (d->dir == NULL)
+        /* Out of memory.  */
+        return -1;
+
+    a->count = 0;
+    a_allocated = 0;
+    a->arg = NULL;
+
+#define REGISTER_ARG(_index_,_type_) \
+  {                                                                    \
+    unsigned int n = (_index_);                                                \
+    if (n >= a_allocated)                                              \
+      {                                                                        \
+       argument *memory;                                               \
+       a_allocated = 2 * a_allocated;                                  \
+       if (a_allocated <= n)                                           \
+         a_allocated = n + 1;                                          \
+       memory = (a->arg                                                \
+                 ? realloc (a->arg, a_allocated * sizeof (argument))   \
+                 : malloc (a_allocated * sizeof (argument)));          \
+       if (memory == NULL)                                             \
+         /* Out of memory.  */                                         \
+         goto error;                                                   \
+       a->arg = memory;                                                \
+      }                                                                        \
+    while (a->count <= n)                                              \
+      a->arg[a->count++].type = TYPE_NONE;                             \
+    if (a->arg[n].type == TYPE_NONE)                                   \
+      a->arg[n].type = (_type_);                                       \
+    else if (a->arg[n].type != (_type_))                               \
+      /* Ambiguous type for positional argument.  */                   \
+      goto error;                                                      \
+  }
+
+    while (*cp != '\0')
+    {
+        char c = *cp++;
+        if (c == '%')
+        {
+            int arg_index = -1;
+            char_directive *dp = &d->dir[d->count];/* pointer to next directive */
+
+            /* Initialize the next directive.  */
+            dp->dir_start = cp - 1;
+            dp->flags = 0;
+            dp->width_start = NULL;
+            dp->width_end = NULL;
+            dp->width_arg_index = -1;
+            dp->precision_start = NULL;
+            dp->precision_end = NULL;
+            dp->precision_arg_index = -1;
+            dp->arg_index = -1;
+
+            /* Test for positional argument.  */
+            if (*cp >= '0' && *cp <= '9')
+            {
+                const char *np;
+
+                for (np = cp; *np >= '0' && *np <= '9'; np++)
+                    ;
+                if (*np == '$')
+                {
+                    unsigned int n = 0;
+
+                    for (np = cp; *np >= '0' && *np <= '9'; np++)
+                        n = 10 * n + (*np - '0');
+                    if (n == 0)
+                        /* Positional argument 0.  */
+                        goto error;
+                    arg_index = n - 1;
+                    cp = np + 1;
+                }
+            }
+
+            /* Read the flags.  */
+            for (;;)
+            {
+                if (*cp == '\'')
+                {
+                    dp->flags |= FLAG_GROUP;
+                    cp++;
+                }
+                else if (*cp == '-')
+                {
+                    dp->flags |= FLAG_LEFT;
+                    cp++;
+                }
+                else if (*cp == '+')
+                {
+                    dp->flags |= FLAG_SHOWSIGN;
+                    cp++;
+                }
+                else if (*cp == ' ')
+                {
+                    dp->flags |= FLAG_SPACE;
+                    cp++;
+                }
+                else if (*cp == '#')
+                {
+                    dp->flags |= FLAG_ALT;
+                    cp++;
+                }
+                else if (*cp == '0')
+                {
+                    dp->flags |= FLAG_ZERO;
+                    cp++;
+                }
+                else
+                    break;
+            }
+
+            /* Parse the field width.  */
+            if (*cp == '*')
+            {
+                dp->width_start = cp;
+                cp++;
+                dp->width_end = cp;
+                if (max_width_length < 1)
+                    max_width_length = 1;
+
+                /* Test for positional argument.  */
+                if (*cp >= '0' && *cp <= '9')
+                {
+                    const char *np;
+
+                    for (np = cp; *np >= '0' && *np <= '9'; np++)
+                        ;
+                    if (*np == '$')
+                    {
+                        unsigned int n = 0;
+
+                        for (np = cp; *np >= '0' && *np <= '9'; np++)
+                            n = 10 * n + (*np - '0');
+                        if (n == 0)
+                            /* Positional argument 0.  */
+                            goto error;
+                        dp->width_arg_index = n - 1;
+                        cp = np + 1;
+                    }
+                }
+                if (dp->width_arg_index < 0)
+                    dp->width_arg_index = arg_posn++;
+                REGISTER_ARG(dp->width_arg_index, TYPE_INT);
+            }
+            else if (*cp >= '0' && *cp <= '9')
+            {
+                unsigned int width_length;
+
+                dp->width_start = cp;
+                for (; *cp >= '0' && *cp <= '9'; cp++)
+                    ;
+                dp->width_end = cp;
+                width_length = dp->width_end - dp->width_start;
+                if (max_width_length < width_length)
+                    max_width_length = width_length;
+            }
+
+            /* Parse the precision.  */
+            if (*cp == '.')
+            {
+                cp++;
+                if (*cp == '*')
+                {
+                    dp->precision_start = cp - 1;
+                    cp++;
+                    dp->precision_end = cp;
+                    if (max_precision_length < 2)
+                        max_precision_length = 2;
+
+                    /* Test for positional argument.  */
+                    if (*cp >= '0' && *cp <= '9')
+                    {
+                        const char *np;
+
+                        for (np = cp; *np >= '0' && *np <= '9'; np++)
+                            ;
+                        if (*np == '$')
+                        {
+                            unsigned int n = 0;
+
+                            for (np = cp; *np >= '0' && *np <= '9'; np++)
+                                n = 10 * n + (*np - '0');
+                            if (n == 0)
+                                /* Positional argument 0.  */
+                                goto error;
+                            dp->precision_arg_index = n - 1;
+                            cp = np + 1;
+                        }
+                    }
+                    if (dp->precision_arg_index < 0)
+                        dp->precision_arg_index = arg_posn++;
+                    REGISTER_ARG(dp->precision_arg_index, TYPE_INT);
+                }
+                else
+                {
+                    unsigned int precision_length;
+
+                    dp->precision_start = cp - 1;
+                    for (; *cp >= '0' && *cp <= '9'; cp++)
+                        ;
+                    dp->precision_end = cp;
+                    precision_length = dp->precision_end - dp->precision_start;
+                    if (max_precision_length < precision_length)
+                        max_precision_length = precision_length;
+                }
+            }
+
+            {
+                arg_type type;
+
+                /* Parse argument type/size specifiers.  */
+                {
+                    int flags = 0;
+
+                    for (;;)
+                    {
+                        if (*cp == 'h')
+                        {
+                            flags |= (1 << (flags & 1));
+                            cp++;
+                        }
+                        else if (*cp == 'L')
+                        {
+                            flags |= 4;
+                            cp++;
+                        }
+                        else if (*cp == 'l')
+                        {
+                            flags += 8;
+                            cp++;
+                        }
+#ifdef HAVE_INT64_AND_I64
+                        else if (cp[0] == 'I' &&
+                                cp[1] == '6' &&
+                                cp[2] == '4')
+                        {
+                            flags = 64;
+                            cp += 3;
+                        }
+#endif
+#ifdef HAVE_INTMAX_T
+                        else if (*cp == 'j')
+                        {
+                            if (sizeof(intmax_t) > sizeof(long))
+                            {
+                                /* intmax_t = long long */
+                                flags += 16;
+                            }
+                            else if (sizeof(intmax_t) > sizeof(int))
+                            {
+                                /* intmax_t = long */
+                                flags += 8;
+                            }
+                            cp++;
+                        }
+#endif
+                        else if (*cp == 'z' || *cp == 'Z')
+                        {
+                            /* 'z' is standardized in ISO C 99, but glibc uses 'Z'
+                             because the warning facility in gcc-2.95.2 understands
+                             only 'Z' (see gcc-2.95.2/gcc/c-common.c:1784).  */
+                            if (sizeof(size_t) > sizeof(long))
+                            {
+                                /* size_t = long long */
+                                flags += 16;
+                            }
+                            else if (sizeof(size_t) > sizeof(int))
+                            {
+                                /* size_t = long */
+                                flags += 8;
+                            }
+                            cp++;
+                        }
+                        else if (*cp == 't')
+                        {
+                            if (sizeof(ptrdiff_t) > sizeof(long))
+                            {
+                                /* ptrdiff_t = long long */
+                                flags += 16;
+                            }
+                            else if (sizeof(ptrdiff_t) > sizeof(int))
+                            {
+                                /* ptrdiff_t = long */
+                                flags += 8;
+                            }
+                            cp++;
+                        }
+                        else
+                            break;
+                    }
+
+                    /* Read the conversion character.  */
+                    c = *cp++;
+                    switch (c)
+                    {
+                        case 'd':
+                        case 'i':
+#ifdef HAVE_INT64_AND_I64
+                            if (flags == 64)
+                            type = TYPE_INT64;
+                            else
+#endif
+#ifdef HAVE_LONG_LONG
+                            if (flags >= 16 || (flags & 4))
+                                type = TYPE_LONGLONGINT;
+                            else
+#endif
+                            if (flags >= 8)
+                                type = TYPE_LONGINT;
+                            else if (flags & 2)
+                                type = TYPE_SCHAR;
+                            else if (flags & 1)
+                                type = TYPE_SHORT;
+                            else
+                                type = TYPE_INT;
+                            break;
+                        case 'o':
+                        case 'u':
+                        case 'x':
+                        case 'X':
+#ifdef HAVE_INT64_AND_I64
+                            if (flags == 64)
+                            type = TYPE_UINT64;
+                            else
+#endif
+#ifdef HAVE_LONG_LONG
+                            if (flags >= 16 || (flags & 4))
+                                type = TYPE_ULONGLONGINT;
+                            else
+#endif
+                            if (flags >= 8)
+                                type = TYPE_ULONGINT;
+                            else if (flags & 2)
+                                type = TYPE_UCHAR;
+                            else if (flags & 1)
+                                type = TYPE_USHORT;
+                            else
+                                type = TYPE_UINT;
+                            break;
+                        case 'f':
+                        case 'F':
+                        case 'e':
+                        case 'E':
+                        case 'g':
+                        case 'G':
+                        case 'a':
+                        case 'A':
+#ifdef HAVE_LONG_DOUBLE
+                            if (flags >= 16 || (flags & 4))
+                                type = TYPE_LONGDOUBLE;
+                            else
+#endif
+                                type = TYPE_DOUBLE;
+                            break;
+                        case 'c':
+                            if (flags >= 8)
+#ifdef HAVE_WINT_T
+                                type = TYPE_WIDE_CHAR;
+#else
+                                goto error;
+#endif
+                            else
+                                type = TYPE_CHAR;
+                            break;
+#ifdef HAVE_WINT_T
+                            case 'C':
+                            type = TYPE_WIDE_CHAR;
+                            c = 'c';
+                            break;
+#endif
+                        case 's':
+                            if (flags >= 8)
+#ifdef HAVE_WCHAR_T
+                                type = TYPE_WIDE_STRING;
+#else
+                                goto error;
+#endif
+                            else
+                                type = TYPE_STRING;
+                            break;
+#ifdef HAVE_WCHAR_T
+                            case 'S':
+                            type = TYPE_WIDE_STRING;
+                            c = 's';
+                            break;
+#endif
+                        case 'p':
+                            type = TYPE_POINTER;
+                            break;
+                        case 'n':
+#ifdef HAVE_LONG_LONG
+                            if (flags >= 16 || (flags & 4))
+                                type = TYPE_COUNT_LONGLONGINT_POINTER;
+                            else
+#endif
+                            if (flags >= 8)
+                                type = TYPE_COUNT_LONGINT_POINTER;
+                            else if (flags & 2)
+                                type = TYPE_COUNT_SCHAR_POINTER;
+                            else if (flags & 1)
+                                type = TYPE_COUNT_SHORT_POINTER;
+                            else
+                                type = TYPE_COUNT_INT_POINTER;
+                            break;
+                        case '%':
+                            type = TYPE_NONE;
+                            break;
+                        default:
+                            /* Unknown conversion character.  */
+                            goto error;
+                    }
+                }
+
+                if (type != TYPE_NONE)
+                {
+                    dp->arg_index = arg_index;
+                    if (dp->arg_index < 0)
+                        dp->arg_index = arg_posn++;
+                    REGISTER_ARG(dp->arg_index, type);
+                }
+                dp->conversion = c;
+                dp->dir_end = cp;
+            }
+
+            d->count++;
+            if (d->count >= d_allocated)
+            {
+                char_directive *memory;
+
+                d_allocated = 2 * d_allocated;
+                memory = realloc(d->dir, d_allocated * sizeof(char_directive));
+                if (memory == NULL)
+                    /* Out of memory.  */
+                    goto error;
+                d->dir = memory;
+            }
+        }
+    }
+    d->dir[d->count].dir_start = cp;
+
+    d->max_width_length = max_width_length;
+    d->max_precision_length = max_precision_length;
+    return 0;
+
+    error: if (a->arg)
+        free(a->arg);
+    if (d->dir)
+        free(d->dir);
+    return -1;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf-parse.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf-parse.h
new file mode 100644 (file)
index 0000000..49c39cb
--- /dev/null
@@ -0,0 +1,71 @@
+/* Parse printf format string.
+ Copyright (C) 1999, 2002 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA.  */
+
+#ifndef _PRINTF_PARSE_H
+#define _PRINTF_PARSE_H
+
+#include "printf-args.h"
+
+/* Private namespace for gnulib functions */
+#define printf_parse _g_gnulib_printf_parse
+
+/* Flags */
+#define FLAG_GROUP      1      /* ' flag */
+#define FLAG_LEFT       2      /* - flag */
+#define FLAG_SHOWSIGN   4      /* + flag */
+#define FLAG_SPACE      8      /* space flag */
+#define FLAG_ALT       16      /* # flag */
+#define FLAG_ZERO      32
+
+/* A parsed directive.  */
+typedef struct
+{
+    const char* dir_start;
+    const char* dir_end;
+    int flags;
+    const char* width_start;
+    const char* width_end;
+    int width_arg_index;
+    const char* precision_start;
+    const char* precision_end;
+    int precision_arg_index;
+    char conversion; /* d i o u x X f e E g G c s p n U % but not C S */
+    int arg_index;
+} char_directive;
+
+/* A parsed format string.  */
+typedef struct
+{
+    unsigned int count;
+    char_directive *dir;
+    unsigned int max_width_length;
+    unsigned int max_precision_length;
+} char_directives;
+
+/* Parses the format string.  Fills in the number N of directives, and fills
+ in directives[0], ..., directives[N-1], and sets directives[N].dir_start
+ to the end of the format string.  Also fills in the arg_type fields of the
+ arguments and the needed count of arguments.  */
+#ifdef STATIC
+STATIC
+#else
+extern
+#endif
+int printf_parse(const char *format, char_directives *d, arguments *a);
+
+#endif /* _PRINTF_PARSE_H */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf.c
new file mode 100644 (file)
index 0000000..f370bea
--- /dev/null
@@ -0,0 +1,150 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 2003 Matthias Clasen
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 2003.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include "g-gnulib.h"
+#include "vasnprintf.h"
+#include "printf.h"
+
+int _g_gnulib_printf(char const *format, ...)
+{
+    va_list args;
+    int retval;
+
+    va_start(args, format);
+    retval = _g_gnulib_vprintf(format, args);
+    va_end(args);
+
+    return retval;
+}
+
+int _g_gnulib_fprintf(FILE *file, char const *format, ...)
+{
+    va_list args;
+    int retval;
+
+    va_start(args, format);
+    retval = _g_gnulib_vfprintf(file, format, args);
+    va_end(args);
+
+    return retval;
+}
+
+int _g_gnulib_sprintf(char *string, char const *format, ...)
+{
+    va_list args;
+    int retval;
+
+    va_start(args, format);
+    retval = _g_gnulib_vsprintf(string, format, args);
+    va_end(args);
+
+    return retval;
+}
+
+int _g_gnulib_snprintf(char *string, size_t n, char const *format, ...)
+{
+    va_list args;
+    int retval;
+
+    va_start(args, format);
+    retval = _g_gnulib_vsnprintf(string, n, format, args);
+    va_end(args);
+
+    return retval;
+}
+
+int _g_gnulib_vprintf(char const *format, va_list args)
+{
+    return _g_gnulib_vfprintf(stdout, format, args);
+}
+
+int _g_gnulib_vfprintf(FILE *file, char const *format, va_list args)
+{
+    char *result;
+    size_t length;
+
+    result = vasnprintf(NULL, &length, format, args);
+    if (result == NULL)
+        return -1;
+
+    fwrite(result, 1, length, file);
+    free(result);
+
+    return length;
+}
+
+int _g_gnulib_vsprintf(char *string, char const *format, va_list args)
+{
+    char *result;
+    size_t length;
+
+    result = vasnprintf(NULL, &length, format, args);
+    if (result == NULL)
+        return -1;
+
+    memcpy(string, result, length + 1);
+    free(result);
+
+    return length;
+}
+
+int _g_gnulib_vsnprintf(char *string, size_t n, char const *format, va_list args)
+{
+    char *result;
+    size_t length;
+
+    result = vasnprintf(NULL, &length, format, args);
+    if (result == NULL)
+        return -1;
+
+    if (n > 0)
+    {
+        memcpy(string, result, MIN(length + 1, n));
+        string[n - 1] = 0;
+    }
+
+    free(result);
+
+    return length;
+}
+
+int _g_gnulib_vasprintf(char **result, char const *format, va_list args)
+{
+    size_t length;
+
+    *result = vasnprintf(NULL, &length, format, args);
+    if (*result == NULL)
+        return -1;
+
+    return length;
+}
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/printf.h
new file mode 100644 (file)
index 0000000..b01f2f9
--- /dev/null
@@ -0,0 +1,36 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 2003  Matthias Clasen
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#ifndef __GNULIB_PRINTF_H__
+#define __GNULIB_PRINTF_H__
+
+#include <stdarg.h>
+#include <stdio.h>
+
+int _g_gnulib_printf(char const *format, ...);
+int _g_gnulib_fprintf(FILE *file, char const *format, ...);
+int _g_gnulib_sprintf(char *string, char const *format, ...);
+int _g_gnulib_snprintf(char *string, size_t n, char const *format, ...);
+int _g_gnulib_vprintf(char const *format, va_list args);
+int _g_gnulib_vfprintf(FILE *file, char const *format, va_list args);
+int _g_gnulib_vsprintf(char *string, char const *format, va_list args);
+int _g_gnulib_vsnprintf(char *string, size_t n, char const *format, va_list args);
+int _g_gnulib_vasprintf(char **result, char const *format, va_list args);
+
+#endif /* __GNULIB_PRINTF_H__ */
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/vasnprintf.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/vasnprintf.c
new file mode 100644 (file)
index 0000000..7e486cd
--- /dev/null
@@ -0,0 +1,1049 @@
+/* vsprintf with automatic memory allocation.
+ Copyright (C) 1999, 2002-2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA.  */
+
+#ifndef _WIN32
+/* Tell glibc's <stdio.h> to provide a prototype for snprintf().
+ This must come before <config.h> because <config.h> may include
+ <features.h>, and once <features.h> has been included, it's too late.  */
+#ifndef _GNU_SOURCE
+# define _GNU_SOURCE    1
+#endif
+#endif
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+#include "glib/galloca.h"
+
+#include "g-gnulib.h"
+
+/* Specification.  */
+#include "vasnprintf.h"
+
+#include <stdio.h>     /* snprintf(), sprintf() */
+#include <stdlib.h>    /* abort(), malloc(), realloc(), free() */
+#include <string.h>    /* memcpy(), strlen() */
+#include <errno.h>     /* errno */
+#include <limits.h>    /* CHAR_BIT */
+#include <float.h>     /* DBL_MAX_EXP, LDBL_MAX_EXP */
+#include "printf-parse.h"
+
+#ifdef HAVE_WCHAR_T
+# ifdef HAVE_WCSLEN
+#  define local_wcslen wcslen
+# else
+/* Solaris 2.5.1 has wcslen() in a separate library libw.so. To avoid
+ a dependency towards this library, here is a local substitute.
+ Define this substitute only once, even if this file is included
+ twice in the same compilation unit.  */
+#  ifndef local_wcslen_defined
+#   define local_wcslen_defined 1
+static size_t
+local_wcslen (const wchar_t *s)
+{
+    const wchar_t *ptr;
+
+    for (ptr = s; *ptr != (wchar_t) 0; ptr++)
+    ;
+    return ptr - s;
+}
+#  endif
+# endif
+#endif
+
+/* For those losing systems which don't have 'alloca' we have to add
+ some additional code emulating it.  */
+#ifdef HAVE_ALLOCA 
+# define freea(p) /* nothing */
+#else
+# define alloca(n) malloc (n) 
+# define freea(p) free (p) 
+#endif
+
+#ifndef HAVE_LONG_LONG_FORMAT
+static int print_long_long(char *buf, int len, int width, int precision, unsigned long flags,
+        char conversion, unsigned long long number)
+{
+    int negative = FALSE;
+    char buffer[128];
+    char *bufferend;
+    char *pointer;
+    int base;
+    static const char *upper = "0123456789ABCDEFX";
+    static const char *lower = "0123456789abcdefx";
+    const char *digits;
+    int i;
+    char *p;
+    int count;
+
+#define EMIT(c)           \
+  if (p - buf == len - 1) \
+    {                     \
+      *p++ = '\0';        \
+      return len;         \
+    }                     \
+  else                    \
+    *p++ = c;
+
+    p = buf;
+
+    switch (conversion)
+    {
+        case 'o':
+            base = 8;
+            digits = lower;
+            negative = FALSE;
+            break;
+        case 'x':
+            base = 16;
+            digits = lower;
+            negative = FALSE;
+            break;
+        case 'X':
+            base = 16;
+            digits = upper;
+            negative = FALSE;
+            break;
+        default:
+            base = 10;
+            digits = lower;
+            negative = (long long) number < 0;
+            if (negative)
+                number = -((long long) number);
+            break;
+    }
+
+    /* Build number */
+    pointer = bufferend = &buffer[sizeof(buffer) - 1];
+    *pointer-- = '\0';
+    for (i = 1; i < (int) sizeof(buffer); i++)
+    {
+        *pointer-- = digits[number % base];
+        number /= base;
+        if (number == 0)
+            break;
+    }
+
+    /* Adjust width */
+    width -= (bufferend - pointer) - 1;
+
+    /* Adjust precision */
+    if (precision != -1)
+    {
+        precision -= (bufferend - pointer) - 1;
+        if (precision < 0)
+            precision = 0;
+        flags |= FLAG_ZERO;
+    }
+
+    /* Adjust width further */
+    if (negative || (flags & FLAG_SHOWSIGN) || (flags & FLAG_SPACE))
+        width--;
+    if (flags & FLAG_ALT)
+    {
+        switch (base)
+        {
+            case 16:
+                width -= 2;
+                break;
+            case 8:
+                width--;
+                break;
+            default:
+                break;
+        }
+    }
+
+    /* Output prefixes spaces if needed */
+    if (!((flags & FLAG_LEFT) || ((flags & FLAG_ZERO) && (precision == -1))))
+    {
+        count = (precision == -1) ? 0 : precision;
+        while (width-- > count)
+            *p++ = ' ';
+    }
+
+    /* width has been adjusted for signs and alternatives */
+    if (negative)
+    {
+        EMIT('-');
+    }
+    else if (flags & FLAG_SHOWSIGN)
+    {
+        EMIT('+');
+    }
+    else if (flags & FLAG_SPACE)
+    {
+        EMIT(' ');
+    }
+
+    if (flags & FLAG_ALT)
+    {
+        switch (base)
+        {
+            case 8:
+                EMIT('0');
+                break;
+            case 16:
+                EMIT('0');
+                EMIT(digits[16]);
+                break;
+            default:
+                break;
+        } /* switch base */
+    }
+
+    /* Output prefixed zero padding if needed */
+    if (flags & FLAG_ZERO)
+    {
+        if (precision == -1)
+            precision = width;
+        while (precision-- > 0)
+        {
+            EMIT('0');
+            width--;
+        }
+    }
+
+    /* Output the number itself */
+    while (*(++pointer))
+    {
+        EMIT(*pointer);
+    }
+
+    /* Output trailing spaces if needed */
+    if (flags & FLAG_LEFT)
+    {
+        while (width-- > 0)
+            EMIT(' ');
+    }
+
+    EMIT('\0');
+
+    return p - buf - 1;
+}
+#endif
+
+char *
+vasnprintf(char *resultbuf, size_t *lengthp, const char *format, va_list args)
+{
+    char_directives d;
+    arguments a;
+
+    if (printf_parse(format, &d, &a) < 0)
+    {
+        errno = EINVAL;
+        return NULL;
+    }
+
+#define CLEANUP() \
+  free (d.dir);                                                                \
+  if (a.arg)                                                           \
+    free (a.arg);
+
+    if (printf_fetchargs(args, &a) < 0)
+    {
+        CLEANUP ();
+        errno = EINVAL;
+        return NULL;
+    }
+
+    {
+        char *buf = (char *) alloca(7 + d.max_width_length + d.max_precision_length + 6);
+        const char *cp;
+        unsigned int i;
+        char_directive *dp;
+        /* Output string accumulator.  */
+        char *result;
+        size_t allocated;
+        size_t length;
+
+        if (resultbuf != NULL)
+        {
+            result = resultbuf;
+            allocated = *lengthp;
+        }
+        else
+        {
+            result = NULL;
+            allocated = 0;
+        }
+        length = 0;
+        /* Invariants:
+         result is either == resultbuf or == NULL or malloc-allocated.
+         If length > 0, then result != NULL.  */
+
+#define ENSURE_ALLOCATION(needed) \
+    if ((needed) > allocated)                                          \
+      {                                                                        \
+       char *memory;                                                   \
+                                                                       \
+       allocated = (allocated > 0 ? 2 * allocated : 12);               \
+       if ((needed) > allocated)                                       \
+         allocated = (needed);                                         \
+       if (result == resultbuf || result == NULL)                      \
+         memory = (char *) malloc (allocated);                         \
+       else                                                            \
+         memory = (char *) realloc (result, allocated);                \
+                                                                       \
+       if (memory == NULL)                                             \
+         {                                                             \
+           if (!(result == resultbuf || result == NULL))               \
+             free (result);                                            \
+           freea (buf);                                                \
+           CLEANUP ();                                                 \
+           errno = ENOMEM;                                             \
+           return NULL;                                                \
+         }                                                             \
+       if (result == resultbuf && length > 0)                          \
+         memcpy (memory, result, length);                              \
+       result = memory;                                                \
+      }
+
+        for (cp = format, i = 0, dp = &d.dir[0];; cp = dp->dir_end, i++, dp++)
+        {
+            if (cp != dp->dir_start)
+            {
+                size_t n = dp->dir_start - cp;
+
+                ENSURE_ALLOCATION(length + n);
+                memcpy(result + length, cp, n);
+                length += n;
+            }
+            if (i == d.count)
+                break;
+
+            /* Execute a single directive.  */
+            if (dp->conversion == '%')
+            {
+                if (!(dp->arg_index < 0))
+                    abort();
+                ENSURE_ALLOCATION(length + 1);
+                result[length] = '%';
+                length += 1;
+            }
+            else
+            {
+                if (!(dp->arg_index >= 0))
+                    abort();
+
+                if (dp->conversion == 'n')
+                {
+                    switch (a.arg[dp->arg_index].type)
+                    {
+                        case TYPE_COUNT_SCHAR_POINTER:
+                            *a.arg[dp->arg_index].a.a_count_schar_pointer = length;
+                            break;
+                        case TYPE_COUNT_SHORT_POINTER:
+                            *a.arg[dp->arg_index].a.a_count_short_pointer = length;
+                            break;
+                        case TYPE_COUNT_INT_POINTER:
+                            *a.arg[dp->arg_index].a.a_count_int_pointer = length;
+                            break;
+                        case TYPE_COUNT_LONGINT_POINTER:
+                            *a.arg[dp->arg_index].a.a_count_longint_pointer = length;
+                            break;
+#ifdef HAVE_LONG_LONG
+                        case TYPE_COUNT_LONGLONGINT_POINTER:
+                            *a.arg[dp->arg_index].a.a_count_longlongint_pointer = length;
+                            break;
+#endif
+                        default:
+                            abort();
+                    }
+                }
+                else
+                {
+                    arg_type type = a.arg[dp->arg_index].type;
+                    char *p;
+                    unsigned int prefix_count;
+                    int prefixes[2];
+#if !HAVE_SNPRINTF
+                    unsigned int tmp_length;
+                    char tmpbuf[700];
+                    char *tmp;
+
+                    /* Allocate a temporary buffer of sufficient size for calling
+                     sprintf.  */
+                    {
+                        unsigned int width;
+                        unsigned int precision;
+
+                        width = 0;
+                        if (dp->width_start != dp->width_end)
+                        {
+                            if (dp->width_arg_index >= 0)
+                            {
+                                int arg;
+
+                                if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+                                    abort();
+                                arg = a.arg[dp->width_arg_index].a.a_int;
+                                width = (arg < 0 ? -arg : arg);
+                            }
+                            else
+                            {
+                                const char *digitp = dp->width_start;
+
+                                do
+                                    width = width * 10 + (*digitp++ - '0');
+                                while (digitp != dp->width_end);
+                            }
+                        }
+
+                        precision = 6;
+                        if (dp->precision_start != dp->precision_end)
+                        {
+                            if (dp->precision_arg_index >= 0)
+                            {
+                                int arg;
+
+                                if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
+                                    abort();
+                                arg = a.arg[dp->precision_arg_index].a.a_int;
+                                precision = (arg < 0 ? 0 : arg);
+                            }
+                            else
+                            {
+                                const char *digitp = dp->precision_start + 1;
+
+                                precision = 0;
+                                while (digitp != dp->precision_end)
+                                    precision = precision * 10 + (*digitp++ - '0');
+                            }
+                        }
+
+                        switch (dp->conversion)
+                        {
+                            case 'd':
+                            case 'i':
+                            case 'u':
+# ifdef HAVE_LONG_LONG
+                                if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
+                                    tmp_length = (unsigned int) (sizeof(unsigned long long)
+                                            * CHAR_BIT * 0.30103 /* binary -> decimal */
+                                            * 2 /* estimate for FLAG_GROUP */
+                                    ) + 1 /* turn floor into ceil */
+                                    + 1; /* account for leading sign */
+                                else
+# endif
+                                if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
+                                    tmp_length = (unsigned int) (sizeof(unsigned long) * CHAR_BIT
+                                            * 0.30103 /* binary -> decimal */
+                                            * 2 /* estimate for FLAG_GROUP */
+                                    ) + 1 /* turn floor into ceil */
+                                    + 1; /* account for leading sign */
+                                else
+                                    tmp_length = (unsigned int) (sizeof(unsigned int) * CHAR_BIT
+                                            * 0.30103 /* binary -> decimal */
+                                            * 2 /* estimate for FLAG_GROUP */
+                                    ) + 1 /* turn floor into ceil */
+                                    + 1; /* account for leading sign */
+                                break;
+
+                            case 'o':
+# ifdef HAVE_LONG_LONG
+                                if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
+                                    tmp_length = (unsigned int) (sizeof(unsigned long long)
+                                            * CHAR_BIT * 0.333334 /* binary -> octal */
+                                    ) + 1 /* turn floor into ceil */
+                                    + 1; /* account for leading sign */
+                                else
+# endif
+                                if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
+                                    tmp_length = (unsigned int) (sizeof(unsigned long) * CHAR_BIT
+                                            * 0.333334 /* binary -> octal */
+                                    ) + 1 /* turn floor into ceil */
+                                    + 1; /* account for leading sign */
+                                else
+                                    tmp_length = (unsigned int) (sizeof(unsigned int) * CHAR_BIT
+                                            * 0.333334 /* binary -> octal */
+                                    ) + 1 /* turn floor into ceil */
+                                    + 1; /* account for leading sign */
+                                break;
+
+                            case 'x':
+                            case 'X':
+# ifdef HAVE_LONG_LONG
+                                if (type == TYPE_LONGLONGINT || type == TYPE_ULONGLONGINT)
+                                    tmp_length = (unsigned int) (sizeof(unsigned long long)
+                                            * CHAR_BIT * 0.25 /* binary -> hexadecimal */
+                                    ) + 1 /* turn floor into ceil */
+                                    + 2; /* account for leading sign or alternate form */
+                                else
+# endif
+# ifdef HAVE_INT64_AND_I64
+                                if (type == TYPE_INT64 || type == TYPE_UINT64)
+                                tmp_length =
+                                (unsigned int) (sizeof (unsigned __int64) * CHAR_BIT
+                                        * 0.25 /* binary -> hexadecimal */
+                                )
+                                + 1 /* turn floor into ceil */
+                                + 2; /* account for leading sign or alternate form */
+                                else
+# endif
+                                if (type == TYPE_LONGINT || type == TYPE_ULONGINT)
+                                    tmp_length = (unsigned int) (sizeof(unsigned long) * CHAR_BIT
+                                            * 0.25 /* binary -> hexadecimal */
+                                    ) + 1 /* turn floor into ceil */
+                                    + 2; /* account for leading sign or alternate form */
+                                else
+                                    tmp_length = (unsigned int) (sizeof(unsigned int) * CHAR_BIT
+                                            * 0.25 /* binary -> hexadecimal */
+                                    ) + 1 /* turn floor into ceil */
+                                    + 2; /* account for leading sign or alternate form */
+                                break;
+
+                            case 'f':
+                            case 'F':
+# ifdef HAVE_LONG_DOUBLE
+                                if (type == TYPE_LONGDOUBLE)
+                                    tmp_length = (unsigned int) (LDBL_MAX_EXP * 0.30103 /* binary -> decimal */
+                                    * 2 /* estimate for FLAG_GROUP */
+                                    ) + 1 /* turn floor into ceil */
+                                    + precision + 10; /* sign, decimal point etc. */
+                                else
+# endif
+                                    tmp_length = (unsigned int) (DBL_MAX_EXP * 0.30103 /* binary -> decimal */
+                                    * 2 /* estimate for FLAG_GROUP */
+                                    ) + 1 /* turn floor into ceil */
+                                    + precision + 10; /* sign, decimal point etc. */
+                                break;
+
+                            case 'e':
+                            case 'E':
+                            case 'g':
+                            case 'G':
+                            case 'a':
+                            case 'A':
+                                tmp_length = precision + 12; /* sign, decimal point, exponent etc. */
+                                break;
+
+                            case 'c':
+# ifdef HAVE_WINT_T
+                                if (type == TYPE_WIDE_CHAR)
+                                tmp_length = MB_CUR_MAX;
+                                else
+# endif
+                                tmp_length = 1;
+                                break;
+
+                            case 's':
+# ifdef HAVE_WCHAR_T
+                                if (type == TYPE_WIDE_STRING)
+                                tmp_length =
+                                (a.arg[dp->arg_index].a.a_wide_string == NULL
+                                        ? 6 /* wcslen(L"(null)") */
+                                        : local_wcslen (a.arg[dp->arg_index].a.a_wide_string))
+                                * MB_CUR_MAX;
+                                else
+# endif
+                                tmp_length =
+                                        a.arg[dp->arg_index].a.a_string == NULL ?
+                                                6 /* strlen("(null)") */
+                                                :
+                                                strlen(a.arg[dp->arg_index].a.a_string);
+                                break;
+
+                            case 'p':
+                                tmp_length = (unsigned int) (sizeof(void *) * CHAR_BIT * 0.25 /* binary -> hexadecimal */
+                                ) + 1 /* turn floor into ceil */
+                                + 2; /* account for leading 0x */
+                                break;
+
+                            default:
+                                abort();
+                        }
+
+                        if (tmp_length < width)
+                            tmp_length = width;
+
+                        tmp_length++; /* account for trailing NUL */
+                    }
+
+                    if (tmp_length <= sizeof(tmpbuf))
+                        tmp = tmpbuf;
+                    else
+                    {
+                        tmp = (char *) malloc(tmp_length);
+                        if (tmp == NULL)
+                        {
+                            /* Out of memory.  */
+                            if (!(result == resultbuf || result == NULL))
+                                free(result);
+                            freea (buf);
+                            CLEANUP ();
+                            errno = ENOMEM;
+                            return NULL;
+                        }
+                    }
+#endif
+
+                    /* Construct the format string for calling snprintf or
+                     sprintf.  */
+                    p = buf;
+                    *p++ = '%';
+                    if (dp->flags & FLAG_GROUP)
+                        *p++ = '\'';
+                    if (dp->flags & FLAG_LEFT)
+                        *p++ = '-';
+                    if (dp->flags & FLAG_SHOWSIGN)
+                        *p++ = '+';
+                    if (dp->flags & FLAG_SPACE)
+                        *p++ = ' ';
+                    if (dp->flags & FLAG_ALT)
+                        *p++ = '#';
+                    if (dp->flags & FLAG_ZERO)
+                        *p++ = '0';
+                    if (dp->width_start != dp->width_end)
+                    {
+                        size_t n = dp->width_end - dp->width_start;
+                        memcpy(p, dp->width_start, n);
+                        p += n;
+                    }
+                    if (dp->precision_start != dp->precision_end)
+                    {
+                        size_t n = dp->precision_end - dp->precision_start;
+                        memcpy(p, dp->precision_start, n);
+                        p += n;
+                    }
+
+                    switch (type)
+                    {
+#ifdef HAVE_INT64_AND_I64
+                        case TYPE_INT64:
+                        case TYPE_UINT64:
+                        *p++ = 'I';
+                        *p++ = '6';
+                        *p++ = '4';
+                        break;
+#endif
+#ifdef HAVE_LONG_LONG
+                        case TYPE_LONGLONGINT:
+                        case TYPE_ULONGLONGINT:
+#ifdef HAVE_INT64_AND_I64      /* The system (sn)printf uses %I64. Also assume
+                                * that long long == __int64.
+                                */
+                            *p++ = 'I';
+                            *p++ = '6';
+                            *p++ = '4';
+                            break;
+#else
+                            *p++ = 'l';
+                            /*FALLTHROUGH*/
+#endif
+#endif
+                        case TYPE_LONGINT:
+                        case TYPE_ULONGINT:
+#ifdef HAVE_WINT_T
+                            case TYPE_WIDE_CHAR:
+#endif
+#ifdef HAVE_WCHAR_T
+                            case TYPE_WIDE_STRING:
+#endif
+                            *p++ = 'l';
+                            break;
+#ifdef HAVE_LONG_DOUBLE
+                        case TYPE_LONGDOUBLE:
+                            *p++ = 'L';
+                            break;
+#endif
+                        default:
+                            break;
+                    }
+                    *p = dp->conversion;
+#if HAVE_SNPRINTF
+                    p[1] = '%';
+                    p[2] = 'n';
+                    p[3] = '\0';
+#else
+                    p[1] = '\0';
+#endif
+
+                    /* Construct the arguments for calling snprintf or sprintf.  */
+                    prefix_count = 0;
+                    if (dp->width_arg_index >= 0)
+                    {
+                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+                            abort();
+                        prefixes[prefix_count++] = a.arg[dp->width_arg_index].a.a_int;
+                    }
+                    if (dp->precision_arg_index >= 0)
+                    {
+                        if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
+                            abort();
+                        prefixes[prefix_count++] = a.arg[dp->precision_arg_index].a.a_int;
+                    }
+
+#if HAVE_SNPRINTF
+                    /* Prepare checking whether snprintf returns the count
+                     via %n.  */
+                    ENSURE_ALLOCATION (length + 1);
+                    result[length] = '\0';
+#endif
+
+                    for (;;)
+                    {
+                        size_t maxlen;
+                        int count;
+                        int retcount;
+
+                        maxlen = allocated - length;
+                        count = -1;
+                        retcount = 0;
+
+#if HAVE_SNPRINTF
+#define SNPRINTF_BUF(arg) \
+                   switch (prefix_count)                                   \
+                     {                                                     \
+                     case 0:                                               \
+                       retcount = snprintf (result + length, maxlen, buf,  \
+                                            arg, &count);                  \
+                       break;                                              \
+                     case 1:                                               \
+                       retcount = snprintf (result + length, maxlen, buf,  \
+                                            prefixes[0], arg, &count);     \
+                       break;                                              \
+                     case 2:                                               \
+                       retcount = snprintf (result + length, maxlen, buf,  \
+                                            prefixes[0], prefixes[1], arg, \
+                                            &count);                       \
+                       break;                                              \
+                     default:                                              \
+                       abort ();                                           \
+                     }
+#else
+#define SNPRINTF_BUF(arg) \
+                   switch (prefix_count)                                   \
+                     {                                                     \
+                     case 0:                                               \
+                       count = sprintf (tmp, buf, arg);                    \
+                       break;                                              \
+                     case 1:                                               \
+                       count = sprintf (tmp, buf, prefixes[0], arg);       \
+                       break;                                              \
+                     case 2:                                               \
+                       count = sprintf (tmp, buf, prefixes[0], prefixes[1],\
+                                        arg);                              \
+                       break;                                              \
+                     default:                                              \
+                       abort ();                                           \
+                     }
+#endif
+
+                        switch (type)
+                        {
+                            case TYPE_SCHAR:
+                            {
+                                int arg = a.arg[dp->arg_index].a.a_schar;
+                                SNPRINTF_BUF(arg);
+                            }
+                                break;
+                            case TYPE_UCHAR:
+                            {
+                                unsigned int arg = a.arg[dp->arg_index].a.a_uchar;
+                                SNPRINTF_BUF(arg);
+                            }
+                                break;
+                            case TYPE_SHORT:
+                            {
+                                int arg = a.arg[dp->arg_index].a.a_short;
+                                SNPRINTF_BUF(arg);
+                            }
+                                break;
+                            case TYPE_USHORT:
+                            {
+                                unsigned int arg = a.arg[dp->arg_index].a.a_ushort;
+                                SNPRINTF_BUF(arg);
+                            }
+                                break;
+                            case TYPE_INT:
+                            {
+                                int arg = a.arg[dp->arg_index].a.a_int;
+                                SNPRINTF_BUF(arg);
+                            }
+                                break;
+                            case TYPE_UINT:
+                            {
+                                unsigned int arg = a.arg[dp->arg_index].a.a_uint;
+                                SNPRINTF_BUF(arg);
+                            }
+                                break;
+                            case TYPE_LONGINT:
+                            {
+                                long int arg = a.arg[dp->arg_index].a.a_longint;
+                                SNPRINTF_BUF(arg);
+                            }
+                                break;
+                            case TYPE_ULONGINT:
+                            {
+                                unsigned long int arg = a.arg[dp->arg_index].a.a_ulongint;
+                                SNPRINTF_BUF(arg);
+                            }
+                                break;
+#ifdef HAVE_INT64_AND_I64
+                                case TYPE_INT64:
+                                {
+                                    __int64 arg = a.arg[dp->arg_index].a.a_int64;
+                                    SNPRINTF_BUF (arg);
+                                }
+                                break;
+                                case TYPE_UINT64:
+                                {
+                                    unsigned __int64 arg = a.arg[dp->arg_index].a.a_uint64;
+                                    SNPRINTF_BUF (arg);
+                                }
+                                break;
+#endif
+#ifdef HAVE_LONG_LONG
+#ifndef HAVE_LONG_LONG_FORMAT
+                            case TYPE_LONGLONGINT:
+                            case TYPE_ULONGLONGINT:
+                            {
+                                unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
+                                int width;
+                                int precision;
+
+                                width = 0;
+                                if (dp->width_start != dp->width_end)
+                                {
+                                    if (dp->width_arg_index >= 0)
+                                    {
+                                        int arg;
+
+                                        if (!(a.arg[dp->width_arg_index].type == TYPE_INT))
+                                            abort();
+                                        arg = a.arg[dp->width_arg_index].a.a_int;
+                                        width = (arg < 0 ? -arg : arg);
+                                    }
+                                    else
+                                    {
+                                        const char *digitp = dp->width_start;
+
+                                        do
+                                            width = width * 10 + (*digitp++ - '0');
+                                        while (digitp != dp->width_end);
+                                    }
+                                }
+
+                                precision = -1;
+                                if (dp->precision_start != dp->precision_end)
+                                {
+                                    if (dp->precision_arg_index >= 0)
+                                    {
+                                        int arg;
+
+                                        if (!(a.arg[dp->precision_arg_index].type == TYPE_INT))
+                                            abort();
+                                        arg = a.arg[dp->precision_arg_index].a.a_int;
+                                        precision = (arg < 0 ? 0 : arg);
+                                    }
+                                    else
+                                    {
+                                        const char *digitp = dp->precision_start + 1;
+
+                                        precision = 0;
+                                        do
+                                            precision = precision * 10 + (*digitp++ - '0');
+                                        while (digitp != dp->precision_end);
+                                    }
+                                }
+
+#if HAVE_SNPRINTF
+                                count = print_long_long (result + length, maxlen,
+                                        width, precision,
+                                        dp->flags,
+                                        dp->conversion,
+                                        arg);
+#else
+                                count = print_long_long(tmp, tmp_length, width, precision,
+                                        dp->flags, dp->conversion, arg);
+#endif
+                            }
+                                break;
+#else
+                                case TYPE_LONGLONGINT:
+                                {
+                                    long long int arg = a.arg[dp->arg_index].a.a_longlongint;
+                                    SNPRINTF_BUF (arg);
+                                }
+                                break;
+                                case TYPE_ULONGLONGINT:
+                                {
+                                    unsigned long long int arg = a.arg[dp->arg_index].a.a_ulonglongint;
+                                    SNPRINTF_BUF (arg);
+                                }
+                                break;
+#endif
+#endif
+                            case TYPE_DOUBLE:
+                            {
+                                double arg = a.arg[dp->arg_index].a.a_double;
+                                SNPRINTF_BUF(arg);
+                            }
+                                break;
+#ifdef HAVE_LONG_DOUBLE
+                            case TYPE_LONGDOUBLE:
+                            {
+                                long double arg = a.arg[dp->arg_index].a.a_longdouble;
+                                SNPRINTF_BUF(arg);
+                            }
+                                break;
+#endif
+                            case TYPE_CHAR:
+                            {
+                                int arg = a.arg[dp->arg_index].a.a_char;
+                                SNPRINTF_BUF(arg);
+                            }
+                                break;
+#ifdef HAVE_WINT_T
+                                case TYPE_WIDE_CHAR:
+                                {
+                                    wint_t arg = a.arg[dp->arg_index].a.a_wide_char;
+                                    SNPRINTF_BUF (arg);
+                                }
+                                break;
+#endif
+                            case TYPE_STRING:
+                            {
+                                const char *arg =
+                                        a.arg[dp->arg_index].a.a_string == NULL ?
+                                                "(null)" : a.arg[dp->arg_index].a.a_string;
+                                SNPRINTF_BUF(arg);
+                            }
+                                break;
+#ifdef HAVE_WCHAR_T
+                                case TYPE_WIDE_STRING:
+                                {
+                                    const wchar_t *arg = a.arg[dp->arg_index].a.a_wide_string == NULL
+                                    ? L"(null)"
+                                    : a.arg[dp->arg_index].a.a_wide_string;
+                                    SNPRINTF_BUF (arg);
+                                }
+                                break;
+#endif
+                            case TYPE_POINTER:
+                            {
+                                void *arg = a.arg[dp->arg_index].a.a_pointer;
+                                SNPRINTF_BUF(arg);
+                            }
+                                break;
+                            default:
+                                abort();
+                        }
+
+#if HAVE_SNPRINTF
+                        /* Portability: Not all implementations of snprintf()
+                         are ISO C 99 compliant.  Determine the number of
+                         bytes that snprintf() has produced or would have
+                         produced.  */
+                        if (count >= 0)
+                        {
+                            /* Verify that snprintf() has NUL-terminated its
+                             result.  */
+                            if (count < maxlen && result[length + count] != '\0')
+                            abort ();
+                            /* Portability hack.  */
+                            if (retcount > count)
+                            count = retcount;
+                        }
+                        else
+                        {
+                            /* snprintf() doesn't understand the '%n'
+                             directive.  */
+                            if (p[1] != '\0')
+                            {
+                                /* Don't use the '%n' directive; instead, look
+                                 at the snprintf() return value.  */
+                                p[1] = '\0';
+                                continue;
+                            }
+                            count = retcount;
+                        }
+#endif
+
+                        /* Attempt to handle failure.  */
+                        if (count < 0)
+                        {
+                            if (!(result == resultbuf || result == NULL))
+                                free(result);
+                            freea (buf);
+                            CLEANUP ();
+                            errno = EINVAL;
+                            return NULL;
+                        }
+
+#if !HAVE_SNPRINTF
+                        if (count >= tmp_length)
+                            /* tmp_length was incorrectly calculated - fix the
+                             code above!  */
+                            abort();
+#endif
+
+                        /* Make room for the result.  */
+                        if (count >= maxlen)
+                        {
+                            /* Need at least count bytes.  But allocate
+                             proportionally, to avoid looping eternally if
+                             snprintf() reports a too small count.  */
+                            size_t n = length + count;
+
+                            if (n < 2 * allocated)
+                                n = 2 * allocated;
+
+                            ENSURE_ALLOCATION(n);
+#if HAVE_SNPRINTF
+                            continue;
+#endif
+                        }
+
+#if HAVE_SNPRINTF
+                        /* The snprintf() result did fit.  */
+#else
+                        /* Append the sprintf() result.  */
+                        memcpy(result + length, tmp, count);
+                        if (tmp != tmpbuf)
+                            free(tmp);
+#endif
+
+                        length += count;
+                        break;
+                    }
+                }
+            }
+        }
+
+        /* Add the final NUL.  */
+        ENSURE_ALLOCATION(length + 1);
+        result[length] = '\0';
+
+        if (result != resultbuf && length + 1 < allocated)
+        {
+            /* Shrink the allocated memory if possible.  */
+            char *memory;
+
+            memory = (char *) realloc(result, length + 1);
+            if (memory != NULL)
+                result = memory;
+        }
+
+        freea (buf);
+        CLEANUP ();
+        *lengthp = length;
+        return result;
+    }
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/vasnprintf.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gnulib/vasnprintf.h
new file mode 100644 (file)
index 0000000..b2a52be
--- /dev/null
@@ -0,0 +1,62 @@
+/* vsprintf with automatic memory allocation.
+ Copyright (C) 2002-2003 Free Software Foundation, Inc.
+
+ This program is free software; you can redistribute it and/or modify it
+ under the terms of the GNU Library General Public License as published
+ by the Free Software Foundation; either version 2, 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with this program; if not, write to the Free Software
+ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ USA.  */
+
+#ifndef _VASNPRINTF_H
+#define _VASNPRINTF_H
+
+/* Get va_list.  */
+#include <stdarg.h>
+
+/* Get size_t.  */
+#include <stddef.h>
+
+#ifndef __attribute__
+/* This feature is available in gcc versions 2.5 and later.  */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 5) || __STRICT_ANSI__
+#  define __attribute__(Spec) /* empty */
+# endif
+/* The __-protected variants of `format' and `printf' attributes
+ are accepted by gcc versions 2.6.4 (effectively 2.7) and later.  */
+# if __GNUC__ < 2 || (__GNUC__ == 2 && __GNUC_MINOR__ < 7)
+#  define __format__ format
+#  define __printf__ printf
+# endif
+#endif
+
+#ifdef __cplusplus
+extern "C"
+{
+#endif
+
+    /* Write formatted output to a string dynamically allocated with malloc().
+     You can pass a preallocated buffer for the result in RESULTBUF and its
+     size in *LENGTHP; otherwise you pass RESULTBUF = NULL.
+     If successful, return the address of the string (this may be = RESULTBUF
+     if no dynamic memory allocation was necessary) and set *LENGTHP to the
+     number of resulting bytes, excluding the trailing NUL.  Upon error, set
+     errno and return NULL.  */
+    extern char * asnprintf(char *resultbuf, size_t *lengthp, const char *format, ...)
+            __attribute__ ((__format__ (__printf__, 3, 4)));
+    extern char * vasnprintf(char *resultbuf, size_t *lengthp, const char *format, va_list args)
+            __attribute__ ((__format__ (__printf__, 3, 0)));
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif /* _VASNPRINTF_H */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/goption.c b/resource/csdk/connectivity/lib/android/glib-master/glib/goption.c
new file mode 100644 (file)
index 0000000..f09c7e1
--- /dev/null
@@ -0,0 +1,2387 @@
+/* goption.c - Option parser
+ *
+ *  Copyright (C) 1999, 2003 Red Hat Software
+ *  Copyright (C) 2004       Anders Carlsson <andersca@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/**
+ * SECTION:option
+ * @Short_description: parses commandline options
+ * @Title: Commandline option parser
+ *
+ * The GOption commandline parser is intended to be a simpler replacement
+ * for the popt library. It supports short and long commandline options,
+ * as shown in the following example:
+ *
+ * <literal>testtreemodel -r 1 --max-size 20 --rand --display=:1.0 -vb -- file1 file2</literal>
+ *
+ * The example demonstrates a number of features of the GOption
+ * commandline parser
+ * <itemizedlist><listitem><para>
+ *   Options can be single letters, prefixed by a single dash. Multiple
+ *   short options can be grouped behind a single dash.
+ * </para></listitem><listitem><para>
+ *   Long options are prefixed by two consecutive dashes.
+ * </para></listitem><listitem><para>
+ *   Options can have an extra argument, which can be a number, a string or
+ *   a filename. For long options, the extra argument can be appended with
+ *   an equals sign after the option name, which is useful if the extra
+ *   argument starts with a dash, which would otherwise cause it to be
+ *   interpreted as another option.
+ * </para></listitem><listitem><para>
+ *   Non-option arguments are returned to the application as rest arguments.
+ * </para></listitem><listitem><para>
+ *   An argument consisting solely of two dashes turns off further parsing,
+ *   any remaining arguments (even those starting with a dash) are returned
+ *   to the application as rest arguments.
+ * </para></listitem></itemizedlist>
+ *
+ * Another important feature of GOption is that it can automatically
+ * generate nicely formatted help output. Unless it is explicitly turned
+ * off with g_option_context_set_help_enabled(), GOption will recognize
+ * the <option>--help</option>, <option>-?</option>,
+ * <option>--help-all</option> and
+ * <option>--help-</option><replaceable>groupname</replaceable> options
+ * (where <replaceable>groupname</replaceable> is the name of a
+ * #GOptionGroup) and write a text similar to the one shown in the
+ * following example to stdout.
+ *
+ * <informalexample><screen>
+ * Usage:
+ *   testtreemodel [OPTION...] - test tree model performance
+ *  
+ * Help Options:
+ *   -h, --help               Show help options
+ *   --help-all               Show all help options
+ *   --help-gtk               Show GTK+ Options
+ *  
+ * Application Options:
+ *   -r, --repeats=N          Average over N repetitions
+ *   -m, --max-size=M         Test up to 2^M items
+ *   --display=DISPLAY        X display to use
+ *   -v, --verbose            Be verbose
+ *   -b, --beep               Beep when done
+ *   --rand                   Randomize the data
+ * </screen></informalexample>
+ *
+ * GOption groups options in #GOptionGroup<!-- -->s, which makes it easy to
+ * incorporate options from multiple sources. The intended use for this is
+ * to let applications collect option groups from the libraries it uses,
+ * add them to their #GOptionContext, and parse all options by a single call
+ * to g_option_context_parse(). See gtk_get_option_group() for an example.
+ *
+ * If an option is declared to be of type string or filename, GOption takes
+ * care of converting it to the right encoding; strings are returned in
+ * UTF-8, filenames are returned in the GLib filename encoding. Note that
+ * this only works if setlocale() has been called before
+ * g_option_context_parse().
+ *
+ * Here is a complete example of setting up GOption to parse the example
+ * commandline above and produce the example help output.
+ *
+ * <informalexample><programlisting>
+ * static gint repeats = 2;
+ * static gint max_size = 8;
+ * static gboolean verbose = FALSE;
+ * static gboolean beep = FALSE;
+ * static gboolean rand = FALSE;
+ *
+ * static GOptionEntry entries[] =
+ * {
+ *   { "repeats", 'r', 0, G_OPTION_ARG_INT, &repeats, "Average over N repetitions", "N" },
+ *   { "max-size", 'm', 0, G_OPTION_ARG_INT, &max_size, "Test up to 2^M items", "M" },
+ *   { "verbose", 'v', 0, G_OPTION_ARG_NONE, &verbose, "Be verbose", NULL },
+ *   { "beep", 'b', 0, G_OPTION_ARG_NONE, &beep, "Beep when done", NULL },
+ *   { "rand", 0, 0, G_OPTION_ARG_NONE, &rand, "Randomize the data", NULL },
+ *   { NULL }
+ * };
+ *
+ * int
+ * main (int argc, char *argv[])
+ * {
+ *   GError *error = NULL;
+ *   GOptionContext *context;
+ *
+ *   context = g_option_context_new ("- test tree model performance");
+ *   g_option_context_add_main_entries (context, entries, GETTEXT_PACKAGE);
+ *   g_option_context_add_group (context, gtk_get_option_group (TRUE));
+ *   if (!g_option_context_parse (context, &argc, &argv, &error))
+ *     {
+ *       g_print ("option parsing failed: %s\n", error->message);
+ *       exit (1);
+ *     }
+ *
+ *   /&ast; ... &ast;/
+ *
+ * }
+ * </programlisting></informalexample>
+ */
+
+#include "config.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <errno.h>
+
+#include "goption.h"
+
+#include "gprintf.h"
+#include "glibintl.h"
+
+#define TRANSLATE(group, str) (((group)->translate_func ? (* (group)->translate_func) ((str), (group)->translate_data) : (str)))
+
+#define NO_ARG(entry) ((entry)->arg == G_OPTION_ARG_NONE ||       \
+                       ((entry)->arg == G_OPTION_ARG_CALLBACK &&  \
+                        ((entry)->flags & G_OPTION_FLAG_NO_ARG)))
+
+#define OPTIONAL_ARG(entry) ((entry)->arg == G_OPTION_ARG_CALLBACK &&  \
+                       (entry)->flags & G_OPTION_FLAG_OPTIONAL_ARG)
+
+typedef struct
+{
+  GOptionArg arg_type;
+  gpointer arg_data;
+  union
+  {
+    gboolean bool;
+    gint integer;
+    gchar *str;
+    gchar **array;
+    gdouble dbl;
+    gint64 int64;
+  } prev;
+  union
+  {
+    gchar *str;
+    struct
+    {
+      gint len;
+      gchar **data;
+    } array;
+  } allocated;
+} Change;
+
+typedef struct
+{
+  gchar **ptr;
+  gchar *value;
+} PendingNull;
+
+struct _GOptionContext
+{
+  GList           *groups;
+
+  gchar           *parameter_string;
+  gchar           *summary;
+  gchar           *description;
+
+  GTranslateFunc   translate_func;
+  GDestroyNotify   translate_notify;
+  gpointer         translate_data;
+
+  guint            help_enabled   : 1;
+  guint            ignore_unknown : 1;
+
+  GOptionGroup    *main_group;
+
+  /* We keep a list of change so we can revert them */
+  GList           *changes;
+
+  /* We also keep track of all argv elements
+   * that should be NULLed or modified.
+   */
+  GList           *pending_nulls;
+};
+
+struct _GOptionGroup
+{
+  gchar           *name;
+  gchar           *description;
+  gchar           *help_description;
+
+  GDestroyNotify   destroy_notify;
+  gpointer         user_data;
+
+  GTranslateFunc   translate_func;
+  GDestroyNotify   translate_notify;
+  gpointer         translate_data;
+
+  GOptionEntry    *entries;
+  gint             n_entries;
+
+  GOptionParseFunc pre_parse_func;
+  GOptionParseFunc post_parse_func;
+  GOptionErrorFunc error_func;
+};
+
+static void free_changes_list (GOptionContext *context,
+                               gboolean        revert);
+static void free_pending_nulls (GOptionContext *context,
+                                gboolean        perform_nulls);
+
+
+static int
+_g_unichar_get_width (gunichar c)
+{
+  if (G_UNLIKELY (g_unichar_iszerowidth (c)))
+    return 0;
+
+  /* we ignore the fact that we should call g_unichar_iswide_cjk() under
+   * some locales (legacy East Asian ones) */
+  if (g_unichar_iswide (c))
+    return 2;
+
+  return 1;
+}
+
+static glong
+_g_utf8_strwidth (const gchar *p,
+                  gssize       max)
+{
+  glong len = 0;
+  const gchar *start = p;
+  g_return_val_if_fail (p != NULL || max == 0, 0);
+
+  if (max < 0)
+    {
+      while (*p)
+        {
+          len += _g_unichar_get_width (g_utf8_get_char (p));
+          p = g_utf8_next_char (p);
+        }
+    }
+  else
+    {
+      if (max == 0 || !*p)
+        return 0;
+
+      /* this case may not be quite correct */
+
+      len += _g_unichar_get_width (g_utf8_get_char (p));
+      p = g_utf8_next_char (p);
+
+      while (p - start < max && *p)
+        {
+          len += _g_unichar_get_width (g_utf8_get_char (p));
+          p = g_utf8_next_char (p);
+        }
+    }
+
+  return len;
+}
+
+
+GQuark
+g_option_error_quark (void)
+{
+  return g_quark_from_static_string ("g-option-context-error-quark");
+}
+
+/**
+ * g_option_context_new:
+ * @parameter_string: a string which is displayed in
+ *    the first line of <option>--help</option> output, after the
+ *    usage summary
+ *    <literal><replaceable>programname</replaceable> [OPTION...]</literal>
+ *
+ * Creates a new option context.
+ *
+ * The @parameter_string can serve multiple purposes. It can be used
+ * to add descriptions for "rest" arguments, which are not parsed by
+ * the #GOptionContext, typically something like "FILES" or
+ * "FILE1 FILE2...". If you are using #G_OPTION_REMAINING for
+ * collecting "rest" arguments, GLib handles this automatically by
+ * using the @arg_description of the corresponding #GOptionEntry in
+ * the usage summary.
+ *
+ * Another usage is to give a short summary of the program
+ * functionality, like " - frob the strings", which will be displayed
+ * in the same line as the usage. For a longer description of the
+ * program functionality that should be displayed as a paragraph
+ * below the usage line, use g_option_context_set_summary().
+ *
+ * Note that the @parameter_string is translated using the
+ * function set with g_option_context_set_translate_func(), so
+ * it should normally be passed untranslated.
+ *
+ * Returns: a newly created #GOptionContext, which must be
+ *    freed with g_option_context_free() after use.
+ *
+ * Since: 2.6
+ */
+GOptionContext *
+g_option_context_new (const gchar *parameter_string)
+
+{
+  GOptionContext *context;
+
+  context = g_new0 (GOptionContext, 1);
+
+  context->parameter_string = g_strdup (parameter_string);
+  context->help_enabled = TRUE;
+  context->ignore_unknown = FALSE;
+
+  return context;
+}
+
+/**
+ * g_option_context_free:
+ * @context: a #GOptionContext
+ *
+ * Frees context and all the groups which have been
+ * added to it.
+ *
+ * Please note that parsed arguments need to be freed separately (see
+ * #GOptionEntry).
+ *
+ * Since: 2.6
+ */
+void g_option_context_free (GOptionContext *context)
+{
+  g_return_if_fail (context != NULL);
+
+  g_list_foreach (context->groups, (GFunc)g_option_group_free, NULL);
+  g_list_free (context->groups);
+
+  if (context->main_group)
+    g_option_group_free (context->main_group);
+
+  free_changes_list (context, FALSE);
+  free_pending_nulls (context, FALSE);
+
+  g_free (context->parameter_string);
+  g_free (context->summary);
+  g_free (context->description);
+
+  if (context->translate_notify)
+    (* context->translate_notify) (context->translate_data);
+
+  g_free (context);
+}
+
+
+/**
+ * g_option_context_set_help_enabled:
+ * @context: a #GOptionContext
+ * @help_enabled: %TRUE to enable <option>--help</option>, %FALSE to disable it
+ *
+ * Enables or disables automatic generation of <option>--help</option>
+ * output. By default, g_option_context_parse() recognizes
+ * <option>--help</option>, <option>-h</option>,
+ * <option>-?</option>, <option>--help-all</option>
+ * and <option>--help-</option><replaceable>groupname</replaceable> and creates
+ * suitable output to stdout.
+ *
+ * Since: 2.6
+ */
+void g_option_context_set_help_enabled (GOptionContext *context,
+                                        gboolean        help_enabled)
+
+{
+  g_return_if_fail (context != NULL);
+
+  context->help_enabled = help_enabled;
+}
+
+/**
+ * g_option_context_get_help_enabled:
+ * @context: a #GOptionContext
+ *
+ * Returns whether automatic <option>--help</option> generation
+ * is turned on for @context. See g_option_context_set_help_enabled().
+ *
+ * Returns: %TRUE if automatic help generation is turned on.
+ *
+ * Since: 2.6
+ */
+gboolean
+g_option_context_get_help_enabled (GOptionContext *context)
+{
+  g_return_val_if_fail (context != NULL, FALSE);
+
+  return context->help_enabled;
+}
+
+/**
+ * g_option_context_set_ignore_unknown_options:
+ * @context: a #GOptionContext
+ * @ignore_unknown: %TRUE to ignore unknown options, %FALSE to produce
+ *    an error when unknown options are met
+ *
+ * Sets whether to ignore unknown options or not. If an argument is
+ * ignored, it is left in the @argv array after parsing. By default,
+ * g_option_context_parse() treats unknown options as error.
+ *
+ * This setting does not affect non-option arguments (i.e. arguments
+ * which don't start with a dash). But note that GOption cannot reliably
+ * determine whether a non-option belongs to a preceding unknown option.
+ *
+ * Since: 2.6
+ **/
+void
+g_option_context_set_ignore_unknown_options (GOptionContext *context,
+                                             gboolean        ignore_unknown)
+{
+  g_return_if_fail (context != NULL);
+
+  context->ignore_unknown = ignore_unknown;
+}
+
+/**
+ * g_option_context_get_ignore_unknown_options:
+ * @context: a #GOptionContext
+ *
+ * Returns whether unknown options are ignored or not. See
+ * g_option_context_set_ignore_unknown_options().
+ *
+ * Returns: %TRUE if unknown options are ignored.
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_option_context_get_ignore_unknown_options (GOptionContext *context)
+{
+  g_return_val_if_fail (context != NULL, FALSE);
+
+  return context->ignore_unknown;
+}
+
+/**
+ * g_option_context_add_group:
+ * @context: a #GOptionContext
+ * @group: the group to add
+ *
+ * Adds a #GOptionGroup to the @context, so that parsing with @context
+ * will recognize the options in the group. Note that the group will
+ * be freed together with the context when g_option_context_free() is
+ * called, so you must not free the group yourself after adding it
+ * to a context.
+ *
+ * Since: 2.6
+ **/
+void
+g_option_context_add_group (GOptionContext *context,
+                            GOptionGroup   *group)
+{
+  GList *list;
+
+  g_return_if_fail (context != NULL);
+  g_return_if_fail (group != NULL);
+  g_return_if_fail (group->name != NULL);
+  g_return_if_fail (group->description != NULL);
+  g_return_if_fail (group->help_description != NULL);
+
+  for (list = context->groups; list; list = list->next)
+    {
+      GOptionGroup *g = (GOptionGroup *)list->data;
+
+      if ((group->name == NULL && g->name == NULL) ||
+          (group->name && g->name && strcmp (group->name, g->name) == 0))
+        g_warning ("A group named \"%s\" is already part of this GOptionContext",
+                   group->name);
+    }
+
+  context->groups = g_list_append (context->groups, group);
+}
+
+/**
+ * g_option_context_set_main_group:
+ * @context: a #GOptionContext
+ * @group: the group to set as main group
+ *
+ * Sets a #GOptionGroup as main group of the @context.
+ * This has the same effect as calling g_option_context_add_group(),
+ * the only difference is that the options in the main group are
+ * treated differently when generating <option>--help</option> output.
+ *
+ * Since: 2.6
+ **/
+void
+g_option_context_set_main_group (GOptionContext *context,
+                                 GOptionGroup   *group)
+{
+  g_return_if_fail (context != NULL);
+  g_return_if_fail (group != NULL);
+
+  if (context->main_group)
+    {
+      g_warning ("This GOptionContext already has a main group");
+
+      return;
+    }
+
+  context->main_group = group;
+}
+
+/**
+ * g_option_context_get_main_group:
+ * @context: a #GOptionContext
+ *
+ * Returns a pointer to the main group of @context.
+ *
+ * Return value: the main group of @context, or %NULL if @context doesn't
+ *  have a main group. Note that group belongs to @context and should
+ *  not be modified or freed.
+ *
+ * Since: 2.6
+ **/
+GOptionGroup *
+g_option_context_get_main_group (GOptionContext *context)
+{
+  g_return_val_if_fail (context != NULL, NULL);
+
+  return context->main_group;
+}
+
+/**
+ * g_option_context_add_main_entries:
+ * @context: a #GOptionContext
+ * @entries: a %NULL-terminated array of #GOptionEntry<!-- -->s
+ * @translation_domain: a translation domain to use for translating
+ *    the <option>--help</option> output for the options in @entries
+ *    with gettext(), or %NULL
+ *
+ * A convenience function which creates a main group if it doesn't
+ * exist, adds the @entries to it and sets the translation domain.
+ *
+ * Since: 2.6
+ **/
+void
+g_option_context_add_main_entries (GOptionContext      *context,
+                                   const GOptionEntry  *entries,
+                                   const gchar         *translation_domain)
+{
+  g_return_if_fail (entries != NULL);
+
+  if (!context->main_group)
+    context->main_group = g_option_group_new (NULL, NULL, NULL, NULL, NULL);
+
+  g_option_group_add_entries (context->main_group, entries);
+  g_option_group_set_translation_domain (context->main_group, translation_domain);
+}
+
+static gint
+calculate_max_length (GOptionGroup *group)
+{
+  GOptionEntry *entry;
+  gint i, len, max_length;
+
+  max_length = 0;
+
+  for (i = 0; i < group->n_entries; i++)
+    {
+      entry = &group->entries[i];
+
+      if (entry->flags & G_OPTION_FLAG_HIDDEN)
+        continue;
+
+      len = _g_utf8_strwidth (entry->long_name, -1);
+
+      if (entry->short_name)
+        len += 4;
+
+      if (!NO_ARG (entry) && entry->arg_description)
+        len += 1 + _g_utf8_strwidth (TRANSLATE (group, entry->arg_description), -1);
+
+      max_length = MAX (max_length, len);
+    }
+
+  return max_length;
+}
+
+static void
+print_entry (GOptionGroup       *group,
+             gint                max_length,
+             const GOptionEntry *entry,
+             GString            *string)
+{
+  GString *str;
+
+  if (entry->flags & G_OPTION_FLAG_HIDDEN)
+    return;
+
+  if (entry->long_name[0] == 0)
+    return;
+
+  str = g_string_new (NULL);
+
+  if (entry->short_name)
+    g_string_append_printf (str, "  -%c, --%s", entry->short_name, entry->long_name);
+  else
+    g_string_append_printf (str, "  --%s", entry->long_name);
+
+  if (entry->arg_description)
+    g_string_append_printf (str, "=%s", TRANSLATE (group, entry->arg_description));
+
+  g_string_append_printf (string, "%s%*s %s\n", str->str,
+                          (int) (max_length + 4 - _g_utf8_strwidth (str->str, -1)), "",
+                          entry->description ? TRANSLATE (group, entry->description) : "");
+  g_string_free (str, TRUE);
+}
+
+static gboolean
+group_has_visible_entries (GOptionContext *context,
+                           GOptionGroup *group,
+                           gboolean      main_entries)
+{
+  GOptionFlags reject_filter = G_OPTION_FLAG_HIDDEN;
+  GOptionEntry *entry;
+  gint i, l;
+  gboolean main_group = group == context->main_group;
+
+  if (!main_entries)
+    reject_filter |= G_OPTION_FLAG_IN_MAIN;
+
+  for (i = 0, l = (group ? group->n_entries : 0); i < l; i++)
+    {
+      entry = &group->entries[i];
+
+      if (main_entries && !main_group && !(entry->flags & G_OPTION_FLAG_IN_MAIN))
+        continue;
+      if (!(entry->flags & reject_filter))
+        return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+group_list_has_visible_entires (GOptionContext *context,
+                                GList          *group_list,
+                                gboolean       main_entries)
+{
+  while (group_list)
+    {
+      if (group_has_visible_entries (context, group_list->data, main_entries))
+        return TRUE;
+
+      group_list = group_list->next;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+context_has_h_entry (GOptionContext *context)
+{
+  gsize i;
+  GList *list;
+
+  if (context->main_group)
+    {
+      for (i = 0; i < context->main_group->n_entries; i++)
+        {
+          if (context->main_group->entries[i].short_name == 'h')
+            return TRUE;
+        }
+    }
+
+  for (list = context->groups; list != NULL; list = g_list_next (list))
+    {
+     GOptionGroup *group;
+
+      group = (GOptionGroup*)list->data;
+      for (i = 0; i < group->n_entries; i++)
+        {
+          if (group->entries[i].short_name == 'h')
+            return TRUE;
+        }
+    }
+  return FALSE;
+}
+
+/**
+ * g_option_context_get_help:
+ * @context: a #GOptionContext
+ * @main_help: if %TRUE, only include the main group
+ * @group: the #GOptionGroup to create help for, or %NULL
+ *
+ * Returns a formatted, translated help text for the given context.
+ * To obtain the text produced by <option>--help</option>, call
+ * <literal>g_option_context_get_help (context, TRUE, NULL)</literal>.
+ * To obtain the text produced by <option>--help-all</option>, call
+ * <literal>g_option_context_get_help (context, FALSE, NULL)</literal>.
+ * To obtain the help text for an option group, call
+ * <literal>g_option_context_get_help (context, FALSE, group)</literal>.
+ *
+ * Returns: A newly allocated string containing the help text
+ *
+ * Since: 2.14
+ */
+gchar *
+g_option_context_get_help (GOptionContext *context,
+                           gboolean        main_help,
+                           GOptionGroup   *group)
+{
+  GList *list;
+  gint max_length, len;
+  gint i;
+  GOptionEntry *entry;
+  GHashTable *shadow_map;
+  gboolean seen[256];
+  const gchar *rest_description;
+  GString *string;
+  guchar token;
+
+  string = g_string_sized_new (1024);
+
+  rest_description = NULL;
+  if (context->main_group)
+    {
+
+      for (i = 0; i < context->main_group->n_entries; i++)
+        {
+          entry = &context->main_group->entries[i];
+          if (entry->long_name[0] == 0)
+            {
+              rest_description = TRANSLATE (context->main_group, entry->arg_description);
+              break;
+            }
+        }
+    }
+
+  g_string_append_printf (string, "%s\n  %s %s",
+                          _("Usage:"), g_get_prgname(), _("[OPTION...]"));
+
+  if (rest_description)
+    {
+      g_string_append (string, " ");
+      g_string_append (string, rest_description);
+    }
+
+  if (context->parameter_string)
+    {
+      g_string_append (string, " ");
+      g_string_append (string, TRANSLATE (context, context->parameter_string));
+    }
+
+  g_string_append (string, "\n\n");
+
+  if (context->summary)
+    {
+      g_string_append (string, TRANSLATE (context, context->summary));
+      g_string_append (string, "\n\n");
+    }
+
+  memset (seen, 0, sizeof (gboolean) * 256);
+  shadow_map = g_hash_table_new (g_str_hash, g_str_equal);
+
+  if (context->main_group)
+    {
+      for (i = 0; i < context->main_group->n_entries; i++)
+        {
+          entry = &context->main_group->entries[i];
+          g_hash_table_insert (shadow_map,
+                               (gpointer)entry->long_name,
+                               entry);
+
+          if (seen[(guchar)entry->short_name])
+            entry->short_name = 0;
+          else
+            seen[(guchar)entry->short_name] = TRUE;
+        }
+    }
+
+  list = context->groups;
+  while (list != NULL)
+    {
+      GOptionGroup *g = list->data;
+      for (i = 0; i < g->n_entries; i++)
+        {
+          entry = &g->entries[i];
+          if (g_hash_table_lookup (shadow_map, entry->long_name) &&
+              !(entry->flags & G_OPTION_FLAG_NOALIAS))
+            entry->long_name = g_strdup_printf ("%s-%s", g->name, entry->long_name);
+          else
+            g_hash_table_insert (shadow_map, (gpointer)entry->long_name, entry);
+
+          if (seen[(guchar)entry->short_name] &&
+              !(entry->flags & G_OPTION_FLAG_NOALIAS))
+            entry->short_name = 0;
+          else
+            seen[(guchar)entry->short_name] = TRUE;
+        }
+      list = list->next;
+    }
+
+  g_hash_table_destroy (shadow_map);
+
+  list = context->groups;
+
+  max_length = _g_utf8_strwidth ("-?, --help", -1);
+
+  if (list)
+    {
+      len = _g_utf8_strwidth ("--help-all", -1);
+      max_length = MAX (max_length, len);
+    }
+
+  if (context->main_group)
+    {
+      len = calculate_max_length (context->main_group);
+      max_length = MAX (max_length, len);
+    }
+
+  while (list != NULL)
+    {
+      GOptionGroup *g = list->data;
+
+      /* First, we check the --help-<groupname> options */
+      len = _g_utf8_strwidth ("--help-", -1) + _g_utf8_strwidth (g->name, -1);
+      max_length = MAX (max_length, len);
+
+      /* Then we go through the entries */
+      len = calculate_max_length (g);
+      max_length = MAX (max_length, len);
+
+      list = list->next;
+    }
+
+  /* Add a bit of padding */
+  max_length += 4;
+
+  if (!group)
+    {
+      list = context->groups;
+
+      token = context_has_h_entry (context) ? '?' : 'h';
+
+      g_string_append_printf (string, "%s\n  -%c, --%-*s %s\n",
+                              _("Help Options:"), token, max_length - 4, "help",
+                              _("Show help options"));
+
+      /* We only want --help-all when there are groups */
+      if (list)
+        g_string_append_printf (string, "  --%-*s %s\n",
+                                max_length, "help-all",
+                                _("Show all help options"));
+
+      while (list)
+        {
+          GOptionGroup *g = list->data;
+
+          if (group_has_visible_entries (context, g, FALSE))
+            g_string_append_printf (string, "  --help-%-*s %s\n",
+                                    max_length - 5, g->name,
+                                    TRANSLATE (g, g->help_description));
+
+          list = list->next;
+        }
+
+      g_string_append (string, "\n");
+    }
+
+  if (group)
+    {
+      /* Print a certain group */
+
+      if (group_has_visible_entries (context, group, FALSE))
+        {
+          g_string_append (string, TRANSLATE (group, group->description));
+          g_string_append (string, "\n");
+          for (i = 0; i < group->n_entries; i++)
+            print_entry (group, max_length, &group->entries[i], string);
+          g_string_append (string, "\n");
+        }
+    }
+  else if (!main_help)
+    {
+      /* Print all groups */
+
+      list = context->groups;
+
+      while (list)
+        {
+          GOptionGroup *g = list->data;
+
+          if (group_has_visible_entries (context, g, FALSE))
+            {
+              g_string_append (string, g->description);
+              g_string_append (string, "\n");
+              for (i = 0; i < g->n_entries; i++)
+                if (!(g->entries[i].flags & G_OPTION_FLAG_IN_MAIN))
+                  print_entry (g, max_length, &g->entries[i], string);
+
+              g_string_append (string, "\n");
+            }
+
+          list = list->next;
+        }
+    }
+
+  /* Print application options if --help or --help-all has been specified */
+  if ((main_help || !group) &&
+      (group_has_visible_entries (context, context->main_group, TRUE) ||
+       group_list_has_visible_entires (context, context->groups, TRUE)))
+    {
+      list = context->groups;
+
+      g_string_append (string,  _("Application Options:"));
+      g_string_append (string, "\n");
+      if (context->main_group)
+        for (i = 0; i < context->main_group->n_entries; i++)
+          print_entry (context->main_group, max_length,
+                       &context->main_group->entries[i], string);
+
+      while (list != NULL)
+        {
+          GOptionGroup *g = list->data;
+
+          /* Print main entries from other groups */
+          for (i = 0; i < g->n_entries; i++)
+            if (g->entries[i].flags & G_OPTION_FLAG_IN_MAIN)
+              print_entry (g, max_length, &g->entries[i], string);
+
+          list = list->next;
+        }
+
+      g_string_append (string, "\n");
+    }
+
+  if (context->description)
+    {
+      g_string_append (string, TRANSLATE (context, context->description));
+      g_string_append (string, "\n");
+    }
+
+  return g_string_free (string, FALSE);
+}
+
+G_GNUC_NORETURN
+static void
+print_help (GOptionContext *context,
+            gboolean        main_help,
+            GOptionGroup   *group)
+{
+  gchar *help;
+
+  help = g_option_context_get_help (context, main_help, group);
+  g_print ("%s", help);
+  g_free (help);
+
+  exit (0);
+}
+
+static gboolean
+parse_int (const gchar *arg_name,
+           const gchar *arg,
+           gint        *result,
+           GError     **error)
+{
+  gchar *end;
+  glong tmp;
+
+  errno = 0;
+  tmp = strtol (arg, &end, 0);
+
+  if (*arg == '\0' || *end != '\0')
+    {
+      g_set_error (error,
+                   G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                   _("Cannot parse integer value '%s' for %s"),
+                   arg, arg_name);
+      return FALSE;
+    }
+
+  *result = tmp;
+  if (*result != tmp || errno == ERANGE)
+    {
+      g_set_error (error,
+                   G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                   _("Integer value '%s' for %s out of range"),
+                   arg, arg_name);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+
+static gboolean
+parse_double (const gchar *arg_name,
+           const gchar *arg,
+           gdouble        *result,
+           GError     **error)
+{
+  gchar *end;
+  gdouble tmp;
+
+  errno = 0;
+  tmp = g_strtod (arg, &end);
+
+  if (*arg == '\0' || *end != '\0')
+    {
+      g_set_error (error,
+                   G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                   _("Cannot parse double value '%s' for %s"),
+                   arg, arg_name);
+      return FALSE;
+    }
+  if (errno == ERANGE)
+    {
+      g_set_error (error,
+                   G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                   _("Double value '%s' for %s out of range"),
+                   arg, arg_name);
+      return FALSE;
+    }
+
+  *result = tmp;
+
+  return TRUE;
+}
+
+
+static gboolean
+parse_int64 (const gchar *arg_name,
+             const gchar *arg,
+             gint64      *result,
+             GError     **error)
+{
+  gchar *end;
+  gint64 tmp;
+
+  errno = 0;
+  tmp = g_ascii_strtoll (arg, &end, 0);
+
+  if (*arg == '\0' || *end != '\0')
+    {
+      g_set_error (error,
+                   G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                   _("Cannot parse integer value '%s' for %s"),
+                   arg, arg_name);
+      return FALSE;
+    }
+  if (errno == ERANGE)
+    {
+      g_set_error (error,
+                   G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                   _("Integer value '%s' for %s out of range"),
+                   arg, arg_name);
+      return FALSE;
+    }
+
+  *result = tmp;
+
+  return TRUE;
+}
+
+
+static Change *
+get_change (GOptionContext *context,
+            GOptionArg      arg_type,
+            gpointer        arg_data)
+{
+  GList *list;
+  Change *change = NULL;
+
+  for (list = context->changes; list != NULL; list = list->next)
+    {
+      change = list->data;
+
+      if (change->arg_data == arg_data)
+        goto found;
+    }
+
+  change = g_new0 (Change, 1);
+  change->arg_type = arg_type;
+  change->arg_data = arg_data;
+
+  context->changes = g_list_prepend (context->changes, change);
+
+ found:
+
+  return change;
+}
+
+static void
+add_pending_null (GOptionContext *context,
+                  gchar         **ptr,
+                  gchar          *value)
+{
+  PendingNull *n;
+
+  n = g_new0 (PendingNull, 1);
+  n->ptr = ptr;
+  n->value = value;
+
+  context->pending_nulls = g_list_prepend (context->pending_nulls, n);
+}
+
+static gboolean
+parse_arg (GOptionContext *context,
+           GOptionGroup   *group,
+           GOptionEntry   *entry,
+           const gchar    *value,
+           const gchar    *option_name,
+           GError        **error)
+
+{
+  Change *change;
+
+  g_assert (value || OPTIONAL_ARG (entry) || NO_ARG (entry));
+
+  switch (entry->arg)
+    {
+    case G_OPTION_ARG_NONE:
+      {
+        change = get_change (context, G_OPTION_ARG_NONE,
+                             entry->arg_data);
+
+        *(gboolean *)entry->arg_data = !(entry->flags & G_OPTION_FLAG_REVERSE);
+        break;
+      }
+    case G_OPTION_ARG_STRING:
+      {
+        gchar *data;
+
+        data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
+
+        if (!data)
+          return FALSE;
+
+        change = get_change (context, G_OPTION_ARG_STRING,
+                             entry->arg_data);
+        g_free (change->allocated.str);
+
+        change->prev.str = *(gchar **)entry->arg_data;
+        change->allocated.str = data;
+
+        *(gchar **)entry->arg_data = data;
+        break;
+      }
+    case G_OPTION_ARG_STRING_ARRAY:
+      {
+        gchar *data;
+
+        data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
+
+        if (!data)
+          return FALSE;
+
+        change = get_change (context, G_OPTION_ARG_STRING_ARRAY,
+                             entry->arg_data);
+
+        if (change->allocated.array.len == 0)
+          {
+            change->prev.array = *(gchar ***)entry->arg_data;
+            change->allocated.array.data = g_new (gchar *, 2);
+          }
+        else
+          change->allocated.array.data =
+            g_renew (gchar *, change->allocated.array.data,
+                     change->allocated.array.len + 2);
+
+        change->allocated.array.data[change->allocated.array.len] = data;
+        change->allocated.array.data[change->allocated.array.len + 1] = NULL;
+
+        change->allocated.array.len ++;
+
+        *(gchar ***)entry->arg_data = change->allocated.array.data;
+
+        break;
+      }
+
+    case G_OPTION_ARG_FILENAME:
+      {
+        gchar *data;
+
+#ifdef G_OS_WIN32
+        data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
+
+        if (!data)
+          return FALSE;
+#else
+        data = g_strdup (value);
+#endif
+        change = get_change (context, G_OPTION_ARG_FILENAME,
+                             entry->arg_data);
+        g_free (change->allocated.str);
+
+        change->prev.str = *(gchar **)entry->arg_data;
+        change->allocated.str = data;
+
+        *(gchar **)entry->arg_data = data;
+        break;
+      }
+
+    case G_OPTION_ARG_FILENAME_ARRAY:
+      {
+        gchar *data;
+
+#ifdef G_OS_WIN32
+        data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
+
+        if (!data)
+          return FALSE;
+#else
+        data = g_strdup (value);
+#endif
+        change = get_change (context, G_OPTION_ARG_STRING_ARRAY,
+                             entry->arg_data);
+
+        if (change->allocated.array.len == 0)
+          {
+            change->prev.array = *(gchar ***)entry->arg_data;
+            change->allocated.array.data = g_new (gchar *, 2);
+          }
+        else
+          change->allocated.array.data =
+            g_renew (gchar *, change->allocated.array.data,
+                     change->allocated.array.len + 2);
+
+        change->allocated.array.data[change->allocated.array.len] = data;
+        change->allocated.array.data[change->allocated.array.len + 1] = NULL;
+
+        change->allocated.array.len ++;
+
+        *(gchar ***)entry->arg_data = change->allocated.array.data;
+
+        break;
+      }
+
+    case G_OPTION_ARG_INT:
+      {
+        gint data;
+
+        if (!parse_int (option_name, value,
+                        &data,
+                        error))
+          return FALSE;
+
+        change = get_change (context, G_OPTION_ARG_INT,
+                             entry->arg_data);
+        change->prev.integer = *(gint *)entry->arg_data;
+        *(gint *)entry->arg_data = data;
+        break;
+      }
+    case G_OPTION_ARG_CALLBACK:
+      {
+        gchar *data;
+        gboolean retval;
+
+        if (!value && entry->flags & G_OPTION_FLAG_OPTIONAL_ARG)
+          data = NULL;
+        else if (entry->flags & G_OPTION_FLAG_NO_ARG)
+          data = NULL;
+        else if (entry->flags & G_OPTION_FLAG_FILENAME)
+          {
+#ifdef G_OS_WIN32
+            data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
+#else
+            data = g_strdup (value);
+#endif
+          }
+        else
+          data = g_locale_to_utf8 (value, -1, NULL, NULL, error);
+
+        if (!(entry->flags & (G_OPTION_FLAG_NO_ARG|G_OPTION_FLAG_OPTIONAL_ARG)) &&
+            !data)
+          return FALSE;
+
+        retval = (* (GOptionArgFunc) entry->arg_data) (option_name, data, group->user_data, error);
+
+        if (!retval && error != NULL && *error == NULL)
+          g_set_error (error,
+                       G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
+                       _("Error parsing option %s"), option_name);
+
+        g_free (data);
+
+        return retval;
+
+        break;
+      }
+    case G_OPTION_ARG_DOUBLE:
+      {
+        gdouble data;
+
+        if (!parse_double (option_name, value,
+                        &data,
+                        error))
+          {
+            return FALSE;
+          }
+
+        change = get_change (context, G_OPTION_ARG_DOUBLE,
+                             entry->arg_data);
+        change->prev.dbl = *(gdouble *)entry->arg_data;
+        *(gdouble *)entry->arg_data = data;
+        break;
+      }
+    case G_OPTION_ARG_INT64:
+      {
+        gint64 data;
+
+        if (!parse_int64 (option_name, value,
+                         &data,
+                         error))
+          {
+            return FALSE;
+          }
+
+        change = get_change (context, G_OPTION_ARG_INT64,
+                             entry->arg_data);
+        change->prev.int64 = *(gint64 *)entry->arg_data;
+        *(gint64 *)entry->arg_data = data;
+        break;
+      }
+    default:
+      g_assert_not_reached ();
+    }
+
+  return TRUE;
+}
+
+static gboolean
+parse_short_option (GOptionContext *context,
+                    GOptionGroup   *group,
+                    gint            idx,
+                    gint           *new_idx,
+                    gchar           arg,
+                    gint           *argc,
+                    gchar        ***argv,
+                    GError        **error,
+                    gboolean       *parsed)
+{
+  gint j;
+
+  for (j = 0; j < group->n_entries; j++)
+    {
+      if (arg == group->entries[j].short_name)
+        {
+          gchar *option_name;
+          gchar *value = NULL;
+
+          option_name = g_strdup_printf ("-%c", group->entries[j].short_name);
+
+          if (NO_ARG (&group->entries[j]))
+            value = NULL;
+          else
+            {
+              if (*new_idx > idx)
+                {
+                  g_set_error (error,
+                               G_OPTION_ERROR, G_OPTION_ERROR_FAILED,
+                               _("Error parsing option %s"), option_name);
+                  g_free (option_name);
+                  return FALSE;
+                }
+
+              if (idx < *argc - 1)
+                {
+                  if (!OPTIONAL_ARG (&group->entries[j]))
+                    {
+                      value = (*argv)[idx + 1];
+                      add_pending_null (context, &((*argv)[idx + 1]), NULL);
+                      *new_idx = idx + 1;
+                    }
+                  else
+                    {
+                      if ((*argv)[idx + 1][0] == '-')
+                        value = NULL;
+                      else
+                        {
+                          value = (*argv)[idx + 1];
+                          add_pending_null (context, &((*argv)[idx + 1]), NULL);
+                          *new_idx = idx + 1;
+                        }
+                    }
+                }
+              else if (idx >= *argc - 1 && OPTIONAL_ARG (&group->entries[j]))
+                value = NULL;
+              else
+                {
+                  g_set_error (error,
+                               G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                               _("Missing argument for %s"), option_name);
+                  g_free (option_name);
+                  return FALSE;
+                }
+            }
+
+          if (!parse_arg (context, group, &group->entries[j],
+                          value, option_name, error))
+            {
+              g_free (option_name);
+              return FALSE;
+            }
+
+          g_free (option_name);
+          *parsed = TRUE;
+        }
+    }
+
+  return TRUE;
+}
+
+static gboolean
+parse_long_option (GOptionContext *context,
+                   GOptionGroup   *group,
+                   gint           *idx,
+                   gchar          *arg,
+                   gboolean        aliased,
+                   gint           *argc,
+                   gchar        ***argv,
+                   GError        **error,
+                   gboolean       *parsed)
+{
+  gint j;
+
+  for (j = 0; j < group->n_entries; j++)
+    {
+      if (*idx >= *argc)
+        return TRUE;
+
+      if (aliased && (group->entries[j].flags & G_OPTION_FLAG_NOALIAS))
+        continue;
+
+      if (NO_ARG (&group->entries[j]) &&
+          strcmp (arg, group->entries[j].long_name) == 0)
+        {
+          gchar *option_name;
+          gboolean retval;
+
+          option_name = g_strconcat ("--", group->entries[j].long_name, NULL);
+          retval = parse_arg (context, group, &group->entries[j],
+                              NULL, option_name, error);
+          g_free (option_name);
+
+          add_pending_null (context, &((*argv)[*idx]), NULL);
+          *parsed = TRUE;
+
+          return retval;
+        }
+      else
+        {
+          gint len = strlen (group->entries[j].long_name);
+
+          if (strncmp (arg, group->entries[j].long_name, len) == 0 &&
+              (arg[len] == '=' || arg[len] == 0))
+            {
+              gchar *value = NULL;
+              gchar *option_name;
+
+              add_pending_null (context, &((*argv)[*idx]), NULL);
+              option_name = g_strconcat ("--", group->entries[j].long_name, NULL);
+
+              if (arg[len] == '=')
+                value = arg + len + 1;
+              else if (*idx < *argc - 1)
+                {
+                  if (!(group->entries[j].flags & G_OPTION_FLAG_OPTIONAL_ARG))
+                    {
+                      value = (*argv)[*idx + 1];
+                      add_pending_null (context, &((*argv)[*idx + 1]), NULL);
+                      (*idx)++;
+                    }
+                  else
+                    {
+                      if ((*argv)[*idx + 1][0] == '-')
+                        {
+                          gboolean retval;
+                          retval = parse_arg (context, group, &group->entries[j],
+                                              NULL, option_name, error);
+                          *parsed = TRUE;
+                          g_free (option_name);
+                          return retval;
+                        }
+                      else
+                        {
+                          value = (*argv)[*idx + 1];
+                          add_pending_null (context, &((*argv)[*idx + 1]), NULL);
+                          (*idx)++;
+                        }
+                    }
+                }
+              else if (*idx >= *argc - 1 &&
+                       group->entries[j].flags & G_OPTION_FLAG_OPTIONAL_ARG)
+                {
+                    gboolean retval;
+                    retval = parse_arg (context, group, &group->entries[j],
+                                        NULL, option_name, error);
+                    *parsed = TRUE;
+                    g_free (option_name);
+                    return retval;
+                }
+              else
+                {
+                  g_set_error (error,
+                               G_OPTION_ERROR, G_OPTION_ERROR_BAD_VALUE,
+                               _("Missing argument for %s"), option_name);
+                  g_free (option_name);
+                  return FALSE;
+                }
+
+              if (!parse_arg (context, group, &group->entries[j],
+                              value, option_name, error))
+                {
+                  g_free (option_name);
+                  return FALSE;
+                }
+
+              g_free (option_name);
+              *parsed = TRUE;
+            }
+        }
+    }
+
+  return TRUE;
+}
+
+static gboolean
+parse_remaining_arg (GOptionContext *context,
+                     GOptionGroup   *group,
+                     gint           *idx,
+                     gint           *argc,
+                     gchar        ***argv,
+                     GError        **error,
+                     gboolean       *parsed)
+{
+  gint j;
+
+  for (j = 0; j < group->n_entries; j++)
+    {
+      if (*idx >= *argc)
+        return TRUE;
+
+      if (group->entries[j].long_name[0])
+        continue;
+
+      g_return_val_if_fail (group->entries[j].arg == G_OPTION_ARG_CALLBACK ||
+                            group->entries[j].arg == G_OPTION_ARG_STRING_ARRAY ||
+                            group->entries[j].arg == G_OPTION_ARG_FILENAME_ARRAY, FALSE);
+
+      add_pending_null (context, &((*argv)[*idx]), NULL);
+
+      if (!parse_arg (context, group, &group->entries[j], (*argv)[*idx], "", error))
+        return FALSE;
+
+      *parsed = TRUE;
+      return TRUE;
+    }
+
+  return TRUE;
+}
+
+static void
+free_changes_list (GOptionContext *context,
+                   gboolean        revert)
+{
+  GList *list;
+
+  for (list = context->changes; list != NULL; list = list->next)
+    {
+      Change *change = list->data;
+
+      if (revert)
+        {
+          switch (change->arg_type)
+            {
+            case G_OPTION_ARG_NONE:
+              *(gboolean *)change->arg_data = change->prev.bool;
+              break;
+            case G_OPTION_ARG_INT:
+              *(gint *)change->arg_data = change->prev.integer;
+              break;
+            case G_OPTION_ARG_STRING:
+            case G_OPTION_ARG_FILENAME:
+              g_free (change->allocated.str);
+              *(gchar **)change->arg_data = change->prev.str;
+              break;
+            case G_OPTION_ARG_STRING_ARRAY:
+            case G_OPTION_ARG_FILENAME_ARRAY:
+              g_strfreev (change->allocated.array.data);
+              *(gchar ***)change->arg_data = change->prev.array;
+              break;
+            case G_OPTION_ARG_DOUBLE:
+              *(gdouble *)change->arg_data = change->prev.dbl;
+              break;
+            case G_OPTION_ARG_INT64:
+              *(gint64 *)change->arg_data = change->prev.int64;
+              break;
+            default:
+              g_assert_not_reached ();
+            }
+        }
+
+      g_free (change);
+    }
+
+  g_list_free (context->changes);
+  context->changes = NULL;
+}
+
+static void
+free_pending_nulls (GOptionContext *context,
+                    gboolean        perform_nulls)
+{
+  GList *list;
+
+  for (list = context->pending_nulls; list != NULL; list = list->next)
+    {
+      PendingNull *n = list->data;
+
+      if (perform_nulls)
+        {
+          if (n->value)
+            {
+              /* Copy back the short options */
+              *(n->ptr)[0] = '-';
+              strcpy (*n->ptr + 1, n->value);
+            }
+          else
+            *n->ptr = NULL;
+        }
+
+      g_free (n->value);
+      g_free (n);
+    }
+
+  g_list_free (context->pending_nulls);
+  context->pending_nulls = NULL;
+}
+
+/**
+ * g_option_context_parse:
+ * @context: a #GOptionContext
+ * @argc: a pointer to the number of command line arguments
+ * @argv: a pointer to the array of command line arguments
+ * @error: a return location for errors
+ *
+ * Parses the command line arguments, recognizing options
+ * which have been added to @context. A side-effect of
+ * calling this function is that g_set_prgname() will be
+ * called.
+ *
+ * If the parsing is successful, any parsed arguments are
+ * removed from the array and @argc and @argv are updated
+ * accordingly. A '--' option is stripped from @argv
+ * unless there are unparsed options before and after it,
+ * or some of the options after it start with '-'. In case
+ * of an error, @argc and @argv are left unmodified.
+ *
+ * If automatic <option>--help</option> support is enabled
+ * (see g_option_context_set_help_enabled()), and the
+ * @argv array contains one of the recognized help options,
+ * this function will produce help output to stdout and
+ * call <literal>exit (0)</literal>.
+ *
+ * Note that function depends on the
+ * <link linkend="setlocale">current locale</link> for
+ * automatic character set conversion of string and filename
+ * arguments.
+ *
+ * Return value: %TRUE if the parsing was successful,
+ *               %FALSE if an error occurred
+ *
+ * Since: 2.6
+ **/
+gboolean
+g_option_context_parse (GOptionContext   *context,
+                        gint             *argc,
+                        gchar          ***argv,
+                        GError          **error)
+{
+  gint i, j, k;
+  GList *list;
+
+  /* Set program name */
+  if (!g_get_prgname())
+    {
+      if (argc && argv && *argc)
+        {
+          gchar *prgname;
+
+          prgname = g_path_get_basename ((*argv)[0]);
+          g_set_prgname (prgname);
+          g_free (prgname);
+        }
+      else
+        g_set_prgname ("<unknown>");
+    }
+
+  /* Call pre-parse hooks */
+  list = context->groups;
+  while (list)
+    {
+      GOptionGroup *group = list->data;
+
+      if (group->pre_parse_func)
+        {
+          if (!(* group->pre_parse_func) (context, group,
+                                          group->user_data, error))
+            goto fail;
+        }
+
+      list = list->next;
+    }
+
+  if (context->main_group && context->main_group->pre_parse_func)
+    {
+      if (!(* context->main_group->pre_parse_func) (context, context->main_group,
+                                                    context->main_group->user_data, error))
+        goto fail;
+    }
+
+  if (argc && argv)
+    {
+      gboolean stop_parsing = FALSE;
+      gboolean has_unknown = FALSE;
+      gint separator_pos = 0;
+
+      for (i = 1; i < *argc; i++)
+        {
+          gchar *arg, *dash;
+          gboolean parsed = FALSE;
+
+          if ((*argv)[i][0] == '-' && (*argv)[i][1] != '\0' && !stop_parsing)
+            {
+              if ((*argv)[i][1] == '-')
+                {
+                  /* -- option */
+
+                  arg = (*argv)[i] + 2;
+
+                  /* '--' terminates list of arguments */
+                  if (*arg == 0)
+                    {
+                      separator_pos = i;
+                      stop_parsing = TRUE;
+                      continue;
+                    }
+
+                  /* Handle help options */
+                  if (context->help_enabled)
+                    {
+                      if (strcmp (arg, "help") == 0)
+                        print_help (context, TRUE, NULL);
+                      else if (strcmp (arg, "help-all") == 0)
+                        print_help (context, FALSE, NULL);
+                      else if (strncmp (arg, "help-", 5) == 0)
+                        {
+                          list = context->groups;
+
+                          while (list)
+                            {
+                              GOptionGroup *group = list->data;
+
+                              if (strcmp (arg + 5, group->name) == 0)
+                                print_help (context, FALSE, group);
+
+                              list = list->next;
+                            }
+                        }
+                    }
+
+                  if (context->main_group &&
+                      !parse_long_option (context, context->main_group, &i, arg,
+                                          FALSE, argc, argv, error, &parsed))
+                    goto fail;
+
+                  if (parsed)
+                    continue;
+
+                  /* Try the groups */
+                  list = context->groups;
+                  while (list)
+                    {
+                      GOptionGroup *group = list->data;
+
+                      if (!parse_long_option (context, group, &i, arg,
+                                              FALSE, argc, argv, error, &parsed))
+                        goto fail;
+
+                      if (parsed)
+                        break;
+
+                      list = list->next;
+                    }
+
+                  if (parsed)
+                    continue;
+
+                  /* Now look for --<group>-<option> */
+                  dash = strchr (arg, '-');
+                  if (dash)
+                    {
+                      /* Try the groups */
+                      list = context->groups;
+                      while (list)
+                        {
+                          GOptionGroup *group = list->data;
+
+                          if (strncmp (group->name, arg, dash - arg) == 0)
+                            {
+                              if (!parse_long_option (context, group, &i, dash + 1,
+                                                      TRUE, argc, argv, error, &parsed))
+                                goto fail;
+
+                              if (parsed)
+                                break;
+                            }
+
+                          list = list->next;
+                        }
+                    }
+
+                  if (context->ignore_unknown)
+                    continue;
+                }
+              else
+                { /* short option */
+                  gint new_i = i, arg_length;
+                  gboolean *nulled_out = NULL;
+                  gboolean has_h_entry = context_has_h_entry (context);
+                  arg = (*argv)[i] + 1;
+                  arg_length = strlen (arg);
+                  nulled_out = g_newa (gboolean, arg_length);
+                  memset (nulled_out, 0, arg_length * sizeof (gboolean));
+                  for (j = 0; j < arg_length; j++)
+                    {
+                      if (context->help_enabled && (arg[j] == '?' ||
+                        (arg[j] == 'h' && !has_h_entry)))
+                        print_help (context, TRUE, NULL);
+                      parsed = FALSE;
+                      if (context->main_group &&
+                          !parse_short_option (context, context->main_group,
+                                               i, &new_i, arg[j],
+                                               argc, argv, error, &parsed))
+                        goto fail;
+                      if (!parsed)
+                        {
+                          /* Try the groups */
+                          list = context->groups;
+                          while (list)
+                            {
+                              GOptionGroup *group = list->data;
+                              if (!parse_short_option (context, group, i, &new_i, arg[j],
+                                                       argc, argv, error, &parsed))
+                                goto fail;
+                              if (parsed)
+                                break;
+                              list = list->next;
+                            }
+                        }
+
+                      if (context->ignore_unknown && parsed)
+                        nulled_out[j] = TRUE;
+                      else if (context->ignore_unknown)
+                        continue;
+                      else if (!parsed)
+                        break;
+                      /* !context->ignore_unknown && parsed */
+                    }
+                  if (context->ignore_unknown)
+                    {
+                      gchar *new_arg = NULL;
+                      gint arg_index = 0;
+                      for (j = 0; j < arg_length; j++)
+                        {
+                          if (!nulled_out[j])
+                            {
+                              if (!new_arg)
+                                new_arg = g_malloc (arg_length + 1);
+                              new_arg[arg_index++] = arg[j];
+                            }
+                        }
+                      if (new_arg)
+                        new_arg[arg_index] = '\0';
+                      add_pending_null (context, &((*argv)[i]), new_arg);
+                    }
+                  else if (parsed)
+                    {
+                      add_pending_null (context, &((*argv)[i]), NULL);
+                      i = new_i;
+                    }
+                }
+
+              if (!parsed)
+                has_unknown = TRUE;
+
+              if (!parsed && !context->ignore_unknown)
+                {
+                  g_set_error (error,
+                               G_OPTION_ERROR, G_OPTION_ERROR_UNKNOWN_OPTION,
+                                   _("Unknown option %s"), (*argv)[i]);
+                  goto fail;
+                }
+            }
+          else
+            {
+              /* Collect remaining args */
+              if (context->main_group &&
+                  !parse_remaining_arg (context, context->main_group, &i,
+                                        argc, argv, error, &parsed))
+                goto fail;
+
+              if (!parsed && (has_unknown || (*argv)[i][0] == '-'))
+                separator_pos = 0;
+            }
+        }
+
+      if (separator_pos > 0)
+        add_pending_null (context, &((*argv)[separator_pos]), NULL);
+
+    }
+
+  /* Call post-parse hooks */
+  list = context->groups;
+  while (list)
+    {
+      GOptionGroup *group = list->data;
+
+      if (group->post_parse_func)
+        {
+          if (!(* group->post_parse_func) (context, group,
+                                           group->user_data, error))
+            goto fail;
+        }
+
+      list = list->next;
+    }
+
+  if (context->main_group && context->main_group->post_parse_func)
+    {
+      if (!(* context->main_group->post_parse_func) (context, context->main_group,
+                                                     context->main_group->user_data, error))
+        goto fail;
+    }
+
+  if (argc && argv)
+    {
+      free_pending_nulls (context, TRUE);
+
+      for (i = 1; i < *argc; i++)
+        {
+          for (k = i; k < *argc; k++)
+            if ((*argv)[k] != NULL)
+              break;
+
+          if (k > i)
+            {
+              k -= i;
+              for (j = i + k; j < *argc; j++)
+                {
+                  (*argv)[j-k] = (*argv)[j];
+                  (*argv)[j] = NULL;
+                }
+              *argc -= k;
+            }
+        }
+    }
+
+  return TRUE;
+
+ fail:
+
+  /* Call error hooks */
+  list = context->groups;
+  while (list)
+    {
+      GOptionGroup *group = list->data;
+
+      if (group->error_func)
+        (* group->error_func) (context, group,
+                               group->user_data, error);
+
+      list = list->next;
+    }
+
+  if (context->main_group && context->main_group->error_func)
+    (* context->main_group->error_func) (context, context->main_group,
+                                         context->main_group->user_data, error);
+
+  free_changes_list (context, TRUE);
+  free_pending_nulls (context, FALSE);
+
+  return FALSE;
+}
+
+/**
+ * g_option_group_new:
+ * @name: the name for the option group, this is used to provide
+ *   help for the options in this group with <option>--help-</option>@name
+ * @description: a description for this group to be shown in
+ *   <option>--help</option>. This string is translated using the translation
+ *   domain or translation function of the group
+ * @help_description: a description for the <option>--help-</option>@name option.
+ *   This string is translated using the translation domain or translation function
+ *   of the group
+ * @user_data: user data that will be passed to the pre- and post-parse hooks,
+ *   the error hook and to callbacks of %G_OPTION_ARG_CALLBACK options, or %NULL
+ * @destroy: a function that will be called to free @user_data, or %NULL
+ *
+ * Creates a new #GOptionGroup.
+ *
+ * Return value: a newly created option group. It should be added
+ *   to a #GOptionContext or freed with g_option_group_free().
+ *
+ * Since: 2.6
+ **/
+GOptionGroup *
+g_option_group_new (const gchar    *name,
+                    const gchar    *description,
+                    const gchar    *help_description,
+                    gpointer        user_data,
+                    GDestroyNotify  destroy)
+
+{
+  GOptionGroup *group;
+
+  group = g_new0 (GOptionGroup, 1);
+  group->name = g_strdup (name);
+  group->description = g_strdup (description);
+  group->help_description = g_strdup (help_description);
+  group->user_data = user_data;
+  group->destroy_notify = destroy;
+
+  return group;
+}
+
+
+/**
+ * g_option_group_free:
+ * @group: a #GOptionGroup
+ *
+ * Frees a #GOptionGroup. Note that you must <emphasis>not</emphasis>
+ * free groups which have been added to a #GOptionContext.
+ *
+ * Since: 2.6
+ **/
+void
+g_option_group_free (GOptionGroup *group)
+{
+  g_return_if_fail (group != NULL);
+
+  g_free (group->name);
+  g_free (group->description);
+  g_free (group->help_description);
+
+  g_free (group->entries);
+
+  if (group->destroy_notify)
+    (* group->destroy_notify) (group->user_data);
+
+  if (group->translate_notify)
+    (* group->translate_notify) (group->translate_data);
+
+  g_free (group);
+}
+
+
+/**
+ * g_option_group_add_entries:
+ * @group: a #GOptionGroup
+ * @entries: a %NULL-terminated array of #GOptionEntry<!-- -->s
+ *
+ * Adds the options specified in @entries to @group.
+ *
+ * Since: 2.6
+ **/
+void
+g_option_group_add_entries (GOptionGroup       *group,
+                            const GOptionEntry *entries)
+{
+  gint i, n_entries;
+
+  g_return_if_fail (entries != NULL);
+
+  for (n_entries = 0; entries[n_entries].long_name != NULL; n_entries++) ;
+
+  group->entries = g_renew (GOptionEntry, group->entries, group->n_entries + n_entries);
+
+  memcpy (group->entries + group->n_entries, entries, sizeof (GOptionEntry) * n_entries);
+
+  for (i = group->n_entries; i < group->n_entries + n_entries; i++)
+    {
+      gchar c = group->entries[i].short_name;
+
+      if (c)
+        {
+          if (c == '-' || !g_ascii_isprint (c))
+            {
+              g_warning (G_STRLOC": ignoring invalid short option '%c' (%d)", c, c);
+              group->entries[i].short_name = 0;
+            }
+        }
+    }
+
+  group->n_entries += n_entries;
+}
+
+/**
+ * g_option_group_set_parse_hooks:
+ * @group: a #GOptionGroup
+ * @pre_parse_func: a function to call before parsing, or %NULL
+ * @post_parse_func: a function to call after parsing, or %NULL
+ *
+ * Associates two functions with @group which will be called
+ * from g_option_context_parse() before the first option is parsed
+ * and after the last option has been parsed, respectively.
+ *
+ * Note that the user data to be passed to @pre_parse_func and
+ * @post_parse_func can be specified when constructing the group
+ * with g_option_group_new().
+ *
+ * Since: 2.6
+ **/
+void
+g_option_group_set_parse_hooks (GOptionGroup     *group,
+                                GOptionParseFunc  pre_parse_func,
+                                GOptionParseFunc  post_parse_func)
+{
+  g_return_if_fail (group != NULL);
+
+  group->pre_parse_func = pre_parse_func;
+  group->post_parse_func = post_parse_func;
+}
+
+/**
+ * g_option_group_set_error_hook:
+ * @group: a #GOptionGroup
+ * @error_func: a function to call when an error occurs
+ *
+ * Associates a function with @group which will be called
+ * from g_option_context_parse() when an error occurs.
+ *
+ * Note that the user data to be passed to @error_func can be
+ * specified when constructing the group with g_option_group_new().
+ *
+ * Since: 2.6
+ **/
+void
+g_option_group_set_error_hook (GOptionGroup     *group,
+                               GOptionErrorFunc  error_func)
+{
+  g_return_if_fail (group != NULL);
+
+  group->error_func = error_func;
+}
+
+
+/**
+ * g_option_group_set_translate_func:
+ * @group: a #GOptionGroup
+ * @func: the #GTranslateFunc, or %NULL
+ * @data: user data to pass to @func, or %NULL
+ * @destroy_notify: a function which gets called to free @data, or %NULL
+ *
+ * Sets the function which is used to translate user-visible
+ * strings, for <option>--help</option> output. Different
+ * groups can use different #GTranslateFunc<!-- -->s. If @func
+ * is %NULL, strings are not translated.
+ *
+ * If you are using gettext(), you only need to set the translation
+ * domain, see g_option_group_set_translation_domain().
+ *
+ * Since: 2.6
+ **/
+void
+g_option_group_set_translate_func (GOptionGroup   *group,
+                                   GTranslateFunc  func,
+                                   gpointer        data,
+                                   GDestroyNotify  destroy_notify)
+{
+  g_return_if_fail (group != NULL);
+
+  if (group->translate_notify)
+    group->translate_notify (group->translate_data);
+
+  group->translate_func = func;
+  group->translate_data = data;
+  group->translate_notify = destroy_notify;
+}
+
+static const gchar *
+dgettext_swapped (const gchar *msgid,
+                  const gchar *domainname)
+{
+  return g_dgettext (domainname, msgid);
+}
+
+/**
+ * g_option_group_set_translation_domain:
+ * @group: a #GOptionGroup
+ * @domain: the domain to use
+ *
+ * A convenience function to use gettext() for translating
+ * user-visible strings.
+ *
+ * Since: 2.6
+ **/
+void
+g_option_group_set_translation_domain (GOptionGroup *group,
+                                       const gchar  *domain)
+{
+  g_return_if_fail (group != NULL);
+
+  g_option_group_set_translate_func (group,
+                                     (GTranslateFunc)dgettext_swapped,
+                                     g_strdup (domain),
+                                     g_free);
+}
+
+/**
+ * g_option_context_set_translate_func:
+ * @context: a #GOptionContext
+ * @func: the #GTranslateFunc, or %NULL
+ * @data: user data to pass to @func, or %NULL
+ * @destroy_notify: a function which gets called to free @data, or %NULL
+ *
+ * Sets the function which is used to translate the contexts
+ * user-visible strings, for <option>--help</option> output.
+ * If @func is %NULL, strings are not translated.
+ *
+ * Note that option groups have their own translation functions,
+ * this function only affects the @parameter_string (see g_option_context_new()),
+ * the summary (see g_option_context_set_summary()) and the description
+ * (see g_option_context_set_description()).
+ *
+ * If you are using gettext(), you only need to set the translation
+ * domain, see g_option_context_set_translation_domain().
+ *
+ * Since: 2.12
+ **/
+void
+g_option_context_set_translate_func (GOptionContext *context,
+                                     GTranslateFunc func,
+                                     gpointer       data,
+                                     GDestroyNotify destroy_notify)
+{
+  g_return_if_fail (context != NULL);
+
+  if (context->translate_notify)
+    context->translate_notify (context->translate_data);
+
+  context->translate_func = func;
+  context->translate_data = data;
+  context->translate_notify = destroy_notify;
+}
+
+/**
+ * g_option_context_set_translation_domain:
+ * @context: a #GOptionContext
+ * @domain: the domain to use
+ *
+ * A convenience function to use gettext() for translating
+ * user-visible strings.
+ *
+ * Since: 2.12
+ **/
+void
+g_option_context_set_translation_domain (GOptionContext *context,
+                                         const gchar     *domain)
+{
+  g_return_if_fail (context != NULL);
+
+  g_option_context_set_translate_func (context,
+                                       (GTranslateFunc)dgettext_swapped,
+                                       g_strdup (domain),
+                                       g_free);
+}
+
+/**
+ * g_option_context_set_summary:
+ * @context: a #GOptionContext
+ * @summary: a string to be shown in <option>--help</option> output
+ *  before the list of options, or %NULL
+ *
+ * Adds a string to be displayed in <option>--help</option> output
+ * before the list of options. This is typically a summary of the
+ * program functionality.
+ *
+ * Note that the summary is translated (see
+ * g_option_context_set_translate_func() and
+ * g_option_context_set_translation_domain()).
+ *
+ * Since: 2.12
+ */
+void
+g_option_context_set_summary (GOptionContext *context,
+                              const gchar    *summary)
+{
+  g_return_if_fail (context != NULL);
+
+  g_free (context->summary);
+  context->summary = g_strdup (summary);
+}
+
+
+/**
+ * g_option_context_get_summary:
+ * @context: a #GOptionContext
+ *
+ * Returns the summary. See g_option_context_set_summary().
+ *
+ * Returns: the summary
+ *
+ * Since: 2.12
+ */
+G_CONST_RETURN gchar *
+g_option_context_get_summary (GOptionContext *context)
+{
+  g_return_val_if_fail (context != NULL, NULL);
+
+  return context->summary;
+}
+
+/**
+ * g_option_context_set_description:
+ * @context: a #GOptionContext
+ * @description: a string to be shown in <option>--help</option> output
+ *   after the list of options, or %NULL
+ *
+ * Adds a string to be displayed in <option>--help</option> output
+ * after the list of options. This text often includes a bug reporting
+ * address.
+ *
+ * Note that the summary is translated (see
+ * g_option_context_set_translate_func()).
+ *
+ * Since: 2.12
+ */
+void
+g_option_context_set_description (GOptionContext *context,
+                                  const gchar    *description)
+{
+  g_return_if_fail (context != NULL);
+
+  g_free (context->description);
+  context->description = g_strdup (description);
+}
+
+
+/**
+ * g_option_context_get_description:
+ * @context: a #GOptionContext
+ *
+ * Returns the description. See g_option_context_set_description().
+ *
+ * Returns: the description
+ *
+ * Since: 2.12
+ */
+G_CONST_RETURN gchar *
+g_option_context_get_description (GOptionContext *context)
+{
+  g_return_val_if_fail (context != NULL, NULL);
+
+  return context->description;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/goption.h b/resource/csdk/connectivity/lib/android/glib-master/glib/goption.h
new file mode 100644 (file)
index 0000000..557d8f7
--- /dev/null
@@ -0,0 +1,370 @@
+/* goption.h - Option parser
+ *
+ *  Copyright (C) 2004  Anders Carlsson <andersca@gnome.org>
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_OPTION_H__
+#define __G_OPTION_H__
+
+#include <glib/gerror.h>
+#include <glib/gquark.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GOptionContext:
+ * 
+ * A <structname>GOptionContext</structname> struct defines which options
+ * are accepted by the commandline option parser. The struct has only private 
+ * fields and should not be directly accessed.
+ */
+typedef struct _GOptionContext GOptionContext;
+
+/**
+ * GOptionGroup:
+ *
+ * A <structname>GOptionGroup</structname> struct defines the options in a single
+ * group. The struct has only private fields and should not be directly accessed.
+ *
+ * All options in a group share the same translation function. Libraries which
+ * need to parse commandline options are expected to provide a function for
+ * getting a <structname>GOptionGroup</structname> holding their options, which
+ * the application can then add to its #GOptionContext.
+ */
+typedef struct _GOptionGroup   GOptionGroup;
+typedef struct _GOptionEntry   GOptionEntry;
+
+/**
+ * GOptionFlags:
+ * @G_OPTION_FLAG_HIDDEN: The option doesn't appear in <option>--help</option>
+ *  output.
+ * @G_OPTION_FLAG_IN_MAIN: The option appears in the main section of the
+ *  <option>--help</option> output, even if it is defined in a group.
+ * @G_OPTION_FLAG_REVERSE: For options of the %G_OPTION_ARG_NONE kind, this flag
+ *  indicates that the sense of the option is reversed.
+ * @G_OPTION_FLAG_NO_ARG: For options of the %G_OPTION_ARG_CALLBACK kind,
+ *  this flag indicates that the callback does not take any argument
+ *  (like a %G_OPTION_ARG_NONE option). Since 2.8
+ * @G_OPTION_FLAG_FILENAME: For options of the %G_OPTION_ARG_CALLBACK
+ *  kind, this flag indicates that the argument should be passed to the
+ *  callback in the GLib filename encoding rather than UTF-8. Since 2.8
+ * @G_OPTION_FLAG_OPTIONAL_ARG: For options of the %G_OPTION_ARG_CALLBACK 
+ *  kind, this flag indicates that the argument supply is optional. If no argument
+ *  is given then data of %GOptionParseFunc will be set to NULL. Since 2.8
+ * @G_OPTION_FLAG_NOALIAS: This flag turns off the automatic conflict resolution
+ *  which prefixes long option names with <literal>groupname-</literal> if 
+ *  there is a conflict. This option should only be used in situations where
+ *  aliasing is necessary to model some legacy commandline interface. It is
+ *  not safe to use this option, unless all option groups are under your 
+ *  direct control. Since 2.8.
+ * 
+ * Flags which modify individual options.
+ */
+typedef enum
+{
+  G_OPTION_FLAG_HIDDEN         = 1 << 0,
+  G_OPTION_FLAG_IN_MAIN                = 1 << 1,
+  G_OPTION_FLAG_REVERSE                = 1 << 2,
+  G_OPTION_FLAG_NO_ARG         = 1 << 3,
+  G_OPTION_FLAG_FILENAME       = 1 << 4,
+  G_OPTION_FLAG_OPTIONAL_ARG    = 1 << 5,
+  G_OPTION_FLAG_NOALIAS                = 1 << 6
+} GOptionFlags;
+
+/**
+ * GOptionArg:
+ * @G_OPTION_ARG_NONE: No extra argument. This is useful for simple flags.
+ * @G_OPTION_ARG_STRING: The option takes a string argument.
+ * @G_OPTION_ARG_INT: The option takes an integer argument.
+ * @G_OPTION_ARG_CALLBACK: The option provides a callback to parse the
+ *  extra argument.
+ * @G_OPTION_ARG_FILENAME: The option takes a filename as argument.
+ * @G_OPTION_ARG_STRING_ARRAY: The option takes a string argument, multiple
+ *  uses of the option are collected into an array of strings.
+ * @G_OPTION_ARG_FILENAME_ARRAY: The option takes a filename as argument, 
+ *  multiple uses of the option are collected into an array of strings.
+ * @G_OPTION_ARG_DOUBLE: The option takes a double argument. The argument
+ *  can be formatted either for the user's locale or for the "C" locale. Since 2.12
+ * @G_OPTION_ARG_INT64: The option takes a 64-bit integer. Like %G_OPTION_ARG_INT
+ *  but for larger numbers. The number can be in decimal base, or in hexadecimal
+ *  (when prefixed with <literal>0x</literal>, for example, <literal>0xffffffff</literal>).
+ *  Since 2.12
+ * 
+ * The #GOptionArg enum values determine which type of extra argument the
+ * options expect to find. If an option expects an extra argument, it
+ * can be specified in several ways; with a short option:
+ * <option>-x arg</option>, with a long option: <option>--name arg</option>
+ * or combined in a single argument: <option>--name=arg</option>.
+ */
+typedef enum
+{
+  G_OPTION_ARG_NONE,
+  G_OPTION_ARG_STRING,
+  G_OPTION_ARG_INT,
+  G_OPTION_ARG_CALLBACK,
+  G_OPTION_ARG_FILENAME,
+  G_OPTION_ARG_STRING_ARRAY,
+  G_OPTION_ARG_FILENAME_ARRAY,
+  G_OPTION_ARG_DOUBLE,
+  G_OPTION_ARG_INT64
+} GOptionArg;
+
+/**
+ * GOptionArgFunc:
+ * @option_name: The name of the option being parsed. This will be either a 
+ *  single dash followed by a single letter (for a short name) or two dashes
+ *  followed by a long option name.
+ * @value: The value to be parsed.
+ * @data: User data added to the #GOptionGroup containing the option when it
+ *  was created with g_option_group_new()
+ * @error: A return location for errors. The error code %G_OPTION_ERROR_FAILED
+ *  is intended to be used for errors in #GOptionArgFunc callbacks.
+ * 
+ * The type of function to be passed as callback for %G_OPTION_ARG_CALLBACK
+ * options.
+ * 
+ * Returns: %TRUE if the option was successfully parsed, %FALSE if an error 
+ *  occurred, in which case @error should be set with g_set_error()
+ */
+typedef gboolean (*GOptionArgFunc) (const gchar    *option_name,
+                                   const gchar    *value,
+                                   gpointer        data,
+                                   GError        **error);
+
+/**
+ * GOptionParseFunc:
+ * @context: The active #GOptionContext
+ * @group: The group to which the function belongs
+ * @data: User data added to the #GOptionGroup containing the option when it
+ *  was created with g_option_group_new()
+ * @error: A return location for error details
+ * 
+ * The type of function that can be called before and after parsing. 
+ * 
+ * Returns: %TRUE if the function completed successfully, %FALSE if an error 
+ *  occurred, in which case @error should be set with g_set_error()
+ */
+typedef gboolean (*GOptionParseFunc) (GOptionContext *context,
+                                     GOptionGroup   *group,
+                                     gpointer        data,
+                                     GError        **error);
+
+/**
+ * GOptionErrorFunc:
+ * @context: The active #GOptionContext
+ * @group: The group to which the function belongs
+ * @data: User data added to the #GOptionGroup containing the option when it
+ *  was created with g_option_group_new()
+ * @error: The #GError containing details about the parse error
+ * 
+ * The type of function to be used as callback when a parse error occurs.
+ */
+typedef void (*GOptionErrorFunc) (GOptionContext *context,
+                                 GOptionGroup   *group,
+                                 gpointer        data,
+                                 GError        **error);
+
+/**
+ * G_OPTION_ERROR:
+ * 
+ * Error domain for option parsing. Errors in this domain will
+ * be from the #GOptionError enumeration. See #GError for information on 
+ * error domains.
+ */
+#define G_OPTION_ERROR (g_option_error_quark ())
+
+/**
+ * GOptionError:
+ * @G_OPTION_ERROR_UNKNOWN_OPTION: An option was not known to the parser.
+ *  This error will only be reported, if the parser hasn't been instructed
+ *  to ignore unknown options, see g_option_context_set_ignore_unknown_options().
+ * @G_OPTION_ERROR_BAD_VALUE: A value couldn't be parsed.
+ * @G_OPTION_ERROR_FAILED: A #GOptionArgFunc callback failed.
+ * 
+ * Error codes returned by option parsing.
+ */
+typedef enum
+{
+  G_OPTION_ERROR_UNKNOWN_OPTION,
+  G_OPTION_ERROR_BAD_VALUE,
+  G_OPTION_ERROR_FAILED
+} GOptionError;
+
+GQuark g_option_error_quark (void);
+
+/**
+ * GOptionEntry:
+ * @long_name: The long name of an option can be used to specify it
+ *  in a commandline as --<replaceable>long_name</replaceable>. Every
+ *  option must have a long name. To resolve conflicts if multiple
+ *  option groups contain the same long name, it is also possible to
+ *  specify the option as 
+ *  --<replaceable>groupname</replaceable>-<replaceable>long_name</replaceable>.
+ * @short_name: If an option has a short name, it can be specified
+ *  -<replaceable>short_name</replaceable> in a commandline. @short_name must be 
+ *  a printable ASCII character different from '-', or zero if the option has no
+ *  short name.
+ * @flags: Flags from #GOptionFlags.
+ * @arg: The type of the option, as a #GOptionArg.
+ * @arg_data: If the @arg type is %G_OPTION_ARG_CALLBACK, then @arg_data must 
+ *  point to a #GOptionArgFunc callback function, which will be called to handle 
+ *  the extra argument. Otherwise, @arg_data is a pointer to a location to store 
+ *  the value, the required type of the location depends on the @arg type:
+ *  <variablelist>
+ *  <varlistentry>
+ *  <term>%G_OPTION_ARG_NONE</term>
+ *  <listitem><para>%gboolean</para></listitem>
+ *  </varlistentry>
+ *  <varlistentry>
+ *  <term>%G_OPTION_ARG_STRING</term>
+ *  <listitem><para>%gchar*</para></listitem>
+ *  </varlistentry>
+ *  <varlistentry>
+ *  <term>%G_OPTION_ARG_INT</term>
+ *  <listitem><para>%gint</para></listitem>
+ *  </varlistentry>
+ *  <varlistentry>
+ *  <term>%G_OPTION_ARG_FILENAME</term>
+ *  <listitem><para>%gchar*</para></listitem>
+ *  </varlistentry>
+ *  <varlistentry>
+ *  <term>%G_OPTION_ARG_STRING_ARRAY</term>
+ *  <listitem><para>%gchar**</para></listitem>
+ *  </varlistentry>
+ *  <varlistentry>
+ *  <term>%G_OPTION_ARG_FILENAME_ARRAY</term>
+ *  <listitem><para>%gchar**</para></listitem>
+ *  </varlistentry>
+ *  <varlistentry>
+ *  <term>%G_OPTION_ARG_DOUBLE</term>
+ *  <listitem><para>%gdouble</para></listitem>
+ *  </varlistentry>
+ *  </variablelist>
+ *  If @arg type is %G_OPTION_ARG_STRING or %G_OPTION_ARG_FILENAME the location
+ *  will contain a newly allocated string if the option was given. That string
+ *  needs to be freed by the callee using g_free(). Likewise if @arg type is
+ *  %G_OPTION_ARG_STRING_ARRAY or %G_OPTION_ARG_FILENAME_ARRAY, the data should
+ *  be freed using g_strfreev().
+ * @description: the description for the option in <option>--help</option>
+ *  output. The @description is translated using the @translate_func of the
+ *  group, see g_option_group_set_translation_domain().
+ * @arg_description: The placeholder to use for the extra argument parsed
+ *  by the option in <option>--help</option>
+ *  output. The @arg_description is translated using the @translate_func of the
+ *  group, see g_option_group_set_translation_domain().
+ * 
+ * A <structname>GOptionEntry</structname> defines a single option.
+ * To have an effect, they must be added to a #GOptionGroup with
+ * g_option_context_add_main_entries() or g_option_group_add_entries().
+ */
+struct _GOptionEntry
+{
+  const gchar *long_name;
+  gchar        short_name;
+  gint         flags;
+
+  GOptionArg   arg;
+  gpointer     arg_data;
+  
+  const gchar *description;
+  const gchar *arg_description;
+};
+
+/**
+ * G_OPTION_REMAINING:
+ * 
+ * If a long option in the main group has this name, it is not treated as a 
+ * regular option. Instead it collects all non-option arguments which would
+ * otherwise be left in <literal>argv</literal>. The option must be of type
+ * %G_OPTION_ARG_CALLBACK, %G_OPTION_ARG_STRING_ARRAY
+ * or %G_OPTION_ARG_FILENAME_ARRAY.
+ * 
+ * 
+ * Using #G_OPTION_REMAINING instead of simply scanning <literal>argv</literal>
+ * for leftover arguments has the advantage that GOption takes care of 
+ * necessary encoding conversions for strings or filenames.
+ * 
+ * Since: 2.6
+ */
+#define G_OPTION_REMAINING ""
+
+GOptionContext *g_option_context_new              (const gchar         *parameter_string);
+void            g_option_context_set_summary      (GOptionContext      *context,
+                                                   const gchar         *summary);
+G_CONST_RETURN gchar *g_option_context_get_summary (GOptionContext     *context);
+void            g_option_context_set_description  (GOptionContext      *context,
+                                                   const gchar         *description);
+G_CONST_RETURN gchar *g_option_context_get_description (GOptionContext     *context);
+void            g_option_context_free             (GOptionContext      *context);
+void           g_option_context_set_help_enabled (GOptionContext      *context,
+                                                  gboolean             help_enabled);
+gboolean       g_option_context_get_help_enabled (GOptionContext      *context);
+void           g_option_context_set_ignore_unknown_options (GOptionContext *context,
+                                                            gboolean        ignore_unknown);
+gboolean        g_option_context_get_ignore_unknown_options (GOptionContext *context);
+
+void            g_option_context_add_main_entries (GOptionContext      *context,
+                                                  const GOptionEntry  *entries,
+                                                  const gchar         *translation_domain);
+gboolean        g_option_context_parse            (GOptionContext      *context,
+                                                  gint                *argc,
+                                                  gchar             ***argv,
+                                                  GError             **error);
+void            g_option_context_set_translate_func (GOptionContext     *context,
+                                                    GTranslateFunc      func,
+                                                    gpointer            data,
+                                                    GDestroyNotify      destroy_notify);
+void            g_option_context_set_translation_domain (GOptionContext  *context,
+                                                        const gchar     *domain);
+
+void            g_option_context_add_group      (GOptionContext *context,
+                                                GOptionGroup   *group);
+void          g_option_context_set_main_group (GOptionContext *context,
+                                              GOptionGroup   *group);
+GOptionGroup *g_option_context_get_main_group (GOptionContext *context);
+gchar        *g_option_context_get_help       (GOptionContext *context,
+                                               gboolean        main_help,
+                                               GOptionGroup   *group);
+
+GOptionGroup *g_option_group_new                    (const gchar        *name,
+                                                    const gchar        *description,
+                                                    const gchar        *help_description,
+                                                    gpointer            user_data,
+                                                    GDestroyNotify      destroy);
+void         g_option_group_set_parse_hooks        (GOptionGroup       *group,
+                                                    GOptionParseFunc    pre_parse_func,
+                                                    GOptionParseFunc    post_parse_func);
+void         g_option_group_set_error_hook         (GOptionGroup       *group,
+                                                    GOptionErrorFunc    error_func);
+void          g_option_group_free                   (GOptionGroup       *group);
+void          g_option_group_add_entries            (GOptionGroup       *group,
+                                                    const GOptionEntry *entries);
+void          g_option_group_set_translate_func     (GOptionGroup       *group,
+                                                    GTranslateFunc      func,
+                                                    gpointer            data,
+                                                    GDestroyNotify      destroy_notify);
+void          g_option_group_set_translation_domain (GOptionGroup       *group,
+                                                    const gchar        *domain);
+
+G_END_DECLS
+
+#endif /* __G_OPTION_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gpattern.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gpattern.c
new file mode 100644 (file)
index 0000000..1c37e98
--- /dev/null
@@ -0,0 +1,442 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997, 1999  Peter Mattis, Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gpattern.h"
+
+#include "gmacros.h"
+#include "gmessages.h"
+#include "gmem.h"
+#include "gunicode.h"
+#include "gutils.h" 
+
+/**
+ * SECTION: patterns
+ * @title: Glob-style pattern matching
+ * @short_description: matches strings against patterns containing '*'
+ *                     (wildcard) and '?' (joker)
+ *
+ * The <function>g_pattern_match*</function> functions match a string
+ * against a pattern containing '*' and '?' wildcards with similar
+ * semantics as the standard glob() function: '*' matches an arbitrary,
+ * possibly empty, string, '?' matches an arbitrary character.
+ *
+ * Note that in contrast to glob(), the '/' character
+ * <emphasis>can</emphasis> be matched by the wildcards, there are no
+ * '[...]' character ranges and '*' and '?' can
+ * <emphasis>not</emphasis> be escaped to include them literally in a
+ * pattern.
+ *
+ * When multiple strings must be matched against the same pattern, it
+ * is better to compile the pattern to a #GPatternSpec using
+ * g_pattern_spec_new() and use g_pattern_match_string() instead of
+ * g_pattern_match_simple(). This avoids the overhead of repeated
+ * pattern compilation.
+ **/
+
+/**
+ * GPatternSpec:
+ *
+ * A <structname>GPatternSpec</structname> is the 'compiled' form of a
+ * pattern. This structure is opaque and its fields cannot be accessed
+ * directly.
+ **/
+
+/* keep enum and structure of gpattern.c and patterntest.c in sync */
+typedef enum
+{
+  G_MATCH_ALL,       /* "*A?A*" */
+  G_MATCH_ALL_TAIL,  /* "*A?AA" */
+  G_MATCH_HEAD,      /* "AAAA*" */
+  G_MATCH_TAIL,      /* "*AAAA" */
+  G_MATCH_EXACT,     /* "AAAAA" */
+  G_MATCH_LAST
+} GMatchType;
+
+struct _GPatternSpec
+{
+  GMatchType match_type;
+  guint      pattern_length;
+  guint      min_length;
+  guint      max_length;
+  gchar     *pattern;
+};
+
+
+/* --- functions --- */
+static inline gboolean
+g_pattern_ph_match (const gchar *match_pattern,
+                   const gchar *match_string,
+                   gboolean    *wildcard_reached_p)
+{
+  register const gchar *pattern, *string;
+  register gchar ch;
+
+  pattern = match_pattern;
+  string = match_string;
+
+  ch = *pattern;
+  pattern++;
+  while (ch)
+    {
+      switch (ch)
+       {
+       case '?':
+         if (!*string)
+           return FALSE;
+         string = g_utf8_next_char (string);
+         break;
+
+       case '*':
+         *wildcard_reached_p = TRUE;
+         do
+           {
+             ch = *pattern;
+             pattern++;
+             if (ch == '?')
+               {
+                 if (!*string)
+                   return FALSE;
+                 string = g_utf8_next_char (string);
+               }
+           }
+         while (ch == '*' || ch == '?');
+         if (!ch)
+           return TRUE;
+         do
+           {
+              gboolean next_wildcard_reached = FALSE;
+             while (ch != *string)
+               {
+                 if (!*string)
+                   return FALSE;
+                 string = g_utf8_next_char (string);
+               }
+             string++;
+             if (g_pattern_ph_match (pattern, string, &next_wildcard_reached))
+               return TRUE;
+              if (next_wildcard_reached)
+                /* the forthcoming pattern substring up to the next wildcard has
+                 * been matched, but a mismatch occoured for the rest of the
+                 * pattern, following the next wildcard.
+                 * there's no need to advance the current match position any
+                 * further if the rest pattern will not match.
+                 */
+               return FALSE;
+           }
+         while (*string);
+         break;
+
+       default:
+         if (ch == *string)
+           string++;
+         else
+           return FALSE;
+         break;
+       }
+
+      ch = *pattern;
+      pattern++;
+    }
+
+  return *string == 0;
+}
+
+/**
+ * g_pattern_match:
+ * @pspec: a #GPatternSpec
+ * @string_length: the length of @string (in bytes, i.e. strlen(),
+ *                 <emphasis>not</emphasis> g_utf8_strlen())
+ * @string: the UTF-8 encoded string to match
+ * @string_reversed: the reverse of @string or %NULL
+ * @Returns: %TRUE if @string matches @pspec
+ *
+ * Matches a string against a compiled pattern. Passing the correct
+ * length of the string given is mandatory. The reversed string can be
+ * omitted by passing %NULL, this is more efficient if the reversed
+ * version of the string to be matched is not at hand, as
+ * g_pattern_match() will only construct it if the compiled pattern
+ * requires reverse matches.
+ *
+ * Note that, if the user code will (possibly) match a string against a
+ * multitude of patterns containing wildcards, chances are high that
+ * some patterns will require a reversed string. In this case, it's
+ * more efficient to provide the reversed string to avoid multiple
+ * constructions thereof in the various calls to g_pattern_match().
+ *
+ * Note also that the reverse of a UTF-8 encoded string can in general
+ * <emphasis>not</emphasis> be obtained by g_strreverse(). This works
+ * only if the string doesn't contain any multibyte characters. GLib
+ * offers the g_utf8_strreverse() function to reverse UTF-8 encoded
+ * strings.
+ **/
+gboolean
+g_pattern_match (GPatternSpec *pspec,
+                guint         string_length,
+                const gchar  *string,
+                const gchar  *string_reversed)
+{
+  g_return_val_if_fail (pspec != NULL, FALSE);
+  g_return_val_if_fail (string != NULL, FALSE);
+
+  if (string_length < pspec->min_length ||
+      string_length > pspec->max_length)
+    return FALSE;
+
+  switch (pspec->match_type)
+    {
+      gboolean dummy;
+    case G_MATCH_ALL:
+      return g_pattern_ph_match (pspec->pattern, string, &dummy);
+    case G_MATCH_ALL_TAIL:
+      if (string_reversed)
+       return g_pattern_ph_match (pspec->pattern, string_reversed, &dummy);
+      else
+       {
+          gboolean result;
+          gchar *tmp;
+         tmp = g_utf8_strreverse (string, string_length);
+         result = g_pattern_ph_match (pspec->pattern, tmp, &dummy);
+         g_free (tmp);
+         return result;
+       }
+    case G_MATCH_HEAD:
+      if (pspec->pattern_length == string_length)
+       return strcmp (pspec->pattern, string) == 0;
+      else if (pspec->pattern_length)
+       return strncmp (pspec->pattern, string, pspec->pattern_length) == 0;
+      else
+       return TRUE;
+    case G_MATCH_TAIL:
+      if (pspec->pattern_length)
+        return strcmp (pspec->pattern, string + (string_length - pspec->pattern_length)) == 0;
+      else
+       return TRUE;
+    case G_MATCH_EXACT:
+      if (pspec->pattern_length != string_length)
+        return FALSE;
+      else
+        return strcmp (pspec->pattern, string) == 0;
+    default:
+      g_return_val_if_fail (pspec->match_type < G_MATCH_LAST, FALSE);
+      return FALSE;
+    }
+}
+
+/**
+ * g_pattern_spec_new:
+ * @pattern: a zero-terminated UTF-8 encoded string
+ * @Returns: a newly-allocated #GPatternSpec
+ *
+ * Compiles a pattern to a #GPatternSpec.
+ **/
+GPatternSpec*
+g_pattern_spec_new (const gchar *pattern)
+{
+  GPatternSpec *pspec;
+  gboolean seen_joker = FALSE, seen_wildcard = FALSE, more_wildcards = FALSE;
+  gint hw_pos = -1, tw_pos = -1, hj_pos = -1, tj_pos = -1;
+  gboolean follows_wildcard = FALSE;
+  guint pending_jokers = 0;
+  const gchar *s;
+  gchar *d;
+  guint i;
+  
+  g_return_val_if_fail (pattern != NULL, NULL);
+
+  /* canonicalize pattern and collect necessary stats */
+  pspec = g_new (GPatternSpec, 1);
+  pspec->pattern_length = strlen (pattern);
+  pspec->min_length = 0;
+  pspec->max_length = 0;
+  pspec->pattern = g_new (gchar, pspec->pattern_length + 1);
+  d = pspec->pattern;
+  for (i = 0, s = pattern; *s != 0; s++)
+    {
+      switch (*s)
+       {
+       case '*':
+         if (follows_wildcard) /* compress multiple wildcards */
+           {
+             pspec->pattern_length--;
+             continue;
+           }
+         follows_wildcard = TRUE;
+         if (hw_pos < 0)
+           hw_pos = i;
+         tw_pos = i;
+         break;
+       case '?':
+         pending_jokers++;
+         pspec->min_length++;
+         pspec->max_length += 4; /* maximum UTF-8 character length */
+         continue;
+       default:
+         for (; pending_jokers; pending_jokers--, i++) {
+           *d++ = '?';
+           if (hj_pos < 0)
+            hj_pos = i;
+           tj_pos = i;
+         }
+         follows_wildcard = FALSE;
+         pspec->min_length++;
+         pspec->max_length++;
+         break;
+       }
+      *d++ = *s;
+      i++;
+    }
+  for (; pending_jokers; pending_jokers--) {
+    *d++ = '?';
+    if (hj_pos < 0)
+      hj_pos = i;
+    tj_pos = i;
+  }
+  *d++ = 0;
+  seen_joker = hj_pos >= 0;
+  seen_wildcard = hw_pos >= 0;
+  more_wildcards = seen_wildcard && hw_pos != tw_pos;
+  if (seen_wildcard)
+    pspec->max_length = G_MAXUINT;
+
+  /* special case sole head/tail wildcard or exact matches */
+  if (!seen_joker && !more_wildcards)
+    {
+      if (pspec->pattern[0] == '*')
+       {
+         pspec->match_type = G_MATCH_TAIL;
+          memmove (pspec->pattern, pspec->pattern + 1, --pspec->pattern_length);
+         pspec->pattern[pspec->pattern_length] = 0;
+         return pspec;
+       }
+      if (pspec->pattern_length > 0 &&
+         pspec->pattern[pspec->pattern_length - 1] == '*')
+       {
+         pspec->match_type = G_MATCH_HEAD;
+         pspec->pattern[--pspec->pattern_length] = 0;
+         return pspec;
+       }
+      if (!seen_wildcard)
+       {
+         pspec->match_type = G_MATCH_EXACT;
+         return pspec;
+       }
+    }
+
+  /* now just need to distinguish between head or tail match start */
+  tw_pos = pspec->pattern_length - 1 - tw_pos; /* last pos to tail distance */
+  tj_pos = pspec->pattern_length - 1 - tj_pos; /* last pos to tail distance */
+  if (seen_wildcard)
+    pspec->match_type = tw_pos > hw_pos ? G_MATCH_ALL_TAIL : G_MATCH_ALL;
+  else /* seen_joker */
+    pspec->match_type = tj_pos > hj_pos ? G_MATCH_ALL_TAIL : G_MATCH_ALL;
+  if (pspec->match_type == G_MATCH_ALL_TAIL) {
+    gchar *tmp = pspec->pattern;
+    pspec->pattern = g_utf8_strreverse (pspec->pattern, pspec->pattern_length);
+    g_free (tmp);
+  }
+  return pspec;
+}
+
+/**
+ * g_pattern_spec_free:
+ * @pspec: a #GPatternSpec
+ *
+ * Frees the memory allocated for the #GPatternSpec.
+ **/
+void
+g_pattern_spec_free (GPatternSpec *pspec)
+{
+  g_return_if_fail (pspec != NULL);
+
+  g_free (pspec->pattern);
+  g_free (pspec);
+}
+
+/**
+ * g_pattern_spec_equal:
+ * @pspec1: a #GPatternSpec
+ * @pspec2: another #GPatternSpec
+ * @Returns: Whether the compiled patterns are equal
+ *
+ * Compares two compiled pattern specs and returns whether they will
+ * match the same set of strings.
+ **/
+gboolean
+g_pattern_spec_equal (GPatternSpec *pspec1,
+                     GPatternSpec *pspec2)
+{
+  g_return_val_if_fail (pspec1 != NULL, FALSE);
+  g_return_val_if_fail (pspec2 != NULL, FALSE);
+
+  return (pspec1->pattern_length == pspec2->pattern_length &&
+         pspec1->match_type == pspec2->match_type &&
+         strcmp (pspec1->pattern, pspec2->pattern) == 0);
+}
+
+/**
+ * g_pattern_match_string:
+ * @pspec: a #GPatternSpec
+ * @string: the UTF-8 encoded string to match
+ * @Returns: %TRUE if @string matches @pspec
+ *
+ * Matches a string against a compiled pattern. If the string is to be
+ * matched against more than one pattern, consider using
+ * g_pattern_match() instead while supplying the reversed string.
+ **/
+gboolean
+g_pattern_match_string (GPatternSpec *pspec,
+                       const gchar  *string)
+{
+  g_return_val_if_fail (pspec != NULL, FALSE);
+  g_return_val_if_fail (string != NULL, FALSE);
+
+  return g_pattern_match (pspec, strlen (string), string, NULL);
+}
+
+/**
+ * g_pattern_match_simple:
+ * @pattern: the UTF-8 encoded pattern
+ * @string: the UTF-8 encoded string to match
+ * @Returns: %TRUE if @string matches @pspec
+ *
+ * Matches a string against a pattern given as a string. If this
+ * function is to be called in a loop, it's more efficient to compile
+ * the pattern once with g_pattern_spec_new() and call
+ * g_pattern_match_string() repeatedly.
+ **/
+gboolean
+g_pattern_match_simple (const gchar *pattern,
+                       const gchar *string)
+{
+  GPatternSpec *pspec;
+  gboolean ergo;
+
+  g_return_val_if_fail (pattern != NULL, FALSE);
+  g_return_val_if_fail (string != NULL, FALSE);
+
+  pspec = g_pattern_spec_new (pattern);
+  ergo = g_pattern_match (pspec, strlen (string), string, NULL);
+  g_pattern_spec_free (pspec);
+
+  return ergo;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gpattern.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gpattern.h
new file mode 100644 (file)
index 0000000..b653d71
--- /dev/null
@@ -0,0 +1,49 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997, 1999  Peter Mattis, Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_PATTERN_H__
+#define __G_PATTERN_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+
+typedef struct _GPatternSpec    GPatternSpec;
+
+GPatternSpec* g_pattern_spec_new       (const gchar  *pattern);
+void          g_pattern_spec_free      (GPatternSpec *pspec);
+gboolean      g_pattern_spec_equal     (GPatternSpec *pspec1,
+                                       GPatternSpec *pspec2);
+gboolean      g_pattern_match          (GPatternSpec *pspec,
+                                       guint         string_length,
+                                       const gchar  *string,
+                                       const gchar  *string_reversed);
+gboolean      g_pattern_match_string   (GPatternSpec *pspec,
+                                       const gchar  *string);
+gboolean      g_pattern_match_simple   (const gchar  *pattern,
+                                       const gchar  *string);
+
+G_END_DECLS
+
+#endif /* __G_PATTERN_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gpoll.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gpoll.c
new file mode 100644 (file)
index 0000000..940abae
--- /dev/null
@@ -0,0 +1,432 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gpoll.c: poll(2) abstraction
+ * Copyright 1998 Owen Taylor
+ * Copyright 2008 Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+#include "glibconfig.h"
+#include "giochannel.h"
+
+/* Uncomment the next line (and the corresponding line in gmain.c) to
+ * enable debugging printouts if the environment variable
+ * G_MAIN_POLL_DEBUG is set to some value.
+ */
+/* #define G_MAIN_POLL_DEBUG */
+
+#ifdef _WIN32
+/* Always enable debugging printout on Windows, as it is more often
+ * needed there...
+ */
+#define G_MAIN_POLL_DEBUG
+#endif
+
+#include <sys/types.h>
+#include <time.h>
+#include <stdlib.h>
+#ifdef HAVE_SYS_TIME_H
+#include <sys/time.h>
+#endif /* HAVE_SYS_TIME_H */
+#ifdef GLIB_HAVE_SYS_POLL_H
+#  include <sys/poll.h>
+#  undef events         /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */
+#  undef revents /* AIX 4.1.5 & 4.3.2 define this for SVR3,4 compatibility */
+
+/* The poll() emulation on OS/X doesn't handle fds=NULL, nfds=0,
+ * so we prefer our own poll emulation.
+ */
+#if defined(_POLL_EMUL_H_) || defined(BROKEN_POLL)
+#undef HAVE_POLL
+#endif
+
+#endif /* GLIB_HAVE_SYS_POLL_H */
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+#include <errno.h>
+
+#ifdef G_OS_WIN32
+#define STRICT
+#include <windows.h>
+#endif /* G_OS_WIN32 */
+
+#include "gpoll.h"
+
+#ifdef G_OS_WIN32
+#include "gprintf.h"
+#endif
+
+#ifdef G_MAIN_POLL_DEBUG
+extern gboolean _g_main_poll_debug;
+#endif
+
+#ifdef HAVE_POLL
+/* SunOS has poll, but doesn't provide a prototype. */
+#  if defined (sun) && !defined (__SVR4)
+extern gint poll (struct pollfd *fds, guint nfsd, gint timeout);
+#  endif  /* !sun */
+
+/**
+ * g_poll:
+ * @fds: file descriptors to poll
+ * @nfds: the number of file descriptors in @fds
+ * @timeout: amount of time to wait, in milliseconds, or -1 to wait forever
+ *
+ * Polls @fds, as with the poll() system call, but portably. (On
+ * systems that don't have poll(), it is emulated using select().)
+ * This is used internally by #GMainContext, but it can be called
+ * directly if you need to block until a file descriptor is ready, but
+ * don't want to run the full main loop.
+ *
+ * Each element of @fds is a #GPollFD describing a single file
+ * descriptor to poll. The %fd field indicates the file descriptor,
+ * and the %events field indicates the events to poll for. On return,
+ * the %revents fields will be filled with the events that actually
+ * occurred.
+ *
+ * On POSIX systems, the file descriptors in @fds can be any sort of
+ * file descriptor, but the situation is much more complicated on
+ * Windows. If you need to use g_poll() in code that has to run on
+ * Windows, the easiest solution is to construct all of your
+ * #GPollFD<!-- -->s with g_io_channel_win32_make_pollfd().
+ *
+ * Return value: the number of entries in @fds whose %revents fields
+ * were filled in, or 0 if the operation timed out, or -1 on error or
+ * if the call was interrupted.
+ *
+ * Since: 2.20
+ **/
+gint
+g_poll (GPollFD *fds,
+       guint    nfds,
+       gint     timeout)
+{
+  return poll ((struct pollfd *)fds, nfds, timeout);
+}
+
+#else  /* !HAVE_POLL */
+
+#ifdef G_OS_WIN32
+
+static int
+poll_rest (gboolean  poll_msgs,
+          HANDLE   *handles,
+          gint      nhandles,
+          GPollFD  *fds,
+          guint     nfds,
+          gint      timeout)
+{
+  DWORD ready;
+  GPollFD *f;
+  int recursed_result;
+
+  if (poll_msgs)
+    {
+      /* Wait for either messages or handles
+       * -> Use MsgWaitForMultipleObjectsEx
+       */
+      if (_g_main_poll_debug)
+       g_print ("  MsgWaitForMultipleObjectsEx(%d, %d)\n", nhandles, timeout);
+
+      ready = MsgWaitForMultipleObjectsEx (nhandles, handles, timeout,
+                                          QS_ALLINPUT, MWMO_ALERTABLE);
+
+      if (ready == WAIT_FAILED)
+       {
+         gchar *emsg = g_win32_error_message (GetLastError ());
+         g_warning ("MsgWaitForMultipleObjectsEx failed: %s", emsg);
+         g_free (emsg);
+       }
+    }
+  else if (nhandles == 0)
+    {
+      /* No handles to wait for, just the timeout */
+      if (timeout == INFINITE)
+       ready = WAIT_FAILED;
+      else
+       {
+         SleepEx (timeout, TRUE);
+         ready = WAIT_TIMEOUT;
+       }
+    }
+  else
+    {
+      /* Wait for just handles
+       * -> Use WaitForMultipleObjectsEx
+       */
+      if (_g_main_poll_debug)
+       g_print ("  WaitForMultipleObjectsEx(%d, %d)\n", nhandles, timeout);
+
+      ready = WaitForMultipleObjectsEx (nhandles, handles, FALSE, timeout, TRUE);
+      if (ready == WAIT_FAILED)
+       {
+         gchar *emsg = g_win32_error_message (GetLastError ());
+         g_warning ("WaitForMultipleObjectsEx failed: %s", emsg);
+         g_free (emsg);
+       }
+    }
+
+  if (_g_main_poll_debug)
+    g_print ("  wait returns %ld%s\n",
+            ready,
+            (ready == WAIT_FAILED ? " (WAIT_FAILED)" :
+             (ready == WAIT_TIMEOUT ? " (WAIT_TIMEOUT)" :
+              (poll_msgs && ready == WAIT_OBJECT_0 + nhandles ? " (msg)" : ""))));
+
+  if (ready == WAIT_FAILED)
+    return -1;
+  else if (ready == WAIT_TIMEOUT ||
+          ready == WAIT_IO_COMPLETION)
+    return 0;
+  else if (poll_msgs && ready == WAIT_OBJECT_0 + nhandles)
+    {
+      for (f = fds; f < &fds[nfds]; ++f)
+       if (f->fd == G_WIN32_MSG_HANDLE && f->events & G_IO_IN)
+         f->revents |= G_IO_IN;
+
+      /* If we have a timeout, or no handles to poll, be satisfied
+       * with just noticing we have messages waiting.
+       */
+      if (timeout != 0 || nhandles == 0)
+       return 1;
+
+      /* If no timeout and handles to poll, recurse to poll them,
+       * too.
+       */
+      recursed_result = poll_rest (FALSE, handles, nhandles, fds, nfds, 0);
+      return (recursed_result == -1) ? -1 : 1 + recursed_result;
+    }
+  else if (ready >= WAIT_OBJECT_0 && ready < WAIT_OBJECT_0 + nhandles)
+    {
+      for (f = fds; f < &fds[nfds]; ++f)
+       {
+         if ((HANDLE) f->fd == handles[ready - WAIT_OBJECT_0])
+           {
+             f->revents = f->events;
+             if (_g_main_poll_debug)
+               g_print ("  got event %p\n", (HANDLE) f->fd);
+           }
+       }
+
+      /* If no timeout and polling several handles, recurse to poll
+       * the rest of them.
+       */
+      if (timeout == 0 && nhandles > 1)
+       {
+         /* Remove the handle that fired */
+         int i;
+         if (ready < nhandles - 1)
+           for (i = ready - WAIT_OBJECT_0 + 1; i < nhandles; i++)
+             handles[i-1] = handles[i];
+         nhandles--;
+         recursed_result = poll_rest (FALSE, handles, nhandles, fds, nfds, 0);
+         return (recursed_result == -1) ? -1 : 1 + recursed_result;
+       }
+      return 1;
+    }
+
+  return 0;
+}
+
+gint
+g_poll (GPollFD *fds,
+       guint    nfds,
+       gint     timeout)
+{
+  HANDLE handles[MAXIMUM_WAIT_OBJECTS];
+  gboolean poll_msgs = FALSE;
+  GPollFD *f;
+  gint nhandles = 0;
+  int retval;
+
+  if (_g_main_poll_debug)
+    g_print ("g_poll: waiting for");
+
+  for (f = fds; f < &fds[nfds]; ++f)
+    if (f->fd == G_WIN32_MSG_HANDLE && (f->events & G_IO_IN))
+      {
+       if (_g_main_poll_debug && !poll_msgs)
+         g_print (" MSG");
+       poll_msgs = TRUE;
+      }
+    else if (f->fd > 0)
+      {
+       /* Don't add the same handle several times into the array, as
+        * docs say that is not allowed, even if it actually does seem
+        * to work.
+        */
+       gint i;
+
+       for (i = 0; i < nhandles; i++)
+         if (handles[i] == (HANDLE) f->fd)
+           break;
+
+       if (i == nhandles)
+         {
+           if (nhandles == MAXIMUM_WAIT_OBJECTS)
+             {
+               g_warning ("Too many handles to wait for!\n");
+               break;
+             }
+           else
+             {
+               if (_g_main_poll_debug)
+                 g_print (" %p", (HANDLE) f->fd);
+               handles[nhandles++] = (HANDLE) f->fd;
+             }
+         }
+      }
+
+  if (_g_main_poll_debug)
+    g_print ("\n");
+
+  for (f = fds; f < &fds[nfds]; ++f)
+    f->revents = 0;
+
+  if (timeout == -1)
+    timeout = INFINITE;
+
+  /* Polling for several things? */
+  if (nhandles > 1 || (nhandles > 0 && poll_msgs))
+    {
+      /* First check if one or several of them are immediately
+       * available
+       */
+      retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, 0);
+
+      /* If not, and we have a significant timeout, poll again with
+       * timeout then. Note that this will return indication for only
+       * one event, or only for messages. We ignore timeouts less than
+       * ten milliseconds as they are mostly pointless on Windows, the
+       * MsgWaitForMultipleObjectsEx() call will timeout right away
+       * anyway.
+       */
+      if (retval == 0 && (timeout == INFINITE || timeout >= 10))
+       retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout);
+    }
+  else
+    {
+      /* Just polling for one thing, so no need to check first if
+       * available immediately
+       */
+      retval = poll_rest (poll_msgs, handles, nhandles, fds, nfds, timeout);
+    }
+
+  if (retval == -1)
+    for (f = fds; f < &fds[nfds]; ++f)
+      f->revents = 0;
+
+  return retval;
+}
+
+#else  /* !G_OS_WIN32 */
+
+/* The following implementation of poll() comes from the GNU C Library.
+ * Copyright (C) 1994, 1996, 1997 Free Software Foundation, Inc.
+ */
+
+#include <string.h> /* for bzero on BSD systems */
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H */
+
+#ifdef G_OS_BEOS
+#undef NO_FD_SET
+#endif /* G_OS_BEOS */
+
+#ifndef NO_FD_SET
+#  define SELECT_MASK fd_set
+#else /* !NO_FD_SET */
+#  ifndef _AIX
+typedef long fd_mask;
+#  endif /* _AIX */
+#  ifdef _IBMR2
+#    define SELECT_MASK void
+#  else /* !_IBMR2 */
+#    define SELECT_MASK int
+#  endif /* !_IBMR2 */
+#endif /* !NO_FD_SET */
+
+gint
+g_poll (GPollFD *fds,
+       guint    nfds,
+       gint     timeout)
+{
+  struct timeval tv;
+  SELECT_MASK rset, wset, xset;
+  GPollFD *f;
+  int ready;
+  int maxfd = 0;
+
+  FD_ZERO (&rset);
+  FD_ZERO (&wset);
+  FD_ZERO (&xset);
+
+  for (f = fds; f < &fds[nfds]; ++f)
+    if (f->fd >= 0)
+      {
+       if (f->events & G_IO_IN)
+         FD_SET (f->fd, &rset);
+       if (f->events & G_IO_OUT)
+         FD_SET (f->fd, &wset);
+       if (f->events & G_IO_PRI)
+         FD_SET (f->fd, &xset);
+       if (f->fd > maxfd && (f->events & (G_IO_IN|G_IO_OUT|G_IO_PRI)))
+         maxfd = f->fd;
+      }
+
+  tv.tv_sec = timeout / 1000;
+  tv.tv_usec = (timeout % 1000) * 1000;
+
+  ready = select (maxfd + 1, &rset, &wset, &xset,
+                 timeout == -1 ? NULL : &tv);
+  if (ready > 0)
+    for (f = fds; f < &fds[nfds]; ++f)
+      {
+       f->revents = 0;
+       if (f->fd >= 0)
+         {
+           if (FD_ISSET (f->fd, &rset))
+             f->revents |= G_IO_IN;
+           if (FD_ISSET (f->fd, &wset))
+             f->revents |= G_IO_OUT;
+           if (FD_ISSET (f->fd, &xset))
+             f->revents |= G_IO_PRI;
+         }
+      }
+
+  return ready;
+}
+
+#endif /* !G_OS_WIN32 */
+
+#endif /* !HAVE_POLL */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gpoll.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gpoll.h
new file mode 100644 (file)
index 0000000..cc79381
--- /dev/null
@@ -0,0 +1,117 @@
+/* gpoll.h - poll(2) support
+ * Copyright (C) 2008 Red Hat, Inc.
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Library General Public
+ * License as published by the Free Software Foundation; either
+ * version 2 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 Library General Public
+ * License along with this library; if not, write to the
+ * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if !defined (__GLIB_H_INSIDE__) && !defined (__G_MAIN_H__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_POLL_H__
+#define __G_POLL_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+/* Any definitions using GPollFD or GPollFunc are primarily
+ * for Unix and not guaranteed to be the compatible on all
+ * operating systems on which GLib runs. Right now, the
+ * GLib does use these functions on Win32 as well, but interprets
+ * them in a fairly different way than on Unix. If you use
+ * these definitions, you are should be prepared to recode
+ * for different operating systems.
+ *
+ * Note that on systems with a working poll(2), that function is used
+ * in place of g_poll(). Thus g_poll() must have the same signature as
+ * poll(), meaning GPollFD must have the same layout as struct pollfd.
+ *
+ *
+ * On Win32, the fd in a GPollFD should be Win32 HANDLE (*not* a file
+ * descriptor as provided by the C runtime) that can be used by
+ * MsgWaitForMultipleObjects. This does *not* include file handles
+ * from CreateFile, SOCKETs, nor pipe handles. (But you can use
+ * WSAEventSelect to signal events when a SOCKET is readable).
+ *
+ * On Win32, fd can also be the special value G_WIN32_MSG_HANDLE to
+ * indicate polling for messages.
+ *
+ * But note that G_WIN32_MSG_HANDLE GPollFDs should not be used by GDK
+ * (GTK) programs, as GDK itself wants to read messages and convert them
+ * to GDK events.
+ *
+ * So, unless you really know what you are doing, it's best not to try
+ * to use the main loop polling stuff for your own needs on
+ * Windows.
+ */
+typedef struct _GPollFD GPollFD;
+
+/**
+ * GPollFunc:
+ * @ufds: an array of #GPollFD elements
+ * @nfsd: the number of elements in @ufds
+ * @timeout_: the maximum time to wait for an event of the file descriptors.
+ *     A negative value indicates an infinite timeout.
+ *
+ * Specifies the type of function passed to g_main_context_set_poll_func().
+ * The semantics of the function should match those of the poll() system call.
+ *
+ * Returns: the number of #GPollFD elements which have events or errors
+ *     reported, or -1 if an error occurred.
+ */
+typedef gint    (*GPollFunc)    (GPollFD *ufds,
+                                 guint    nfsd,
+                                 gint     timeout_);
+
+/**
+ * GPollFD:
+ * @fd: the file descriptor to poll (or a <type>HANDLE</type> on Win32)
+ * @events: a bitwise combination from #GIOCondition, specifying which
+ *     events should be polled for. Typically for reading from a file
+ *     descriptor you would use %G_IO_IN | %G_IO_HUP | %G_IO_ERR, and
+ *     for writing you would use %G_IO_OUT | %G_IO_ERR.
+ * @revents: a bitwise combination of flags from #GIOCondition, returned
+ *     from the poll() function to indicate which events occurred.
+ */
+struct _GPollFD
+{
+#if defined (G_OS_WIN32) && GLIB_SIZEOF_VOID_P == 8
+  gint64       fd;
+#else
+  gint         fd;
+#endif
+  gushort      events;
+  gushort      revents;
+};
+
+#ifdef G_OS_WIN32
+#if GLIB_SIZEOF_VOID_P == 8
+#define G_POLLFD_FORMAT "%#I64x"
+#else
+#define G_POLLFD_FORMAT "%#x"
+#endif
+#else
+#define G_POLLFD_FORMAT "%d"
+#endif
+
+gint g_poll (GPollFD *fds,
+            guint    nfds,
+            gint     timeout);
+
+G_END_DECLS
+
+#endif /* __G_POLL_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gprimes.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gprimes.c
new file mode 100644 (file)
index 0000000..6698c56
--- /dev/null
@@ -0,0 +1,86 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "gprimes.h"
+
+
+static const guint g_primes[] =
+{
+  11,
+  19,
+  37,
+  73,
+  109,
+  163,
+  251,
+  367,
+  557,
+  823,
+  1237,
+  1861,
+  2777,
+  4177,
+  6247,
+  9371,
+  14057,
+  21089,
+  31627,
+  47431,
+  71143,
+  106721,
+  160073,
+  240101,
+  360163,
+  540217,
+  810343,
+  1215497,
+  1823231,
+  2734867,
+  4102283,
+  6153409,
+  9230113,
+  13845163,
+};
+
+static const guint g_nprimes = sizeof (g_primes) / sizeof (g_primes[0]);
+
+guint
+g_spaced_primes_closest (guint num)
+{
+  gint i;
+
+  for (i = 0; i < g_nprimes; i++)
+    if (g_primes[i] > num)
+      return g_primes[i];
+
+  return g_primes[g_nprimes - 1];
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gprimes.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gprimes.h
new file mode 100644 (file)
index 0000000..af57286
--- /dev/null
@@ -0,0 +1,51 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_PRIMES_H__
+#define __G_PRIMES_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+/* Prime numbers.
+ */
+
+/* This function returns prime numbers spaced by approximately 1.5-2.0
+ * and is for use in resizing data structures which prefer
+ * prime-valued sizes. The closest spaced prime function returns the
+ * next largest prime, or the highest it knows about which is about
+ * MAXINT/4.
+ */
+guint     g_spaced_primes_closest (guint num) G_GNUC_CONST;
+
+G_END_DECLS
+
+#endif /* __G_PRIMES_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gprintf.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gprintf.c
new file mode 100644 (file)
index 0000000..7ef15d3
--- /dev/null
@@ -0,0 +1,344 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997, 2002  Peter Mattis, Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#ifndef _WIN32
+#define _GNU_SOURCE            /* For vasprintf */
+#endif
+
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include "gprintf.h"
+#include "gprintfint.h"
+
+
+/**
+ * g_printf:
+ * @format: a standard printf() format string, but notice 
+ *          <link linkend="string-precision">string precision pitfalls</link>.
+ * @Varargs: the arguments to insert in the output.
+ *
+ * An implementation of the standard printf() function which supports 
+ * positional parameters, as specified in the Single Unix Specification.
+ *
+ * Returns: the number of bytes printed.
+ *
+ * Since: 2.2
+ **/
+gint
+g_printf (gchar const *format,
+         ...)
+{
+  va_list args;
+  gint retval;
+
+  va_start (args, format);
+  retval = g_vprintf (format, args);
+  va_end (args);
+  
+  return retval;
+}
+
+/**
+ * g_fprintf:
+ * @file: the stream to write to.
+ * @format: a standard printf() format string, but notice 
+ *          <link linkend="string-precision">string precision pitfalls</link>.
+ * @Varargs: the arguments to insert in the output.
+ *
+ * An implementation of the standard fprintf() function which supports 
+ * positional parameters, as specified in the Single Unix Specification.
+ *
+ * Returns: the number of bytes printed.
+ *
+ * Since: 2.2
+ **/
+gint
+g_fprintf (FILE        *file, 
+           gchar const *format,
+          ...)
+{
+  va_list args;
+  gint retval;
+
+  va_start (args, format);
+  retval = g_vfprintf (file, format, args);
+  va_end (args);
+  
+  return retval;
+}
+
+/**
+ * g_sprintf:
+ * @string: A pointer to a memory buffer to contain the resulting string. It
+ *          is up to the caller to ensure that the allocated buffer is large
+ *          enough to hold the formatted result
+ * @format: a standard printf() format string, but notice
+ *          <link linkend="string-precision">string precision pitfalls</link>.
+ * @Varargs: the arguments to insert in the output.
+ *
+ * An implementation of the standard sprintf() function which supports
+ * positional parameters, as specified in the Single Unix Specification.
+ *
+ * Note that it is usually better to use g_snprintf(), to avoid the
+ * risk of buffer overflow.
+ *
+ * See also g_strdup_printf().
+ *
+ * Returns: the number of bytes printed.
+ *
+ * Since: 2.2
+ **/
+gint
+g_sprintf (gchar       *string,
+          gchar const *format,
+          ...)
+{
+  va_list args;
+  gint retval;
+
+  va_start (args, format);
+  retval = g_vsprintf (string, format, args);
+  va_end (args);
+  
+  return retval;
+}
+
+/**
+ * g_snprintf:
+ * @string: the buffer to hold the output.
+ * @n: the maximum number of bytes to produce (including the
+ *     terminating nul character).
+ * @format: a standard printf() format string, but notice
+ *          <link linkend="string-precision">string precision pitfalls</link>.
+ * @Varargs: the arguments to insert in the output.
+ *
+ * A safer form of the standard sprintf() function. The output is guaranteed
+ * to not exceed @n characters (including the terminating nul character), so
+ * it is easy to ensure that a buffer overflow cannot occur.
+ *
+ * See also g_strdup_printf().
+ *
+ * In versions of GLib prior to 1.2.3, this function may return -1 if the
+ * output was truncated, and the truncated string may not be nul-terminated.
+ * In versions prior to 1.3.12, this function returns the length of the output
+ * string.
+ *
+ * The return value of g_snprintf() conforms to the snprintf()
+ * function as standardized in ISO C99. Note that this is different from
+ * traditional snprintf(), which returns the length of the output string.
+ *
+ * The format string may contain positional parameters, as specified in
+ * the Single Unix Specification.
+ *
+ * Returns: the number of bytes which would be produced if the buffer 
+ *     was large enough.
+ **/
+gint
+g_snprintf (gchar      *string,
+           gulong       n,
+           gchar const *format,
+           ...)
+{
+  va_list args;
+  gint retval;
+
+  va_start (args, format);
+  retval = g_vsnprintf (string, n, format, args);
+  va_end (args);
+  
+  return retval;
+}
+
+/**
+ * g_vprintf:
+ * @format: a standard printf() format string, but notice 
+ *          <link linkend="string-precision">string precision pitfalls</link>.
+ * @args: the list of arguments to insert in the output.
+ *
+ * An implementation of the standard vprintf() function which supports 
+ * positional parameters, as specified in the Single Unix Specification.
+ *
+ * Returns: the number of bytes printed.
+ *
+ * Since: 2.2
+ **/
+gint
+g_vprintf (gchar const *format,
+          va_list      args)
+{
+  g_return_val_if_fail (format != NULL, -1);
+
+  return _g_vprintf (format, args);
+}
+
+/**
+ * g_vfprintf:
+ * @file: the stream to write to.
+ * @format: a standard printf() format string, but notice 
+ *          <link linkend="string-precision">string precision pitfalls</link>.
+ * @args: the list of arguments to insert in the output.
+ *
+ * An implementation of the standard fprintf() function which supports 
+ * positional parameters, as specified in the Single Unix Specification.
+ *
+ * Returns: the number of bytes printed.
+ *
+ * Since: 2.2
+ **/
+gint
+g_vfprintf (FILE        *file,
+            gchar const *format,
+           va_list      args)
+{
+  g_return_val_if_fail (format != NULL, -1);
+
+  return _g_vfprintf (file, format, args);
+}
+
+/**
+ * g_vsprintf:
+ * @string: the buffer to hold the output.
+ * @format: a standard printf() format string, but notice 
+ *          <link linkend="string-precision">string precision pitfalls</link>.
+ * @args: the list of arguments to insert in the output.
+ *
+ * An implementation of the standard vsprintf() function which supports 
+ * positional parameters, as specified in the Single Unix Specification.
+ *
+ * Returns: the number of bytes printed.
+ *
+ * Since: 2.2
+ **/
+gint
+g_vsprintf (gchar       *string,
+           gchar const *format,
+           va_list      args)
+{
+  g_return_val_if_fail (string != NULL, -1);
+  g_return_val_if_fail (format != NULL, -1);
+
+  return _g_vsprintf (string, format, args);
+}
+
+/** 
+ * g_vsnprintf:
+ * @string: the buffer to hold the output.
+ * @n: the maximum number of bytes to produce (including the 
+ *     terminating nul character).
+ * @format: a standard printf() format string, but notice 
+ *          <link linkend="string-precision">string precision pitfalls</link>.
+ * @args: the list of arguments to insert in the output.
+ *
+ * A safer form of the standard vsprintf() function. The output is guaranteed
+ * to not exceed @n characters (including the terminating nul character), so 
+ * it is easy to ensure that a buffer overflow cannot occur.
+ *
+ * See also g_strdup_vprintf().
+ *
+ * In versions of GLib prior to 1.2.3, this function may return -1 if the 
+ * output was truncated, and the truncated string may not be nul-terminated.
+ * In versions prior to 1.3.12, this function returns the length of the output 
+ * string.
+ *
+ * The return value of g_vsnprintf() conforms to the vsnprintf() function 
+ * as standardized in ISO C99. Note that this is different from traditional 
+ * vsnprintf(), which returns the length of the output string.
+ *
+ * The format string may contain positional parameters, as specified in 
+ * the Single Unix Specification.
+ *
+ * Returns: the number of bytes which would be produced if the buffer 
+ *  was large enough.
+ */
+gint
+g_vsnprintf (gchar      *string,
+            gulong       n,
+            gchar const *format,
+            va_list      args)
+{
+  g_return_val_if_fail (n == 0 || string != NULL, -1);
+  g_return_val_if_fail (format != NULL, -1);
+
+  return _g_vsnprintf (string, n, format, args);
+}
+
+/**
+ * g_vasprintf:
+ * @string: the return location for the newly-allocated string.
+ * @format: a standard printf() format string, but notice
+ *          <link linkend="string-precision">string precision pitfalls</link>.
+ * @args: the list of arguments to insert in the output.
+ *
+ * An implementation of the GNU vasprintf() function which supports 
+ * positional parameters, as specified in the Single Unix Specification.
+ * This function is similar to g_vsprintf(), except that it allocates a 
+ * string to hold the output, instead of putting the output in a buffer 
+ * you allocate in advance.
+ *
+ * Returns: the number of bytes printed.
+ *
+ * Since: 2.4
+ **/
+gint 
+g_vasprintf (gchar      **string,
+            gchar const *format,
+            va_list      args)
+{
+  gint len;
+  g_return_val_if_fail (string != NULL, -1);
+
+#if !defined(HAVE_GOOD_PRINTF)
+
+  len = _g_gnulib_vasprintf (string, format, args);
+  if (len < 0)
+    *string = NULL;
+
+#elif defined (HAVE_VASPRINTF)
+
+  len = vasprintf (string, format, args);
+  if (len < 0)
+    *string = NULL;
+  else if (!g_mem_is_system_malloc ()) 
+    {
+      /* vasprintf returns malloc-allocated memory */
+      gchar *string1 = g_strndup (*string, len);
+      free (*string);
+      *string = string1;
+    }
+
+#else
+
+  {
+    va_list args2;
+
+    G_VA_COPY (args2, args);
+
+    *string = g_new (gchar, g_printf_string_upper_bound (format, args));
+
+    len = _g_vsprintf (*string, format, args2);
+    va_end (args2);
+  }
+#endif
+
+  return len;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gprintf.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gprintf.h
new file mode 100644 (file)
index 0000000..d96870f
--- /dev/null
@@ -0,0 +1,52 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997, 2002  Peter Mattis, Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_PRINTF_H__
+#define __G_PRINTF_H__
+
+#include <glib.h>
+#include <stdio.h>
+#include <stdarg.h>
+
+G_BEGIN_DECLS
+
+gint                  g_printf    (gchar const *format,
+                                   ...) G_GNUC_PRINTF (1, 2);
+gint                  g_fprintf   (FILE        *file,
+                                  gchar const *format,
+                                  ...) G_GNUC_PRINTF (2, 3);
+gint                  g_sprintf   (gchar       *string,
+                                  gchar const *format,
+                                  ...) G_GNUC_PRINTF (2, 3);
+
+gint                  g_vprintf   (gchar const *format,
+                                   va_list      args);
+gint                  g_vfprintf  (FILE        *file,
+                                  gchar const *format,
+                                  va_list      args);
+gint                  g_vsprintf  (gchar       *string,
+                                  gchar const *format,
+                                  va_list      args);
+gint                  g_vasprintf (gchar      **string,
+                                  gchar const *format,
+                                  va_list      args);
+
+G_END_DECLS
+
+#endif /* __G_PRINTF_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gprintfint.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gprintfint.h
new file mode 100644 (file)
index 0000000..0c975a1
--- /dev/null
@@ -0,0 +1,59 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 2002.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+#ifndef __G_PRINTFINT_H__
+#define __G_PRINTFINT_H__
+
+#ifdef HAVE_GOOD_PRINTF
+
+#define _g_printf    printf
+#define _g_fprintf   fprintf
+#define _g_sprintf   sprintf
+#define _g_snprintf  snprintf
+
+#define _g_vprintf   vprintf
+#define _g_vfprintf  vfprintf
+#define _g_vsprintf  vsprintf
+#define _g_vsnprintf vsnprintf
+
+#else
+
+#include "gnulib/printf.h"
+
+#define _g_printf    _g_gnulib_printf
+#define _g_fprintf   _g_gnulib_fprintf
+#define _g_sprintf   _g_gnulib_sprintf
+#define _g_snprintf  _g_gnulib_snprintf
+
+#define _g_vprintf   _g_gnulib_vprintf
+#define _g_vfprintf  _g_gnulib_vfprintf
+#define _g_vsprintf  _g_gnulib_vsprintf
+#define _g_vsnprintf _g_gnulib_vsnprintf
+
+#endif
+
+#endif /* __G_PRINTF_H__ */
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gqsort.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gqsort.c
new file mode 100644 (file)
index 0000000..f0acecf
--- /dev/null
@@ -0,0 +1,285 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1991, 1992, 1996, 1997,1999,2004 Free Software Foundation, Inc.
+ * Copyright (C) 2000 Eazel, Inc.
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * This file was originally part of the GNU C Library, and was modified to allow
+ * user data to be passed in to the sorting function.
+ *
+ * Written by Douglas C. Schmidt (schmidt@ics.uci.edu).
+ * Modified by Maciej Stachowiak (mjs@eazel.com)
+ *
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with GLib
+ * at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#include "config.h"
+
+#include <limits.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "gqsort.h"
+
+#include "gtestutils.h"
+
+/* Byte-wise swap two items of size SIZE. */
+#define SWAP(a, b, size)                                                     \
+  do                                                                         \
+    {                                                                        \
+      register size_t __size = (size);                                       \
+      register char *__a = (a), *__b = (b);                                  \
+      do                                                                     \
+       {                                                                     \
+         char __tmp = *__a;                                                  \
+         *__a++ = *__b;                                                      \
+         *__b++ = __tmp;                                                     \
+       } while (--__size > 0);                                               \
+    } while (0)
+
+/* Discontinue quicksort algorithm when partition gets below this size.
+   This particular magic number was chosen to work best on a Sun 4/260. */
+#define MAX_THRESH 4
+
+/* Stack node declarations used to store unfulfilled partition obligations. */
+typedef struct
+  {
+    char *lo;
+    char *hi;
+  } stack_node;
+
+/* The next 4 #defines implement a very fast in-line stack abstraction. */
+/* The stack needs log (total_elements) entries (we could even subtract
+   log(MAX_THRESH)).  Since total_elements has type size_t, we get as
+   upper bound for log (total_elements):
+   bits per byte (CHAR_BIT) * sizeof(size_t).  */
+#define STACK_SIZE     (CHAR_BIT * sizeof(size_t))
+#define PUSH(low, high)        ((void) ((top->lo = (low)), (top->hi = (high)), ++top))
+#define        POP(low, high)  ((void) (--top, (low = top->lo), (high = top->hi)))
+#define        STACK_NOT_EMPTY (stack < top)
+
+
+/* Order size using quicksort.  This implementation incorporates
+   four optimizations discussed in Sedgewick:
+
+   1. Non-recursive, using an explicit stack of pointer that store the
+      next array partition to sort.  To save time, this maximum amount
+      of space required to store an array of SIZE_MAX is allocated on the
+      stack.  Assuming a 32-bit (64 bit) integer for size_t, this needs
+      only 32 * sizeof(stack_node) == 256 bytes (for 64 bit: 1024 bytes).
+      Pretty cheap, actually.
+
+   2. Chose the pivot element using a median-of-three decision tree.
+      This reduces the probability of selecting a bad pivot value and
+      eliminates certain extraneous comparisons.
+
+   3. Only quicksorts TOTAL_ELEMS / MAX_THRESH partitions, leaving
+      insertion sort to order the MAX_THRESH items within each partition.
+      This is a big win, since insertion sort is faster for small, mostly
+      sorted array segments.
+
+   4. The larger of the two sub-partitions is always pushed onto the
+      stack first, with the algorithm then concentrating on the
+      smaller partition.  This *guarantees* no more than log (total_elems)
+      stack size is needed (actually O(1) in this case)!  */
+
+/**
+ * g_qsort_with_data:
+ * @pbase: start of array to sort
+ * @total_elems: elements in the array
+ * @size: size of each element
+ * @compare_func: function to compare elements
+ * @user_data: data to pass to @compare_func
+ *
+ * This is just like the standard C qsort() function, but
+ * the comparison routine accepts a user data argument.
+ * 
+ **/
+void
+g_qsort_with_data (gconstpointer    pbase,
+                  gint             total_elems,
+                  gsize            size,
+                  GCompareDataFunc compare_func,
+                  gpointer         user_data)
+{
+  register char *base_ptr = (char *) pbase;
+
+  const size_t max_thresh = MAX_THRESH * size;
+
+  g_return_if_fail (total_elems >= 0);
+  g_return_if_fail (pbase != NULL || total_elems == 0);
+  g_return_if_fail (compare_func != NULL);
+
+  if (total_elems == 0)
+    /* Avoid lossage with unsigned arithmetic below.  */
+    return;
+
+  if (total_elems > MAX_THRESH)
+    {
+      char *lo = base_ptr;
+      char *hi = &lo[size * (total_elems - 1)];
+      stack_node stack[STACK_SIZE];
+      stack_node *top = stack;
+
+      PUSH (NULL, NULL);
+
+      while (STACK_NOT_EMPTY)
+        {
+          char *left_ptr;
+          char *right_ptr;
+
+         /* Select median value from among LO, MID, and HI. Rearrange
+            LO and HI so the three values are sorted. This lowers the
+            probability of picking a pathological pivot value and
+            skips a comparison for both the LEFT_PTR and RIGHT_PTR in
+            the while loops. */
+
+         char *mid = lo + size * ((hi - lo) / size >> 1);
+
+         if ((*compare_func) ((void *) mid, (void *) lo, user_data) < 0)
+           SWAP (mid, lo, size);
+         if ((*compare_func) ((void *) hi, (void *) mid, user_data) < 0)
+           SWAP (mid, hi, size);
+         else
+           goto jump_over;
+         if ((*compare_func) ((void *) mid, (void *) lo, user_data) < 0)
+           SWAP (mid, lo, size);
+       jump_over:;
+
+         left_ptr  = lo + size;
+         right_ptr = hi - size;
+
+         /* Here's the famous ``collapse the walls'' section of quicksort.
+            Gotta like those tight inner loops!  They are the main reason
+            that this algorithm runs much faster than others. */
+         do
+           {
+             while ((*compare_func) ((void *) left_ptr, (void *) mid, user_data) < 0)
+               left_ptr += size;
+
+             while ((*compare_func) ((void *) mid, (void *) right_ptr, user_data) < 0)
+               right_ptr -= size;
+
+             if (left_ptr < right_ptr)
+               {
+                 SWAP (left_ptr, right_ptr, size);
+                 if (mid == left_ptr)
+                   mid = right_ptr;
+                 else if (mid == right_ptr)
+                   mid = left_ptr;
+                 left_ptr += size;
+                 right_ptr -= size;
+               }
+             else if (left_ptr == right_ptr)
+               {
+                 left_ptr += size;
+                 right_ptr -= size;
+                 break;
+               }
+           }
+         while (left_ptr <= right_ptr);
+
+          /* Set up pointers for next iteration.  First determine whether
+             left and right partitions are below the threshold size.  If so,
+             ignore one or both.  Otherwise, push the larger partition's
+             bounds on the stack and continue sorting the smaller one. */
+
+          if ((size_t) (right_ptr - lo) <= max_thresh)
+            {
+              if ((size_t) (hi - left_ptr) <= max_thresh)
+               /* Ignore both small partitions. */
+                POP (lo, hi);
+              else
+               /* Ignore small left partition. */
+                lo = left_ptr;
+            }
+          else if ((size_t) (hi - left_ptr) <= max_thresh)
+           /* Ignore small right partition. */
+            hi = right_ptr;
+          else if ((right_ptr - lo) > (hi - left_ptr))
+            {
+             /* Push larger left partition indices. */
+              PUSH (lo, right_ptr);
+              lo = left_ptr;
+            }
+          else
+            {
+             /* Push larger right partition indices. */
+              PUSH (left_ptr, hi);
+              hi = right_ptr;
+            }
+        }
+    }
+
+  /* Once the BASE_PTR array is partially sorted by quicksort the rest
+     is completely sorted using insertion sort, since this is efficient
+     for partitions below MAX_THRESH size. BASE_PTR points to the beginning
+     of the array to sort, and END_PTR points at the very last element in
+     the array (*not* one beyond it!). */
+
+#define min(x, y) ((x) < (y) ? (x) : (y))
+
+  {
+    char *const end_ptr = &base_ptr[size * (total_elems - 1)];
+    char *tmp_ptr = base_ptr;
+    char *thresh = min(end_ptr, base_ptr + max_thresh);
+    register char *run_ptr;
+
+    /* Find smallest element in first threshold and place it at the
+       array's beginning.  This is the smallest array element,
+       and the operation speeds up insertion sort's inner loop. */
+
+    for (run_ptr = tmp_ptr + size; run_ptr <= thresh; run_ptr += size)
+      if ((*compare_func) ((void *) run_ptr, (void *) tmp_ptr, user_data) < 0)
+        tmp_ptr = run_ptr;
+
+    if (tmp_ptr != base_ptr)
+      SWAP (tmp_ptr, base_ptr, size);
+
+    /* Insertion sort, running from left-hand-side up to right-hand-side.  */
+
+    run_ptr = base_ptr + size;
+    while ((run_ptr += size) <= end_ptr)
+      {
+       tmp_ptr = run_ptr - size;
+       while ((*compare_func) ((void *) run_ptr, (void *) tmp_ptr, user_data) < 0)
+         tmp_ptr -= size;
+
+       tmp_ptr += size;
+        if (tmp_ptr != run_ptr)
+          {
+            char *trav;
+
+           trav = run_ptr + size;
+           while (--trav >= run_ptr)
+              {
+                char c = *trav;
+                char *hi, *lo;
+
+                for (hi = lo = trav; (lo -= size) >= tmp_ptr; hi = lo)
+                  *hi = *lo;
+                *hi = c;
+              }
+          }
+      }
+  }
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gqsort.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gqsort.h
new file mode 100644 (file)
index 0000000..3a47a58
--- /dev/null
@@ -0,0 +1,46 @@
+ /* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_QSORT_H__
+#define __G_QSORT_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+void g_qsort_with_data (gconstpointer    pbase,
+                       gint             total_elems,
+                       gsize            size,
+                       GCompareDataFunc compare_func,
+                       gpointer         user_data);
+
+G_END_DECLS
+
+#endif /* __G_QSORT_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gquark.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gquark.h
new file mode 100644 (file)
index 0000000..a0cbe2f
--- /dev/null
@@ -0,0 +1,52 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_QUARK_H__
+#define __G_QUARK_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+typedef guint32 GQuark;
+
+/* Quarks (string<->id association)
+ */
+GQuark                g_quark_try_string         (const gchar *string);
+GQuark                g_quark_from_static_string (const gchar *string);
+GQuark                g_quark_from_string        (const gchar *string);
+G_CONST_RETURN gchar* g_quark_to_string          (GQuark       quark) G_GNUC_CONST;
+
+G_CONST_RETURN gchar* g_intern_string            (const gchar *string);
+G_CONST_RETURN gchar* g_intern_static_string     (const gchar *string);
+
+G_END_DECLS
+
+#endif /* __G_QUARK_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gqueue.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gqueue.c
new file mode 100644 (file)
index 0000000..5e5535e
--- /dev/null
@@ -0,0 +1,1011 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * GQueue: Double ended queue implementation, piggy backed on GList.
+ * Copyright (C) 1998 Tim Janik
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "gqueue.h"
+
+#include "gtestutils.h"
+
+/**
+ * g_queue_new:
+ *
+ * Creates a new #GQueue.
+ *
+ * Returns: a new #GQueue.
+ **/
+GQueue*
+g_queue_new (void)
+{
+  return g_slice_new0 (GQueue);
+}
+
+/**
+ * g_queue_free:
+ * @queue: a #GQueue.
+ *
+ * Frees the memory allocated for the #GQueue. Only call this function if
+ * @queue was created with g_queue_new(). If queue elements contain
+ * dynamically-allocated memory, they should be freed first.
+ **/
+void
+g_queue_free (GQueue *queue)
+{
+  g_return_if_fail (queue != NULL);
+
+  g_list_free (queue->head);
+  g_slice_free (GQueue, queue);
+}
+
+/**
+ * g_queue_init:
+ * @queue: an uninitialized #GQueue
+ *
+ * A statically-allocated #GQueue must be initialized with this function
+ * before it can be used. Alternatively you can initialize it with
+ * #G_QUEUE_INIT. It is not necessary to initialize queues created with
+ * g_queue_new().
+ *
+ * Since: 2.14
+ **/
+void
+g_queue_init (GQueue *queue)
+{
+  g_return_if_fail (queue != NULL);
+
+  queue->head = queue->tail = NULL;
+  queue->length = 0;
+}
+
+/**
+ * g_queue_clear:
+ * @queue: a #GQueue
+ *
+ * Removes all the elements in @queue. If queue elements contain
+ * dynamically-allocated memory, they should be freed first.
+ *
+ * Since: 2.14
+ */
+void
+g_queue_clear (GQueue *queue)
+{
+  g_return_if_fail (queue != NULL);
+
+  g_list_free (queue->head);
+  g_queue_init (queue);
+}
+
+/**
+ * g_queue_is_empty:
+ * @queue: a #GQueue.
+ *
+ * Returns %TRUE if the queue is empty.
+ *
+ * Returns: %TRUE if the queue is empty.
+ **/
+gboolean
+g_queue_is_empty (GQueue *queue)
+{
+  g_return_val_if_fail (queue != NULL, TRUE);
+
+  return queue->head == NULL;
+}
+
+/**
+ * g_queue_get_length:
+ * @queue: a #GQueue
+ * 
+ * Returns the number of items in @queue.
+ * 
+ * Return value: The number of items in @queue.
+ * 
+ * Since: 2.4
+ **/
+guint
+g_queue_get_length (GQueue *queue)
+{
+  g_return_val_if_fail (queue != NULL, 0);
+
+  return queue->length;
+}
+
+/**
+ * g_queue_reverse:
+ * @queue: a #GQueue
+ * 
+ * Reverses the order of the items in @queue.
+ * 
+ * Since: 2.4
+ **/
+void
+g_queue_reverse (GQueue *queue)
+{
+  g_return_if_fail (queue != NULL);
+
+  queue->tail = queue->head;
+  queue->head = g_list_reverse (queue->head);
+}
+
+/**
+ * g_queue_copy:
+ * @queue: a #GQueue
+ * 
+ * Copies a @queue. Note that is a shallow copy. If the elements in the
+ * queue consist of pointers to data, the pointers are copied, but the
+ * actual data is not.
+ * 
+ * Return value: A copy of @queue
+ * 
+ * Since: 2.4
+ **/
+GQueue *
+g_queue_copy (GQueue *queue)
+{
+  GQueue *result;
+  GList *list;
+
+  g_return_val_if_fail (queue != NULL, NULL);
+
+  result = g_queue_new ();
+
+  for (list = queue->head; list != NULL; list = list->next)
+    g_queue_push_tail (result, list->data);
+
+  return result;
+}
+
+/**
+ * g_queue_foreach:
+ * @queue: a #GQueue
+ * @func: the function to call for each element's data
+ * @user_data: user data to pass to @func
+ * 
+ * Calls @func for each element in the queue passing @user_data to the
+ * function.
+ * 
+ * Since: 2.4
+ **/
+void
+g_queue_foreach (GQueue   *queue,
+                GFunc     func,
+                gpointer  user_data)
+{
+  GList *list;
+
+  g_return_if_fail (queue != NULL);
+  g_return_if_fail (func != NULL);
+  
+  list = queue->head;
+  while (list)
+    {
+      GList *next = list->next;
+      func (list->data, user_data);
+      list = next;
+    }
+}
+
+/**
+ * g_queue_find:
+ * @queue: a #GQueue
+ * @data: data to find
+ * 
+ * Finds the first link in @queue which contains @data.
+ * 
+ * Return value: The first link in @queue which contains @data.
+ * 
+ * Since: 2.4
+ **/
+GList *
+g_queue_find (GQueue        *queue,
+             gconstpointer  data)
+{
+  g_return_val_if_fail (queue != NULL, NULL);
+
+  return g_list_find (queue->head, data);
+}
+
+/**
+ * g_queue_find_custom:
+ * @queue: a #GQueue
+ * @data: user data passed to @func
+ * @func: a #GCompareFunc to call for each element. It should return 0
+ * when the desired element is found
+ *
+ * Finds an element in a #GQueue, using a supplied function to find the
+ * desired element. It iterates over the queue, calling the given function
+ * which should return 0 when the desired element is found. The function
+ * takes two gconstpointer arguments, the #GQueue element's data as the
+ * first argument and the given user data as the second argument.
+ * 
+ * Return value: The found link, or %NULL if it wasn't found
+ * 
+ * Since: 2.4
+ **/
+GList *
+g_queue_find_custom    (GQueue        *queue,
+                       gconstpointer  data,
+                       GCompareFunc   func)
+{
+  g_return_val_if_fail (queue != NULL, NULL);
+  g_return_val_if_fail (func != NULL, NULL);
+
+  return g_list_find_custom (queue->head, data, func);
+}
+
+/**
+ * g_queue_sort:
+ * @queue: a #GQueue
+ * @compare_func: the #GCompareDataFunc used to sort @queue. This function
+ *     is passed two elements of the queue and should return 0 if they are
+ *     equal, a negative value if the first comes before the second, and
+ *     a positive value if the second comes before the first.
+ * @user_data: user data passed to @compare_func
+ * 
+ * Sorts @queue using @compare_func. 
+ * 
+ * Since: 2.4
+ **/
+void
+g_queue_sort (GQueue           *queue,
+             GCompareDataFunc  compare_func,
+             gpointer          user_data)
+{
+  g_return_if_fail (queue != NULL);
+  g_return_if_fail (compare_func != NULL);
+
+  queue->head = g_list_sort_with_data (queue->head, compare_func, user_data);
+  queue->tail = g_list_last (queue->head);
+}
+
+/**
+ * g_queue_push_head:
+ * @queue: a #GQueue.
+ * @data: the data for the new element.
+ *
+ * Adds a new element at the head of the queue.
+ **/
+void
+g_queue_push_head (GQueue  *queue,
+                  gpointer data)
+{
+  g_return_if_fail (queue != NULL);
+
+  queue->head = g_list_prepend (queue->head, data);
+  if (!queue->tail)
+    queue->tail = queue->head;
+  queue->length++;
+}
+
+/**
+ * g_queue_push_nth:
+ * @queue: a #GQueue
+ * @data: the data for the new element
+ * @n: the position to insert the new element. If @n is negative or
+ *     larger than the number of elements in the @queue, the element is
+ *     added to the end of the queue.
+ * 
+ * Inserts a new element into @queue at the given position
+ * 
+ * Since: 2.4
+ **/
+void
+g_queue_push_nth (GQueue   *queue,
+                 gpointer  data,
+                 gint      n)
+{
+  g_return_if_fail (queue != NULL);
+
+  if (n < 0 || n >= queue->length)
+    {
+      g_queue_push_tail (queue, data);
+      return;
+    }
+
+  g_queue_insert_before (queue, g_queue_peek_nth_link (queue, n), data);
+}
+
+/**
+ * g_queue_push_head_link:
+ * @queue: a #GQueue.
+ * @link_: a single #GList element, <emphasis>not</emphasis> a list with
+ *     more than one element.
+ *
+ * Adds a new element at the head of the queue.
+ **/
+void
+g_queue_push_head_link (GQueue *queue,
+                       GList  *link)
+{
+  g_return_if_fail (queue != NULL);
+  g_return_if_fail (link != NULL);
+  g_return_if_fail (link->prev == NULL);
+  g_return_if_fail (link->next == NULL);
+
+  link->next = queue->head;
+  if (queue->head)
+    queue->head->prev = link;
+  else
+    queue->tail = link;
+  queue->head = link;
+  queue->length++;
+}
+
+/**
+ * g_queue_push_tail:
+ * @queue: a #GQueue.
+ * @data: the data for the new element.
+ *
+ * Adds a new element at the tail of the queue.
+ **/
+void
+g_queue_push_tail (GQueue  *queue,
+                  gpointer data)
+{
+  g_return_if_fail (queue != NULL);
+
+  queue->tail = g_list_append (queue->tail, data);
+  if (queue->tail->next)
+    queue->tail = queue->tail->next;
+  else
+    queue->head = queue->tail;
+  queue->length++;
+}
+
+/**
+ * g_queue_push_tail_link:
+ * @queue: a #GQueue.
+ * @link_: a single #GList element, <emphasis>not</emphasis> a list with
+ *   more than one element.
+ *
+ * Adds a new element at the tail of the queue.
+ **/
+void
+g_queue_push_tail_link (GQueue *queue,
+                       GList  *link)
+{
+  g_return_if_fail (queue != NULL);
+  g_return_if_fail (link != NULL);
+  g_return_if_fail (link->prev == NULL);
+  g_return_if_fail (link->next == NULL);
+
+  link->prev = queue->tail;
+  if (queue->tail)
+    queue->tail->next = link;
+  else
+    queue->head = link;
+  queue->tail = link;
+  queue->length++;
+}
+
+/**
+ * g_queue_push_nth_link:
+ * @queue: a #GQueue
+ * @n: the position to insert the link. If this is negative or larger than
+ *     the number of elements in @queue, the link is added to the end of
+ *     @queue.
+ * @link_: the link to add to @queue
+ * 
+ * Inserts @link into @queue at the given position.
+ * 
+ * Since: 2.4
+ **/
+void
+g_queue_push_nth_link  (GQueue  *queue,
+                       gint     n,
+                       GList   *link_)
+{
+  GList *next;
+  GList *prev;
+  
+  g_return_if_fail (queue != NULL);
+  g_return_if_fail (link_ != NULL);
+
+  if (n < 0 || n >= queue->length)
+    {
+      g_queue_push_tail_link (queue, link_);
+      return;
+    }
+
+  g_assert (queue->head);
+  g_assert (queue->tail);
+
+  next = g_queue_peek_nth_link (queue, n);
+  prev = next->prev;
+
+  if (prev)
+    prev->next = link_;
+  next->prev = link_;
+
+  link_->next = next;
+  link_->prev = prev;
+
+  if (queue->head->prev)
+    queue->head = queue->head->prev;
+
+  if (queue->tail->next)
+    queue->tail = queue->tail->next;
+  
+  queue->length++;
+}
+
+/**
+ * g_queue_pop_head:
+ * @queue: a #GQueue.
+ *
+ * Removes the first element of the queue.
+ *
+ * Returns: the data of the first element in the queue, or %NULL if the queue
+ *   is empty.
+ **/
+gpointer
+g_queue_pop_head (GQueue *queue)
+{
+  g_return_val_if_fail (queue != NULL, NULL);
+
+  if (queue->head)
+    {
+      GList *node = queue->head;
+      gpointer data = node->data;
+
+      queue->head = node->next;
+      if (queue->head)
+       queue->head->prev = NULL;
+      else
+       queue->tail = NULL;
+      g_list_free_1 (node);
+      queue->length--;
+
+      return data;
+    }
+
+  return NULL;
+}
+
+/**
+ * g_queue_pop_head_link:
+ * @queue: a #GQueue.
+ *
+ * Removes the first element of the queue.
+ *
+ * Returns: the #GList element at the head of the queue, or %NULL if the queue
+ *   is empty.
+ **/
+GList*
+g_queue_pop_head_link (GQueue *queue)
+{
+  g_return_val_if_fail (queue != NULL, NULL);
+
+  if (queue->head)
+    {
+      GList *node = queue->head;
+
+      queue->head = node->next;
+      if (queue->head)
+       {
+         queue->head->prev = NULL;
+         node->next = NULL;
+       }
+      else
+       queue->tail = NULL;
+      queue->length--;
+
+      return node;
+    }
+
+  return NULL;
+}
+
+/**
+ * g_queue_peek_head_link:
+ * @queue: a #GQueue
+ * 
+ * Returns the first link in @queue
+ * 
+ * Return value: the first link in @queue, or %NULL if @queue is empty
+ * 
+ * Since: 2.4
+ **/
+GList*
+g_queue_peek_head_link (GQueue *queue)
+{
+  g_return_val_if_fail (queue != NULL, NULL);
+
+  return queue->head;
+}
+
+/**
+ * g_queue_peek_tail_link:
+ * @queue: a #GQueue
+ * 
+ * Returns the last link @queue.
+ * 
+ * Return value: the last link in @queue, or %NULL if @queue is empty
+ * 
+ * Since: 2.4
+ **/
+GList*
+g_queue_peek_tail_link (GQueue *queue)
+{
+  g_return_val_if_fail (queue != NULL, NULL);
+
+  return queue->tail;
+}
+
+/**
+ * g_queue_pop_tail:
+ * @queue: a #GQueue.
+ *
+ * Removes the last element of the queue.
+ *
+ * Returns: the data of the last element in the queue, or %NULL if the queue
+ *   is empty.
+ **/
+gpointer
+g_queue_pop_tail (GQueue *queue)
+{
+  g_return_val_if_fail (queue != NULL, NULL);
+
+  if (queue->tail)
+    {
+      GList *node = queue->tail;
+      gpointer data = node->data;
+
+      queue->tail = node->prev;
+      if (queue->tail)
+       queue->tail->next = NULL;
+      else
+       queue->head = NULL;
+      queue->length--;
+      g_list_free_1 (node);
+
+      return data;
+    }
+  
+  return NULL;
+}
+
+/**
+ * g_queue_pop_nth:
+ * @queue: a #GQueue
+ * @n: the position of the element.
+ * 
+ * Removes the @n'th element of @queue.
+ * 
+ * Return value: the element's data, or %NULL if @n is off the end of @queue.
+ * 
+ * Since: 2.4
+ **/
+gpointer
+g_queue_pop_nth (GQueue *queue,
+                guint   n)
+{
+  GList *nth_link;
+  gpointer result;
+  
+  g_return_val_if_fail (queue != NULL, NULL);
+
+  if (n >= queue->length)
+    return NULL;
+  
+  nth_link = g_queue_peek_nth_link (queue, n);
+  result = nth_link->data;
+
+  g_queue_delete_link (queue, nth_link);
+
+  return result;
+}
+
+/**
+ * g_queue_pop_tail_link:
+ * @queue: a #GQueue.
+ *
+ * Removes the last element of the queue.
+ *
+ * Returns: the #GList element at the tail of the queue, or %NULL if the queue
+ *   is empty.
+ **/
+GList*
+g_queue_pop_tail_link (GQueue *queue)
+{
+  g_return_val_if_fail (queue != NULL, NULL);
+  
+  if (queue->tail)
+    {
+      GList *node = queue->tail;
+      
+      queue->tail = node->prev;
+      if (queue->tail)
+       {
+         queue->tail->next = NULL;
+         node->prev = NULL;
+       }
+      else
+       queue->head = NULL;
+      queue->length--;
+      
+      return node;
+    }
+  
+  return NULL;
+}
+
+/**
+ * g_queue_pop_nth_link:
+ * @queue: a #GQueue
+ * @n: the link's position
+ * 
+ * Removes and returns the link at the given position.
+ * 
+ * Return value: The @n'th link, or %NULL if @n is off the end of @queue.
+ * 
+ * Since: 2.4
+ **/
+GList*
+g_queue_pop_nth_link (GQueue *queue,
+                     guint   n)
+{
+  GList *link;
+  
+  g_return_val_if_fail (queue != NULL, NULL);
+
+  if (n >= queue->length)
+    return NULL;
+  
+  link = g_queue_peek_nth_link (queue, n);
+  g_queue_unlink (queue, link);
+
+  return link;
+}
+
+/**
+ * g_queue_peek_nth_link:
+ * @queue: a #GQueue
+ * @n: the position of the link
+ * 
+ * Returns the link at the given position
+ * 
+ * Return value: The link at the @n'th position, or %NULL if @n is off the
+ * end of the list
+ * 
+ * Since: 2.4
+ **/
+GList *
+g_queue_peek_nth_link (GQueue *queue,
+                      guint   n)
+{
+  GList *link;
+  gint i;
+  
+  g_return_val_if_fail (queue != NULL, NULL);
+
+  if (n >= queue->length)
+    return NULL;
+  
+  if (n > queue->length / 2)
+    {
+      n = queue->length - n - 1;
+
+      link = queue->tail;
+      for (i = 0; i < n; ++i)
+       link = link->prev;
+    }
+  else
+    {
+      link = queue->head;
+      for (i = 0; i < n; ++i)
+       link = link->next;
+    }
+
+  return link;
+}
+
+/**
+ * g_queue_link_index:
+ * @queue: a #Gqueue
+ * @link_: A #GList link
+ * 
+ * Returns the position of @link_ in @queue.
+ * 
+ * Return value: The position of @link_, or -1 if the link is
+ * not part of @queue
+ * 
+ * Since: 2.4
+ **/
+gint
+g_queue_link_index (GQueue *queue,
+                   GList  *link_)
+{
+  g_return_val_if_fail (queue != NULL, -1);
+
+  return g_list_position (queue->head, link_);
+}
+
+/**
+ * g_queue_unlink
+ * @queue: a #GQueue
+ * @link_: a #GList link that <emphasis>must</emphasis> be part of @queue
+ *
+ * Unlinks @link_ so that it will no longer be part of @queue. The link is
+ * not freed.
+ *
+ * @link_ must be part of @queue,
+ * 
+ * Since: 2.4
+ **/
+void
+g_queue_unlink (GQueue *queue,
+               GList  *link_)
+{
+  g_return_if_fail (queue != NULL);
+  g_return_if_fail (link_ != NULL);
+
+  if (link_ == queue->tail)
+    queue->tail = queue->tail->prev;
+  
+  queue->head = g_list_remove_link (queue->head, link_);
+  queue->length--;
+}
+
+/**
+ * g_queue_delete_link:
+ * @queue: a #GQueue
+ * @link_: a #GList link that <emphasis>must</emphasis> be part of @queue
+ *
+ * Removes @link_ from @queue and frees it.
+ *
+ * @link_ must be part of @queue.
+ * 
+ * Since: 2.4
+ **/
+void
+g_queue_delete_link (GQueue *queue,
+                    GList  *link_)
+{
+  g_return_if_fail (queue != NULL);
+  g_return_if_fail (link_ != NULL);
+
+  g_queue_unlink (queue, link_);
+  g_list_free (link_);
+}
+
+/**
+ * g_queue_peek_head:
+ * @queue: a #GQueue.
+ *
+ * Returns the first element of the queue.
+ *
+ * Returns: the data of the first element in the queue, or %NULL if the queue
+ *   is empty.
+ **/
+gpointer
+g_queue_peek_head (GQueue *queue)
+{
+  g_return_val_if_fail (queue != NULL, NULL);
+
+  return queue->head ? queue->head->data : NULL;
+}
+
+/**
+ * g_queue_peek_tail:
+ * @queue: a #GQueue.
+ *
+ * Returns the last element of the queue.
+ *
+ * Returns: the data of the last element in the queue, or %NULL if the queue
+ *   is empty.
+ **/
+gpointer
+g_queue_peek_tail (GQueue *queue)
+{
+  g_return_val_if_fail (queue != NULL, NULL);
+
+  return queue->tail ? queue->tail->data : NULL;
+}
+
+/**
+ * g_queue_peek_nth:
+ * @queue: a #GQueue
+ * @n: the position of the element.
+ * 
+ * Returns the @n'th element of @queue. 
+ * 
+ * Return value: The data for the @n'th element of @queue, or %NULL if @n is
+ *   off the end of @queue.
+ * 
+ * Since: 2.4
+ **/
+gpointer
+g_queue_peek_nth (GQueue *queue,
+                 guint   n)
+{
+  GList *link;
+  
+  g_return_val_if_fail (queue != NULL, NULL);
+
+  link = g_queue_peek_nth_link (queue, n);
+
+  if (link)
+    return link->data;
+
+  return NULL;
+}
+
+/**
+ * g_queue_index:
+ * @queue: a #GQueue
+ * @data: the data to find.
+ * 
+ * Returns the position of the first element in @queue which contains @data.
+ * 
+ * Return value: The position of the first element in @queue which contains @data, or -1 if no element in @queue contains @data.
+ * 
+ * Since: 2.4
+ **/
+gint
+g_queue_index (GQueue        *queue,
+              gconstpointer  data)
+{
+  g_return_val_if_fail (queue != NULL, -1);
+
+  return g_list_index (queue->head, data);
+}
+
+/**
+ * g_queue_remove:
+ * @queue: a #GQueue
+ * @data: data to remove.
+ * 
+ * Removes the first element in @queue that contains @data. 
+ * 
+ * Since: 2.4
+ **/
+void
+g_queue_remove (GQueue        *queue,
+               gconstpointer  data)
+{
+  GList *link;
+  
+  g_return_if_fail (queue != NULL);
+
+  link = g_list_find (queue->head, data);
+
+  if (link)
+    g_queue_delete_link (queue, link);
+}
+
+/**
+ * g_queue_remove_all:
+ * @queue: a #GQueue
+ * @data: data to remove
+ * 
+ * Remove all elemeents in @queue which contains @data.
+ * 
+ * Since: 2.4
+ **/
+void
+g_queue_remove_all (GQueue        *queue,
+                   gconstpointer  data)
+{
+  GList *list;
+  
+  g_return_if_fail (queue != NULL);
+
+  list = queue->head;
+  while (list)
+    {
+      GList *next = list->next;
+
+      if (list->data == data)
+       g_queue_delete_link (queue, list);
+      
+      list = next;
+    }
+}
+
+/**
+ * g_queue_insert_before:
+ * @queue: a #GQueue
+ * @sibling: a #GList link that <emphasis>must</emphasis> be part of @queue
+ * @data: the data to insert
+ * 
+ * Inserts @data into @queue before @sibling.
+ *
+ * @sibling must be part of @queue.
+ * 
+ * Since: 2.4
+ **/
+void
+g_queue_insert_before (GQueue   *queue,
+                      GList    *sibling,
+                      gpointer  data)
+{
+  g_return_if_fail (queue != NULL);
+  g_return_if_fail (sibling != NULL);
+
+  queue->head = g_list_insert_before (queue->head, sibling, data);
+  queue->length++;
+}
+
+/**
+ * g_queue_insert_after:
+ * @queue: a #GQueue
+ * @sibling: a #GList link that <emphasis>must</emphasis> be part of @queue
+ * @data: the data to insert
+ *
+ * Inserts @data into @queue after @sibling
+ *
+ * @sibling must be part of @queue
+ * 
+ * Since: 2.4
+ **/
+void
+g_queue_insert_after (GQueue   *queue,
+                     GList    *sibling,
+                     gpointer  data)
+{
+  g_return_if_fail (queue != NULL);
+  g_return_if_fail (sibling != NULL);
+
+  if (sibling == queue->tail)
+    g_queue_push_tail (queue, data);
+  else
+    g_queue_insert_before (queue, sibling->next, data);
+}
+
+/**
+ * g_queue_insert_sorted:
+ * @queue: a #GQueue
+ * @data: the data to insert
+ * @func: the #GCompareDataFunc used to compare elements in the queue. It is
+ *     called with two elements of the @queue and @user_data. It should
+ *     return 0 if the elements are equal, a negative value if the first
+ *     element comes before the second, and a positive value if the second
+ *     element comes before the first.
+ * @user_data: user data passed to @func.
+ * 
+ * Inserts @data into @queue using @func to determine the new position.
+ * 
+ * Since: 2.4
+ **/
+void
+g_queue_insert_sorted (GQueue           *queue,
+                      gpointer          data,
+                      GCompareDataFunc  func,
+                      gpointer          user_data)
+{
+  GList *list;
+  
+  g_return_if_fail (queue != NULL);
+
+  list = queue->head;
+  while (list && func (list->data, data, user_data) < 0)
+    list = list->next;
+
+  if (list)
+    g_queue_insert_before (queue, list, data);
+  else
+    g_queue_push_tail (queue, data);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gqueue.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gqueue.h
new file mode 100644 (file)
index 0000000..e78488f
--- /dev/null
@@ -0,0 +1,127 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_QUEUE_H__
+#define __G_QUEUE_H__
+
+#include <glib/glist.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GQueue         GQueue;
+
+struct _GQueue
+{
+  GList *head;
+  GList *tail;
+  guint  length;
+};
+
+#define G_QUEUE_INIT { NULL, NULL, 0 }
+
+/* Queues
+ */
+GQueue*  g_queue_new            (void);
+void     g_queue_free           (GQueue           *queue);
+void     g_queue_init           (GQueue           *queue);
+void     g_queue_clear          (GQueue           *queue);
+gboolean g_queue_is_empty       (GQueue           *queue);
+guint    g_queue_get_length     (GQueue           *queue);
+void     g_queue_reverse        (GQueue           *queue);
+GQueue * g_queue_copy           (GQueue           *queue);
+void     g_queue_foreach        (GQueue           *queue,
+                                GFunc             func,
+                                gpointer          user_data);
+GList *  g_queue_find           (GQueue           *queue,
+                                gconstpointer     data);
+GList *  g_queue_find_custom    (GQueue           *queue,
+                                gconstpointer     data,
+                                GCompareFunc      func);
+void     g_queue_sort           (GQueue           *queue,
+                                GCompareDataFunc  compare_func,
+                                gpointer          user_data);
+
+void     g_queue_push_head      (GQueue           *queue,
+                                gpointer          data);
+void     g_queue_push_tail      (GQueue           *queue,
+                                gpointer          data);
+void     g_queue_push_nth       (GQueue           *queue,
+                                gpointer          data,
+                                gint              n);
+gpointer g_queue_pop_head       (GQueue           *queue);
+gpointer g_queue_pop_tail       (GQueue           *queue);
+gpointer g_queue_pop_nth        (GQueue           *queue,
+                                guint             n);
+gpointer g_queue_peek_head      (GQueue           *queue);
+gpointer g_queue_peek_tail      (GQueue           *queue);
+gpointer g_queue_peek_nth       (GQueue           *queue,
+                                guint             n);
+gint     g_queue_index          (GQueue           *queue,
+                                gconstpointer     data);
+void     g_queue_remove         (GQueue           *queue,
+                                gconstpointer     data);
+void     g_queue_remove_all     (GQueue           *queue,
+                                gconstpointer     data);
+void     g_queue_insert_before  (GQueue           *queue,
+                                GList            *sibling,
+                                gpointer          data);
+void     g_queue_insert_after   (GQueue           *queue,
+                                GList            *sibling,
+                                gpointer          data);
+void     g_queue_insert_sorted  (GQueue           *queue,
+                                gpointer          data,
+                                GCompareDataFunc  func,
+                                gpointer          user_data);
+
+void     g_queue_push_head_link (GQueue           *queue,
+                                GList            *link_);
+void     g_queue_push_tail_link (GQueue           *queue,
+                                GList            *link_);
+void     g_queue_push_nth_link  (GQueue           *queue,
+                                gint              n,
+                                GList            *link_);
+GList*   g_queue_pop_head_link  (GQueue           *queue);
+GList*   g_queue_pop_tail_link  (GQueue           *queue);
+GList*   g_queue_pop_nth_link   (GQueue           *queue,
+                                guint             n);
+GList*   g_queue_peek_head_link (GQueue           *queue);
+GList*   g_queue_peek_tail_link (GQueue           *queue);
+GList*   g_queue_peek_nth_link  (GQueue           *queue,
+                                guint             n);
+gint     g_queue_link_index     (GQueue           *queue,
+                                GList            *link_);
+void     g_queue_unlink         (GQueue           *queue,
+                                GList            *link_);
+void     g_queue_delete_link    (GQueue           *queue,
+                                GList            *link_);
+
+G_END_DECLS
+
+#endif /* __G_QUEUE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/grand.c b/resource/csdk/connectivity/lib/android/glib-master/glib/grand.c
new file mode 100644 (file)
index 0000000..a70ce7b
--- /dev/null
@@ -0,0 +1,700 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* Originally developed and coded by Makoto Matsumoto and Takuji
+ * Nishimura.  Please mail <matumoto@math.keio.ac.jp>, if you're using
+ * code from this file in your own programs or libraries.
+ * Further information on the Mersenne Twister can be found at
+ * http://www.math.sci.hiroshima-u.ac.jp/~m-mat/MT/emt.html
+ * This code was adapted to glib by Sebastian Wilhelmi.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include <math.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#include "grand.h"
+
+#include "gmain.h"
+#include "gmem.h"
+#include "gtestutils.h"
+#include "gthread.h"
+#include "gthreadprivate.h"
+
+#ifdef G_OS_WIN32
+#include <process.h>           /* For getpid() */
+#endif
+
+/**
+ * SECTION: random_numbers
+ * @title: Random Numbers
+ * @short_description: pseudo-random number generator
+ *
+ * The following functions allow you to use a portable, fast and good
+ * pseudo-random number generator (PRNG). It uses the Mersenne Twister
+ * PRNG, which was originally developed by Makoto Matsumoto and Takuji
+ * Nishimura. Further information can be found at
+ * <ulink url="http://www.math.keio.ac.jp/~matumoto/emt.html">
+ * www.math.keio.ac.jp/~matumoto/emt.html</ulink>.
+ *
+ * If you just need a random number, you simply call the
+ * <function>g_random_*</function> functions, which will create a
+ * globally used #GRand and use the according
+ * <function>g_rand_*</function> functions internally. Whenever you
+ * need a stream of reproducible random numbers, you better create a
+ * #GRand yourself and use the <function>g_rand_*</function> functions
+ * directly, which will also be slightly faster. Initializing a #GRand
+ * with a certain seed will produce exactly the same series of random
+ * numbers on all platforms. This can thus be used as a seed for e.g.
+ * games.
+ *
+ * The <function>g_rand*_range</function> functions will return high
+ * quality equally distributed random numbers, whereas for example the
+ * <literal>(g_random_int()&percnt;max)</literal> approach often
+ * doesn't yield equally distributed numbers.
+ *
+ * GLib changed the seeding algorithm for the pseudo-random number
+ * generator Mersenne Twister, as used by
+ * <structname>GRand</structname> and <structname>GRandom</structname>.
+ * This was necessary, because some seeds would yield very bad
+ * pseudo-random streams.  Also the pseudo-random integers generated by
+ * <function>g_rand*_int_range()</function> will have a slightly better
+ * equal distribution with the new version of GLib.
+ *
+ * The original seeding and generation algorithms, as found in GLib
+ * 2.0.x, can be used instead of the new ones by setting the
+ * environment variable <envar>G_RANDOM_VERSION</envar> to the value of
+ * '2.0'. Use the GLib-2.0 algorithms only if you have sequences of
+ * numbers generated with Glib-2.0 that you need to reproduce exactly.
+ **/
+
+/**
+ * GRand:
+ *
+ * The #GRand struct is an opaque data structure. It should only be
+ * accessed through the <function>g_rand_*</function> functions.
+ **/
+
+G_LOCK_DEFINE_STATIC (global_random);
+static GRand* global_random = NULL;
+
+/* Period parameters */  
+#define N 624
+#define M 397
+#define MATRIX_A 0x9908b0df   /* constant vector a */
+#define UPPER_MASK 0x80000000 /* most significant w-r bits */
+#define LOWER_MASK 0x7fffffff /* least significant r bits */
+
+/* Tempering parameters */   
+#define TEMPERING_MASK_B 0x9d2c5680
+#define TEMPERING_MASK_C 0xefc60000
+#define TEMPERING_SHIFT_U(y)  (y >> 11)
+#define TEMPERING_SHIFT_S(y)  (y << 7)
+#define TEMPERING_SHIFT_T(y)  (y << 15)
+#define TEMPERING_SHIFT_L(y)  (y >> 18)
+
+static guint
+get_random_version (void)
+{
+  static gboolean initialized = FALSE;
+  static guint random_version;
+  
+  if (!initialized)
+    {
+      const gchar *version_string = g_getenv ("G_RANDOM_VERSION");
+      if (!version_string || version_string[0] == '\000' || 
+         strcmp (version_string, "2.2") == 0)
+       random_version = 22;
+      else if (strcmp (version_string, "2.0") == 0)
+       random_version = 20;
+      else
+       {
+         g_warning ("Unknown G_RANDOM_VERSION \"%s\". Using version 2.2.",
+                    version_string);
+         random_version = 22;
+       }
+      initialized = TRUE;
+    }
+  
+  return random_version;
+}
+
+/* This is called from g_thread_init(). It's used to
+ * initialize some static data in a threadsafe way.
+ */
+void 
+_g_rand_thread_init (void)
+{
+  (void)get_random_version ();
+}
+
+struct _GRand
+{
+  guint32 mt[N]; /* the array for the state vector  */
+  guint mti; 
+};
+
+/**
+ * g_rand_new_with_seed:
+ * @seed: a value to initialize the random number generator.
+ * 
+ * Creates a new random number generator initialized with @seed.
+ * 
+ * Return value: the new #GRand.
+ **/
+GRand*
+g_rand_new_with_seed (guint32 seed)
+{
+  GRand *rand = g_new0 (GRand, 1);
+  g_rand_set_seed (rand, seed);
+  return rand;
+}
+
+/**
+ * g_rand_new_with_seed_array:
+ * @seed: an array of seeds to initialize the random number generator.
+ * @seed_length: an array of seeds to initialize the random number generator.
+ * 
+ * Creates a new random number generator initialized with @seed.
+ * 
+ * Return value: the new #GRand.
+ *
+ * Since: 2.4
+ **/
+GRand*
+g_rand_new_with_seed_array (const guint32 *seed, guint seed_length)
+{
+  GRand *rand = g_new0 (GRand, 1);
+  g_rand_set_seed_array (rand, seed, seed_length);
+  return rand;
+}
+
+/**
+ * g_rand_new:
+ * 
+ * Creates a new random number generator initialized with a seed taken
+ * either from <filename>/dev/urandom</filename> (if existing) or from 
+ * the current time (as a fallback).
+ * 
+ * Return value: the new #GRand.
+ **/
+GRand* 
+g_rand_new (void)
+{
+  guint32 seed[4];
+  GTimeVal now;
+#ifdef G_OS_UNIX
+  static gboolean dev_urandom_exists = TRUE;
+
+  if (dev_urandom_exists)
+    {
+      FILE* dev_urandom;
+
+      do
+        {
+         errno = 0;
+         dev_urandom = fopen("/dev/urandom", "rb");
+       }
+      while G_UNLIKELY (errno == EINTR);
+
+      if (dev_urandom)
+       {
+         int r;
+
+         setvbuf (dev_urandom, NULL, _IONBF, 0);
+         do
+           {
+             errno = 0;
+             r = fread (seed, sizeof (seed), 1, dev_urandom);
+           }
+         while G_UNLIKELY (errno == EINTR);
+
+         if (r != 1)
+           dev_urandom_exists = FALSE;
+
+         fclose (dev_urandom);
+       }       
+      else
+       dev_urandom_exists = FALSE;
+    }
+#else
+  static gboolean dev_urandom_exists = FALSE;
+#endif
+
+  if (!dev_urandom_exists)
+    {  
+      g_get_current_time (&now);
+      seed[0] = now.tv_sec;
+      seed[1] = now.tv_usec;
+      seed[2] = getpid ();
+#ifdef G_OS_UNIX
+      seed[3] = getppid ();
+#else
+      seed[3] = 0;
+#endif
+    }
+
+  return g_rand_new_with_seed_array (seed, 4);
+}
+
+/**
+ * g_rand_free:
+ * @rand_: a #GRand.
+ *
+ * Frees the memory allocated for the #GRand.
+ **/
+void
+g_rand_free (GRand* rand)
+{
+  g_return_if_fail (rand != NULL);
+
+  g_free (rand);
+}
+
+/**
+ * g_rand_copy:
+ * @rand_: a #GRand.
+ *
+ * Copies a #GRand into a new one with the same exact state as before.
+ * This way you can take a snapshot of the random number generator for
+ * replaying later.
+ *
+ * Return value: the new #GRand.
+ *
+ * Since: 2.4
+ **/
+GRand *
+g_rand_copy (GRand* rand)
+{
+  GRand* new_rand;
+
+  g_return_val_if_fail (rand != NULL, NULL);
+
+  new_rand = g_new0 (GRand, 1);
+  memcpy (new_rand, rand, sizeof (GRand));
+
+  return new_rand;
+}
+
+/**
+ * g_rand_set_seed:
+ * @rand_: a #GRand.
+ * @seed: a value to reinitialize the random number generator.
+ *
+ * Sets the seed for the random number generator #GRand to @seed.
+ **/
+void
+g_rand_set_seed (GRand* rand, guint32 seed)
+{
+  g_return_if_fail (rand != NULL);
+
+  switch (get_random_version ())
+    {
+    case 20:
+      /* setting initial seeds to mt[N] using         */
+      /* the generator Line 25 of Table 1 in          */
+      /* [KNUTH 1981, The Art of Computer Programming */
+      /*    Vol. 2 (2nd Ed.), pp102]                  */
+      
+      if (seed == 0) /* This would make the PRNG procude only zeros */
+       seed = 0x6b842128; /* Just set it to another number */
+      
+      rand->mt[0]= seed;
+      for (rand->mti=1; rand->mti<N; rand->mti++)
+       rand->mt[rand->mti] = (69069 * rand->mt[rand->mti-1]);
+      
+      break;
+    case 22:
+      /* See Knuth TAOCP Vol2. 3rd Ed. P.106 for multiplier. */
+      /* In the previous version (see above), MSBs of the    */
+      /* seed affect only MSBs of the array mt[].            */
+      
+      rand->mt[0]= seed;
+      for (rand->mti=1; rand->mti<N; rand->mti++)
+       rand->mt[rand->mti] = 1812433253UL * 
+         (rand->mt[rand->mti-1] ^ (rand->mt[rand->mti-1] >> 30)) + rand->mti; 
+      break;
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+/**
+ * g_rand_set_seed_array:
+ * @rand_: a #GRand.
+ * @seed: array to initialize with
+ * @seed_length: length of array
+ *
+ * Initializes the random number generator by an array of
+ * longs.  Array can be of arbitrary size, though only the
+ * first 624 values are taken.  This function is useful
+ * if you have many low entropy seeds, or if you require more then
+ * 32bits of actual entropy for your application.
+ *
+ * Since: 2.4
+ **/
+void
+g_rand_set_seed_array (GRand* rand, const guint32 *seed, guint seed_length)
+{
+  int i, j, k;
+
+  g_return_if_fail (rand != NULL);
+  g_return_if_fail (seed_length >= 1);
+
+  g_rand_set_seed (rand, 19650218UL);
+
+  i=1; j=0;
+  k = (N>seed_length ? N : seed_length);
+  for (; k; k--)
+    {
+      rand->mt[i] = (rand->mt[i] ^
+                    ((rand->mt[i-1] ^ (rand->mt[i-1] >> 30)) * 1664525UL))
+             + seed[j] + j; /* non linear */
+      rand->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+      i++; j++;
+      if (i>=N)
+        {
+         rand->mt[0] = rand->mt[N-1];
+         i=1;
+       }
+      if (j>=seed_length)
+       j=0;
+    }
+  for (k=N-1; k; k--)
+    {
+      rand->mt[i] = (rand->mt[i] ^
+                    ((rand->mt[i-1] ^ (rand->mt[i-1] >> 30)) * 1566083941UL))
+             - i; /* non linear */
+      rand->mt[i] &= 0xffffffffUL; /* for WORDSIZE > 32 machines */
+      i++;
+      if (i>=N)
+        {
+         rand->mt[0] = rand->mt[N-1];
+         i=1;
+       }
+    }
+
+  rand->mt[0] = 0x80000000UL; /* MSB is 1; assuring non-zero initial array */ 
+}
+
+/**
+ * g_rand_boolean:
+ * @rand_: a #GRand.
+ * @Returns: a random #gboolean.
+ *
+ * Returns a random #gboolean from @rand_. This corresponds to a
+ * unbiased coin toss.
+ **/
+/**
+ * g_rand_int:
+ * @rand_: a #GRand.
+ *
+ * Returns the next random #guint32 from @rand_ equally distributed over
+ * the range [0..2^32-1].
+ *
+ * Return value: A random number.
+ **/
+guint32
+g_rand_int (GRand* rand)
+{
+  guint32 y;
+  static const guint32 mag01[2]={0x0, MATRIX_A};
+  /* mag01[x] = x * MATRIX_A  for x=0,1 */
+
+  g_return_val_if_fail (rand != NULL, 0);
+
+  if (rand->mti >= N) { /* generate N words at one time */
+    int kk;
+    
+    for (kk=0;kk<N-M;kk++) {
+      y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
+      rand->mt[kk] = rand->mt[kk+M] ^ (y >> 1) ^ mag01[y & 0x1];
+    }
+    for (;kk<N-1;kk++) {
+      y = (rand->mt[kk]&UPPER_MASK)|(rand->mt[kk+1]&LOWER_MASK);
+      rand->mt[kk] = rand->mt[kk+(M-N)] ^ (y >> 1) ^ mag01[y & 0x1];
+    }
+    y = (rand->mt[N-1]&UPPER_MASK)|(rand->mt[0]&LOWER_MASK);
+    rand->mt[N-1] = rand->mt[M-1] ^ (y >> 1) ^ mag01[y & 0x1];
+    
+    rand->mti = 0;
+  }
+  
+  y = rand->mt[rand->mti++];
+  y ^= TEMPERING_SHIFT_U(y);
+  y ^= TEMPERING_SHIFT_S(y) & TEMPERING_MASK_B;
+  y ^= TEMPERING_SHIFT_T(y) & TEMPERING_MASK_C;
+  y ^= TEMPERING_SHIFT_L(y);
+  
+  return y; 
+}
+
+/* transform [0..2^32] -> [0..1] */
+#define G_RAND_DOUBLE_TRANSFORM 2.3283064365386962890625e-10
+
+/**
+ * g_rand_int_range:
+ * @rand_: a #GRand.
+ * @begin: lower closed bound of the interval.
+ * @end: upper open bound of the interval.
+ *
+ * Returns the next random #gint32 from @rand_ equally distributed over
+ * the range [@begin..@end-1].
+ *
+ * Return value: A random number.
+ **/
+gint32 
+g_rand_int_range (GRand* rand, gint32 begin, gint32 end)
+{
+  guint32 dist = end - begin;
+  guint32 random;
+
+  g_return_val_if_fail (rand != NULL, begin);
+  g_return_val_if_fail (end > begin, begin);
+
+  switch (get_random_version ())
+    {
+    case 20:
+      if (dist <= 0x10000L) /* 2^16 */
+       {
+         /* This method, which only calls g_rand_int once is only good
+          * for (end - begin) <= 2^16, because we only have 32 bits set
+          * from the one call to g_rand_int (). */
+         
+         /* we are using (trans + trans * trans), because g_rand_int only
+          * covers [0..2^32-1] and thus g_rand_int * trans only covers
+          * [0..1-2^-32], but the biggest double < 1 is 1-2^-52. 
+          */
+         
+         gdouble double_rand = g_rand_int (rand) * 
+           (G_RAND_DOUBLE_TRANSFORM +
+            G_RAND_DOUBLE_TRANSFORM * G_RAND_DOUBLE_TRANSFORM);
+         
+         random = (gint32) (double_rand * dist);
+       }
+      else
+       {
+         /* Now we use g_rand_double_range (), which will set 52 bits for
+            us, so that it is safe to round and still get a decent
+            distribution */
+         random = (gint32) g_rand_double_range (rand, 0, dist);
+       }
+      break;
+    case 22:
+      if (dist == 0)
+       random = 0;
+      else 
+       {
+         /* maxvalue is set to the predecessor of the greatest
+          * multiple of dist less or equal 2^32. */
+         guint32 maxvalue;
+         if (dist <= 0x80000000u) /* 2^31 */
+           {
+             /* maxvalue = 2^32 - 1 - (2^32 % dist) */
+             guint32 leftover = (0x80000000u % dist) * 2;
+             if (leftover >= dist) leftover -= dist;
+             maxvalue = 0xffffffffu - leftover;
+           }
+         else
+           maxvalue = dist - 1;
+         
+         do
+           random = g_rand_int (rand);
+         while (random > maxvalue);
+         
+         random %= dist;
+       }
+      break;
+    default:
+      random = 0;              /* Quiet GCC */
+      g_assert_not_reached ();
+    }      
+  return begin + random;
+}
+
+/**
+ * g_rand_double:
+ * @rand_: a #GRand.
+ *
+ * Returns the next random #gdouble from @rand_ equally distributed over
+ * the range [0..1).
+ *
+ * Return value: A random number.
+ **/
+gdouble 
+g_rand_double (GRand* rand)
+{    
+  /* We set all 52 bits after the point for this, not only the first
+     32. Thats why we need two calls to g_rand_int */
+  gdouble retval = g_rand_int (rand) * G_RAND_DOUBLE_TRANSFORM;
+  retval = (retval + g_rand_int (rand)) * G_RAND_DOUBLE_TRANSFORM;
+
+  /* The following might happen due to very bad rounding luck, but
+   * actually this should be more than rare, we just try again then */
+  if (retval >= 1.0) 
+    return g_rand_double (rand);
+
+  return retval;
+}
+
+/**
+ * g_rand_double_range:
+ * @rand_: a #GRand.
+ * @begin: lower closed bound of the interval.
+ * @end: upper open bound of the interval.
+ *
+ * Returns the next random #gdouble from @rand_ equally distributed over
+ * the range [@begin..@end).
+ *
+ * Return value: A random number.
+ **/
+gdouble 
+g_rand_double_range (GRand* rand, gdouble begin, gdouble end)
+{
+  return g_rand_double (rand) * (end - begin) + begin;
+}
+
+/**
+ * g_random_boolean:
+ * @Returns: a random #gboolean.
+ *
+ * Returns a random #gboolean. This corresponds to a unbiased coin toss.
+ **/
+/**
+ * g_random_int:
+ *
+ * Return a random #guint32 equally distributed over the range
+ * [0..2^32-1].
+ *
+ * Return value: A random number.
+ **/
+guint32
+g_random_int (void)
+{
+  guint32 result;
+  G_LOCK (global_random);
+  if (!global_random)
+    global_random = g_rand_new ();
+  
+  result = g_rand_int (global_random);
+  G_UNLOCK (global_random);
+  return result;
+}
+
+/**
+ * g_random_int_range:
+ * @begin: lower closed bound of the interval.
+ * @end: upper open bound of the interval.
+ *
+ * Returns a random #gint32 equally distributed over the range
+ * [@begin..@end-1].
+ *
+ * Return value: A random number.
+ **/
+gint32 
+g_random_int_range (gint32 begin, gint32 end)
+{
+  gint32 result;
+  G_LOCK (global_random);
+  if (!global_random)
+    global_random = g_rand_new ();
+  
+  result = g_rand_int_range (global_random, begin, end);
+  G_UNLOCK (global_random);
+  return result;
+}
+
+/**
+ * g_random_double:
+ *
+ * Returns a random #gdouble equally distributed over the range [0..1).
+ *
+ * Return value: A random number.
+ **/
+gdouble 
+g_random_double (void)
+{
+  double result;
+  G_LOCK (global_random);
+  if (!global_random)
+    global_random = g_rand_new ();
+  
+  result = g_rand_double (global_random);
+  G_UNLOCK (global_random);
+  return result;
+}
+
+/**
+ * g_random_double_range:
+ * @begin: lower closed bound of the interval.
+ * @end: upper open bound of the interval.
+ *
+ * Returns a random #gdouble equally distributed over the range [@begin..@end).
+ *
+ * Return value: A random number.
+ **/
+gdouble 
+g_random_double_range (gdouble begin, gdouble end)
+{
+  double result;
+  G_LOCK (global_random);
+  if (!global_random)
+    global_random = g_rand_new ();
+  result = g_rand_double_range (global_random, begin, end);
+  G_UNLOCK (global_random);
+  return result;
+}
+
+/**
+ * g_random_set_seed:
+ * @seed: a value to reinitialize the global random number generator.
+ * 
+ * Sets the seed for the global random number generator, which is used
+ * by the <function>g_random_*</function> functions, to @seed.
+ **/
+void
+g_random_set_seed (guint32 seed)
+{
+  G_LOCK (global_random);
+  if (!global_random)
+    global_random = g_rand_new_with_seed (seed);
+  else
+    g_rand_set_seed (global_random, seed);
+  G_UNLOCK (global_random);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/grand.h b/resource/csdk/connectivity/lib/android/glib-master/glib/grand.h
new file mode 100644 (file)
index 0000000..07907df
--- /dev/null
@@ -0,0 +1,85 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_RAND_H__
+#define __G_RAND_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GRand           GRand;
+
+/* GRand - a good and fast random number generator: Mersenne Twister
+ * see http://www.math.keio.ac.jp/~matumoto/emt.html for more info.
+ * The range functions return a value in the intervall [begin, end).
+ * int          -> [0..2^32-1]
+ * int_range    -> [begin..end-1]
+ * double       -> [0..1)
+ * double_range -> [begin..end)
+ */
+
+GRand*  g_rand_new_with_seed  (guint32  seed);
+GRand*  g_rand_new_with_seed_array (const guint32 *seed,
+                                   guint seed_length);
+GRand*  g_rand_new            (void);
+void    g_rand_free           (GRand   *rand_);
+GRand*  g_rand_copy           (GRand   *rand_);
+void    g_rand_set_seed       (GRand   *rand_,
+                              guint32  seed);
+void   g_rand_set_seed_array (GRand   *rand_,
+                              const guint32 *seed,
+                              guint    seed_length);
+
+#define g_rand_boolean(rand_) ((g_rand_int (rand_) & (1 << 15)) != 0)
+
+guint32 g_rand_int            (GRand   *rand_);
+gint32  g_rand_int_range      (GRand   *rand_,
+                              gint32   begin,
+                              gint32   end);
+gdouble g_rand_double         (GRand   *rand_);
+gdouble g_rand_double_range   (GRand   *rand_,
+                              gdouble  begin,
+                              gdouble  end);
+void    g_random_set_seed     (guint32  seed);
+
+#define g_random_boolean() ((g_random_int () & (1 << 15)) != 0)
+
+guint32 g_random_int          (void);
+gint32  g_random_int_range    (gint32   begin,
+                              gint32   end);
+gdouble g_random_double       (void);
+gdouble g_random_double_range (gdouble  begin,
+                              gdouble  end);
+
+
+G_END_DECLS
+
+#endif /* __G_RAND_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gregex.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gregex.c
new file mode 100644 (file)
index 0000000..b62bda7
--- /dev/null
@@ -0,0 +1,2852 @@
+/* GRegex -- regular expression API wrapper around PCRE.
+ *
+ * Copyright (C) 1999, 2000 Scott Wimer
+ * Copyright (C) 2004, Matthias Clasen <mclasen@redhat.com>
+ * Copyright (C) 2005 - 2007, Marco Barisione <marco@barisione.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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#ifdef USE_SYSTEM_PCRE
+#include <pcre.h>
+#else
+#include "pcre/pcre.h"
+#endif
+
+#include "gtypes.h"
+#include "gregex.h"
+#include "glibintl.h"
+#include "glist.h"
+#include "gmessages.h"
+#include "gstrfuncs.h"
+#include "gatomic.h"
+
+/**
+ * SECTION:gregex
+ * @title: Perl-compatible regular expressions
+ * @short_description: matches strings against regular expressions
+ * @see_also: <xref linkend="glib-regex-syntax"/>
+ *
+ * The <function>g_regex_*()</function> functions implement regular
+ * expression pattern matching using syntax and semantics similar to
+ * Perl regular expression.
+ *
+ * Some functions accept a @start_position argument, setting it differs
+ * from just passing over a shortened string and setting #G_REGEX_MATCH_NOTBOL
+ * in the case of a pattern that begins with any kind of lookbehind assertion.
+ * For example, consider the pattern "\Biss\B" which finds occurrences of "iss"
+ * in the middle of words. ("\B" matches only if the current position in the
+ * subject is not a word boundary.) When applied to the string "Mississipi"
+ * from the fourth byte, namely "issipi", it does not match, because "\B" is
+ * always false at the start of the subject, which is deemed to be a word
+ * boundary. However, if the entire string is passed , but with
+ * @start_position set to 4, it finds the second occurrence of "iss" because
+ * it is able to look behind the starting point to discover that it is
+ * preceded by a letter.
+ *
+ * Note that, unless you set the #G_REGEX_RAW flag, all the strings passed
+ * to these functions must be encoded in UTF-8. The lengths and the positions
+ * inside the strings are in bytes and not in characters, so, for instance,
+ * "\xc3\xa0" (i.e. "&agrave;") is two bytes long but it is treated as a
+ * single character. If you set #G_REGEX_RAW the strings can be non-valid
+ * UTF-8 strings and a byte is treated as a character, so "\xc3\xa0" is two
+ * bytes and two characters long.
+ *
+ * When matching a pattern, "\n" matches only against a "\n" character in
+ * the string, and "\r" matches only a "\r" character. To match any newline
+ * sequence use "\R". This particular group matches either the two-character
+ * sequence CR + LF ("\r\n"), or one of the single characters LF (linefeed,
+ * U+000A, "\n"), VT vertical tab, U+000B, "\v"), FF (formfeed, U+000C, "\f"),
+ * CR (carriage return, U+000D, "\r"), NEL (next line, U+0085), LS (line
+ * separator, U+2028), or PS (paragraph separator, U+2029).
+ *
+ * The behaviour of the dot, circumflex, and dollar metacharacters are
+ * affected by newline characters, the default is to recognize any newline
+ * character (the same characters recognized by "\R"). This can be changed
+ * with #G_REGEX_NEWLINE_CR, #G_REGEX_NEWLINE_LF and #G_REGEX_NEWLINE_CRLF
+ * compile options, and with #G_REGEX_MATCH_NEWLINE_ANY,
+ * #G_REGEX_MATCH_NEWLINE_CR, #G_REGEX_MATCH_NEWLINE_LF and
+ * #G_REGEX_MATCH_NEWLINE_CRLF match options. These settings are also
+ * relevant when compiling a pattern if #G_REGEX_EXTENDED is set, and an
+ * unescaped "#" outside a character class is encountered. This indicates
+ * a comment that lasts until after the next newline.
+ *
+ * Creating and manipulating the same #GRegex structure from different
+ * threads is not a problem as #GRegex does not modify its internal
+ * state between creation and destruction, on the other hand #GMatchInfo
+ * is not threadsafe.
+ *
+ * The regular expressions low-level functionalities are obtained through
+ * the excellent <ulink url="http://www.pcre.org/">PCRE</ulink> library
+ * written by Philip Hazel.
+ */
+
+/* Mask of all the possible values for GRegexCompileFlags. */
+#define G_REGEX_COMPILE_MASK (G_REGEX_CASELESS          | \
+                              G_REGEX_MULTILINE         | \
+                              G_REGEX_DOTALL            | \
+                              G_REGEX_EXTENDED          | \
+                              G_REGEX_ANCHORED          | \
+                              G_REGEX_DOLLAR_ENDONLY    | \
+                              G_REGEX_UNGREEDY          | \
+                              G_REGEX_RAW               | \
+                              G_REGEX_NO_AUTO_CAPTURE   | \
+                              G_REGEX_OPTIMIZE          | \
+                              G_REGEX_DUPNAMES          | \
+                              G_REGEX_NEWLINE_CR        | \
+                              G_REGEX_NEWLINE_LF        | \
+                              G_REGEX_NEWLINE_CRLF)
+
+/* Mask of all the possible values for GRegexMatchFlags. */
+#define G_REGEX_MATCH_MASK (G_REGEX_MATCH_ANCHORED      | \
+                            G_REGEX_MATCH_NOTBOL        | \
+                            G_REGEX_MATCH_NOTEOL        | \
+                            G_REGEX_MATCH_NOTEMPTY      | \
+                            G_REGEX_MATCH_PARTIAL       | \
+                            G_REGEX_MATCH_NEWLINE_CR    | \
+                            G_REGEX_MATCH_NEWLINE_LF    | \
+                            G_REGEX_MATCH_NEWLINE_CRLF  | \
+                            G_REGEX_MATCH_NEWLINE_ANY)
+
+/* if the string is in UTF-8 use g_utf8_ functions, else use
+ * use just +/- 1. */
+#define NEXT_CHAR(re, s) (((re)->compile_opts & PCRE_UTF8) ? \
+                                g_utf8_next_char (s) : \
+                                ((s) + 1))
+#define PREV_CHAR(re, s) (((re)->compile_opts & PCRE_UTF8) ? \
+                                g_utf8_prev_char (s) : \
+                                ((s) - 1))
+
+struct _GMatchInfo
+{
+  GRegex *regex;                /* the regex */
+  GRegexMatchFlags match_opts;  /* options used at match time on the regex */
+  gint matches;                 /* number of matching sub patterns */
+  gint pos;                     /* position in the string where last match left off */
+  gint *offsets;                /* array of offsets paired 0,1 ; 2,3 ; 3,4 etc */
+  gint n_offsets;               /* number of offsets */
+  gint *workspace;              /* workspace for pcre_dfa_exec() */
+  gint n_workspace;             /* number of workspace elements */
+  const gchar *string;          /* string passed to the match function */
+  gssize string_len;            /* length of string */
+};
+
+struct _GRegex
+{
+  volatile gint ref_count;      /* the ref count for the immutable part */
+  gchar *pattern;               /* the pattern */
+  pcre *pcre_re;                /* compiled form of the pattern */
+  GRegexCompileFlags compile_opts;      /* options used at compile time on the pattern */
+  GRegexMatchFlags match_opts;  /* options used at match time on the regex */
+  pcre_extra *extra;            /* data stored when G_REGEX_OPTIMIZE is used */
+};
+
+/* TRUE if ret is an error code, FALSE otherwise. */
+#define IS_PCRE_ERROR(ret) ((ret) < PCRE_ERROR_NOMATCH && (ret) != PCRE_ERROR_PARTIAL)
+
+typedef struct _InterpolationData InterpolationData;
+static gboolean  interpolation_list_needs_match (GList *list);
+static gboolean  interpolate_replacement        (const GMatchInfo *match_info,
+                                                 GString *result,
+                                                 gpointer data);
+static GList    *split_replacement              (const gchar *replacement,
+                                                 GError **error);
+static void      free_interpolation_data        (InterpolationData *data);
+
+
+static const gchar *
+match_error (gint errcode)
+{
+  switch (errcode)
+    {
+    case PCRE_ERROR_NOMATCH:
+      /* not an error */
+      break;
+    case PCRE_ERROR_NULL:
+      /* NULL argument, this should not happen in GRegex */
+      g_warning ("A NULL argument was passed to PCRE");
+      break;
+    case PCRE_ERROR_BADOPTION:
+      return "bad options";
+    case PCRE_ERROR_BADMAGIC:
+      return _("corrupted object");
+    case PCRE_ERROR_UNKNOWN_OPCODE:
+      return N_("internal error or corrupted object");
+    case PCRE_ERROR_NOMEMORY:
+      return _("out of memory");
+    case PCRE_ERROR_NOSUBSTRING:
+      /* not used by pcre_exec() */
+      break;
+    case PCRE_ERROR_MATCHLIMIT:
+      return _("backtracking limit reached");
+    case PCRE_ERROR_CALLOUT:
+      /* callouts are not implemented */
+      break;
+    case PCRE_ERROR_BADUTF8:
+    case PCRE_ERROR_BADUTF8_OFFSET:
+      /* we do not check if strings are valid */
+      break;
+    case PCRE_ERROR_PARTIAL:
+      /* not an error */
+      break;
+    case PCRE_ERROR_BADPARTIAL:
+      return _("the pattern contains items not supported for partial matching");
+    case PCRE_ERROR_INTERNAL:
+      return _("internal error");
+    case PCRE_ERROR_BADCOUNT:
+      /* negative ovecsize, this should not happen in GRegex */
+      g_warning ("A negative ovecsize was passed to PCRE");
+      break;
+    case PCRE_ERROR_DFA_UITEM:
+      return _("the pattern contains items not supported for partial matching");
+    case PCRE_ERROR_DFA_UCOND:
+      return _("back references as conditions are not supported for partial matching");
+    case PCRE_ERROR_DFA_UMLIMIT:
+      /* the match_field field is not used in GRegex */
+      break;
+    case PCRE_ERROR_DFA_WSSIZE:
+      /* handled expanding the workspace */
+      break;
+    case PCRE_ERROR_DFA_RECURSE:
+    case PCRE_ERROR_RECURSIONLIMIT:
+      return _("recursion limit reached");
+    case PCRE_ERROR_NULLWSLIMIT:
+      return _("workspace limit for empty substrings reached");
+    case PCRE_ERROR_BADNEWLINE:
+      return _("invalid combination of newline flags");
+    default:
+      break;
+    }
+  return _("unknown error");
+}
+
+static void
+translate_compile_error (gint *errcode, const gchar **errmsg)
+{
+  /* Compile errors are created adding 100 to the error code returned
+   * by PCRE.
+   * If errcode is known we put the translatable error message in
+   * erromsg. If errcode is unknown we put the generic
+   * G_REGEX_ERROR_COMPILE error code in errcode and keep the
+   * untranslated error message returned by PCRE.
+   * Note that there can be more PCRE errors with the same GRegexError
+   * and that some PCRE errors are useless for us.
+   */
+  *errcode += 100;
+
+  switch (*errcode)
+    {
+    case G_REGEX_ERROR_STRAY_BACKSLASH:
+      *errmsg = _("\\ at end of pattern");
+      break;
+    case G_REGEX_ERROR_MISSING_CONTROL_CHAR:
+      *errmsg = _("\\c at end of pattern");
+      break;
+    case G_REGEX_ERROR_UNRECOGNIZED_ESCAPE:
+      *errmsg = _("unrecognized character follows \\");
+      break;
+    case 137:
+      /* A number of Perl escapes are not handled by PCRE.
+       * Therefore it explicitly raises ERR37.
+       */
+      *errcode = G_REGEX_ERROR_UNRECOGNIZED_ESCAPE;
+      *errmsg = _("case-changing escapes (\\l, \\L, \\u, \\U) are not allowed here");
+      break;
+    case G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER:
+      *errmsg = _("numbers out of order in {} quantifier");
+      break;
+    case G_REGEX_ERROR_QUANTIFIER_TOO_BIG:
+      *errmsg = _("number too big in {} quantifier");
+      break;
+    case G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS:
+      *errmsg = _("missing terminating ] for character class");
+      break;
+    case G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS:
+      *errmsg = _("invalid escape sequence in character class");
+      break;
+    case G_REGEX_ERROR_RANGE_OUT_OF_ORDER:
+      *errmsg = _("range out of order in character class");
+      break;
+    case G_REGEX_ERROR_NOTHING_TO_REPEAT:
+      *errmsg = _("nothing to repeat");
+      break;
+    case G_REGEX_ERROR_UNRECOGNIZED_CHARACTER:
+      *errmsg = _("unrecognized character after (?");
+      break;
+    case 124:
+      *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER;
+      *errmsg = _("unrecognized character after (?<");
+      break;
+    case 141:
+      *errcode = G_REGEX_ERROR_UNRECOGNIZED_CHARACTER;
+      *errmsg = _("unrecognized character after (?P");
+      break;
+    case G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS:
+      *errmsg = _("POSIX named classes are supported only within a class");
+      break;
+    case G_REGEX_ERROR_UNMATCHED_PARENTHESIS:
+      *errmsg = _("missing terminating )");
+      break;
+    case 122:
+      *errcode = G_REGEX_ERROR_UNMATCHED_PARENTHESIS;
+      *errmsg = _(") without opening (");
+      break;
+    case 129:
+      *errcode = G_REGEX_ERROR_UNMATCHED_PARENTHESIS;
+      /* translators: '(?R' and '(?[+-]digits' are both meant as (groups of)
+       * sequences here, '(?-54' would be an example for the second group.
+       */
+      *errmsg = _("(?R or (?[+-]digits must be followed by )");
+      break;
+    case G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE:
+      *errmsg = _("reference to non-existent subpattern");
+      break;
+    case G_REGEX_ERROR_UNTERMINATED_COMMENT:
+      *errmsg = _("missing ) after comment");
+      break;
+    case G_REGEX_ERROR_EXPRESSION_TOO_LARGE:
+      *errmsg = _("regular expression too large");
+      break;
+    case G_REGEX_ERROR_MEMORY_ERROR:
+      *errmsg = _("failed to get memory");
+      break;
+    case G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND:
+      *errmsg = _("lookbehind assertion is not fixed length");
+      break;
+    case G_REGEX_ERROR_MALFORMED_CONDITION:
+      *errmsg = _("malformed number or name after (?(");
+      break;
+    case G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES:
+      *errmsg = _("conditional group contains more than two branches");
+      break;
+    case G_REGEX_ERROR_ASSERTION_EXPECTED:
+      *errmsg = _("assertion expected after (?(");
+      break;
+    case G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME:
+      *errmsg = _("unknown POSIX class name");
+      break;
+    case G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED:
+      *errmsg = _("POSIX collating elements are not supported");
+      break;
+    case G_REGEX_ERROR_HEX_CODE_TOO_LARGE:
+      *errmsg = _("character value in \\x{...} sequence is too large");
+      break;
+    case G_REGEX_ERROR_INVALID_CONDITION:
+      *errmsg = _("invalid condition (?(0)");
+      break;
+    case G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND:
+      *errmsg = _("\\C not allowed in lookbehind assertion");
+      break;
+    case G_REGEX_ERROR_INFINITE_LOOP:
+      *errmsg = _("recursive call could loop indefinitely");
+      break;
+    case G_REGEX_ERROR_MISSING_SUBPATTERN_NAME_TERMINATOR:
+      *errmsg = _("missing terminator in subpattern name");
+      break;
+    case G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME:
+      *errmsg = _("two named subpatterns have the same name");
+      break;
+    case G_REGEX_ERROR_MALFORMED_PROPERTY:
+      *errmsg = _("malformed \\P or \\p sequence");
+      break;
+    case G_REGEX_ERROR_UNKNOWN_PROPERTY:
+      *errmsg = _("unknown property name after \\P or \\p");
+      break;
+    case G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG:
+      *errmsg = _("subpattern name is too long (maximum 32 characters)");
+      break;
+    case G_REGEX_ERROR_TOO_MANY_SUBPATTERNS:
+      *errmsg = _("too many named subpatterns (maximum 10,000)");
+      break;
+    case G_REGEX_ERROR_INVALID_OCTAL_VALUE:
+      *errmsg = _("octal value is greater than \\377");
+      break;
+    case G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE:
+      *errmsg = _("DEFINE group contains more than one branch");
+      break;
+    case G_REGEX_ERROR_DEFINE_REPETION:
+      *errmsg = _("repeating a DEFINE group is not allowed");
+      break;
+    case G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS:
+      *errmsg = _("inconsistent NEWLINE options");
+      break;
+    case G_REGEX_ERROR_MISSING_BACK_REFERENCE:
+      *errmsg = _("\\g is not followed by a braced name or an optionally "
+                 "braced non-zero number");
+      break;
+    case 11:
+      *errcode = G_REGEX_ERROR_INTERNAL;
+      *errmsg = _("unexpected repeat");
+      break;
+    case 23:
+      *errcode = G_REGEX_ERROR_INTERNAL;
+      *errmsg = _("code overflow");
+      break;
+    case 52:
+      *errcode = G_REGEX_ERROR_INTERNAL;
+      *errmsg = _("overran compiling workspace");
+      break;
+    case 53:
+      *errcode = G_REGEX_ERROR_INTERNAL;
+      *errmsg = _("previously-checked referenced subpattern not found");
+      break;
+    case 16:
+      /* This should not happen as we never pass a NULL erroffset */
+      g_warning ("erroffset passed as NULL");
+      *errcode = G_REGEX_ERROR_COMPILE;
+      break;
+    case 17:
+      /* This should not happen as we check options before passing them
+       * to pcre_compile2() */
+      g_warning ("unknown option bit(s) set");
+      *errcode = G_REGEX_ERROR_COMPILE;
+      break;
+    case 32:
+    case 44:
+    case 45:
+      /* These errors should not happen as we are using an UTF8-enabled PCRE
+       * and we do not check if strings are valid */
+      g_warning ("%s", *errmsg);
+      *errcode = G_REGEX_ERROR_COMPILE;
+      break;
+    default:
+      *errcode = G_REGEX_ERROR_COMPILE;
+    }
+}
+
+/* GMatchInfo */
+
+static GMatchInfo *
+match_info_new (const GRegex *regex,
+                const gchar  *string,
+                gint          string_len,
+                gint          start_position,
+                gint          match_options,
+                gboolean      is_dfa)
+{
+  GMatchInfo *match_info;
+
+  if (string_len < 0)
+    string_len = strlen (string);
+
+  match_info = g_new0 (GMatchInfo, 1);
+  match_info->regex = g_regex_ref ((GRegex *)regex);
+  match_info->string = string;
+  match_info->string_len = string_len;
+  match_info->matches = PCRE_ERROR_NOMATCH;
+  match_info->pos = start_position;
+  match_info->match_opts = match_options;
+
+  if (is_dfa)
+    {
+      /* These values should be enough for most cases, if they are not
+       * enough g_regex_match_all_full() will expand them. */
+      match_info->n_offsets = 24;
+      match_info->n_workspace = 100;
+      match_info->workspace = g_new (gint, match_info->n_workspace);
+    }
+  else
+    {
+      gint capture_count;
+      pcre_fullinfo (regex->pcre_re, regex->extra,
+                     PCRE_INFO_CAPTURECOUNT, &capture_count);
+      match_info->n_offsets = (capture_count + 1) * 3;
+    }
+
+  match_info->offsets = g_new0 (gint, match_info->n_offsets);
+  /* Set an invalid position for the previous match. */
+  match_info->offsets[0] = -1;
+  match_info->offsets[1] = -1;
+
+  return match_info;
+}
+
+/**
+ * g_match_info_get_regex:
+ * @match_info: a #GMatchInfo
+ *
+ * Returns #GRegex object used in @match_info. It belongs to Glib
+ * and must not be freed. Use g_regex_ref() if you need to keep it
+ * after you free @match_info object.
+ *
+ * Returns: #GRegex object used in @match_info
+ *
+ * Since: 2.14
+ */
+GRegex *
+g_match_info_get_regex (const GMatchInfo *match_info)
+{
+  g_return_val_if_fail (match_info != NULL, NULL);
+  return match_info->regex;
+}
+
+/**
+ * g_match_info_get_string:
+ * @match_info: a #GMatchInfo
+ *
+ * Returns the string searched with @match_info. This is the
+ * string passed to g_regex_match() or g_regex_replace() so
+ * you may not free it before calling this function.
+ *
+ * Returns: the string searched with @match_info
+ *
+ * Since: 2.14
+ */
+const gchar *
+g_match_info_get_string (const GMatchInfo *match_info)
+{
+  g_return_val_if_fail (match_info != NULL, NULL);
+  return match_info->string;
+}
+
+/**
+ * g_match_info_free:
+ * @match_info: a #GMatchInfo
+ *
+ * Frees all the memory associated with the #GMatchInfo structure.
+ *
+ * Since: 2.14
+ */
+void
+g_match_info_free (GMatchInfo *match_info)
+{
+  if (match_info)
+    {
+      g_regex_unref (match_info->regex);
+      g_free (match_info->offsets);
+      g_free (match_info->workspace);
+      g_free (match_info);
+    }
+}
+
+/**
+ * g_match_info_next:
+ * @match_info: a #GMatchInfo structure
+ * @error: location to store the error occuring, or %NULL to ignore errors
+ *
+ * Scans for the next match using the same parameters of the previous
+ * call to g_regex_match_full() or g_regex_match() that returned
+ * @match_info.
+ *
+ * The match is done on the string passed to the match function, so you
+ * cannot free it before calling this function.
+ *
+ * Returns: %TRUE is the string matched, %FALSE otherwise
+ *
+ * Since: 2.14
+ */
+gboolean
+g_match_info_next (GMatchInfo  *match_info,
+                   GError     **error)
+{
+  gint prev_match_start;
+  gint prev_match_end;
+
+  g_return_val_if_fail (match_info != NULL, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  g_return_val_if_fail (match_info->pos >= 0, FALSE);
+
+  prev_match_start = match_info->offsets[0];
+  prev_match_end = match_info->offsets[1];
+
+  match_info->matches = pcre_exec (match_info->regex->pcre_re,
+                                   match_info->regex->extra,
+                                   match_info->string,
+                                   match_info->string_len,
+                                   match_info->pos,
+                                   match_info->regex->match_opts | match_info->match_opts,
+                                   match_info->offsets,
+                                   match_info->n_offsets);
+  if (IS_PCRE_ERROR (match_info->matches))
+    {
+      g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH,
+                   _("Error while matching regular expression %s: %s"),
+                   match_info->regex->pattern, match_error (match_info->matches));
+      return FALSE;
+    }
+
+  /* avoid infinite loops if the pattern is an empty string or something
+   * equivalent */
+  if (match_info->pos == match_info->offsets[1])
+    {
+      if (match_info->pos > match_info->string_len)
+        {
+          /* we have reached the end of the string */
+          match_info->pos = -1;
+          match_info->matches = PCRE_ERROR_NOMATCH;
+          return FALSE;
+        }
+
+      match_info->pos = NEXT_CHAR (match_info->regex,
+                                   &match_info->string[match_info->pos]) -
+                                   match_info->string;
+    }
+  else
+    {
+      match_info->pos = match_info->offsets[1];
+    }
+
+  /* it's possible to get two identical matches when we are matching
+   * empty strings, for instance if the pattern is "(?=[A-Z0-9])" and
+   * the string is "RegExTest" we have:
+   *  - search at position 0: match from 0 to 0
+   *  - search at position 1: match from 3 to 3
+   *  - search at position 3: match from 3 to 3 (duplicate)
+   *  - search at position 4: match from 5 to 5
+   *  - search at position 5: match from 5 to 5 (duplicate)
+   *  - search at position 6: no match -> stop
+   * so we have to ignore the duplicates.
+   * see bug #515944: http://bugzilla.gnome.org/show_bug.cgi?id=515944 */
+  if (match_info->matches >= 0 &&
+      prev_match_start == match_info->offsets[0] &&
+      prev_match_end == match_info->offsets[1])
+    {
+      /* ignore this match and search the next one */
+      return g_match_info_next (match_info, error);
+    }
+
+  return match_info->matches >= 0;
+}
+
+/**
+ * g_match_info_matches:
+ * @match_info: a #GMatchInfo structure
+ *
+ * Returns whether the previous match operation succeeded.
+ *
+ * Returns: %TRUE if the previous match operation succeeded,
+ *   %FALSE otherwise
+ *
+ * Since: 2.14
+ */
+gboolean
+g_match_info_matches (const GMatchInfo *match_info)
+{
+  g_return_val_if_fail (match_info != NULL, FALSE);
+
+  return match_info->matches >= 0;
+}
+
+/**
+ * g_match_info_get_match_count:
+ * @match_info: a #GMatchInfo structure
+ *
+ * Retrieves the number of matched substrings (including substring 0,
+ * that is the whole matched text), so 1 is returned if the pattern
+ * has no substrings in it and 0 is returned if the match failed.
+ *
+ * If the last match was obtained using the DFA algorithm, that is
+ * using g_regex_match_all() or g_regex_match_all_full(), the retrieved
+ * count is not that of the number of capturing parentheses but that of
+ * the number of matched substrings.
+ *
+ * Returns: Number of matched substrings, or -1 if an error occurred
+ *
+ * Since: 2.14
+ */
+gint
+g_match_info_get_match_count (const GMatchInfo *match_info)
+{
+  g_return_val_if_fail (match_info, -1);
+
+  if (match_info->matches == PCRE_ERROR_NOMATCH)
+    /* no match */
+    return 0;
+  else if (match_info->matches < PCRE_ERROR_NOMATCH)
+    /* error */
+    return -1;
+  else
+    /* match */
+    return match_info->matches;
+}
+
+/**
+ * g_match_info_is_partial_match:
+ * @match_info: a #GMatchInfo structure
+ *
+ * Usually if the string passed to g_regex_match*() matches as far as
+ * it goes, but is too short to match the entire pattern, %FALSE is
+ * returned. There are circumstances where it might be helpful to
+ * distinguish this case from other cases in which there is no match.
+ *
+ * Consider, for example, an application where a human is required to
+ * type in data for a field with specific formatting requirements. An
+ * example might be a date in the form ddmmmyy, defined by the pattern
+ * "^\d?\d(jan|feb|mar|apr|may|jun|jul|aug|sep|oct|nov|dec)\d\d$".
+ * If the application sees the user’s keystrokes one by one, and can
+ * check that what has been typed so far is potentially valid, it is
+ * able to raise an error as soon as a mistake is made.
+ *
+ * GRegex supports the concept of partial matching by means of the
+ * #G_REGEX_MATCH_PARTIAL flag. When this is set the return code for
+ * g_regex_match() or g_regex_match_full() is, as usual, %TRUE
+ * for a complete match, %FALSE otherwise. But, when these functions
+ * return %FALSE, you can check if the match was partial calling
+ * g_match_info_is_partial_match().
+ *
+ * When using partial matching you cannot use g_match_info_fetch*().
+ *
+ * Because of the way certain internal optimizations are implemented
+ * the partial matching algorithm cannot be used with all patterns.
+ * So repeated single characters such as "a{2,4}" and repeated single
+ * meta-sequences such as "\d+" are not permitted if the maximum number
+ * of occurrences is greater than one. Optional items such as "\d?"
+ * (where the maximum is one) are permitted. Quantifiers with any values
+ * are permitted after parentheses, so the invalid examples above can be
+ * coded thus "(a){2,4}" and "(\d)+". If #G_REGEX_MATCH_PARTIAL is set
+ * for a pattern that does not conform to the restrictions, matching
+ * functions return an error.
+ *
+ * Returns: %TRUE if the match was partial, %FALSE otherwise
+ *
+ * Since: 2.14
+ */
+gboolean
+g_match_info_is_partial_match (const GMatchInfo *match_info)
+{
+  g_return_val_if_fail (match_info != NULL, FALSE);
+
+  return match_info->matches == PCRE_ERROR_PARTIAL;
+}
+
+/**
+ * g_match_info_expand_references:
+ * @match_info: a #GMatchInfo or %NULL
+ * @string_to_expand: the string to expand
+ * @error: location to store the error occuring, or %NULL to ignore errors
+ *
+ * Returns a new string containing the text in @string_to_expand with
+ * references and escape sequences expanded. References refer to the last
+ * match done with @string against @regex and have the same syntax used by
+ * g_regex_replace().
+ *
+ * The @string_to_expand must be UTF-8 encoded even if #G_REGEX_RAW was
+ * passed to g_regex_new().
+ *
+ * The backreferences are extracted from the string passed to the match
+ * function, so you cannot call this function after freeing the string.
+ *
+ * @match_info may be %NULL in which case @string_to_expand must not
+ * contain references. For instance "foo\n" does not refer to an actual
+ * pattern and '\n' merely will be replaced with \n character,
+ * while to expand "\0" (whole match) one needs the result of a match.
+ * Use g_regex_check_replacement() to find out whether @string_to_expand
+ * contains references.
+ *
+ * Returns: (allow-none): the expanded string, or %NULL if an error occurred
+ *
+ * Since: 2.14
+ */
+gchar *
+g_match_info_expand_references (const GMatchInfo  *match_info,
+                                const gchar       *string_to_expand,
+                                GError           **error)
+{
+  GString *result;
+  GList *list;
+  GError *tmp_error = NULL;
+
+  g_return_val_if_fail (string_to_expand != NULL, NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+
+  list = split_replacement (string_to_expand, &tmp_error);
+  if (tmp_error != NULL)
+    {
+      g_propagate_error (error, tmp_error);
+      return NULL;
+    }
+
+  if (!match_info && interpolation_list_needs_match (list))
+    {
+      g_critical ("String '%s' contains references to the match, can't "
+                  "expand references without GMatchInfo object",
+                  string_to_expand);
+      return NULL;
+    }
+
+  result = g_string_sized_new (strlen (string_to_expand));
+  interpolate_replacement (match_info, result, list);
+
+  g_list_foreach (list, (GFunc)free_interpolation_data, NULL);
+  g_list_free (list);
+
+  return g_string_free (result, FALSE);
+}
+
+/**
+ * g_match_info_fetch:
+ * @match_info: #GMatchInfo structure
+ * @match_num: number of the sub expression
+ *
+ * Retrieves the text matching the @match_num<!-- -->'th capturing
+ * parentheses. 0 is the full text of the match, 1 is the first paren
+ * set, 2 the second, and so on.
+ *
+ * If @match_num is a valid sub pattern but it didn't match anything
+ * (e.g. sub pattern 1, matching "b" against "(a)?b") then an empty
+ * string is returned.
+ *
+ * If the match was obtained using the DFA algorithm, that is using
+ * g_regex_match_all() or g_regex_match_all_full(), the retrieved
+ * string is not that of a set of parentheses but that of a matched
+ * substring. Substrings are matched in reverse order of length, so
+ * 0 is the longest match.
+ *
+ * The string is fetched from the string passed to the match function,
+ * so you cannot call this function after freeing the string.
+ *
+ * Returns: (allow-none): The matched substring, or %NULL if an error
+ *     occurred. You have to free the string yourself
+ *
+ * Since: 2.14
+ */
+gchar *
+g_match_info_fetch (const GMatchInfo *match_info,
+                    gint              match_num)
+{
+  /* we cannot use pcre_get_substring() because it allocates the
+   * string using pcre_malloc(). */
+  gchar *match = NULL;
+  gint start, end;
+
+  g_return_val_if_fail (match_info != NULL, NULL);
+  g_return_val_if_fail (match_num >= 0, NULL);
+
+  /* match_num does not exist or it didn't matched, i.e. matching "b"
+   * against "(a)?b" then group 0 is empty. */
+  if (!g_match_info_fetch_pos (match_info, match_num, &start, &end))
+    match = NULL;
+  else if (start == -1)
+    match = g_strdup ("");
+  else
+    match = g_strndup (&match_info->string[start], end - start);
+
+  return match;
+}
+
+/**
+ * g_match_info_fetch_pos:
+ * @match_info: #GMatchInfo structure
+ * @match_num: number of the sub expression
+ * @start_pos: (out) (allow-none): pointer to location where to store
+ *     the start position, or %NULL
+ * @end_pos: (out) (allow-none): pointer to location where to store
+ *     the end position, or %NULL
+ *
+ * Retrieves the position in bytes of the @match_num<!-- -->'th capturing
+ * parentheses. 0 is the full text of the match, 1 is the first
+ * paren set, 2 the second, and so on.
+ *
+ * If @match_num is a valid sub pattern but it didn't match anything
+ * (e.g. sub pattern 1, matching "b" against "(a)?b") then @start_pos
+ * and @end_pos are set to -1 and %TRUE is returned.
+ *
+ * If the match was obtained using the DFA algorithm, that is using
+ * g_regex_match_all() or g_regex_match_all_full(), the retrieved
+ * position is not that of a set of parentheses but that of a matched
+ * substring. Substrings are matched in reverse order of length, so
+ * 0 is the longest match.
+ *
+ * Returns: %TRUE if the position was fetched, %FALSE otherwise. If
+ *   the position cannot be fetched, @start_pos and @end_pos are left
+ *   unchanged
+ *
+ * Since: 2.14
+ */
+gboolean
+g_match_info_fetch_pos (const GMatchInfo *match_info,
+                        gint              match_num,
+                        gint             *start_pos,
+                        gint             *end_pos)
+{
+  g_return_val_if_fail (match_info != NULL, FALSE);
+  g_return_val_if_fail (match_num >= 0, FALSE);
+
+  /* make sure the sub expression number they're requesting is less than
+   * the total number of sub expressions that were matched. */
+  if (match_num >= match_info->matches)
+    return FALSE;
+
+  if (start_pos != NULL)
+    *start_pos = match_info->offsets[2 * match_num];
+
+  if (end_pos != NULL)
+    *end_pos = match_info->offsets[2 * match_num + 1];
+
+  return TRUE;
+}
+
+/*
+ * Returns number of first matched subpattern with name @name.
+ * There may be more than one in case when DUPNAMES is used,
+ * and not all subpatterns with that name match;
+ * pcre_get_stringnumber() does not work in that case.
+ */
+static gint
+get_matched_substring_number (const GMatchInfo *match_info,
+                              const gchar      *name)
+{
+  gint entrysize;
+  gchar *first, *last;
+  guchar *entry;
+
+  if (!(match_info->regex->compile_opts & G_REGEX_DUPNAMES))
+    return pcre_get_stringnumber (match_info->regex->pcre_re, name);
+
+  /* This code is copied from pcre_get.c: get_first_set() */
+  entrysize = pcre_get_stringtable_entries (match_info->regex->pcre_re,
+                                            name,
+                                            &first,
+                                            &last);
+
+  if (entrysize <= 0)
+    return entrysize;
+
+  for (entry = (guchar*) first; entry <= (guchar*) last; entry += entrysize)
+    {
+      gint n = (entry[0] << 8) + entry[1];
+      if (match_info->offsets[n*2] >= 0)
+        return n;
+    }
+
+  return (first[0] << 8) + first[1];
+}
+
+/**
+ * g_match_info_fetch_named:
+ * @match_info: #GMatchInfo structure
+ * @name: name of the subexpression
+ *
+ * Retrieves the text matching the capturing parentheses named @name.
+ *
+ * If @name is a valid sub pattern name but it didn't match anything
+ * (e.g. sub pattern "X", matching "b" against "(?P&lt;X&gt;a)?b")
+ * then an empty string is returned.
+ *
+ * The string is fetched from the string passed to the match function,
+ * so you cannot call this function after freeing the string.
+ *
+ * Returns: (allow-none): The matched substring, or %NULL if an error
+ *     occurred. You have to free the string yourself
+ *
+ * Since: 2.14
+ */
+gchar *
+g_match_info_fetch_named (const GMatchInfo *match_info,
+                          const gchar      *name)
+{
+  /* we cannot use pcre_get_named_substring() because it allocates the
+   * string using pcre_malloc(). */
+  gint num;
+
+  g_return_val_if_fail (match_info != NULL, NULL);
+  g_return_val_if_fail (name != NULL, NULL);
+
+  num = get_matched_substring_number (match_info, name);
+  if (num < 0)
+    return NULL;
+  else
+    return g_match_info_fetch (match_info, num);
+}
+
+/**
+ * g_match_info_fetch_named_pos:
+ * @match_info: #GMatchInfo structure
+ * @name: name of the subexpression
+ * @start_pos: (out) (allow-none): pointer to location where to store
+ *     the start position, or %NULL
+ * @end_pos: (out) (allow-none): pointer to location where to store
+ *     the end position, or %NULL
+ *
+ * Retrieves the position in bytes of the capturing parentheses named @name.
+ *
+ * If @name is a valid sub pattern name but it didn't match anything
+ * (e.g. sub pattern "X", matching "b" against "(?P&lt;X&gt;a)?b")
+ * then @start_pos and @end_pos are set to -1 and %TRUE is returned.
+ *
+ * Returns: %TRUE if the position was fetched, %FALSE otherwise.
+ *     If the position cannot be fetched, @start_pos and @end_pos
+ *     are left unchanged.
+ *
+ * Since: 2.14
+ */
+gboolean
+g_match_info_fetch_named_pos (const GMatchInfo *match_info,
+                              const gchar      *name,
+                              gint             *start_pos,
+                              gint             *end_pos)
+{
+  gint num;
+
+  g_return_val_if_fail (match_info != NULL, FALSE);
+  g_return_val_if_fail (name != NULL, FALSE);
+
+  num = get_matched_substring_number (match_info, name);
+  if (num < 0)
+    return FALSE;
+
+  return g_match_info_fetch_pos (match_info, num, start_pos, end_pos);
+}
+
+/**
+ * g_match_info_fetch_all:
+ * @match_info: a #GMatchInfo structure
+ *
+ * Bundles up pointers to each of the matching substrings from a match
+ * and stores them in an array of gchar pointers. The first element in
+ * the returned array is the match number 0, i.e. the entire matched
+ * text.
+ *
+ * If a sub pattern didn't match anything (e.g. sub pattern 1, matching
+ * "b" against "(a)?b") then an empty string is inserted.
+ *
+ * If the last match was obtained using the DFA algorithm, that is using
+ * g_regex_match_all() or g_regex_match_all_full(), the retrieved
+ * strings are not that matched by sets of parentheses but that of the
+ * matched substring. Substrings are matched in reverse order of length,
+ * so the first one is the longest match.
+ *
+ * The strings are fetched from the string passed to the match function,
+ * so you cannot call this function after freeing the string.
+ *
+ * Returns: (allow-none): a %NULL-terminated array of gchar * pointers.
+ *     It must be freed using g_strfreev(). If the previous match failed
+ *     %NULL is returned
+ *
+ * Since: 2.14
+ */
+gchar **
+g_match_info_fetch_all (const GMatchInfo *match_info)
+{
+  /* we cannot use pcre_get_substring_list() because the returned value
+   * isn't suitable for g_strfreev(). */
+  gchar **result;
+  gint i;
+
+  g_return_val_if_fail (match_info != NULL, NULL);
+
+  if (match_info->matches < 0)
+    return NULL;
+
+  result = g_new (gchar *, match_info->matches + 1);
+  for (i = 0; i < match_info->matches; i++)
+    result[i] = g_match_info_fetch (match_info, i);
+  result[i] = NULL;
+
+  return result;
+}
+
+
+/* GRegex */
+
+GQuark
+g_regex_error_quark (void)
+{
+  static GQuark error_quark = 0;
+
+  if (error_quark == 0)
+    error_quark = g_quark_from_static_string ("g-regex-error-quark");
+
+  return error_quark;
+}
+
+/**
+ * g_regex_ref:
+ * @regex: a #GRegex
+ *
+ * Increases reference count of @regex by 1.
+ *
+ * Returns: @regex
+ *
+ * Since: 2.14
+ */
+GRegex *
+g_regex_ref (GRegex *regex)
+{
+  g_return_val_if_fail (regex != NULL, NULL);
+  g_atomic_int_inc (&regex->ref_count);
+  return regex;
+}
+
+/**
+ * g_regex_unref:
+ * @regex: a #GRegex
+ *
+ * Decreases reference count of @regex by 1. When reference count drops
+ * to zero, it frees all the memory associated with the regex structure.
+ *
+ * Since: 2.14
+ */
+void
+g_regex_unref (GRegex *regex)
+{
+  g_return_if_fail (regex != NULL);
+
+  if (g_atomic_int_exchange_and_add (&regex->ref_count, -1) - 1 == 0)
+    {
+      g_free (regex->pattern);
+      if (regex->pcre_re != NULL)
+        pcre_free (regex->pcre_re);
+      if (regex->extra != NULL)
+        pcre_free (regex->extra);
+      g_free (regex);
+    }
+}
+
+/**
+ * g_regex_new:
+ * @pattern: the regular expression
+ * @compile_options: compile options for the regular expression, or 0
+ * @match_options: match options for the regular expression, or 0
+ * @error: return location for a #GError
+ *
+ * Compiles the regular expression to an internal form, and does
+ * the initial setup of the #GRegex structure.
+ *
+ * Returns: a #GRegex structure. Call g_regex_unref() when you
+ *   are done with it
+ *
+ * Since: 2.14
+ */
+GRegex *
+g_regex_new (const gchar         *pattern,
+             GRegexCompileFlags   compile_options,
+             GRegexMatchFlags     match_options,
+             GError             **error)
+{
+  GRegex *regex;
+  pcre *re;
+  const gchar *errmsg;
+  gint erroffset;
+  gint errcode;
+  gboolean optimize = FALSE;
+  static gboolean initialized = FALSE;
+  unsigned long int pcre_compile_options;
+
+  g_return_val_if_fail (pattern != NULL, NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+  g_return_val_if_fail ((compile_options & ~G_REGEX_COMPILE_MASK) == 0, NULL);
+  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);
+
+  if (!initialized)
+    {
+      gint support;
+      const gchar *msg;
+
+      pcre_config (PCRE_CONFIG_UTF8, &support);
+      if (!support)
+        {
+          msg = N_("PCRE library is compiled without UTF8 support");
+          g_critical ("%s", msg);
+          g_set_error_literal (error, G_REGEX_ERROR, G_REGEX_ERROR_COMPILE, gettext (msg));
+          return NULL;
+        }
+
+      pcre_config (PCRE_CONFIG_UNICODE_PROPERTIES, &support);
+      if (!support)
+        {
+          msg = N_("PCRE library is compiled without UTF8 properties support");
+          g_critical ("%s", msg);
+          g_set_error_literal (error, G_REGEX_ERROR, G_REGEX_ERROR_COMPILE, gettext (msg));
+          return NULL;
+        }
+
+      initialized = TRUE;
+    }
+
+  /* G_REGEX_OPTIMIZE has the same numeric value of PCRE_NO_UTF8_CHECK,
+   * as we do not need to wrap PCRE_NO_UTF8_CHECK. */
+  if (compile_options & G_REGEX_OPTIMIZE)
+    optimize = TRUE;
+
+  /* In GRegex the string are, by default, UTF-8 encoded. PCRE
+   * instead uses UTF-8 only if required with PCRE_UTF8. */
+  if (compile_options & G_REGEX_RAW)
+    {
+      /* disable utf-8 */
+      compile_options &= ~G_REGEX_RAW;
+    }
+  else
+    {
+      /* enable utf-8 */
+      compile_options |= PCRE_UTF8 | PCRE_NO_UTF8_CHECK;
+      match_options |= PCRE_NO_UTF8_CHECK;
+    }
+
+  /* PCRE_NEWLINE_ANY is the default for the internal PCRE but
+   * not for the system one. */
+  if (!(compile_options & G_REGEX_NEWLINE_CR) &&
+      !(compile_options & G_REGEX_NEWLINE_LF))
+    {
+      compile_options |= PCRE_NEWLINE_ANY;
+    }
+
+  /* compile the pattern */
+  re = pcre_compile2 (pattern, compile_options, &errcode,
+                      &errmsg, &erroffset, NULL);
+
+  /* if the compilation failed, set the error member and return
+   * immediately */
+  if (re == NULL)
+    {
+      GError *tmp_error;
+
+      /* Translate the PCRE error code to GRegexError and use a translated
+       * error message if possible */
+      translate_compile_error (&errcode, &errmsg);
+
+      /* PCRE uses byte offsets but we want to show character offsets */
+      erroffset = g_utf8_pointer_to_offset (pattern, &pattern[erroffset]);
+
+      tmp_error = g_error_new (G_REGEX_ERROR, errcode,
+                               _("Error while compiling regular "
+                                 "expression %s at char %d: %s"),
+                               pattern, erroffset, errmsg);
+      g_propagate_error (error, tmp_error);
+
+      return NULL;
+    }
+
+  /* For options set at the beginning of the pattern, pcre puts them into
+   * compile options, e.g. "(?i)foo" will make the pcre structure store
+   * PCRE_CASELESS even though it wasn't explicitly given for compilation. */
+  pcre_fullinfo (re, NULL, PCRE_INFO_OPTIONS, &pcre_compile_options);
+  compile_options = pcre_compile_options;
+
+  if (!(compile_options & G_REGEX_DUPNAMES))
+    {
+      gboolean jchanged = FALSE;
+      pcre_fullinfo (re, NULL, PCRE_INFO_JCHANGED, &jchanged);
+      if (jchanged)
+        compile_options |= G_REGEX_DUPNAMES;
+    }
+
+  regex = g_new0 (GRegex, 1);
+  regex->ref_count = 1;
+  regex->pattern = g_strdup (pattern);
+  regex->pcre_re = re;
+  regex->compile_opts = compile_options;
+  regex->match_opts = match_options;
+
+  if (optimize)
+    {
+      regex->extra = pcre_study (regex->pcre_re, 0, &errmsg);
+      if (errmsg != NULL)
+        {
+          GError *tmp_error = g_error_new (G_REGEX_ERROR,
+                                           G_REGEX_ERROR_OPTIMIZE,
+                                           _("Error while optimizing "
+                                             "regular expression %s: %s"),
+                                           regex->pattern,
+                                           errmsg);
+          g_propagate_error (error, tmp_error);
+
+          g_regex_unref (regex);
+          return NULL;
+        }
+    }
+
+  return regex;
+}
+
+/**
+ * g_regex_get_pattern:
+ * @regex: a #GRegex structure
+ *
+ * Gets the pattern string associated with @regex, i.e. a copy of
+ * the string passed to g_regex_new().
+ *
+ * Returns: the pattern of @regex
+ *
+ * Since: 2.14
+ */
+const gchar *
+g_regex_get_pattern (const GRegex *regex)
+{
+  g_return_val_if_fail (regex != NULL, NULL);
+
+  return regex->pattern;
+}
+
+/**
+ * g_regex_get_max_backref:
+ * @regex: a #GRegex
+ *
+ * Returns the number of the highest back reference
+ * in the pattern, or 0 if the pattern does not contain
+ * back references.
+ *
+ * Returns: the number of the highest back reference
+ *
+ * Since: 2.14
+ */
+gint
+g_regex_get_max_backref (const GRegex *regex)
+{
+  gint value;
+
+  pcre_fullinfo (regex->pcre_re, regex->extra,
+                 PCRE_INFO_BACKREFMAX, &value);
+
+  return value;
+}
+
+/**
+ * g_regex_get_capture_count:
+ * @regex: a #GRegex
+ *
+ * Returns the number of capturing subpatterns in the pattern.
+ *
+ * Returns: the number of capturing subpatterns
+ *
+ * Since: 2.14
+ */
+gint
+g_regex_get_capture_count (const GRegex *regex)
+{
+  gint value;
+
+  pcre_fullinfo (regex->pcre_re, regex->extra,
+                 PCRE_INFO_CAPTURECOUNT, &value);
+
+  return value;
+}
+
+/**
+ * g_regex_get_compile_flags:
+ * @regex: a #GRegex
+ *
+ * Returns the compile options that @regex was created with.
+ *
+ * Returns: flags from #GRegexCompileFlags
+ *
+ * Since: 2.26
+ */
+GRegexCompileFlags
+g_regex_get_compile_flags (const GRegex *regex)
+{
+  g_return_val_if_fail (regex != NULL, 0);
+
+  return regex->compile_opts;
+}
+
+/**
+ * g_regex_get_match_flags:
+ * @regex: a #GRegex
+ *
+ * Returns the match options that @regex was created with.
+ *
+ * Returns: flags from #GRegexMatchFlags
+ *
+ * Since: 2.26
+ */
+GRegexMatchFlags
+g_regex_get_match_flags (const GRegex *regex)
+{
+  g_return_val_if_fail (regex != NULL, 0);
+
+  return regex->match_opts;
+}
+
+/**
+ * g_regex_match_simple:
+ * @pattern: the regular expression
+ * @string: the string to scan for matches
+ * @compile_options: compile options for the regular expression, or 0
+ * @match_options: match options, or 0
+ *
+ * Scans for a match in @string for @pattern.
+ *
+ * This function is equivalent to g_regex_match() but it does not
+ * require to compile the pattern with g_regex_new(), avoiding some
+ * lines of code when you need just to do a match without extracting
+ * substrings, capture counts, and so on.
+ *
+ * If this function is to be called on the same @pattern more than
+ * once, it's more efficient to compile the pattern once with
+ * g_regex_new() and then use g_regex_match().
+ *
+ * Returns: %TRUE if the string matched, %FALSE otherwise
+ *
+ * Since: 2.14
+ */
+gboolean
+g_regex_match_simple (const gchar        *pattern,
+                      const gchar        *string,
+                      GRegexCompileFlags  compile_options,
+                      GRegexMatchFlags    match_options)
+{
+  GRegex *regex;
+  gboolean result;
+
+  regex = g_regex_new (pattern, compile_options, 0, NULL);
+  if (!regex)
+    return FALSE;
+  result = g_regex_match_full (regex, string, -1, 0, match_options, NULL, NULL);
+  g_regex_unref (regex);
+  return result;
+}
+
+/**
+ * g_regex_match:
+ * @regex: a #GRegex structure from g_regex_new()
+ * @string: the string to scan for matches
+ * @match_options: match options
+ * @match_info: (out) (allow-none): pointer to location where to store
+ *     the #GMatchInfo, or %NULL if you do not need it
+ *
+ * Scans for a match in string for the pattern in @regex.
+ * The @match_options are combined with the match options specified
+ * when the @regex structure was created, letting you have more
+ * flexibility in reusing #GRegex structures.
+ *
+ * A #GMatchInfo structure, used to get information on the match,
+ * is stored in @match_info if not %NULL. Note that if @match_info
+ * is not %NULL then it is created even if the function returns %FALSE,
+ * i.e. you must free it regardless if regular expression actually matched.
+ *
+ * To retrieve all the non-overlapping matches of the pattern in
+ * string you can use g_match_info_next().
+ *
+ * |[
+ * static void
+ * print_uppercase_words (const gchar *string)
+ * {
+ *   /&ast; Print all uppercase-only words. &ast;/
+ *   GRegex *regex;
+ *   GMatchInfo *match_info;
+ *   &nbsp;
+ *   regex = g_regex_new ("[A-Z]+", 0, 0, NULL);
+ *   g_regex_match (regex, string, 0, &amp;match_info);
+ *   while (g_match_info_matches (match_info))
+ *     {
+ *       gchar *word = g_match_info_fetch (match_info, 0);
+ *       g_print ("Found: %s\n", word);
+ *       g_free (word);
+ *       g_match_info_next (match_info, NULL);
+ *     }
+ *   g_match_info_free (match_info);
+ *   g_regex_unref (regex);
+ * }
+ * ]|
+ *
+ * @string is not copied and is used in #GMatchInfo internally. If
+ * you use any #GMatchInfo method (except g_match_info_free()) after
+ * freeing or modifying @string then the behaviour is undefined.
+ *
+ * Returns: %TRUE is the string matched, %FALSE otherwise
+ *
+ * Since: 2.14
+ */
+gboolean
+g_regex_match (const GRegex      *regex,
+               const gchar       *string,
+               GRegexMatchFlags   match_options,
+               GMatchInfo       **match_info)
+{
+  return g_regex_match_full (regex, string, -1, 0, match_options,
+                             match_info, NULL);
+}
+
+/**
+ * g_regex_match_full:
+ * @regex: a #GRegex structure from g_regex_new()
+ * @string: (array length=string_len): the string to scan for matches
+ * @string_len: the length of @string, or -1 if @string is nul-terminated
+ * @start_position: starting index of the string to match
+ * @match_options: match options
+ * @match_info: (out) (allow-none): pointer to location where to store
+ *     the #GMatchInfo, or %NULL if you do not need it
+ * @error: location to store the error occuring, or %NULL to ignore errors
+ *
+ * Scans for a match in string for the pattern in @regex.
+ * The @match_options are combined with the match options specified
+ * when the @regex structure was created, letting you have more
+ * flexibility in reusing #GRegex structures.
+ *
+ * Setting @start_position differs from just passing over a shortened
+ * string and setting #G_REGEX_MATCH_NOTBOL in the case of a pattern
+ * that begins with any kind of lookbehind assertion, such as "\b".
+ *
+ * A #GMatchInfo structure, used to get information on the match, is
+ * stored in @match_info if not %NULL. Note that if @match_info is
+ * not %NULL then it is created even if the function returns %FALSE,
+ * i.e. you must free it regardless if regular expression actually
+ * matched.
+ *
+ * @string is not copied and is used in #GMatchInfo internally. If
+ * you use any #GMatchInfo method (except g_match_info_free()) after
+ * freeing or modifying @string then the behaviour is undefined.
+ *
+ * To retrieve all the non-overlapping matches of the pattern in
+ * string you can use g_match_info_next().
+ *
+ * |[
+ * static void
+ * print_uppercase_words (const gchar *string)
+ * {
+ *   /&ast; Print all uppercase-only words. &ast;/
+ *   GRegex *regex;
+ *   GMatchInfo *match_info;
+ *   GError *error = NULL;
+ *   &nbsp;
+ *   regex = g_regex_new ("[A-Z]+", 0, 0, NULL);
+ *   g_regex_match_full (regex, string, -1, 0, 0, &amp;match_info, &amp;error);
+ *   while (g_match_info_matches (match_info))
+ *     {
+ *       gchar *word = g_match_info_fetch (match_info, 0);
+ *       g_print ("Found: %s\n", word);
+ *       g_free (word);
+ *       g_match_info_next (match_info, &amp;error);
+ *     }
+ *   g_match_info_free (match_info);
+ *   g_regex_unref (regex);
+ *   if (error != NULL)
+ *     {
+ *       g_printerr ("Error while matching: %s\n", error->message);
+ *       g_error_free (error);
+ *     }
+ * }
+ * ]|
+ *
+ * Returns: %TRUE is the string matched, %FALSE otherwise
+ *
+ * Since: 2.14
+ */
+gboolean
+g_regex_match_full (const GRegex      *regex,
+                    const gchar       *string,
+                    gssize             string_len,
+                    gint               start_position,
+                    GRegexMatchFlags   match_options,
+                    GMatchInfo       **match_info,
+                    GError           **error)
+{
+  GMatchInfo *info;
+  gboolean match_ok;
+
+  g_return_val_if_fail (regex != NULL, FALSE);
+  g_return_val_if_fail (string != NULL, FALSE);
+  g_return_val_if_fail (start_position >= 0, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, FALSE);
+
+  info = match_info_new (regex, string, string_len, start_position,
+                         match_options, FALSE);
+  match_ok = g_match_info_next (info, error);
+  if (match_info != NULL)
+    *match_info = info;
+  else
+    g_match_info_free (info);
+
+  return match_ok;
+}
+
+/**
+ * g_regex_match_all:
+ * @regex: a #GRegex structure from g_regex_new()
+ * @string: the string to scan for matches
+ * @match_options: match options
+ * @match_info: (out) (allow-none): pointer to location where to store
+ *     the #GMatchInfo, or %NULL if you do not need it
+ *
+ * Using the standard algorithm for regular expression matching only
+ * the longest match in the string is retrieved. This function uses
+ * a different algorithm so it can retrieve all the possible matches.
+ * For more documentation see g_regex_match_all_full().
+ *
+ * A #GMatchInfo structure, used to get information on the match, is
+ * stored in @match_info if not %NULL. Note that if @match_info is
+ * not %NULL then it is created even if the function returns %FALSE,
+ * i.e. you must free it regardless if regular expression actually
+ * matched.
+ *
+ * @string is not copied and is used in #GMatchInfo internally. If
+ * you use any #GMatchInfo method (except g_match_info_free()) after
+ * freeing or modifying @string then the behaviour is undefined.
+ *
+ * Returns: %TRUE is the string matched, %FALSE otherwise
+ *
+ * Since: 2.14
+ */
+gboolean
+g_regex_match_all (const GRegex      *regex,
+                   const gchar       *string,
+                   GRegexMatchFlags   match_options,
+                   GMatchInfo       **match_info)
+{
+  return g_regex_match_all_full (regex, string, -1, 0, match_options,
+                                 match_info, NULL);
+}
+
+/**
+ * g_regex_match_all_full:
+ * @regex: a #GRegex structure from g_regex_new()
+ * @string: (array length=string_len): the string to scan for matches
+ * @string_len: the length of @string, or -1 if @string is nul-terminated
+ * @start_position: starting index of the string to match
+ * @match_options: match options
+ * @match_info: (out) (allow-none): pointer to location where to store
+ *     the #GMatchInfo, or %NULL if you do not need it
+ * @error: location to store the error occuring, or %NULL to ignore errors
+ *
+ * Using the standard algorithm for regular expression matching only
+ * the longest match in the string is retrieved, it is not possibile
+ * to obtain all the available matches. For instance matching
+ * "&lt;a&gt; &lt;b&gt; &lt;c&gt;" against the pattern "&lt;.*&gt;"
+ * you get "&lt;a&gt; &lt;b&gt; &lt;c&gt;".
+ *
+ * This function uses a different algorithm (called DFA, i.e. deterministic
+ * finite automaton), so it can retrieve all the possible matches, all
+ * starting at the same point in the string. For instance matching
+ * "&lt;a&gt; &lt;b&gt; &lt;c&gt;" against the pattern "&lt;.*&gt;"
+ * you would obtain three matches: "&lt;a&gt; &lt;b&gt; &lt;c&gt;",
+ * "&lt;a&gt; &lt;b&gt;" and "&lt;a&gt;".
+ *
+ * The number of matched strings is retrieved using
+ * g_match_info_get_match_count(). To obtain the matched strings and
+ * their position you can use, respectively, g_match_info_fetch() and
+ * g_match_info_fetch_pos(). Note that the strings are returned in
+ * reverse order of length; that is, the longest matching string is
+ * given first.
+ *
+ * Note that the DFA algorithm is slower than the standard one and it
+ * is not able to capture substrings, so backreferences do not work.
+ *
+ * Setting @start_position differs from just passing over a shortened
+ * string and setting #G_REGEX_MATCH_NOTBOL in the case of a pattern
+ * that begins with any kind of lookbehind assertion, such as "\b".
+ *
+ * A #GMatchInfo structure, used to get information on the match, is
+ * stored in @match_info if not %NULL. Note that if @match_info is
+ * not %NULL then it is created even if the function returns %FALSE,
+ * i.e. you must free it regardless if regular expression actually
+ * matched.
+ *
+ * @string is not copied and is used in #GMatchInfo internally. If
+ * you use any #GMatchInfo method (except g_match_info_free()) after
+ * freeing or modifying @string then the behaviour is undefined.
+ *
+ * Returns: %TRUE is the string matched, %FALSE otherwise
+ *
+ * Since: 2.14
+ */
+gboolean
+g_regex_match_all_full (const GRegex      *regex,
+                        const gchar       *string,
+                        gssize             string_len,
+                        gint               start_position,
+                        GRegexMatchFlags   match_options,
+                        GMatchInfo       **match_info,
+                        GError           **error)
+{
+  GMatchInfo *info;
+  gboolean done;
+
+  g_return_val_if_fail (regex != NULL, FALSE);
+  g_return_val_if_fail (string != NULL, FALSE);
+  g_return_val_if_fail (start_position >= 0, FALSE);
+  g_return_val_if_fail (error == NULL || *error == NULL, FALSE);
+  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, FALSE);
+
+  info = match_info_new (regex, string, string_len, start_position,
+                         match_options, TRUE);
+
+  done = FALSE;
+  while (!done)
+    {
+      done = TRUE;
+      info->matches = pcre_dfa_exec (regex->pcre_re, regex->extra,
+                                     info->string, info->string_len,
+                                     info->pos,
+                                     regex->match_opts | match_options,
+                                     info->offsets, info->n_offsets,
+                                     info->workspace, info->n_workspace);
+      if (info->matches == PCRE_ERROR_DFA_WSSIZE)
+        {
+          /* info->workspace is too small. */
+          info->n_workspace *= 2;
+          info->workspace = g_realloc (info->workspace,
+                                       info->n_workspace * sizeof (gint));
+          done = FALSE;
+        }
+      else if (info->matches == 0)
+        {
+          /* info->offsets is too small. */
+          info->n_offsets *= 2;
+          info->offsets = g_realloc (info->offsets,
+                                     info->n_offsets * sizeof (gint));
+          done = FALSE;
+        }
+      else if (IS_PCRE_ERROR (info->matches))
+        {
+          g_set_error (error, G_REGEX_ERROR, G_REGEX_ERROR_MATCH,
+                       _("Error while matching regular expression %s: %s"),
+                       regex->pattern, match_error (info->matches));
+        }
+    }
+
+  /* set info->pos to -1 so that a call to g_match_info_next() fails. */
+  info->pos = -1;
+
+  if (match_info != NULL)
+    *match_info = info;
+  else
+    g_match_info_free (info);
+
+  return info->matches >= 0;
+}
+
+/**
+ * g_regex_get_string_number:
+ * @regex: #GRegex structure
+ * @name: name of the subexpression
+ *
+ * Retrieves the number of the subexpression named @name.
+ *
+ * Returns: The number of the subexpression or -1 if @name
+ *   does not exists
+ *
+ * Since: 2.14
+ */
+gint
+g_regex_get_string_number (const GRegex *regex,
+                           const gchar  *name)
+{
+  gint num;
+
+  g_return_val_if_fail (regex != NULL, -1);
+  g_return_val_if_fail (name != NULL, -1);
+
+  num = pcre_get_stringnumber (regex->pcre_re, name);
+  if (num == PCRE_ERROR_NOSUBSTRING)
+    num = -1;
+
+  return num;
+}
+
+/**
+ * g_regex_split_simple:
+ * @pattern: the regular expression
+ * @string: the string to scan for matches
+ * @compile_options: compile options for the regular expression, or 0
+ * @match_options: match options, or 0
+ *
+ * Breaks the string on the pattern, and returns an array of
+ * the tokens. If the pattern contains capturing parentheses,
+ * then the text for each of the substrings will also be returned.
+ * If the pattern does not match anywhere in the string, then the
+ * whole string is returned as the first token.
+ *
+ * This function is equivalent to g_regex_split() but it does
+ * not require to compile the pattern with g_regex_new(), avoiding
+ * some lines of code when you need just to do a split without
+ * extracting substrings, capture counts, and so on.
+ *
+ * If this function is to be called on the same @pattern more than
+ * once, it's more efficient to compile the pattern once with
+ * g_regex_new() and then use g_regex_split().
+ *
+ * As a special case, the result of splitting the empty string ""
+ * is an empty vector, not a vector containing a single string.
+ * The reason for this special case is that being able to represent
+ * a empty vector is typically more useful than consistent handling
+ * of empty elements. If you do need to represent empty elements,
+ * you'll need to check for the empty string before calling this
+ * function.
+ *
+ * A pattern that can match empty strings splits @string into
+ * separate characters wherever it matches the empty string between
+ * characters. For example splitting "ab c" using as a separator
+ * "\s*", you will get "a", "b" and "c".
+ *
+ * Returns: a %NULL-terminated array of strings. Free it using g_strfreev()
+ *
+ * Since: 2.14
+ **/
+gchar **
+g_regex_split_simple (const gchar        *pattern,
+                      const gchar        *string,
+                      GRegexCompileFlags  compile_options,
+                      GRegexMatchFlags    match_options)
+{
+  GRegex *regex;
+  gchar **result;
+
+  regex = g_regex_new (pattern, compile_options, 0, NULL);
+  if (!regex)
+    return NULL;
+  result = g_regex_split_full (regex, string, -1, 0, match_options, 0, NULL);
+  g_regex_unref (regex);
+  return result;
+}
+
+/**
+ * g_regex_split:
+ * @regex: a #GRegex structure
+ * @string: the string to split with the pattern
+ * @match_options: match time option flags
+ *
+ * Breaks the string on the pattern, and returns an array of the tokens.
+ * If the pattern contains capturing parentheses, then the text for each
+ * of the substrings will also be returned. If the pattern does not match
+ * anywhere in the string, then the whole string is returned as the first
+ * token.
+ *
+ * As a special case, the result of splitting the empty string "" is an
+ * empty vector, not a vector containing a single string. The reason for
+ * this special case is that being able to represent a empty vector is
+ * typically more useful than consistent handling of empty elements. If
+ * you do need to represent empty elements, you'll need to check for the
+ * empty string before calling this function.
+ *
+ * A pattern that can match empty strings splits @string into separate
+ * characters wherever it matches the empty string between characters.
+ * For example splitting "ab c" using as a separator "\s*", you will get
+ * "a", "b" and "c".
+ *
+ * Returns: a %NULL-terminated gchar ** array. Free it using g_strfreev()
+ *
+ * Since: 2.14
+ **/
+gchar **
+g_regex_split (const GRegex     *regex,
+               const gchar      *string,
+               GRegexMatchFlags  match_options)
+{
+  return g_regex_split_full (regex, string, -1, 0,
+                             match_options, 0, NULL);
+}
+
+/**
+ * g_regex_split_full:
+ * @regex: a #GRegex structure
+ * @string: (array length=string_len): the string to split with the pattern
+ * @string_len: the length of @string, or -1 if @string is nul-terminated
+ * @start_position: starting index of the string to match
+ * @match_options: match time option flags
+ * @max_tokens: the maximum number of tokens to split @string into.
+ *   If this is less than 1, the string is split completely
+ * @error: return location for a #GError
+ *
+ * Breaks the string on the pattern, and returns an array of the tokens.
+ * If the pattern contains capturing parentheses, then the text for each
+ * of the substrings will also be returned. If the pattern does not match
+ * anywhere in the string, then the whole string is returned as the first
+ * token.
+ *
+ * As a special case, the result of splitting the empty string "" is an
+ * empty vector, not a vector containing a single string. The reason for
+ * this special case is that being able to represent a empty vector is
+ * typically more useful than consistent handling of empty elements. If
+ * you do need to represent empty elements, you'll need to check for the
+ * empty string before calling this function.
+ *
+ * A pattern that can match empty strings splits @string into separate
+ * characters wherever it matches the empty string between characters.
+ * For example splitting "ab c" using as a separator "\s*", you will get
+ * "a", "b" and "c".
+ *
+ * Setting @start_position differs from just passing over a shortened
+ * string and setting #G_REGEX_MATCH_NOTBOL in the case of a pattern
+ * that begins with any kind of lookbehind assertion, such as "\b".
+ *
+ * Returns: a %NULL-terminated gchar ** array. Free it using g_strfreev()
+ *
+ * Since: 2.14
+ **/
+gchar **
+g_regex_split_full (const GRegex      *regex,
+                    const gchar       *string,
+                    gssize             string_len,
+                    gint               start_position,
+                    GRegexMatchFlags   match_options,
+                    gint               max_tokens,
+                    GError           **error)
+{
+  GError *tmp_error = NULL;
+  GMatchInfo *match_info;
+  GList *list, *last;
+  gint i;
+  gint token_count;
+  gboolean match_ok;
+  /* position of the last separator. */
+  gint last_separator_end;
+  /* was the last match 0 bytes long? */
+  gboolean last_match_is_empty;
+  /* the returned array of char **s */
+  gchar **string_list;
+
+  g_return_val_if_fail (regex != NULL, NULL);
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (start_position >= 0, NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);
+
+  if (max_tokens <= 0)
+    max_tokens = G_MAXINT;
+
+  if (string_len < 0)
+    string_len = strlen (string);
+
+  /* zero-length string */
+  if (string_len - start_position == 0)
+    return g_new0 (gchar *, 1);
+
+  if (max_tokens == 1)
+    {
+      string_list = g_new0 (gchar *, 2);
+      string_list[0] = g_strndup (&string[start_position],
+                                  string_len - start_position);
+      return string_list;
+    }
+
+  list = NULL;
+  token_count = 0;
+  last_separator_end = start_position;
+  last_match_is_empty = FALSE;
+
+  match_ok = g_regex_match_full (regex, string, string_len, start_position,
+                                 match_options, &match_info, &tmp_error);
+  while (tmp_error == NULL)
+    {
+      if (match_ok)
+        {
+          last_match_is_empty =
+                    (match_info->offsets[0] == match_info->offsets[1]);
+
+          /* we need to skip empty separators at the same position of the end
+           * of another separator. e.g. the string is "a b" and the separator
+           * is " *", so from 1 to 2 we have a match and at position 2 we have
+           * an empty match. */
+          if (last_separator_end != match_info->offsets[1])
+            {
+              gchar *token;
+              gint match_count;
+
+              token = g_strndup (string + last_separator_end,
+                                 match_info->offsets[0] - last_separator_end);
+              list = g_list_prepend (list, token);
+              token_count++;
+
+              /* if there were substrings, these need to be added to
+               * the list. */
+              match_count = g_match_info_get_match_count (match_info);
+              if (match_count > 1)
+                {
+                  for (i = 1; i < match_count; i++)
+                    list = g_list_prepend (list, g_match_info_fetch (match_info, i));
+                }
+            }
+        }
+      else
+        {
+          /* if there was no match, copy to end of string. */
+          if (!last_match_is_empty)
+            {
+              gchar *token = g_strndup (string + last_separator_end,
+                                        match_info->string_len - last_separator_end);
+              list = g_list_prepend (list, token);
+            }
+          /* no more tokens, end the loop. */
+          break;
+        }
+
+      /* -1 to leave room for the last part. */
+      if (token_count >= max_tokens - 1)
+        {
+          /* we have reached the maximum number of tokens, so we copy
+           * the remaining part of the string. */
+          if (last_match_is_empty)
+            {
+              /* the last match was empty, so we have moved one char
+               * after the real position to avoid empty matches at the
+               * same position. */
+              match_info->pos = PREV_CHAR (regex, &string[match_info->pos]) - string;
+            }
+          /* the if is needed in the case we have terminated the available
+           * tokens, but we are at the end of the string, so there are no
+           * characters left to copy. */
+          if (string_len > match_info->pos)
+            {
+              gchar *token = g_strndup (string + match_info->pos,
+                                        string_len - match_info->pos);
+              list = g_list_prepend (list, token);
+            }
+          /* end the loop. */
+          break;
+        }
+
+      last_separator_end = match_info->pos;
+      if (last_match_is_empty)
+        /* if the last match was empty, g_match_info_next() has moved
+         * forward to avoid infinite loops, but we still need to copy that
+         * character. */
+        last_separator_end = PREV_CHAR (regex, &string[last_separator_end]) - string;
+
+      match_ok = g_match_info_next (match_info, &tmp_error);
+    }
+  g_match_info_free (match_info);
+  if (tmp_error != NULL)
+    {
+      g_propagate_error (error, tmp_error);
+      g_list_foreach (list, (GFunc)g_free, NULL);
+      g_list_free (list);
+      match_info->pos = -1;
+      return NULL;
+    }
+
+  string_list = g_new (gchar *, g_list_length (list) + 1);
+  i = 0;
+  for (last = g_list_last (list); last; last = g_list_previous (last))
+    string_list[i++] = last->data;
+  string_list[i] = NULL;
+  g_list_free (list);
+
+  return string_list;
+}
+
+enum
+{
+  REPL_TYPE_STRING,
+  REPL_TYPE_CHARACTER,
+  REPL_TYPE_SYMBOLIC_REFERENCE,
+  REPL_TYPE_NUMERIC_REFERENCE,
+  REPL_TYPE_CHANGE_CASE
+};
+
+typedef enum
+{
+  CHANGE_CASE_NONE         = 1 << 0,
+  CHANGE_CASE_UPPER        = 1 << 1,
+  CHANGE_CASE_LOWER        = 1 << 2,
+  CHANGE_CASE_UPPER_SINGLE = 1 << 3,
+  CHANGE_CASE_LOWER_SINGLE = 1 << 4,
+  CHANGE_CASE_SINGLE_MASK  = CHANGE_CASE_UPPER_SINGLE | CHANGE_CASE_LOWER_SINGLE,
+  CHANGE_CASE_LOWER_MASK   = CHANGE_CASE_LOWER | CHANGE_CASE_LOWER_SINGLE,
+  CHANGE_CASE_UPPER_MASK   = CHANGE_CASE_UPPER | CHANGE_CASE_UPPER_SINGLE
+} ChangeCase;
+
+struct _InterpolationData
+{
+  gchar     *text;
+  gint       type;
+  gint       num;
+  gchar      c;
+  ChangeCase change_case;
+};
+
+static void
+free_interpolation_data (InterpolationData *data)
+{
+  g_free (data->text);
+  g_free (data);
+}
+
+static const gchar *
+expand_escape (const gchar        *replacement,
+               const gchar        *p,
+               InterpolationData  *data,
+               GError            **error)
+{
+  const gchar *q, *r;
+  gint x, d, h, i;
+  const gchar *error_detail;
+  gint base = 0;
+  GError *tmp_error = NULL;
+
+  p++;
+  switch (*p)
+    {
+    case 't':
+      p++;
+      data->c = '\t';
+      data->type = REPL_TYPE_CHARACTER;
+      break;
+    case 'n':
+      p++;
+      data->c = '\n';
+      data->type = REPL_TYPE_CHARACTER;
+      break;
+    case 'v':
+      p++;
+      data->c = '\v';
+      data->type = REPL_TYPE_CHARACTER;
+      break;
+    case 'r':
+      p++;
+      data->c = '\r';
+      data->type = REPL_TYPE_CHARACTER;
+      break;
+    case 'f':
+      p++;
+      data->c = '\f';
+      data->type = REPL_TYPE_CHARACTER;
+      break;
+    case 'a':
+      p++;
+      data->c = '\a';
+      data->type = REPL_TYPE_CHARACTER;
+      break;
+    case 'b':
+      p++;
+      data->c = '\b';
+      data->type = REPL_TYPE_CHARACTER;
+      break;
+    case '\\':
+      p++;
+      data->c = '\\';
+      data->type = REPL_TYPE_CHARACTER;
+      break;
+    case 'x':
+      p++;
+      x = 0;
+      if (*p == '{')
+        {
+          p++;
+          do
+            {
+              h = g_ascii_xdigit_value (*p);
+              if (h < 0)
+                {
+                  error_detail = _("hexadecimal digit or '}' expected");
+                  goto error;
+                }
+              x = x * 16 + h;
+              p++;
+            }
+          while (*p != '}');
+          p++;
+        }
+      else
+        {
+          for (i = 0; i < 2; i++)
+            {
+              h = g_ascii_xdigit_value (*p);
+              if (h < 0)
+                {
+                  error_detail = _("hexadecimal digit expected");
+                  goto error;
+                }
+              x = x * 16 + h;
+              p++;
+            }
+        }
+      data->type = REPL_TYPE_STRING;
+      data->text = g_new0 (gchar, 8);
+      g_unichar_to_utf8 (x, data->text);
+      break;
+    case 'l':
+      p++;
+      data->type = REPL_TYPE_CHANGE_CASE;
+      data->change_case = CHANGE_CASE_LOWER_SINGLE;
+      break;
+    case 'u':
+      p++;
+      data->type = REPL_TYPE_CHANGE_CASE;
+      data->change_case = CHANGE_CASE_UPPER_SINGLE;
+      break;
+    case 'L':
+      p++;
+      data->type = REPL_TYPE_CHANGE_CASE;
+      data->change_case = CHANGE_CASE_LOWER;
+      break;
+    case 'U':
+      p++;
+      data->type = REPL_TYPE_CHANGE_CASE;
+      data->change_case = CHANGE_CASE_UPPER;
+      break;
+    case 'E':
+      p++;
+      data->type = REPL_TYPE_CHANGE_CASE;
+      data->change_case = CHANGE_CASE_NONE;
+      break;
+    case 'g':
+      p++;
+      if (*p != '<')
+        {
+          error_detail = _("missing '<' in symbolic reference");
+          goto error;
+        }
+      q = p + 1;
+      do
+        {
+          p++;
+          if (!*p)
+            {
+              error_detail = _("unfinished symbolic reference");
+              goto error;
+            }
+        }
+      while (*p != '>');
+      if (p - q == 0)
+        {
+          error_detail = _("zero-length symbolic reference");
+          goto error;
+        }
+      if (g_ascii_isdigit (*q))
+        {
+          x = 0;
+          do
+            {
+              h = g_ascii_digit_value (*q);
+              if (h < 0)
+                {
+                  error_detail = _("digit expected");
+                  p = q;
+                  goto error;
+                }
+              x = x * 10 + h;
+              q++;
+            }
+          while (q != p);
+          data->num = x;
+          data->type = REPL_TYPE_NUMERIC_REFERENCE;
+        }
+      else
+        {
+          r = q;
+          do
+            {
+              if (!g_ascii_isalnum (*r))
+                {
+                  error_detail = _("illegal symbolic reference");
+                  p = r;
+                  goto error;
+                }
+              r++;
+            }
+          while (r != p);
+          data->text = g_strndup (q, p - q);
+          data->type = REPL_TYPE_SYMBOLIC_REFERENCE;
+        }
+      p++;
+      break;
+    case '0':
+      /* if \0 is followed by a number is an octal number representing a
+       * character, else it is a numeric reference. */
+      if (g_ascii_digit_value (*g_utf8_next_char (p)) >= 0)
+        {
+          base = 8;
+          p = g_utf8_next_char (p);
+        }
+    case '1':
+    case '2':
+    case '3':
+    case '4':
+    case '5':
+    case '6':
+    case '7':
+    case '8':
+    case '9':
+      x = 0;
+      d = 0;
+      for (i = 0; i < 3; i++)
+        {
+          h = g_ascii_digit_value (*p);
+          if (h < 0)
+            break;
+          if (h > 7)
+            {
+              if (base == 8)
+                break;
+              else
+                base = 10;
+            }
+          if (i == 2 && base == 10)
+            break;
+          x = x * 8 + h;
+          d = d * 10 + h;
+          p++;
+        }
+      if (base == 8 || i == 3)
+        {
+          data->type = REPL_TYPE_STRING;
+          data->text = g_new0 (gchar, 8);
+          g_unichar_to_utf8 (x, data->text);
+        }
+      else
+        {
+          data->type = REPL_TYPE_NUMERIC_REFERENCE;
+          data->num = d;
+        }
+      break;
+    case 0:
+      error_detail = _("stray final '\\'");
+      goto error;
+      break;
+    default:
+      error_detail = _("unknown escape sequence");
+      goto error;
+    }
+
+  return p;
+
+ error:
+  /* G_GSSIZE_FORMAT doesn't work with gettext, so we use %lu */
+  tmp_error = g_error_new (G_REGEX_ERROR,
+                           G_REGEX_ERROR_REPLACE,
+                           _("Error while parsing replacement "
+                             "text \"%s\" at char %lu: %s"),
+                           replacement,
+                           (gulong)(p - replacement),
+                           error_detail);
+  g_propagate_error (error, tmp_error);
+
+  return NULL;
+}
+
+static GList *
+split_replacement (const gchar  *replacement,
+                   GError      **error)
+{
+  GList *list = NULL;
+  InterpolationData *data;
+  const gchar *p, *start;
+
+  start = p = replacement;
+  while (*p)
+    {
+      if (*p == '\\')
+        {
+          data = g_new0 (InterpolationData, 1);
+          start = p = expand_escape (replacement, p, data, error);
+          if (p == NULL)
+            {
+              g_list_foreach (list, (GFunc)free_interpolation_data, NULL);
+              g_list_free (list);
+              free_interpolation_data (data);
+
+              return NULL;
+            }
+          list = g_list_prepend (list, data);
+        }
+      else
+        {
+          p++;
+          if (*p == '\\' || *p == '\0')
+            {
+              if (p - start > 0)
+                {
+                  data = g_new0 (InterpolationData, 1);
+                  data->text = g_strndup (start, p - start);
+                  data->type = REPL_TYPE_STRING;
+                  list = g_list_prepend (list, data);
+                }
+            }
+        }
+    }
+
+  return g_list_reverse (list);
+}
+
+/* Change the case of c based on change_case. */
+#define CHANGE_CASE(c, change_case) \
+        (((change_case) & CHANGE_CASE_LOWER_MASK) ? \
+                g_unichar_tolower (c) : \
+                g_unichar_toupper (c))
+
+static void
+string_append (GString     *string,
+               const gchar *text,
+               ChangeCase  *change_case)
+{
+  gunichar c;
+
+  if (text[0] == '\0')
+    return;
+
+  if (*change_case == CHANGE_CASE_NONE)
+    {
+      g_string_append (string, text);
+    }
+  else if (*change_case & CHANGE_CASE_SINGLE_MASK)
+    {
+      c = g_utf8_get_char (text);
+      g_string_append_unichar (string, CHANGE_CASE (c, *change_case));
+      g_string_append (string, g_utf8_next_char (text));
+      *change_case = CHANGE_CASE_NONE;
+    }
+  else
+    {
+      while (*text != '\0')
+        {
+          c = g_utf8_get_char (text);
+          g_string_append_unichar (string, CHANGE_CASE (c, *change_case));
+          text = g_utf8_next_char (text);
+        }
+    }
+}
+
+static gboolean
+interpolate_replacement (const GMatchInfo *match_info,
+                         GString          *result,
+                         gpointer          data)
+{
+  GList *list;
+  InterpolationData *idata;
+  gchar *match;
+  ChangeCase change_case = CHANGE_CASE_NONE;
+
+  for (list = data; list; list = list->next)
+    {
+      idata = list->data;
+      switch (idata->type)
+        {
+        case REPL_TYPE_STRING:
+          string_append (result, idata->text, &change_case);
+          break;
+        case REPL_TYPE_CHARACTER:
+          g_string_append_c (result, CHANGE_CASE (idata->c, change_case));
+          if (change_case & CHANGE_CASE_SINGLE_MASK)
+            change_case = CHANGE_CASE_NONE;
+          break;
+        case REPL_TYPE_NUMERIC_REFERENCE:
+          match = g_match_info_fetch (match_info, idata->num);
+          if (match)
+            {
+              string_append (result, match, &change_case);
+              g_free (match);
+            }
+          break;
+        case REPL_TYPE_SYMBOLIC_REFERENCE:
+          match = g_match_info_fetch_named (match_info, idata->text);
+          if (match)
+            {
+              string_append (result, match, &change_case);
+              g_free (match);
+            }
+          break;
+        case REPL_TYPE_CHANGE_CASE:
+          change_case = idata->change_case;
+          break;
+        }
+    }
+
+  return FALSE;
+}
+
+/* whether actual match_info is needed for replacement, i.e.
+ * whether there are references
+ */
+static gboolean
+interpolation_list_needs_match (GList *list)
+{
+  while (list != NULL)
+    {
+      InterpolationData *data = list->data;
+
+      if (data->type == REPL_TYPE_SYMBOLIC_REFERENCE ||
+          data->type == REPL_TYPE_NUMERIC_REFERENCE)
+        {
+          return TRUE;
+        }
+
+      list = list->next;
+    }
+
+  return FALSE;
+}
+
+/**
+ * g_regex_replace:
+ * @regex: a #GRegex structure
+ * @string: (array length=string_len): the string to perform matches against
+ * @string_len: the length of @string, or -1 if @string is nul-terminated
+ * @start_position: starting index of the string to match
+ * @replacement: text to replace each match with
+ * @match_options: options for the match
+ * @error: location to store the error occuring, or %NULL to ignore errors
+ *
+ * Replaces all occurrences of the pattern in @regex with the
+ * replacement text. Backreferences of the form '\number' or
+ * '\g&lt;number&gt;' in the replacement text are interpolated by the
+ * number-th captured subexpression of the match, '\g&lt;name&gt;' refers
+ * to the captured subexpression with the given name. '\0' refers to the
+ * complete match, but '\0' followed by a number is the octal representation
+ * of a character. To include a literal '\' in the replacement, write '\\'.
+ * There are also escapes that changes the case of the following text:
+ *
+ * <variablelist>
+ * <varlistentry><term>\l</term>
+ * <listitem>
+ * <para>Convert to lower case the next character</para>
+ * </listitem>
+ * </varlistentry>
+ * <varlistentry><term>\u</term>
+ * <listitem>
+ * <para>Convert to upper case the next character</para>
+ * </listitem>
+ * </varlistentry>
+ * <varlistentry><term>\L</term>
+ * <listitem>
+ * <para>Convert to lower case till \E</para>
+ * </listitem>
+ * </varlistentry>
+ * <varlistentry><term>\U</term>
+ * <listitem>
+ * <para>Convert to upper case till \E</para>
+ * </listitem>
+ * </varlistentry>
+ * <varlistentry><term>\E</term>
+ * <listitem>
+ * <para>End case modification</para>
+ * </listitem>
+ * </varlistentry>
+ * </variablelist>
+ *
+ * If you do not need to use backreferences use g_regex_replace_literal().
+ *
+ * The @replacement string must be UTF-8 encoded even if #G_REGEX_RAW was
+ * passed to g_regex_new(). If you want to use not UTF-8 encoded stings
+ * you can use g_regex_replace_literal().
+ *
+ * Setting @start_position differs from just passing over a shortened
+ * string and setting #G_REGEX_MATCH_NOTBOL in the case of a pattern that
+ * begins with any kind of lookbehind assertion, such as "\b".
+ *
+ * Returns: a newly allocated string containing the replacements
+ *
+ * Since: 2.14
+ */
+gchar *
+g_regex_replace (const GRegex      *regex,
+                 const gchar       *string,
+                 gssize             string_len,
+                 gint               start_position,
+                 const gchar       *replacement,
+                 GRegexMatchFlags   match_options,
+                 GError           **error)
+{
+  gchar *result;
+  GList *list;
+  GError *tmp_error = NULL;
+
+  g_return_val_if_fail (regex != NULL, NULL);
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (start_position >= 0, NULL);
+  g_return_val_if_fail (replacement != NULL, NULL);
+  g_return_val_if_fail (error == NULL || *error == NULL, NULL);
+  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);
+
+  list = split_replacement (replacement, &tmp_error);
+  if (tmp_error != NULL)
+    {
+      g_propagate_error (error, tmp_error);
+      return NULL;
+    }
+
+  result = g_regex_replace_eval (regex,
+                                 string, string_len, start_position,
+                                 match_options,
+                                 interpolate_replacement,
+                                 (gpointer)list,
+                                 &tmp_error);
+  if (tmp_error != NULL)
+    g_propagate_error (error, tmp_error);
+
+  g_list_foreach (list, (GFunc)free_interpolation_data, NULL);
+  g_list_free (list);
+
+  return result;
+}
+
+static gboolean
+literal_replacement (const GMatchInfo *match_info,
+                     GString          *result,
+                     gpointer          data)
+{
+  g_string_append (result, data);
+  return FALSE;
+}
+
+/**
+ * g_regex_replace_literal:
+ * @regex: a #GRegex structure
+ * @string: (array length=string_len): the string to perform matches against
+ * @string_len: the length of @string, or -1 if @string is nul-terminated
+ * @start_position: starting index of the string to match
+ * @replacement: text to replace each match with
+ * @match_options: options for the match
+ * @error: location to store the error occuring, or %NULL to ignore errors
+ *
+ * Replaces all occurrences of the pattern in @regex with the
+ * replacement text. @replacement is replaced literally, to
+ * include backreferences use g_regex_replace().
+ *
+ * Setting @start_position differs from just passing over a
+ * shortened string and setting #G_REGEX_MATCH_NOTBOL in the
+ * case of a pattern that begins with any kind of lookbehind
+ * assertion, such as "\b".
+ *
+ * Returns: a newly allocated string containing the replacements
+ *
+ * Since: 2.14
+ */
+gchar *
+g_regex_replace_literal (const GRegex      *regex,
+                         const gchar       *string,
+                         gssize             string_len,
+                         gint               start_position,
+                         const gchar       *replacement,
+                         GRegexMatchFlags   match_options,
+                         GError           **error)
+{
+  g_return_val_if_fail (replacement != NULL, NULL);
+  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);
+
+  return g_regex_replace_eval (regex,
+                               string, string_len, start_position,
+                               match_options,
+                               literal_replacement,
+                               (gpointer)replacement,
+                               error);
+}
+
+/**
+ * g_regex_replace_eval:
+ * @regex: a #GRegex structure from g_regex_new()
+ * @string: (array length=string_len): string to perform matches against
+ * @string_len: the length of @string, or -1 if @string is nul-terminated
+ * @start_position: starting index of the string to match
+ * @match_options: options for the match
+ * @eval: a function to call for each match
+ * @user_data: user data to pass to the function
+ * @error: location to store the error occuring, or %NULL to ignore errors
+ *
+ * Replaces occurrences of the pattern in regex with the output of
+ * @eval for that occurrence.
+ *
+ * Setting @start_position differs from just passing over a shortened
+ * string and setting #G_REGEX_MATCH_NOTBOL in the case of a pattern
+ * that begins with any kind of lookbehind assertion, such as "\b".
+ *
+ * The following example uses g_regex_replace_eval() to replace multiple
+ * strings at once:
+ * |[
+ * static gboolean
+ * eval_cb (const GMatchInfo *info,
+ *          GString          *res,
+ *          gpointer          data)
+ * {
+ *   gchar *match;
+ *   gchar *r;
+ *
+ *    match = g_match_info_fetch (info, 0);
+ *    r = g_hash_table_lookup ((GHashTable *)data, match);
+ *    g_string_append (res, r);
+ *    g_free (match);
+ *
+ *    return FALSE;
+ * }
+ *
+ * /&ast; ... &ast;/
+ *
+ * GRegex *reg;
+ * GHashTable *h;
+ * gchar *res;
+ *
+ * h = g_hash_table_new (g_str_hash, g_str_equal);
+ *
+ * g_hash_table_insert (h, "1", "ONE");
+ * g_hash_table_insert (h, "2", "TWO");
+ * g_hash_table_insert (h, "3", "THREE");
+ * g_hash_table_insert (h, "4", "FOUR");
+ *
+ * reg = g_regex_new ("1|2|3|4", 0, 0, NULL);
+ * res = g_regex_replace_eval (reg, text, -1, 0, 0, eval_cb, h, NULL);
+ * g_hash_table_destroy (h);
+ *
+ * /&ast; ... &ast;/
+ * ]|
+ *
+ * Returns: a newly allocated string containing the replacements
+ *
+ * Since: 2.14
+ */
+gchar *
+g_regex_replace_eval (const GRegex        *regex,
+                      const gchar         *string,
+                      gssize               string_len,
+                      gint                 start_position,
+                      GRegexMatchFlags     match_options,
+                      GRegexEvalCallback   eval,
+                      gpointer             user_data,
+                      GError             **error)
+{
+  GMatchInfo *match_info;
+  GString *result;
+  gint str_pos = 0;
+  gboolean done = FALSE;
+  GError *tmp_error = NULL;
+
+  g_return_val_if_fail (regex != NULL, NULL);
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (start_position >= 0, NULL);
+  g_return_val_if_fail (eval != NULL, NULL);
+  g_return_val_if_fail ((match_options & ~G_REGEX_MATCH_MASK) == 0, NULL);
+
+  if (string_len < 0)
+    string_len = strlen (string);
+
+  result = g_string_sized_new (string_len);
+
+  /* run down the string making matches. */
+  g_regex_match_full (regex, string, string_len, start_position,
+                      match_options, &match_info, &tmp_error);
+  while (!done && g_match_info_matches (match_info))
+    {
+      g_string_append_len (result,
+                           string + str_pos,
+                           match_info->offsets[0] - str_pos);
+      done = (*eval) (match_info, result, user_data);
+      str_pos = match_info->offsets[1];
+      g_match_info_next (match_info, &tmp_error);
+    }
+  g_match_info_free (match_info);
+  if (tmp_error != NULL)
+    {
+      g_propagate_error (error, tmp_error);
+      g_string_free (result, TRUE);
+      return NULL;
+    }
+
+  g_string_append_len (result, string + str_pos, string_len - str_pos);
+  return g_string_free (result, FALSE);
+}
+
+/**
+ * g_regex_check_replacement:
+ * @replacement: the replacement string
+ * @has_references: (out) (allow-none): location to store information about
+ *   references in @replacement or %NULL
+ * @error: location to store error
+ *
+ * Checks whether @replacement is a valid replacement string
+ * (see g_regex_replace()), i.e. that all escape sequences in
+ * it are valid.
+ *
+ * If @has_references is not %NULL then @replacement is checked
+ * for pattern references. For instance, replacement text 'foo\n'
+ * does not contain references and may be evaluated without information
+ * about actual match, but '\0\1' (whole match followed by first
+ * subpattern) requires valid #GMatchInfo object.
+ *
+ * Returns: whether @replacement is a valid replacement string
+ *
+ * Since: 2.14
+ */
+gboolean
+g_regex_check_replacement (const gchar  *replacement,
+                           gboolean     *has_references,
+                           GError      **error)
+{
+  GList *list;
+  GError *tmp = NULL;
+
+  list = split_replacement (replacement, &tmp);
+
+  if (tmp)
+  {
+    g_propagate_error (error, tmp);
+    return FALSE;
+  }
+
+  if (has_references)
+    *has_references = interpolation_list_needs_match (list);
+
+  g_list_foreach (list, (GFunc) free_interpolation_data, NULL);
+  g_list_free (list);
+
+  return TRUE;
+}
+
+/**
+ * g_regex_escape_string:
+ * @string: (array length=length): the string to escape
+ * @length: the length of @string, or -1 if @string is nul-terminated
+ *
+ * Escapes the special characters used for regular expressions
+ * in @string, for instance "a.b*c" becomes "a\.b\*c". This
+ * function is useful to dynamically generate regular expressions.
+ *
+ * @string can contain nul characters that are replaced with "\0",
+ * in this case remember to specify the correct length of @string
+ * in @length.
+ *
+ * Returns: a newly-allocated escaped string
+ *
+ * Since: 2.14
+ */
+gchar *
+g_regex_escape_string (const gchar *string,
+                       gint         length)
+{
+  GString *escaped;
+  const char *p, *piece_start, *end;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  if (length < 0)
+    length = strlen (string);
+
+  end = string + length;
+  p = piece_start = string;
+  escaped = g_string_sized_new (length + 1);
+
+  while (p < end)
+    {
+      switch (*p)
+        {
+        case '\0':
+        case '\\':
+        case '|':
+        case '(':
+        case ')':
+        case '[':
+        case ']':
+        case '{':
+        case '}':
+        case '^':
+        case '$':
+        case '*':
+        case '+':
+        case '?':
+        case '.':
+          if (p != piece_start)
+            /* copy the previous piece. */
+            g_string_append_len (escaped, piece_start, p - piece_start);
+          g_string_append_c (escaped, '\\');
+          if (*p == '\0')
+            g_string_append_c (escaped, '0');
+          else
+            g_string_append_c (escaped, *p);
+          piece_start = ++p;
+          break;
+        default:
+          p = g_utf8_next_char (p);
+          break;
+        }
+  }
+
+  if (piece_start < end)
+    g_string_append_len (escaped, piece_start, end - piece_start);
+
+  return g_string_free (escaped, FALSE);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gregex.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gregex.h
new file mode 100644 (file)
index 0000000..ce1b44a
--- /dev/null
@@ -0,0 +1,471 @@
+/* GRegex -- regular expression API wrapper around PCRE.
+ *
+ * Copyright (C) 1999, 2000 Scott Wimer
+ * Copyright (C) 2004, Matthias Clasen <mclasen@redhat.com>
+ * Copyright (C) 2005 - 2007, Marco Barisione <marco@barisione.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 St, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_REGEX_H__
+#define __G_REGEX_H__
+
+#include <glib/gerror.h>
+#include <glib/gstring.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GRegexError:
+ * @G_REGEX_ERROR_COMPILE: Compilation of the regular expression failed.
+ * @G_REGEX_ERROR_OPTIMIZE: Optimization of the regular expression failed.
+ * @G_REGEX_ERROR_REPLACE: Replacement failed due to an ill-formed replacement
+ *     string.
+ * @G_REGEX_ERROR_MATCH: The match process failed.
+ * @G_REGEX_ERROR_INTERNAL: Internal error of the regular expression engine.
+ *     Since 2.16
+ * @G_REGEX_ERROR_STRAY_BACKSLASH: "\\" at end of pattern. Since 2.16
+ * @G_REGEX_ERROR_MISSING_CONTROL_CHAR: "\\c" at end of pattern. Since 2.16
+ * @G_REGEX_ERROR_UNRECOGNIZED_ESCAPE: Unrecognized character follows "\\".
+ *     Since 2.16
+ * @G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER: Numbers out of order in "{}"
+ *     quantifier. Since 2.16
+ * @G_REGEX_ERROR_QUANTIFIER_TOO_BIG: Number too big in "{}" quantifier.
+ *     Since 2.16
+ * @G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS: Missing terminating "]" for
+ *     character class. Since 2.16
+ * @G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS: Invalid escape sequence
+ *     in character class. Since 2.16
+ * @G_REGEX_ERROR_RANGE_OUT_OF_ORDER: Range out of order in character class.
+ *     Since 2.16
+ * @G_REGEX_ERROR_NOTHING_TO_REPEAT: Nothing to repeat. Since 2.16
+ * @G_REGEX_ERROR_UNRECOGNIZED_CHARACTER: Unrecognized character after "(?",
+ *     "(?&lt;" or "(?P". Since 2.16
+ * @G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS: POSIX named classes are
+ *     supported only within a class. Since 2.16
+ * @G_REGEX_ERROR_UNMATCHED_PARENTHESIS: Missing terminating ")" or ")"
+ *     without opening "(". Since 2.16
+ * @G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE: Reference to non-existent
+ *     subpattern. Since 2.16
+ * @G_REGEX_ERROR_UNTERMINATED_COMMENT: Missing terminating ")" after comment.
+ *     Since 2.16
+ * @G_REGEX_ERROR_EXPRESSION_TOO_LARGE: Regular expression too large.
+ *     Since 2.16
+ * @G_REGEX_ERROR_MEMORY_ERROR: Failed to get memory. Since 2.16
+ * @G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND: Lookbehind assertion is not
+ *     fixed length. Since 2.16
+ * @G_REGEX_ERROR_MALFORMED_CONDITION: Malformed number or name after "(?(".
+ *     Since 2.16
+ * @G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES: Conditional group contains
+ *     more than two branches. Since 2.16
+ * @G_REGEX_ERROR_ASSERTION_EXPECTED: Assertion expected after "(?(".
+ *     Since 2.16
+ * @G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME: Unknown POSIX class name.
+ *     Since 2.16
+ * @G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED: POSIX collating
+ *     elements are not supported. Since 2.16
+ * @G_REGEX_ERROR_HEX_CODE_TOO_LARGE: Character value in "\\x{...}" sequence
+ *     is too large. Since 2.16
+ * @G_REGEX_ERROR_INVALID_CONDITION: Invalid condition "(?(0)". Since 2.16
+ * @G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND: \\C not allowed in
+ *     lookbehind assertion. Since 2.16
+ * @G_REGEX_ERROR_INFINITE_LOOP: Recursive call could loop indefinitely.
+ *     Since 2.16
+ * @G_REGEX_ERROR_MISSING_SUBPATTERN_NAME_TERMINATOR: Missing terminator
+ *     in subpattern name. Since 2.16
+ * @G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME: Two named subpatterns have
+ *     the same name. Since 2.16
+ * @G_REGEX_ERROR_MALFORMED_PROPERTY: Malformed "\\P" or "\\p" sequence.
+ *     Since 2.16
+ * @G_REGEX_ERROR_UNKNOWN_PROPERTY: Unknown property name after "\\P" or
+ *     "\\p". Since 2.16
+ * @G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG: Subpattern name is too long
+ *     (maximum 32 characters). Since 2.16
+ * @G_REGEX_ERROR_TOO_MANY_SUBPATTERNS: Too many named subpatterns (maximum
+ *     10,000). Since 2.16
+ * @G_REGEX_ERROR_INVALID_OCTAL_VALUE: Octal value is greater than "\\377".
+ *     Since 2.16
+ * @G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE: "DEFINE" group contains more
+ *     than one branch. Since 2.16
+ * @G_REGEX_ERROR_DEFINE_REPETION: Repeating a "DEFINE" group is not allowed.
+ *     Since 2.16
+ * @G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS: Inconsistent newline options.
+ *     Since 2.16
+ * @G_REGEX_ERROR_MISSING_BACK_REFERENCE: "\\g" is not followed by a braced
+ *     name or an optionally braced non-zero number. Since 2.16
+ *
+ * Error codes returned by regular expressions functions.
+ *
+ * Since: 2.14
+ */
+typedef enum
+{
+  G_REGEX_ERROR_COMPILE,
+  G_REGEX_ERROR_OPTIMIZE,
+  G_REGEX_ERROR_REPLACE,
+  G_REGEX_ERROR_MATCH,
+  G_REGEX_ERROR_INTERNAL,
+
+  /* These are the error codes from PCRE + 100 */
+  G_REGEX_ERROR_STRAY_BACKSLASH = 101,
+  G_REGEX_ERROR_MISSING_CONTROL_CHAR = 102,
+  G_REGEX_ERROR_UNRECOGNIZED_ESCAPE = 103,
+  G_REGEX_ERROR_QUANTIFIERS_OUT_OF_ORDER = 104,
+  G_REGEX_ERROR_QUANTIFIER_TOO_BIG = 105,
+  G_REGEX_ERROR_UNTERMINATED_CHARACTER_CLASS = 106,
+  G_REGEX_ERROR_INVALID_ESCAPE_IN_CHARACTER_CLASS = 107,
+  G_REGEX_ERROR_RANGE_OUT_OF_ORDER = 108,
+  G_REGEX_ERROR_NOTHING_TO_REPEAT = 109,
+  G_REGEX_ERROR_UNRECOGNIZED_CHARACTER = 112,
+  G_REGEX_ERROR_POSIX_NAMED_CLASS_OUTSIDE_CLASS = 113,
+  G_REGEX_ERROR_UNMATCHED_PARENTHESIS = 114,
+  G_REGEX_ERROR_INEXISTENT_SUBPATTERN_REFERENCE = 115,
+  G_REGEX_ERROR_UNTERMINATED_COMMENT = 118,
+  G_REGEX_ERROR_EXPRESSION_TOO_LARGE = 120,
+  G_REGEX_ERROR_MEMORY_ERROR = 121,
+  G_REGEX_ERROR_VARIABLE_LENGTH_LOOKBEHIND = 125,
+  G_REGEX_ERROR_MALFORMED_CONDITION = 126,
+  G_REGEX_ERROR_TOO_MANY_CONDITIONAL_BRANCHES = 127,
+  G_REGEX_ERROR_ASSERTION_EXPECTED = 128,
+  G_REGEX_ERROR_UNKNOWN_POSIX_CLASS_NAME = 130,
+  G_REGEX_ERROR_POSIX_COLLATING_ELEMENTS_NOT_SUPPORTED = 131,
+  G_REGEX_ERROR_HEX_CODE_TOO_LARGE = 134,
+  G_REGEX_ERROR_INVALID_CONDITION = 135,
+  G_REGEX_ERROR_SINGLE_BYTE_MATCH_IN_LOOKBEHIND = 136,
+  G_REGEX_ERROR_INFINITE_LOOP = 140,
+  G_REGEX_ERROR_MISSING_SUBPATTERN_NAME_TERMINATOR = 142,
+  G_REGEX_ERROR_DUPLICATE_SUBPATTERN_NAME = 143,
+  G_REGEX_ERROR_MALFORMED_PROPERTY = 146,
+  G_REGEX_ERROR_UNKNOWN_PROPERTY = 147,
+  G_REGEX_ERROR_SUBPATTERN_NAME_TOO_LONG = 148,
+  G_REGEX_ERROR_TOO_MANY_SUBPATTERNS = 149,
+  G_REGEX_ERROR_INVALID_OCTAL_VALUE = 151,
+  G_REGEX_ERROR_TOO_MANY_BRANCHES_IN_DEFINE = 154,
+  G_REGEX_ERROR_DEFINE_REPETION = 155,
+  G_REGEX_ERROR_INCONSISTENT_NEWLINE_OPTIONS = 156,
+  G_REGEX_ERROR_MISSING_BACK_REFERENCE = 157
+} GRegexError;
+
+/**
+ * G_REGEX_ERROR:
+ *
+ * Error domain for regular expressions. Errors in this domain will be
+ * from the #GRegexError enumeration. See #GError for information on
+ * error domains.
+ *
+ * Since: 2.14
+ */
+#define G_REGEX_ERROR g_regex_error_quark ()
+
+GQuark g_regex_error_quark (void);
+
+/**
+ * GRegexCompileFlags:
+ * @G_REGEX_CASELESS: Letters in the pattern match both upper- and
+ *     lowercase letters. This option can be changed within a pattern
+ *     by a "(?i)" option setting.
+ * @G_REGEX_MULTILINE: By default, GRegex treats the strings as consisting
+ *     of a single line of characters (even if it actually contains
+ *     newlines). The "start of line" metacharacter ("^") matches only
+ *     at the start of the string, while the "end of line" metacharacter
+ *     ("$") matches only at the end of the string, or before a terminating
+ *     newline (unless #G_REGEX_DOLLAR_ENDONLY is set). When
+ *     #G_REGEX_MULTILINE is set, the "start of line" and "end of line"
+ *     constructs match immediately following or immediately before any
+ *     newline in the string, respectively, as well as at the very start
+ *     and end. This can be changed within a pattern by a "(?m)" option
+ *     setting.
+ * @G_REGEX_DOTALL: A dot metacharater (".") in the pattern matches all
+ *     characters, including newlines. Without it, newlines are excluded.
+ *     This option can be changed within a pattern by a ("?s") option setting.
+ * @G_REGEX_EXTENDED: Whitespace data characters in the pattern are
+ *     totally ignored except when escaped or inside a character class.
+ *     Whitespace does not include the VT character (code 11). In addition,
+ *     characters between an unescaped "#" outside a character class and
+ *     the next newline character, inclusive, are also ignored. This can
+ *     be changed within a pattern by a "(?x)" option setting.
+ * @G_REGEX_ANCHORED: The pattern is forced to be "anchored", that is,
+ *     it is constrained to match only at the first matching point in the
+ *     string that is being searched. This effect can also be achieved by
+ *     appropriate constructs in the pattern itself such as the "^"
+ *     metacharater.
+ * @G_REGEX_DOLLAR_ENDONLY: A dollar metacharacter ("$") in the pattern
+ *     matches only at the end of the string. Without this option, a
+ *     dollar also matches immediately before the final character if
+ *     it is a newline (but not before any other newlines). This option
+ *     is ignored if #G_REGEX_MULTILINE is set.
+ * @G_REGEX_UNGREEDY: Inverts the "greediness" of the quantifiers so that
+ *     they are not greedy by default, but become greedy if followed by "?".
+ *     It can also be set by a "(?U)" option setting within the pattern.
+ * @G_REGEX_RAW: Usually strings must be valid UTF-8 strings, using this
+ *     flag they are considered as a raw sequence of bytes.
+ *     @G_REGEX_NO_AUTO_CAPTURE: Disables the use of numbered capturing
+ *     parentheses in the pattern. Any opening parenthesis that is not
+ *     followed by "?" behaves as if it were followed by "?:" but named
+ *     parentheses can still be used for capturing (and they acquire numbers
+ *     in the usual way).
+ * @G_REGEX_OPTIMIZE: Optimize the regular expression. If the pattern will
+ *     be used many times, then it may be worth the effort to optimize it
+ *     to improve the speed of matches.
+ * @G_REGEX_DUPNAMES: Names used to identify capturing subpatterns need not
+ *     be unique. This can be helpful for certain types of pattern when it
+ *     is known that only one instance of the named subpattern can ever be
+ *     matched.
+ * @G_REGEX_NEWLINE_CR: Usually any newline character is recognized, if this
+ *     option is set, the only recognized newline character is '\r'.
+ * @G_REGEX_NEWLINE_LF: Usually any newline character is recognized, if this
+ *     option is set, the only recognized newline character is '\n'.
+ * @G_REGEX_NEWLINE_CRLF: Usually any newline character is recognized, if this
+ *     option is set, the only recognized newline character sequence is '\r\n'.
+ *
+ * Flags specifying compile-time options.
+ *
+ * Since: 2.14
+ */
+/* Remember to update G_REGEX_COMPILE_MASK in gregex.c after
+ * adding a new flag. */
+typedef enum
+{
+  G_REGEX_CASELESS          = 1 << 0,
+  G_REGEX_MULTILINE         = 1 << 1,
+  G_REGEX_DOTALL            = 1 << 2,
+  G_REGEX_EXTENDED          = 1 << 3,
+  G_REGEX_ANCHORED          = 1 << 4,
+  G_REGEX_DOLLAR_ENDONLY    = 1 << 5,
+  G_REGEX_UNGREEDY          = 1 << 9,
+  G_REGEX_RAW               = 1 << 11,
+  G_REGEX_NO_AUTO_CAPTURE   = 1 << 12,
+  G_REGEX_OPTIMIZE          = 1 << 13,
+  G_REGEX_DUPNAMES          = 1 << 19,
+  G_REGEX_NEWLINE_CR        = 1 << 20,
+  G_REGEX_NEWLINE_LF        = 1 << 21,
+  G_REGEX_NEWLINE_CRLF      = G_REGEX_NEWLINE_CR | G_REGEX_NEWLINE_LF
+} GRegexCompileFlags;
+
+/**
+ * GRegexMatchFlags:
+ * @G_REGEX_MATCH_ANCHORED: The pattern is forced to be "anchored", that is,
+ *     it is constrained to match only at the first matching point in the
+ *     string that is being searched. This effect can also be achieved by
+ *     appropriate constructs in the pattern itself such as the "^"
+ *     metacharater.
+ * @G_REGEX_MATCH_NOTBOL: Specifies that first character of the string is
+ *     not the beginning of a line, so the circumflex metacharacter should
+ *     not match before it. Setting this without #G_REGEX_MULTILINE (at
+ *     compile time) causes circumflex never to match. This option affects
+ *     only the behaviour of the circumflex metacharacter, it does not
+ *     affect "\A".
+ * @G_REGEX_MATCH_NOTEOL: Specifies that the end of the subject string is
+ *     not the end of a line, so the dollar metacharacter should not match
+ *     it nor (except in multiline mode) a newline immediately before it.
+ *     Setting this without #G_REGEX_MULTILINE (at compile time) causes
+ *     dollar never to match. This option affects only the behaviour of
+ *     the dollar metacharacter, it does not affect "\Z" or "\z".
+ * @G_REGEX_MATCH_NOTEMPTY: An empty string is not considered to be a valid
+ *     match if this option is set. If there are alternatives in the pattern,
+ *     they are tried. If all the alternatives match the empty string, the
+ *     entire match fails. For example, if the pattern "a?b?" is applied to
+ *     a string not beginning with "a" or "b", it matches the empty string
+ *     at the start of the string. With this flag set, this match is not
+ *     valid, so GRegex searches further into the string for occurrences
+ *     of "a" or "b".
+ * @G_REGEX_MATCH_PARTIAL: Turns on the partial matching feature, for more
+ *     documentation on partial matching see g_match_info_is_partial_match().
+ * @G_REGEX_MATCH_NEWLINE_CR: Overrides the newline definition set when
+ *     creating a new #GRegex, setting the '\r' character as line terminator.
+ * @G_REGEX_MATCH_NEWLINE_LF: Overrides the newline definition set when
+ *     creating a new #GRegex, setting the '\n' character as line terminator.
+ * @G_REGEX_MATCH_NEWLINE_CRLF: Overrides the newline definition set when
+ *     creating a new #GRegex, setting the '\r\n' characters as line terminator.
+ * @G_REGEX_MATCH_NEWLINE_ANY: Overrides the newline definition set when
+ *     creating a new #GRegex, any newline character or character sequence
+ *     is recognized.
+ *
+ * Flags specifying match-time options.
+ *
+ * Since: 2.14
+ */
+/* Remember to update G_REGEX_MATCH_MASK in gregex.c after
+ * adding a new flag. */
+typedef enum
+{
+  G_REGEX_MATCH_ANCHORED      = 1 << 4,
+  G_REGEX_MATCH_NOTBOL        = 1 << 7,
+  G_REGEX_MATCH_NOTEOL        = 1 << 8,
+  G_REGEX_MATCH_NOTEMPTY      = 1 << 10,
+  G_REGEX_MATCH_PARTIAL       = 1 << 15,
+  G_REGEX_MATCH_NEWLINE_CR    = 1 << 20,
+  G_REGEX_MATCH_NEWLINE_LF    = 1 << 21,
+  G_REGEX_MATCH_NEWLINE_CRLF  = G_REGEX_MATCH_NEWLINE_CR | G_REGEX_MATCH_NEWLINE_LF,
+  G_REGEX_MATCH_NEWLINE_ANY   = 1 << 22
+} GRegexMatchFlags;
+
+/**
+ * GRegex:
+ *
+ * A GRegex is the "compiled" form of a regular expression pattern. This
+ * structure is opaque and its fields cannot be accessed directly.
+ *
+ * Since: 2.14
+ */
+typedef struct _GRegex         GRegex;
+
+
+typedef struct _GMatchInfo     GMatchInfo;
+
+/**
+ * GRegexEvalCallback:
+ * @match_info: the #GMatchInfo generated by the match.
+ *     Use g_match_info_get_regex() and g_match_info_get_string() if you
+ *     need the #GRegex or the matched string.
+ * @result: a #GString containing the new string
+ * @user_data: user data passed to g_regex_replace_eval()
+ *
+ * Specifies the type of the function passed to g_regex_replace_eval().
+ * It is called for each occurance of the pattern in the string passed
+ * to g_regex_replace_eval(), and it should append the replacement to
+ * @result.
+ *
+ * Returns: %FALSE to continue the replacement process, %TRUE to stop it
+ *
+ * Since: 2.14
+ */
+typedef gboolean (*GRegexEvalCallback)         (const GMatchInfo *match_info,
+                                                GString          *result,
+                                                gpointer          user_data);
+
+
+GRegex          *g_regex_new                   (const gchar         *pattern,
+                                                GRegexCompileFlags   compile_options,
+                                                GRegexMatchFlags     match_options,
+                                                GError             **error);
+GRegex           *g_regex_ref                  (GRegex              *regex);
+void             g_regex_unref                 (GRegex              *regex);
+const gchar     *g_regex_get_pattern           (const GRegex        *regex);
+gint             g_regex_get_max_backref       (const GRegex        *regex);
+gint             g_regex_get_capture_count     (const GRegex        *regex);
+gint             g_regex_get_string_number     (const GRegex        *regex, 
+                                                const gchar         *name);
+gchar           *g_regex_escape_string         (const gchar         *string,
+                                                gint                 length);
+
+GRegexCompileFlags g_regex_get_compile_flags    (const GRegex        *regex);
+GRegexMatchFlags   g_regex_get_match_flags      (const GRegex        *regex);
+
+/* Matching. */
+gboolean         g_regex_match_simple          (const gchar         *pattern,
+                                                const gchar         *string,
+                                                GRegexCompileFlags   compile_options,
+                                                GRegexMatchFlags     match_options);
+gboolean         g_regex_match                 (const GRegex        *regex,
+                                                const gchar         *string,
+                                                GRegexMatchFlags     match_options,
+                                                GMatchInfo         **match_info);
+gboolean         g_regex_match_full            (const GRegex        *regex,
+                                                const gchar         *string,
+                                                gssize               string_len,
+                                                gint                 start_position,
+                                                GRegexMatchFlags     match_options,
+                                                GMatchInfo         **match_info,
+                                                GError             **error);
+gboolean         g_regex_match_all             (const GRegex        *regex,
+                                                const gchar         *string,
+                                                GRegexMatchFlags     match_options,
+                                                GMatchInfo         **match_info);
+gboolean         g_regex_match_all_full        (const GRegex        *regex,
+                                                const gchar         *string,
+                                                gssize               string_len,
+                                                gint                 start_position,
+                                                GRegexMatchFlags     match_options,
+                                                GMatchInfo         **match_info,
+                                                GError             **error);
+
+/* String splitting. */
+gchar          **g_regex_split_simple          (const gchar         *pattern,
+                                                const gchar         *string,
+                                                GRegexCompileFlags   compile_options,
+                                                GRegexMatchFlags     match_options);
+gchar          **g_regex_split                 (const GRegex        *regex,
+                                                const gchar         *string,
+                                                GRegexMatchFlags     match_options);
+gchar          **g_regex_split_full            (const GRegex        *regex,
+                                                const gchar         *string,
+                                                gssize               string_len,
+                                                gint                 start_position,
+                                                GRegexMatchFlags     match_options,
+                                                gint                 max_tokens,
+                                                GError             **error);
+
+/* String replacement. */
+gchar           *g_regex_replace               (const GRegex        *regex,
+                                                const gchar         *string,
+                                                gssize               string_len,
+                                                gint                 start_position,
+                                                const gchar         *replacement,
+                                                GRegexMatchFlags     match_options,
+                                                GError             **error);
+gchar           *g_regex_replace_literal       (const GRegex        *regex,
+                                                const gchar         *string,
+                                                gssize               string_len,
+                                                gint                 start_position,
+                                                const gchar         *replacement,
+                                                GRegexMatchFlags     match_options,
+                                                GError             **error);
+gchar           *g_regex_replace_eval          (const GRegex        *regex,
+                                                const gchar         *string,
+                                                gssize               string_len,
+                                                gint                 start_position,
+                                                GRegexMatchFlags     match_options,
+                                                GRegexEvalCallback   eval,
+                                                gpointer             user_data,
+                                                GError             **error);
+gboolean         g_regex_check_replacement     (const gchar         *replacement,
+                                                gboolean            *has_references,
+                                                GError             **error);
+
+/* Match info */
+GRegex          *g_match_info_get_regex        (const GMatchInfo    *match_info);
+const gchar      *g_match_info_get_string       (const GMatchInfo    *match_info);
+
+void             g_match_info_free             (GMatchInfo          *match_info);
+gboolean         g_match_info_next             (GMatchInfo          *match_info,
+                                                GError             **error);
+gboolean         g_match_info_matches          (const GMatchInfo    *match_info);
+gint             g_match_info_get_match_count  (const GMatchInfo    *match_info);
+gboolean         g_match_info_is_partial_match (const GMatchInfo    *match_info);
+gchar           *g_match_info_expand_references(const GMatchInfo    *match_info,
+                                                const gchar         *string_to_expand,
+                                                GError             **error);
+gchar           *g_match_info_fetch            (const GMatchInfo    *match_info,
+                                                gint                 match_num);
+gboolean         g_match_info_fetch_pos        (const GMatchInfo    *match_info,
+                                                gint                 match_num,
+                                                gint                *start_pos,
+                                                gint                *end_pos);
+gchar           *g_match_info_fetch_named      (const GMatchInfo    *match_info,
+                                                const gchar         *name);
+gboolean         g_match_info_fetch_named_pos  (const GMatchInfo    *match_info,
+                                                const gchar         *name,
+                                                gint                *start_pos,
+                                                gint                *end_pos);
+gchar          **g_match_info_fetch_all        (const GMatchInfo    *match_info);
+
+G_END_DECLS
+
+#endif  /*  __G_REGEX_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/grel.c b/resource/csdk/connectivity/lib/android/glib-master/glib/grel.c
new file mode 100644 (file)
index 0000000..59d5bbb
--- /dev/null
@@ -0,0 +1,675 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/* 
+ * MT safe
+ */
+
+#include "config.h"
+
+#include <stdarg.h>
+#include <string.h>
+
+#include "ghash.h"
+#include "gmessages.h"
+#include "gtestutils.h"
+#include "gstring.h"
+
+#undef G_DISABLE_DEPRECATED
+
+#include "grel.h"
+
+/**
+ * SECTION: relations
+ * @title: Relations and Tuples
+ * @short_description: tables of data which can be indexed on any
+ *                     number of fields
+ *
+ * A #GRelation is a table of data which can be indexed on any number
+ * of fields, rather like simple database tables. A #GRelation contains
+ * a number of records, called tuples. Each record contains a number of
+ * fields. Records are not ordered, so it is not possible to find the
+ * record at a particular index.
+ *
+ * Note that #GRelation tables are currently limited to 2 fields.
+ *
+ * To create a GRelation, use g_relation_new().
+ *
+ * To specify which fields should be indexed, use g_relation_index().
+ * Note that this must be called before any tuples are added to the
+ * #GRelation.
+ *
+ * To add records to a #GRelation use g_relation_insert().
+ *
+ * To determine if a given record appears in a #GRelation, use
+ * g_relation_exists(). Note that fields are compared directly, so
+ * pointers must point to the exact same position (i.e. different
+ * copies of the same string will not match.)
+ *
+ * To count the number of records which have a particular value in a
+ * given field, use g_relation_count().
+ *
+ * To get all the records which have a particular value in a given
+ * field, use g_relation_select(). To access fields of the resulting
+ * records, use g_tuples_index(). To free the resulting records use
+ * g_tuples_destroy().
+ *
+ * To delete all records which have a particular value in a given
+ * field, use g_relation_delete().
+ *
+ * To destroy the #GRelation, use g_relation_destroy().
+ *
+ * To help debug #GRelation objects, use g_relation_print().
+ *
+ * GRelation has been marked as deprecated, since this API has never
+ * been fully implemented, is not very actively maintained and rarely
+ * used.
+ **/
+
+typedef struct _GRealTuples        GRealTuples;
+
+/**
+ * GRelation:
+ *
+ * The #GRelation struct is an opaque data structure to represent a
+ * <link linkend="glib-Relations-and-Tuples">Relation</link>. It should
+ * only be accessed via the following functions.
+ **/
+struct _GRelation
+{
+  gint fields;
+  gint current_field;
+  
+  GHashTable   *all_tuples;
+  GHashTable  **hashed_tuple_tables;
+  
+  gint count;
+};
+
+/**
+ * GTuples:
+ * @len: the number of records that matched.
+ *
+ * The #GTuples struct is used to return records (or tuples) from the
+ * #GRelation by g_relation_select(). It only contains one public
+ * member - the number of records that matched. To access the matched
+ * records, you must use g_tuples_index().
+ **/
+struct _GRealTuples
+{
+  gint      len;
+  gint      width;
+  gpointer *data;
+};
+
+static gboolean
+tuple_equal_2 (gconstpointer v_a,
+              gconstpointer v_b)
+{
+  gpointer* a = (gpointer*) v_a;
+  gpointer* b = (gpointer*) v_b;
+  
+  return a[0] == b[0] && a[1] == b[1];
+}
+
+static guint
+tuple_hash_2 (gconstpointer v_a)
+{
+#if GLIB_SIZEOF_VOID_P > GLIB_SIZEOF_LONG
+  /* In practise this snippet has been written for 64-bit Windows
+   * where ints are 32 bits, pointers 64 bits. More exotic platforms
+   * need more tweaks.
+   */
+  guint* a = (guint*) v_a;
+
+  return (a[0] ^ a[1] ^ a[2] ^ a[3]);
+#else
+  gpointer* a = (gpointer*) v_a;
+  
+  return (gulong)a[0] ^ (gulong)a[1];
+#endif
+}
+
+static GHashFunc
+tuple_hash (gint fields)
+{
+  switch (fields)
+    {
+    case 2:
+      return tuple_hash_2;
+    default:
+      g_error ("no tuple hash for %d", fields);
+    }
+  
+  return NULL;
+}
+
+static GEqualFunc
+tuple_equal (gint fields)
+{
+  switch (fields)
+    {
+    case 2:
+      return tuple_equal_2;
+    default:
+      g_error ("no tuple equal for %d", fields);
+    }
+  
+  return NULL;
+}
+
+/**
+ * g_relation_new:
+ * @fields: the number of fields.
+ * @Returns: a new #GRelation.
+ *
+ * Creates a new #GRelation with the given number of fields. Note that
+ * currently the number of fields must be 2.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+GRelation*
+g_relation_new (gint fields)
+{
+  GRelation* rel = g_new0 (GRelation, 1);
+  
+  rel->fields = fields;
+  rel->all_tuples = g_hash_table_new (tuple_hash (fields), tuple_equal (fields));
+  rel->hashed_tuple_tables = g_new0 (GHashTable*, fields);
+  
+  return rel;
+}
+
+static void
+relation_delete_value_tuple (gpointer tuple_key,
+                             gpointer tuple_value,
+                             gpointer user_data)
+{
+  GRelation *relation = user_data;
+  gpointer *tuple = tuple_value;
+  g_slice_free1 (relation->fields * sizeof (gpointer), tuple);
+}
+
+static void
+g_relation_free_array (gpointer key, gpointer value, gpointer user_data)
+{
+  g_hash_table_destroy ((GHashTable*) value);
+}
+
+/**
+ * g_relation_destroy:
+ * @relation: a #GRelation.
+ *
+ * Destroys the #GRelation, freeing all memory allocated. However, it
+ * does not free memory allocated for the tuple data, so you should
+ * free that first if appropriate.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+void
+g_relation_destroy (GRelation *relation)
+{
+  gint i;
+  
+  if (relation)
+    {
+      for (i = 0; i < relation->fields; i += 1)
+       {
+         if (relation->hashed_tuple_tables[i])
+           {
+             g_hash_table_foreach (relation->hashed_tuple_tables[i], g_relation_free_array, NULL);
+             g_hash_table_destroy (relation->hashed_tuple_tables[i]);
+           }
+       }
+
+      g_hash_table_foreach (relation->all_tuples, relation_delete_value_tuple, relation);
+      g_hash_table_destroy (relation->all_tuples);
+      
+      g_free (relation->hashed_tuple_tables);
+      g_free (relation);
+    }
+}
+
+/**
+ * g_relation_index:
+ * @relation: a #GRelation.
+ * @field: the field to index, counting from 0.
+ * @hash_func: a function to produce a hash value from the field data.
+ * @key_equal_func: a function to compare two values of the given field.
+ *
+ * Creates an index on the given field. Note that this must be called
+ * before any records are added to the #GRelation.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+void
+g_relation_index (GRelation   *relation,
+                 gint         field,
+                 GHashFunc    hash_func,
+                 GEqualFunc   key_equal_func)
+{
+  g_return_if_fail (relation != NULL);
+  
+  g_return_if_fail (relation->count == 0 && relation->hashed_tuple_tables[field] == NULL);
+  
+  relation->hashed_tuple_tables[field] = g_hash_table_new (hash_func, key_equal_func);
+}
+
+/**
+ * g_relation_insert:
+ * @relation: a #GRelation.
+ * @Varargs: the fields of the record to add. These must match the
+ *           number of fields in the #GRelation, and of type #gpointer
+ *           or #gconstpointer.
+ *
+ * Inserts a record into a #GRelation.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+void
+g_relation_insert (GRelation   *relation,
+                  ...)
+{
+  gpointer* tuple = g_slice_alloc (relation->fields * sizeof (gpointer));
+  va_list args;
+  gint i;
+  
+  va_start (args, relation);
+  
+  for (i = 0; i < relation->fields; i += 1)
+    tuple[i] = va_arg (args, gpointer);
+  
+  va_end (args);
+  
+  g_hash_table_insert (relation->all_tuples, tuple, tuple);
+  
+  relation->count += 1;
+  
+  for (i = 0; i < relation->fields; i += 1)
+    {
+      GHashTable *table;
+      gpointer    key;
+      GHashTable *per_key_table;
+      
+      table = relation->hashed_tuple_tables[i];
+      
+      if (table == NULL)
+       continue;
+      
+      key = tuple[i];
+      per_key_table = g_hash_table_lookup (table, key);
+      
+      if (per_key_table == NULL)
+       {
+         per_key_table = g_hash_table_new (tuple_hash (relation->fields), tuple_equal (relation->fields));
+         g_hash_table_insert (table, key, per_key_table);
+       }
+      
+      g_hash_table_insert (per_key_table, tuple, tuple);
+    }
+}
+
+static void
+g_relation_delete_tuple (gpointer tuple_key,
+                        gpointer tuple_value,
+                        gpointer user_data)
+{
+  gpointer      *tuple = (gpointer*) tuple_value;
+  GRelation     *relation = (GRelation *) user_data;
+  gint           j;
+  
+  g_assert (tuple_key == tuple_value);
+  
+  for (j = 0; j < relation->fields; j += 1)
+    {
+      GHashTable *one_table = relation->hashed_tuple_tables[j];
+      gpointer    one_key;
+      GHashTable *per_key_table;
+      
+      if (one_table == NULL)
+       continue;
+      
+      if (j == relation->current_field)
+       /* can't delete from the table we're foreaching in */
+       continue;
+      
+      one_key = tuple[j];
+      
+      per_key_table = g_hash_table_lookup (one_table, one_key);
+      
+      g_hash_table_remove (per_key_table, tuple);
+    }
+  
+  if (g_hash_table_remove (relation->all_tuples, tuple))
+    g_slice_free1 (relation->fields * sizeof (gpointer), tuple);
+  
+  relation->count -= 1;
+}
+
+/**
+ * g_relation_delete:
+ * @relation: a #GRelation.
+ * @key: the value to compare with.
+ * @field: the field of each record to match.
+ * @Returns: the number of records deleted.
+ *
+ * Deletes any records from a #GRelation that have the given key value
+ * in the given field.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+gint
+g_relation_delete  (GRelation     *relation,
+                   gconstpointer  key,
+                   gint           field)
+{
+  GHashTable *table; 
+  GHashTable *key_table;
+  gint        count;
+  
+  g_return_val_if_fail (relation != NULL, 0);
+
+  table = relation->hashed_tuple_tables[field];
+  count = relation->count;
+
+  g_return_val_if_fail (table != NULL, 0);
+  
+  key_table = g_hash_table_lookup (table, key);
+  
+  if (!key_table)
+    return 0;
+  
+  relation->current_field = field;
+  
+  g_hash_table_foreach (key_table, g_relation_delete_tuple, relation);
+  
+  g_hash_table_remove (table, key);
+  
+  g_hash_table_destroy (key_table);
+  
+  /* @@@ FIXME: Remove empty hash tables. */
+  
+  return count - relation->count;
+}
+
+static void
+g_relation_select_tuple (gpointer tuple_key,
+                        gpointer tuple_value,
+                        gpointer user_data)
+{
+  gpointer    *tuple = (gpointer*) tuple_value;
+  GRealTuples *tuples = (GRealTuples*) user_data;
+  gint stride = sizeof (gpointer) * tuples->width;
+  
+  g_assert (tuple_key == tuple_value);
+  
+  memcpy (tuples->data + (tuples->len * tuples->width),
+         tuple,
+         stride);
+  
+  tuples->len += 1;
+}
+
+/**
+ * g_relation_select:
+ * @relation: a #GRelation.
+ * @key: the value to compare with.
+ * @field: the field of each record to match.
+ * @Returns: the records (tuples) that matched.
+ *
+ * Returns all of the tuples which have the given key in the given
+ * field. Use g_tuples_index() to access the returned records. The
+ * returned records should be freed with g_tuples_destroy().
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+GTuples*
+g_relation_select (GRelation     *relation,
+                  gconstpointer  key,
+                  gint           field)
+{
+  GHashTable  *table;
+  GHashTable  *key_table;
+  GRealTuples *tuples; 
+  gint count;
+  
+  g_return_val_if_fail (relation != NULL, NULL);
+
+  table = relation->hashed_tuple_tables[field];
+
+  g_return_val_if_fail (table != NULL, NULL);
+  
+  tuples = g_new0 (GRealTuples, 1);
+  key_table = g_hash_table_lookup (table, key);
+  
+  if (!key_table)
+    return (GTuples*)tuples;
+  
+  count = g_relation_count (relation, key, field);
+  
+  tuples->data = g_malloc (sizeof (gpointer) * relation->fields * count);
+  tuples->width = relation->fields;
+  
+  g_hash_table_foreach (key_table, g_relation_select_tuple, tuples);
+  
+  g_assert (count == tuples->len);
+  
+  return (GTuples*)tuples;
+}
+
+/**
+ * g_relation_count:
+ * @relation: a #GRelation.
+ * @key: the value to compare with.
+ * @field: the field of each record to match.
+ * @Returns: the number of matches.
+ *
+ * Returns the number of tuples in a #GRelation that have the given
+ * value in the given field.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+gint
+g_relation_count (GRelation     *relation,
+                 gconstpointer  key,
+                 gint           field)
+{
+  GHashTable  *table;
+  GHashTable  *key_table;
+  
+  g_return_val_if_fail (relation != NULL, 0);
+
+  table = relation->hashed_tuple_tables[field];
+
+  g_return_val_if_fail (table != NULL, 0);
+  
+  key_table = g_hash_table_lookup (table, key);
+  
+  if (!key_table)
+    return 0;
+  
+  return g_hash_table_size (key_table);
+}
+
+/**
+ * g_relation_exists:
+ * @relation: a #GRelation.
+ * @Varargs: the fields of the record to compare. The number must match
+ *           the number of fields in the #GRelation.
+ * @Returns: %TRUE if a record matches.
+ *
+ * Returns %TRUE if a record with the given values exists in a
+ * #GRelation. Note that the values are compared directly, so that, for
+ * example, two copies of the same string will not match.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+gboolean
+g_relation_exists (GRelation   *relation, ...)
+{
+  gpointer *tuple = g_slice_alloc (relation->fields * sizeof (gpointer));
+  va_list args;
+  gint i;
+  gboolean result;
+  
+  va_start(args, relation);
+  
+  for (i = 0; i < relation->fields; i += 1)
+    tuple[i] = va_arg(args, gpointer);
+  
+  va_end(args);
+  
+  result = g_hash_table_lookup (relation->all_tuples, tuple) != NULL;
+  
+  g_slice_free1 (relation->fields * sizeof (gpointer), tuple);
+  
+  return result;
+}
+
+/**
+ * g_tuples_destroy:
+ * @tuples: the tuple data to free.
+ *
+ * Frees the records which were returned by g_relation_select(). This
+ * should always be called after g_relation_select() when you are
+ * finished with the records. The records are not removed from the
+ * #GRelation.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+void
+g_tuples_destroy (GTuples *tuples0)
+{
+  GRealTuples *tuples = (GRealTuples*) tuples0;
+  
+  if (tuples)
+    {
+      g_free (tuples->data);
+      g_free (tuples);
+    }
+}
+
+/**
+ * g_tuples_index:
+ * @tuples: the tuple data, returned by g_relation_select().
+ * @index_: the index of the record.
+ * @field: the field to return.
+ * @Returns: the field of the record.
+ *
+ * Gets a field from the records returned by g_relation_select(). It
+ * returns the given field of the record at the given index. The
+ * returned value should not be changed.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+gpointer
+g_tuples_index (GTuples     *tuples0,
+               gint         index,
+               gint         field)
+{
+  GRealTuples *tuples = (GRealTuples*) tuples0;
+  
+  g_return_val_if_fail (tuples0 != NULL, NULL);
+  g_return_val_if_fail (field < tuples->width, NULL);
+  
+  return tuples->data[index * tuples->width + field];
+}
+
+/* Print
+ */
+
+static void
+g_relation_print_one (gpointer tuple_key,
+                     gpointer tuple_value,
+                     gpointer user_data)
+{
+  gint i;
+  GString *gstring;
+  GRelation* rel = (GRelation*) user_data;
+  gpointer* tuples = (gpointer*) tuple_value;
+
+  gstring = g_string_new ("[");
+  
+  for (i = 0; i < rel->fields; i += 1)
+    {
+      g_string_append_printf (gstring, "%p", tuples[i]);
+      
+      if (i < (rel->fields - 1))
+       g_string_append (gstring, ",");
+    }
+  
+  g_string_append (gstring, "]");
+  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "%s", gstring->str);
+  g_string_free (gstring, TRUE);
+}
+
+static void
+g_relation_print_index (gpointer tuple_key,
+                       gpointer tuple_value,
+                       gpointer user_data)
+{
+  GRelation* rel = (GRelation*) user_data;
+  GHashTable* table = (GHashTable*) tuple_value;
+  
+  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "*** key %p", tuple_key);
+  
+  g_hash_table_foreach (table,
+                       g_relation_print_one,
+                       rel);
+}
+
+/**
+ * g_relation_print:
+ * @relation: a #GRelation.
+ *
+ * Outputs information about all records in a #GRelation, as well as
+ * the indexes. It is for debugging.
+ *
+ * Deprecated: 2.26: Rarely used API
+ **/
+void
+g_relation_print (GRelation *relation)
+{
+  gint i;
+  
+  g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "*** all tuples (%d)", relation->count);
+  
+  g_hash_table_foreach (relation->all_tuples,
+                       g_relation_print_one,
+                       relation);
+  
+  for (i = 0; i < relation->fields; i += 1)
+    {
+      if (relation->hashed_tuple_tables[i] == NULL)
+       continue;
+      
+      g_log (G_LOG_DOMAIN, G_LOG_LEVEL_INFO, "*** index %d", i);
+      
+      g_hash_table_foreach (relation->hashed_tuple_tables[i],
+                           g_relation_print_index,
+                           relation);
+    }
+  
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/grel.h b/resource/csdk/connectivity/lib/android/glib-master/glib/grel.h
new file mode 100644 (file)
index 0000000..5cb8d09
--- /dev/null
@@ -0,0 +1,101 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_REL_H__
+#define __G_REL_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GRelation       GRelation;
+typedef struct _GTuples         GTuples;
+
+struct _GTuples
+{
+  guint len;
+};
+
+/* GRelation
+ *
+ * Indexed Relations.  Imagine a really simple table in a
+ * database.  Relations are not ordered.  This data type is meant for
+ * maintaining a N-way mapping.
+ *
+ * g_relation_new() creates a relation with FIELDS fields
+ *
+ * g_relation_destroy() frees all resources
+ * g_tuples_destroy() frees the result of g_relation_select()
+ *
+ * g_relation_index() indexes relation FIELD with the provided
+ *   equality and hash functions.  this must be done before any
+ *   calls to insert are made.
+ *
+ * g_relation_insert() inserts a new tuple.  you are expected to
+ *   provide the right number of fields.
+ *
+ * g_relation_delete() deletes all relations with KEY in FIELD
+ * g_relation_select() returns ...
+ * g_relation_count() counts ...
+ */
+
+#ifndef G_DISABLE_DEPRECATED
+
+GRelation* g_relation_new     (gint         fields);
+void       g_relation_destroy (GRelation   *relation);
+void       g_relation_index   (GRelation   *relation,
+                               gint         field,
+                               GHashFunc    hash_func,
+                               GEqualFunc   key_equal_func);
+void       g_relation_insert  (GRelation   *relation,
+                               ...);
+gint       g_relation_delete  (GRelation   *relation,
+                               gconstpointer  key,
+                               gint         field);
+GTuples*   g_relation_select  (GRelation   *relation,
+                               gconstpointer  key,
+                               gint         field);
+gint       g_relation_count   (GRelation   *relation,
+                               gconstpointer  key,
+                               gint         field);
+gboolean   g_relation_exists  (GRelation   *relation,
+                               ...);
+void       g_relation_print   (GRelation   *relation);
+
+void       g_tuples_destroy   (GTuples     *tuples);
+gpointer   g_tuples_index     (GTuples     *tuples,
+                               gint         index_,
+                               gint         field);
+
+#endif
+
+G_END_DECLS
+
+#endif /* __G_REL_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gscanner.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gscanner.c
new file mode 100644 (file)
index 0000000..1234a60
--- /dev/null
@@ -0,0 +1,1767 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * GScanner: Flexible lexical scanner for general purpose.
+ * Copyright (C) 1997, 1998 Tim Janik
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include <errno.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <string.h>
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef G_OS_WIN32
+#include <io.h> /* For _read() */
+#endif
+
+#include "gscanner.h"
+
+#include "gprintfint.h"
+#include "gstrfuncs.h"
+#include "gstring.h"
+#include "gtestutils.h"
+
+/* --- defines --- */
+#define        to_lower(c)                             ( \
+       (guchar) (                                                      \
+         ( (((guchar)(c))>='A' && ((guchar)(c))<='Z') * ('a'-'A') ) |  \
+         ( (((guchar)(c))>=192 && ((guchar)(c))<=214) * (224-192) ) |  \
+         ( (((guchar)(c))>=216 && ((guchar)(c))<=222) * (248-216) ) |  \
+         ((guchar)(c))                                                 \
+       )                                                               \
+)
+#define        READ_BUFFER_SIZE        (4000)
+
+
+/* --- typedefs --- */
+typedef        struct  _GScannerKey    GScannerKey;
+
+struct _GScannerKey
+{
+  guint                 scope_id;
+  gchar                *symbol;
+  gpointer      value;
+};
+
+
+/* --- variables --- */
+static const GScannerConfig g_scanner_config_template =
+{
+  (
+   " \t\r\n"
+   )                   /* cset_skip_characters */,
+  (
+   G_CSET_a_2_z
+   "_"
+   G_CSET_A_2_Z
+   )                   /* cset_identifier_first */,
+  (
+   G_CSET_a_2_z
+   "_"
+   G_CSET_A_2_Z
+   G_CSET_DIGITS
+   G_CSET_LATINS
+   G_CSET_LATINC
+   )                   /* cset_identifier_nth */,
+  ( "#\n" )            /* cpair_comment_single */,
+  
+  FALSE                        /* case_sensitive */,
+  
+  TRUE                 /* skip_comment_multi */,
+  TRUE                 /* skip_comment_single */,
+  TRUE                 /* scan_comment_multi */,
+  TRUE                 /* scan_identifier */,
+  FALSE                        /* scan_identifier_1char */,
+  FALSE                        /* scan_identifier_NULL */,
+  TRUE                 /* scan_symbols */,
+  FALSE                        /* scan_binary */,
+  TRUE                 /* scan_octal */,
+  TRUE                 /* scan_float */,
+  TRUE                 /* scan_hex */,
+  FALSE                        /* scan_hex_dollar */,
+  TRUE                 /* scan_string_sq */,
+  TRUE                 /* scan_string_dq */,
+  TRUE                 /* numbers_2_int */,
+  FALSE                        /* int_2_float */,
+  FALSE                        /* identifier_2_string */,
+  TRUE                 /* char_2_token */,
+  FALSE                        /* symbol_2_token */,
+  FALSE                        /* scope_0_fallback */,
+  FALSE                        /* store_int64 */,
+};
+
+
+/* --- prototypes --- */
+static inline
+GScannerKey*   g_scanner_lookup_internal (GScanner     *scanner,
+                                          guint         scope_id,
+                                          const gchar  *symbol);
+static gboolean        g_scanner_key_equal       (gconstpointer v1,
+                                          gconstpointer v2);
+static guint   g_scanner_key_hash        (gconstpointer v);
+static void    g_scanner_get_token_ll    (GScanner     *scanner,
+                                          GTokenType   *token_p,
+                                          GTokenValue  *value_p,
+                                          guint        *line_p,
+                                          guint        *position_p);
+static void    g_scanner_get_token_i     (GScanner     *scanner,
+                                          GTokenType   *token_p,
+                                          GTokenValue  *value_p,
+                                          guint        *line_p,
+                                          guint        *position_p);
+
+static guchar  g_scanner_peek_next_char  (GScanner     *scanner);
+static guchar  g_scanner_get_char        (GScanner     *scanner,
+                                          guint        *line_p,
+                                          guint        *position_p);
+static void    g_scanner_msg_handler     (GScanner     *scanner,
+                                          gchar        *message,
+                                          gboolean      is_error);
+
+
+/* --- functions --- */
+static inline gint
+g_scanner_char_2_num (guchar   c,
+                     guchar    base)
+{
+  if (c >= '0' && c <= '9')
+    c -= '0';
+  else if (c >= 'A' && c <= 'Z')
+    c -= 'A' - 10;
+  else if (c >= 'a' && c <= 'z')
+    c -= 'a' - 10;
+  else
+    return -1;
+  
+  if (c < base)
+    return c;
+  
+  return -1;
+}
+
+GScanner*
+g_scanner_new (const GScannerConfig *config_templ)
+{
+  GScanner *scanner;
+  
+  if (!config_templ)
+    config_templ = &g_scanner_config_template;
+  
+  scanner = g_new0 (GScanner, 1);
+  
+  scanner->user_data = NULL;
+  scanner->max_parse_errors = 1;
+  scanner->parse_errors        = 0;
+  scanner->input_name = NULL;
+  g_datalist_init (&scanner->qdata);
+  
+  scanner->config = g_new0 (GScannerConfig, 1);
+  
+  scanner->config->case_sensitive       = config_templ->case_sensitive;
+  scanner->config->cset_skip_characters         = config_templ->cset_skip_characters;
+  if (!scanner->config->cset_skip_characters)
+    scanner->config->cset_skip_characters = "";
+  scanner->config->cset_identifier_first = config_templ->cset_identifier_first;
+  scanner->config->cset_identifier_nth  = config_templ->cset_identifier_nth;
+  scanner->config->cpair_comment_single         = config_templ->cpair_comment_single;
+  scanner->config->skip_comment_multi   = config_templ->skip_comment_multi;
+  scanner->config->skip_comment_single  = config_templ->skip_comment_single;
+  scanner->config->scan_comment_multi   = config_templ->scan_comment_multi;
+  scanner->config->scan_identifier      = config_templ->scan_identifier;
+  scanner->config->scan_identifier_1char = config_templ->scan_identifier_1char;
+  scanner->config->scan_identifier_NULL         = config_templ->scan_identifier_NULL;
+  scanner->config->scan_symbols                 = config_templ->scan_symbols;
+  scanner->config->scan_binary          = config_templ->scan_binary;
+  scanner->config->scan_octal           = config_templ->scan_octal;
+  scanner->config->scan_float           = config_templ->scan_float;
+  scanner->config->scan_hex             = config_templ->scan_hex;
+  scanner->config->scan_hex_dollar      = config_templ->scan_hex_dollar;
+  scanner->config->scan_string_sq       = config_templ->scan_string_sq;
+  scanner->config->scan_string_dq       = config_templ->scan_string_dq;
+  scanner->config->numbers_2_int        = config_templ->numbers_2_int;
+  scanner->config->int_2_float          = config_templ->int_2_float;
+  scanner->config->identifier_2_string  = config_templ->identifier_2_string;
+  scanner->config->char_2_token                 = config_templ->char_2_token;
+  scanner->config->symbol_2_token       = config_templ->symbol_2_token;
+  scanner->config->scope_0_fallback     = config_templ->scope_0_fallback;
+  scanner->config->store_int64          = config_templ->store_int64;
+  
+  scanner->token = G_TOKEN_NONE;
+  scanner->value.v_int64 = 0;
+  scanner->line = 1;
+  scanner->position = 0;
+  
+  scanner->next_token = G_TOKEN_NONE;
+  scanner->next_value.v_int64 = 0;
+  scanner->next_line = 1;
+  scanner->next_position = 0;
+  
+  scanner->symbol_table = g_hash_table_new (g_scanner_key_hash, g_scanner_key_equal);
+  scanner->input_fd = -1;
+  scanner->text = NULL;
+  scanner->text_end = NULL;
+  scanner->buffer = NULL;
+  scanner->scope_id = 0;
+  
+  scanner->msg_handler = g_scanner_msg_handler;
+  
+  return scanner;
+}
+
+static inline void
+g_scanner_free_value (GTokenType     *token_p,
+                     GTokenValue     *value_p)
+{
+  switch (*token_p)
+    {
+    case G_TOKEN_STRING:
+    case G_TOKEN_IDENTIFIER:
+    case G_TOKEN_IDENTIFIER_NULL:
+    case G_TOKEN_COMMENT_SINGLE:
+    case G_TOKEN_COMMENT_MULTI:
+      g_free (value_p->v_string);
+      break;
+      
+    default:
+      break;
+    }
+  
+  *token_p = G_TOKEN_NONE;
+}
+
+static void
+g_scanner_destroy_symbol_table_entry (gpointer _key,
+                                     gpointer _value,
+                                     gpointer _data)
+{
+  GScannerKey *key = _key;
+  
+  g_free (key->symbol);
+  g_free (key);
+}
+
+void
+g_scanner_destroy (GScanner    *scanner)
+{
+  g_return_if_fail (scanner != NULL);
+  
+  g_datalist_clear (&scanner->qdata);
+  g_hash_table_foreach (scanner->symbol_table, 
+                       g_scanner_destroy_symbol_table_entry, NULL);
+  g_hash_table_destroy (scanner->symbol_table);
+  g_scanner_free_value (&scanner->token, &scanner->value);
+  g_scanner_free_value (&scanner->next_token, &scanner->next_value);
+  g_free (scanner->config);
+  g_free (scanner->buffer);
+  g_free (scanner);
+}
+
+static void
+g_scanner_msg_handler (GScanner                *scanner,
+                      gchar            *message,
+                      gboolean         is_error)
+{
+  g_return_if_fail (scanner != NULL);
+  
+  _g_fprintf (stderr, "%s:%d: ",
+             scanner->input_name ? scanner->input_name : "<memory>",
+             scanner->line);
+  if (is_error)
+    _g_fprintf (stderr, "error: ");
+  _g_fprintf (stderr, "%s\n", message);
+}
+
+void
+g_scanner_error (GScanner      *scanner,
+                const gchar    *format,
+                ...)
+{
+  g_return_if_fail (scanner != NULL);
+  g_return_if_fail (format != NULL);
+  
+  scanner->parse_errors++;
+  
+  if (scanner->msg_handler)
+    {
+      va_list args;
+      gchar *string;
+      
+      va_start (args, format);
+      string = g_strdup_vprintf (format, args);
+      va_end (args);
+      
+      scanner->msg_handler (scanner, string, TRUE);
+      
+      g_free (string);
+    }
+}
+
+void
+g_scanner_warn (GScanner       *scanner,
+               const gchar    *format,
+               ...)
+{
+  g_return_if_fail (scanner != NULL);
+  g_return_if_fail (format != NULL);
+  
+  if (scanner->msg_handler)
+    {
+      va_list args;
+      gchar *string;
+      
+      va_start (args, format);
+      string = g_strdup_vprintf (format, args);
+      va_end (args);
+      
+      scanner->msg_handler (scanner, string, FALSE);
+      
+      g_free (string);
+    }
+}
+
+static gboolean
+g_scanner_key_equal (gconstpointer v1,
+                    gconstpointer v2)
+{
+  const GScannerKey *key1 = v1;
+  const GScannerKey *key2 = v2;
+  
+  return (key1->scope_id == key2->scope_id) && (strcmp (key1->symbol, key2->symbol) == 0);
+}
+
+static guint
+g_scanner_key_hash (gconstpointer v)
+{
+  const GScannerKey *key = v;
+  gchar *c;
+  guint h;
+  
+  h = key->scope_id;
+  for (c = key->symbol; *c; c++)
+    h = (h << 5) - h + *c;
+  
+  return h;
+}
+
+static inline GScannerKey*
+g_scanner_lookup_internal (GScanner    *scanner,
+                          guint         scope_id,
+                          const gchar  *symbol)
+{
+  GScannerKey  *key_p;
+  GScannerKey key;
+  
+  key.scope_id = scope_id;
+  
+  if (!scanner->config->case_sensitive)
+    {
+      gchar *d;
+      const gchar *c;
+      
+      key.symbol = g_new (gchar, strlen (symbol) + 1);
+      for (d = key.symbol, c = symbol; *c; c++, d++)
+       *d = to_lower (*c);
+      *d = 0;
+      key_p = g_hash_table_lookup (scanner->symbol_table, &key);
+      g_free (key.symbol);
+    }
+  else
+    {
+      key.symbol = (gchar*) symbol;
+      key_p = g_hash_table_lookup (scanner->symbol_table, &key);
+    }
+  
+  return key_p;
+}
+
+void
+g_scanner_scope_add_symbol (GScanner   *scanner,
+                           guint        scope_id,
+                           const gchar *symbol,
+                           gpointer     value)
+{
+  GScannerKey  *key;
+  
+  g_return_if_fail (scanner != NULL);
+  g_return_if_fail (symbol != NULL);
+  
+  key = g_scanner_lookup_internal (scanner, scope_id, symbol);
+  
+  if (!key)
+    {
+      key = g_new (GScannerKey, 1);
+      key->scope_id = scope_id;
+      key->symbol = g_strdup (symbol);
+      key->value = value;
+      if (!scanner->config->case_sensitive)
+       {
+         gchar *c;
+         
+         c = key->symbol;
+         while (*c != 0)
+           {
+             *c = to_lower (*c);
+             c++;
+           }
+       }
+      g_hash_table_insert (scanner->symbol_table, key, key);
+    }
+  else
+    key->value = value;
+}
+
+void
+g_scanner_scope_remove_symbol (GScanner           *scanner,
+                              guint        scope_id,
+                              const gchar *symbol)
+{
+  GScannerKey  *key;
+  
+  g_return_if_fail (scanner != NULL);
+  g_return_if_fail (symbol != NULL);
+  
+  key = g_scanner_lookup_internal (scanner, scope_id, symbol);
+  
+  if (key)
+    {
+      g_hash_table_remove (scanner->symbol_table, key);
+      g_free (key->symbol);
+      g_free (key);
+    }
+}
+
+gpointer
+g_scanner_lookup_symbol (GScanner      *scanner,
+                        const gchar    *symbol)
+{
+  GScannerKey  *key;
+  guint scope_id;
+  
+  g_return_val_if_fail (scanner != NULL, NULL);
+  
+  if (!symbol)
+    return NULL;
+  
+  scope_id = scanner->scope_id;
+  key = g_scanner_lookup_internal (scanner, scope_id, symbol);
+  if (!key && scope_id && scanner->config->scope_0_fallback)
+    key = g_scanner_lookup_internal (scanner, 0, symbol);
+  
+  if (key)
+    return key->value;
+  else
+    return NULL;
+}
+
+gpointer
+g_scanner_scope_lookup_symbol (GScanner              *scanner,
+                              guint           scope_id,
+                              const gchar    *symbol)
+{
+  GScannerKey  *key;
+  
+  g_return_val_if_fail (scanner != NULL, NULL);
+  
+  if (!symbol)
+    return NULL;
+  
+  key = g_scanner_lookup_internal (scanner, scope_id, symbol);
+  
+  if (key)
+    return key->value;
+  else
+    return NULL;
+}
+
+guint
+g_scanner_set_scope (GScanner      *scanner,
+                    guint           scope_id)
+{
+  guint old_scope_id;
+  
+  g_return_val_if_fail (scanner != NULL, 0);
+  
+  old_scope_id = scanner->scope_id;
+  scanner->scope_id = scope_id;
+  
+  return old_scope_id;
+}
+
+static void
+g_scanner_foreach_internal (gpointer  _key,
+                           gpointer  _value,
+                           gpointer  _user_data)
+{
+  GScannerKey *key;
+  gpointer *d;
+  GHFunc func;
+  gpointer user_data;
+  guint *scope_id;
+  
+  d = _user_data;
+  func = (GHFunc) d[0];
+  user_data = d[1];
+  scope_id = d[2];
+  key = _value;
+  
+  if (key->scope_id == *scope_id)
+    func (key->symbol, key->value, user_data);
+}
+
+void
+g_scanner_scope_foreach_symbol (GScanner       *scanner,
+                               guint           scope_id,
+                               GHFunc          func,
+                               gpointer        user_data)
+{
+  gpointer d[3];
+  
+  g_return_if_fail (scanner != NULL);
+  
+  d[0] = (gpointer) func;
+  d[1] = user_data;
+  d[2] = &scope_id;
+  
+  g_hash_table_foreach (scanner->symbol_table, g_scanner_foreach_internal, d);
+}
+
+GTokenType
+g_scanner_peek_next_token (GScanner    *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
+  
+  if (scanner->next_token == G_TOKEN_NONE)
+    {
+      scanner->next_line = scanner->line;
+      scanner->next_position = scanner->position;
+      g_scanner_get_token_i (scanner,
+                            &scanner->next_token,
+                            &scanner->next_value,
+                            &scanner->next_line,
+                            &scanner->next_position);
+    }
+  
+  return scanner->next_token;
+}
+
+GTokenType
+g_scanner_get_next_token (GScanner     *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
+  
+  if (scanner->next_token != G_TOKEN_NONE)
+    {
+      g_scanner_free_value (&scanner->token, &scanner->value);
+      
+      scanner->token = scanner->next_token;
+      scanner->value = scanner->next_value;
+      scanner->line = scanner->next_line;
+      scanner->position = scanner->next_position;
+      scanner->next_token = G_TOKEN_NONE;
+    }
+  else
+    g_scanner_get_token_i (scanner,
+                          &scanner->token,
+                          &scanner->value,
+                          &scanner->line,
+                          &scanner->position);
+  
+  return scanner->token;
+}
+
+GTokenType
+g_scanner_cur_token (GScanner *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, G_TOKEN_EOF);
+  
+  return scanner->token;
+}
+
+GTokenValue
+g_scanner_cur_value (GScanner *scanner)
+{
+  GTokenValue v;
+  
+  v.v_int64 = 0;
+  
+  g_return_val_if_fail (scanner != NULL, v);
+
+  /* MSC isn't capable of handling return scanner->value; ? */
+
+  v = scanner->value;
+
+  return v;
+}
+
+guint
+g_scanner_cur_line (GScanner *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, 0);
+  
+  return scanner->line;
+}
+
+guint
+g_scanner_cur_position (GScanner *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, 0);
+  
+  return scanner->position;
+}
+
+gboolean
+g_scanner_eof (GScanner        *scanner)
+{
+  g_return_val_if_fail (scanner != NULL, TRUE);
+  
+  return scanner->token == G_TOKEN_EOF || scanner->token == G_TOKEN_ERROR;
+}
+
+void
+g_scanner_input_file (GScanner *scanner,
+                     gint      input_fd)
+{
+  g_return_if_fail (scanner != NULL);
+  g_return_if_fail (input_fd >= 0);
+
+  if (scanner->input_fd >= 0)
+    g_scanner_sync_file_offset (scanner);
+
+  scanner->token = G_TOKEN_NONE;
+  scanner->value.v_int64 = 0;
+  scanner->line = 1;
+  scanner->position = 0;
+  scanner->next_token = G_TOKEN_NONE;
+
+  scanner->input_fd = input_fd;
+  scanner->text = NULL;
+  scanner->text_end = NULL;
+
+  if (!scanner->buffer)
+    scanner->buffer = g_new (gchar, READ_BUFFER_SIZE + 1);
+}
+
+void
+g_scanner_input_text (GScanner   *scanner,
+                     const gchar *text,
+                     guint        text_len)
+{
+  g_return_if_fail (scanner != NULL);
+  if (text_len)
+    g_return_if_fail (text != NULL);
+  else
+    text = NULL;
+
+  if (scanner->input_fd >= 0)
+    g_scanner_sync_file_offset (scanner);
+
+  scanner->token = G_TOKEN_NONE;
+  scanner->value.v_int64 = 0;
+  scanner->line = 1;
+  scanner->position = 0;
+  scanner->next_token = G_TOKEN_NONE;
+
+  scanner->input_fd = -1;
+  scanner->text = text;
+  scanner->text_end = text + text_len;
+
+  if (scanner->buffer)
+    {
+      g_free (scanner->buffer);
+      scanner->buffer = NULL;
+    }
+}
+
+static guchar
+g_scanner_peek_next_char (GScanner *scanner)
+{
+  if (scanner->text < scanner->text_end)
+    {
+      return *scanner->text;
+    }
+  else if (scanner->input_fd >= 0)
+    {
+      gint count;
+      gchar *buffer;
+
+      buffer = scanner->buffer;
+      do
+       {
+         count = read (scanner->input_fd, buffer, READ_BUFFER_SIZE);
+       }
+      while (count == -1 && (errno == EINTR || errno == EAGAIN));
+
+      if (count < 1)
+       {
+         scanner->input_fd = -1;
+
+         return 0;
+       }
+      else
+       {
+         scanner->text = buffer;
+         scanner->text_end = buffer + count;
+
+         return *buffer;
+       }
+    }
+  else
+    return 0;
+}
+
+void
+g_scanner_sync_file_offset (GScanner *scanner)
+{
+  g_return_if_fail (scanner != NULL);
+
+  /* for file input, rewind the filedescriptor to the current
+   * buffer position and blow the file read ahead buffer. useful
+   * for third party uses of our file descriptor, which hooks 
+   * onto the current scanning position.
+   */
+
+  if (scanner->input_fd >= 0 && scanner->text_end > scanner->text)
+    {
+      gint buffered;
+
+      buffered = scanner->text_end - scanner->text;
+      if (lseek (scanner->input_fd, - buffered, SEEK_CUR) >= 0)
+       {
+         /* we succeeded, blow our buffer's contents now */
+         scanner->text = NULL;
+         scanner->text_end = NULL;
+       }
+      else
+       errno = 0;
+    }
+}
+
+static guchar
+g_scanner_get_char (GScanner   *scanner,
+                   guint       *line_p,
+                   guint       *position_p)
+{
+  guchar fchar;
+
+  if (scanner->text < scanner->text_end)
+    fchar = *(scanner->text++);
+  else if (scanner->input_fd >= 0)
+    {
+      gint count;
+      gchar *buffer;
+
+      buffer = scanner->buffer;
+      do
+       {
+         count = read (scanner->input_fd, buffer, READ_BUFFER_SIZE);
+       }
+      while (count == -1 && (errno == EINTR || errno == EAGAIN));
+
+      if (count < 1)
+       {
+         scanner->input_fd = -1;
+         fchar = 0;
+       }
+      else
+       {
+         scanner->text = buffer + 1;
+         scanner->text_end = buffer + count;
+         fchar = *buffer;
+         if (!fchar)
+           {
+             g_scanner_sync_file_offset (scanner);
+             scanner->text_end = scanner->text;
+             scanner->input_fd = -1;
+           }
+       }
+    }
+  else
+    fchar = 0;
+  
+  if (fchar == '\n')
+    {
+      (*position_p) = 0;
+      (*line_p)++;
+    }
+  else if (fchar)
+    {
+      (*position_p)++;
+    }
+  
+  return fchar;
+}
+
+void
+g_scanner_unexp_token (GScanner                *scanner,
+                      GTokenType        expected_token,
+                      const gchar      *identifier_spec,
+                      const gchar      *symbol_spec,
+                      const gchar      *symbol_name,
+                      const gchar      *message,
+                      gint              is_error)
+{
+  gchar        *token_string;
+  guint        token_string_len;
+  gchar        *expected_string;
+  guint        expected_string_len;
+  gchar        *message_prefix;
+  gboolean print_unexp;
+  void (*msg_handler)  (GScanner*, const gchar*, ...);
+  
+  g_return_if_fail (scanner != NULL);
+  
+  if (is_error)
+    msg_handler = g_scanner_error;
+  else
+    msg_handler = g_scanner_warn;
+  
+  if (!identifier_spec)
+    identifier_spec = "identifier";
+  if (!symbol_spec)
+    symbol_spec = "symbol";
+  
+  token_string_len = 56;
+  token_string = g_new (gchar, token_string_len + 1);
+  expected_string_len = 64;
+  expected_string = g_new (gchar, expected_string_len + 1);
+  print_unexp = TRUE;
+  
+  switch (scanner->token)
+    {
+    case G_TOKEN_EOF:
+      _g_snprintf (token_string, token_string_len, "end of file");
+      break;
+      
+    default:
+      if (scanner->token >= 1 && scanner->token <= 255)
+       {
+         if ((scanner->token >= ' ' && scanner->token <= '~') ||
+             strchr (scanner->config->cset_identifier_first, scanner->token) ||
+             strchr (scanner->config->cset_identifier_nth, scanner->token))
+           _g_snprintf (token_string, token_string_len, "character `%c'", scanner->token);
+         else
+           _g_snprintf (token_string, token_string_len, "character `\\%o'", scanner->token);
+         break;
+       }
+      else if (!scanner->config->symbol_2_token)
+       {
+         _g_snprintf (token_string, token_string_len, "(unknown) token <%d>", scanner->token);
+         break;
+       }
+      /* fall through */
+    case G_TOKEN_SYMBOL:
+      if (expected_token == G_TOKEN_SYMBOL ||
+         (scanner->config->symbol_2_token &&
+          expected_token > G_TOKEN_LAST))
+       print_unexp = FALSE;
+      if (symbol_name)
+       _g_snprintf (token_string,
+                    token_string_len,
+                    "%s%s `%s'",
+                    print_unexp ? "" : "invalid ",
+                    symbol_spec,
+                    symbol_name);
+      else
+       _g_snprintf (token_string,
+                    token_string_len,
+                    "%s%s",
+                    print_unexp ? "" : "invalid ",
+                    symbol_spec);
+      break;
+      
+    case G_TOKEN_ERROR:
+      print_unexp = FALSE;
+      expected_token = G_TOKEN_NONE;
+      switch (scanner->value.v_error)
+       {
+       case G_ERR_UNEXP_EOF:
+         _g_snprintf (token_string, token_string_len, "scanner: unexpected end of file");
+         break;
+         
+       case G_ERR_UNEXP_EOF_IN_STRING:
+         _g_snprintf (token_string, token_string_len, "scanner: unterminated string constant");
+         break;
+         
+       case G_ERR_UNEXP_EOF_IN_COMMENT:
+         _g_snprintf (token_string, token_string_len, "scanner: unterminated comment");
+         break;
+         
+       case G_ERR_NON_DIGIT_IN_CONST:
+         _g_snprintf (token_string, token_string_len, "scanner: non digit in constant");
+         break;
+         
+       case G_ERR_FLOAT_RADIX:
+         _g_snprintf (token_string, token_string_len, "scanner: invalid radix for floating constant");
+         break;
+         
+       case G_ERR_FLOAT_MALFORMED:
+         _g_snprintf (token_string, token_string_len, "scanner: malformed floating constant");
+         break;
+         
+       case G_ERR_DIGIT_RADIX:
+         _g_snprintf (token_string, token_string_len, "scanner: digit is beyond radix");
+         break;
+         
+       case G_ERR_UNKNOWN:
+       default:
+         _g_snprintf (token_string, token_string_len, "scanner: unknown error");
+         break;
+       }
+      break;
+      
+    case G_TOKEN_CHAR:
+      _g_snprintf (token_string, token_string_len, "character `%c'", scanner->value.v_char);
+      break;
+      
+    case G_TOKEN_IDENTIFIER:
+    case G_TOKEN_IDENTIFIER_NULL:
+      if (expected_token == G_TOKEN_IDENTIFIER ||
+         expected_token == G_TOKEN_IDENTIFIER_NULL)
+       print_unexp = FALSE;
+      _g_snprintf (token_string,
+                 token_string_len,
+                 "%s%s `%s'",
+                 print_unexp ? "" : "invalid ",
+                 identifier_spec,
+                 scanner->token == G_TOKEN_IDENTIFIER ? scanner->value.v_string : "null");
+      break;
+      
+    case G_TOKEN_BINARY:
+    case G_TOKEN_OCTAL:
+    case G_TOKEN_INT:
+    case G_TOKEN_HEX:
+      if (scanner->config->store_int64)
+       _g_snprintf (token_string, token_string_len, "number `%" G_GUINT64_FORMAT "'", scanner->value.v_int64);
+      else
+       _g_snprintf (token_string, token_string_len, "number `%lu'", scanner->value.v_int);
+      break;
+      
+    case G_TOKEN_FLOAT:
+      _g_snprintf (token_string, token_string_len, "number `%.3f'", scanner->value.v_float);
+      break;
+      
+    case G_TOKEN_STRING:
+      if (expected_token == G_TOKEN_STRING)
+       print_unexp = FALSE;
+      _g_snprintf (token_string,
+                  token_string_len,
+                  "%s%sstring constant \"%s\"",
+                  print_unexp ? "" : "invalid ",
+                  scanner->value.v_string[0] == 0 ? "empty " : "",
+                  scanner->value.v_string);
+      token_string[token_string_len - 2] = '"';
+      token_string[token_string_len - 1] = 0;
+      break;
+      
+    case G_TOKEN_COMMENT_SINGLE:
+    case G_TOKEN_COMMENT_MULTI:
+      _g_snprintf (token_string, token_string_len, "comment");
+      break;
+      
+    case G_TOKEN_NONE:
+      /* somehow the user's parsing code is screwed, there isn't much
+       * we can do about it.
+       * Note, a common case to trigger this is
+       * g_scanner_peek_next_token(); g_scanner_unexp_token();
+       * without an intermediate g_scanner_get_next_token().
+       */
+      g_assert_not_reached ();
+      break;
+    }
+  
+  
+  switch (expected_token)
+    {
+      gboolean need_valid;
+      gchar *tstring;
+    case G_TOKEN_EOF:
+      _g_snprintf (expected_string, expected_string_len, "end of file");
+      break;
+    default:
+      if (expected_token >= 1 && expected_token <= 255)
+       {
+         if ((expected_token >= ' ' && expected_token <= '~') ||
+             strchr (scanner->config->cset_identifier_first, expected_token) ||
+             strchr (scanner->config->cset_identifier_nth, expected_token))
+           _g_snprintf (expected_string, expected_string_len, "character `%c'", expected_token);
+         else
+           _g_snprintf (expected_string, expected_string_len, "character `\\%o'", expected_token);
+         break;
+       }
+      else if (!scanner->config->symbol_2_token)
+       {
+         _g_snprintf (expected_string, expected_string_len, "(unknown) token <%d>", expected_token);
+         break;
+       }
+      /* fall through */
+    case G_TOKEN_SYMBOL:
+      need_valid = (scanner->token == G_TOKEN_SYMBOL ||
+                   (scanner->config->symbol_2_token &&
+                    scanner->token > G_TOKEN_LAST));
+      _g_snprintf (expected_string,
+                  expected_string_len,
+                  "%s%s",
+                  need_valid ? "valid " : "",
+                  symbol_spec);
+      /* FIXME: should we attempt to lookup the symbol_name for symbol_2_token? */
+      break;
+    case G_TOKEN_CHAR:
+      _g_snprintf (expected_string, expected_string_len, "%scharacter",
+                  scanner->token == G_TOKEN_CHAR ? "valid " : "");
+      break;
+    case G_TOKEN_BINARY:
+      tstring = "binary";
+      _g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
+      break;
+    case G_TOKEN_OCTAL:
+      tstring = "octal";
+      _g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
+      break;
+    case G_TOKEN_INT:
+      tstring = "integer";
+      _g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
+      break;
+    case G_TOKEN_HEX:
+      tstring = "hexadecimal";
+      _g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
+      break;
+    case G_TOKEN_FLOAT:
+      tstring = "float";
+      _g_snprintf (expected_string, expected_string_len, "%snumber (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
+      break;
+    case G_TOKEN_STRING:
+      _g_snprintf (expected_string,
+                  expected_string_len,
+                  "%sstring constant",
+                  scanner->token == G_TOKEN_STRING ? "valid " : "");
+      break;
+    case G_TOKEN_IDENTIFIER:
+    case G_TOKEN_IDENTIFIER_NULL:
+      need_valid = (scanner->token == G_TOKEN_IDENTIFIER_NULL ||
+                   scanner->token == G_TOKEN_IDENTIFIER);
+      _g_snprintf (expected_string,
+                  expected_string_len,
+                  "%s%s",
+                  need_valid ? "valid " : "",
+                  identifier_spec);
+      break;
+    case G_TOKEN_COMMENT_SINGLE:
+      tstring = "single-line";
+      _g_snprintf (expected_string, expected_string_len, "%scomment (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
+      break;
+    case G_TOKEN_COMMENT_MULTI:
+      tstring = "multi-line";
+      _g_snprintf (expected_string, expected_string_len, "%scomment (%s)",
+                  scanner->token == expected_token ? "valid " : "", tstring);
+      break;
+    case G_TOKEN_NONE:
+    case G_TOKEN_ERROR:
+      /* this is handled upon printout */
+      break;
+    }
+  
+  if (message && message[0] != 0)
+    message_prefix = " - ";
+  else
+    {
+      message_prefix = "";
+      message = "";
+    }
+  if (expected_token == G_TOKEN_ERROR)
+    {
+      msg_handler (scanner,
+                  "failure around %s%s%s",
+                  token_string,
+                  message_prefix,
+                  message);
+    }
+  else if (expected_token == G_TOKEN_NONE)
+    {
+      if (print_unexp)
+       msg_handler (scanner,
+                    "unexpected %s%s%s",
+                    token_string,
+                    message_prefix,
+                    message);
+      else
+       msg_handler (scanner,
+                    "%s%s%s",
+                    token_string,
+                    message_prefix,
+                    message);
+    }
+  else
+    {
+      if (print_unexp)
+       msg_handler (scanner,
+                    "unexpected %s, expected %s%s%s",
+                    token_string,
+                    expected_string,
+                    message_prefix,
+                    message);
+      else
+       msg_handler (scanner,
+                    "%s, expected %s%s%s",
+                    token_string,
+                    expected_string,
+                    message_prefix,
+                    message);
+    }
+  
+  g_free (token_string);
+  g_free (expected_string);
+}
+
+static void
+g_scanner_get_token_i (GScanner        *scanner,
+                      GTokenType       *token_p,
+                      GTokenValue      *value_p,
+                      guint            *line_p,
+                      guint            *position_p)
+{
+  do
+    {
+      g_scanner_free_value (token_p, value_p);
+      g_scanner_get_token_ll (scanner, token_p, value_p, line_p, position_p);
+    }
+  while (((*token_p > 0 && *token_p < 256) &&
+         strchr (scanner->config->cset_skip_characters, *token_p)) ||
+        (*token_p == G_TOKEN_CHAR &&
+         strchr (scanner->config->cset_skip_characters, value_p->v_char)) ||
+        (*token_p == G_TOKEN_COMMENT_MULTI &&
+         scanner->config->skip_comment_multi) ||
+        (*token_p == G_TOKEN_COMMENT_SINGLE &&
+         scanner->config->skip_comment_single));
+  
+  switch (*token_p)
+    {
+    case G_TOKEN_IDENTIFIER:
+      if (scanner->config->identifier_2_string)
+       *token_p = G_TOKEN_STRING;
+      break;
+      
+    case G_TOKEN_SYMBOL:
+      if (scanner->config->symbol_2_token)
+       *token_p = (GTokenType) value_p->v_symbol;
+      break;
+      
+    case G_TOKEN_BINARY:
+    case G_TOKEN_OCTAL:
+    case G_TOKEN_HEX:
+      if (scanner->config->numbers_2_int)
+       *token_p = G_TOKEN_INT;
+      break;
+      
+    default:
+      break;
+    }
+  
+  if (*token_p == G_TOKEN_INT &&
+      scanner->config->int_2_float)
+    {
+      *token_p = G_TOKEN_FLOAT;
+      if (scanner->config->store_int64)
+        {
+#ifdef _MSC_VER
+          /* work around error C2520, see gvaluetransform.c */
+          value_p->v_float = (__int64)value_p->v_int64;
+#else
+          value_p->v_float = value_p->v_int64;
+#endif
+        }
+      else
+       value_p->v_float = value_p->v_int;
+    }
+  
+  errno = 0;
+}
+
+static void
+g_scanner_get_token_ll (GScanner       *scanner,
+                        GTokenType     *token_p,
+                        GTokenValue    *value_p,
+                        guint          *line_p,
+                        guint          *position_p)
+{
+  GScannerConfig *config;
+  GTokenType      token;
+  gboolean        in_comment_multi;
+  gboolean        in_comment_single;
+  gboolean        in_string_sq;
+  gboolean        in_string_dq;
+  GString        *gstring;
+  GTokenValue     value;
+  guchar          ch;
+  
+  config = scanner->config;
+  (*value_p).v_int64 = 0;
+  
+  if ((scanner->text >= scanner->text_end && scanner->input_fd < 0) ||
+      scanner->token == G_TOKEN_EOF)
+    {
+      *token_p = G_TOKEN_EOF;
+      return;
+    }
+  
+  in_comment_multi = FALSE;
+  in_comment_single = FALSE;
+  in_string_sq = FALSE;
+  in_string_dq = FALSE;
+  gstring = NULL;
+  
+  do /* while (ch != 0) */
+    {
+      gboolean dotted_float = FALSE;
+      
+      ch = g_scanner_get_char (scanner, line_p, position_p);
+      
+      value.v_int64 = 0;
+      token = G_TOKEN_NONE;
+      
+      /* this is *evil*, but needed ;(
+       * we first check for identifier first character, because         it
+       * might interfere with other key chars like slashes or numbers
+       */
+      if (config->scan_identifier &&
+         ch && strchr (config->cset_identifier_first, ch))
+       goto identifier_precedence;
+      
+      switch (ch)
+       {
+       case 0:
+         token = G_TOKEN_EOF;
+         (*position_p)++;
+         /* ch = 0; */
+         break;
+         
+       case '/':
+         if (!config->scan_comment_multi ||
+             g_scanner_peek_next_char (scanner) != '*')
+           goto default_case;
+         g_scanner_get_char (scanner, line_p, position_p);
+         token = G_TOKEN_COMMENT_MULTI;
+         in_comment_multi = TRUE;
+         gstring = g_string_new (NULL);
+         while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
+           {
+             if (ch == '*' && g_scanner_peek_next_char (scanner) == '/')
+               {
+                 g_scanner_get_char (scanner, line_p, position_p);
+                 in_comment_multi = FALSE;
+                 break;
+               }
+             else
+               gstring = g_string_append_c (gstring, ch);
+           }
+         ch = 0;
+         break;
+         
+       case '\'':
+         if (!config->scan_string_sq)
+           goto default_case;
+         token = G_TOKEN_STRING;
+         in_string_sq = TRUE;
+         gstring = g_string_new (NULL);
+         while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
+           {
+             if (ch == '\'')
+               {
+                 in_string_sq = FALSE;
+                 break;
+               }
+             else
+               gstring = g_string_append_c (gstring, ch);
+           }
+         ch = 0;
+         break;
+         
+       case '"':
+         if (!config->scan_string_dq)
+           goto default_case;
+         token = G_TOKEN_STRING;
+         in_string_dq = TRUE;
+         gstring = g_string_new (NULL);
+         while ((ch = g_scanner_get_char (scanner, line_p, position_p)) != 0)
+           {
+             if (ch == '"')
+               {
+                 in_string_dq = FALSE;
+                 break;
+               }
+             else
+               {
+                 if (ch == '\\')
+                   {
+                     ch = g_scanner_get_char (scanner, line_p, position_p);
+                     switch (ch)
+                       {
+                         guint i;
+                         guint fchar;
+                         
+                       case 0:
+                         break;
+                         
+                       case '\\':
+                         gstring = g_string_append_c (gstring, '\\');
+                         break;
+                         
+                       case 'n':
+                         gstring = g_string_append_c (gstring, '\n');
+                         break;
+                         
+                       case 't':
+                         gstring = g_string_append_c (gstring, '\t');
+                         break;
+                         
+                       case 'r':
+                         gstring = g_string_append_c (gstring, '\r');
+                         break;
+                         
+                       case 'b':
+                         gstring = g_string_append_c (gstring, '\b');
+                         break;
+                         
+                       case 'f':
+                         gstring = g_string_append_c (gstring, '\f');
+                         break;
+                         
+                       case '0':
+                       case '1':
+                       case '2':
+                       case '3':
+                       case '4':
+                       case '5':
+                       case '6':
+                       case '7':
+                         i = ch - '0';
+                         fchar = g_scanner_peek_next_char (scanner);
+                         if (fchar >= '0' && fchar <= '7')
+                           {
+                             ch = g_scanner_get_char (scanner, line_p, position_p);
+                             i = i * 8 + ch - '0';
+                             fchar = g_scanner_peek_next_char (scanner);
+                             if (fchar >= '0' && fchar <= '7')
+                               {
+                                 ch = g_scanner_get_char (scanner, line_p, position_p);
+                                 i = i * 8 + ch - '0';
+                               }
+                           }
+                         gstring = g_string_append_c (gstring, i);
+                         break;
+                         
+                       default:
+                         gstring = g_string_append_c (gstring, ch);
+                         break;
+                       }
+                   }
+                 else
+                   gstring = g_string_append_c (gstring, ch);
+               }
+           }
+         ch = 0;
+         break;
+         
+       case '.':
+         if (!config->scan_float)
+           goto default_case;
+         token = G_TOKEN_FLOAT;
+         dotted_float = TRUE;
+         ch = g_scanner_get_char (scanner, line_p, position_p);
+         goto number_parsing;
+         
+       case '$':
+         if (!config->scan_hex_dollar)
+           goto default_case;
+         token = G_TOKEN_HEX;
+         ch = g_scanner_get_char (scanner, line_p, position_p);
+         goto number_parsing;
+         
+       case '0':
+         if (config->scan_octal)
+           token = G_TOKEN_OCTAL;
+         else
+           token = G_TOKEN_INT;
+         ch = g_scanner_peek_next_char (scanner);
+         if (config->scan_hex && (ch == 'x' || ch == 'X'))
+           {
+             token = G_TOKEN_HEX;
+             g_scanner_get_char (scanner, line_p, position_p);
+             ch = g_scanner_get_char (scanner, line_p, position_p);
+             if (ch == 0)
+               {
+                 token = G_TOKEN_ERROR;
+                 value.v_error = G_ERR_UNEXP_EOF;
+                 (*position_p)++;
+                 break;
+               }
+             if (g_scanner_char_2_num (ch, 16) < 0)
+               {
+                 token = G_TOKEN_ERROR;
+                 value.v_error = G_ERR_DIGIT_RADIX;
+                 ch = 0;
+                 break;
+               }
+           }
+         else if (config->scan_binary && (ch == 'b' || ch == 'B'))
+           {
+             token = G_TOKEN_BINARY;
+             g_scanner_get_char (scanner, line_p, position_p);
+             ch = g_scanner_get_char (scanner, line_p, position_p);
+             if (ch == 0)
+               {
+                 token = G_TOKEN_ERROR;
+                 value.v_error = G_ERR_UNEXP_EOF;
+                 (*position_p)++;
+                 break;
+               }
+             if (g_scanner_char_2_num (ch, 10) < 0)
+               {
+                 token = G_TOKEN_ERROR;
+                 value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+                 ch = 0;
+                 break;
+               }
+           }
+         else
+           ch = '0';
+         /* fall through */
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+       number_parsing:
+       {
+          gboolean in_number = TRUE;
+         gchar *endptr;
+         
+         if (token == G_TOKEN_NONE)
+           token = G_TOKEN_INT;
+         
+         gstring = g_string_new (dotted_float ? "0." : "");
+         gstring = g_string_append_c (gstring, ch);
+         
+         do /* while (in_number) */
+           {
+             gboolean is_E;
+             
+             is_E = token == G_TOKEN_FLOAT && (ch == 'e' || ch == 'E');
+             
+             ch = g_scanner_peek_next_char (scanner);
+             
+             if (g_scanner_char_2_num (ch, 36) >= 0 ||
+                 (config->scan_float && ch == '.') ||
+                 (is_E && (ch == '+' || ch == '-')))
+               {
+                 ch = g_scanner_get_char (scanner, line_p, position_p);
+                 
+                 switch (ch)
+                   {
+                   case '.':
+                     if (token != G_TOKEN_INT && token != G_TOKEN_OCTAL)
+                       {
+                         value.v_error = token == G_TOKEN_FLOAT ? G_ERR_FLOAT_MALFORMED : G_ERR_FLOAT_RADIX;
+                         token = G_TOKEN_ERROR;
+                         in_number = FALSE;
+                       }
+                     else
+                       {
+                         token = G_TOKEN_FLOAT;
+                         gstring = g_string_append_c (gstring, ch);
+                       }
+                     break;
+                     
+                   case '0':
+                   case '1':
+                   case '2':
+                   case '3':
+                   case '4':
+                   case '5':
+                   case '6':
+                   case '7':
+                   case '8':
+                   case '9':
+                     gstring = g_string_append_c (gstring, ch);
+                     break;
+                     
+                   case '-':
+                   case '+':
+                     if (token != G_TOKEN_FLOAT)
+                       {
+                         token = G_TOKEN_ERROR;
+                         value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+                         in_number = FALSE;
+                       }
+                     else
+                       gstring = g_string_append_c (gstring, ch);
+                     break;
+                     
+                   case 'e':
+                   case 'E':
+                     if ((token != G_TOKEN_HEX && !config->scan_float) ||
+                         (token != G_TOKEN_HEX &&
+                          token != G_TOKEN_OCTAL &&
+                          token != G_TOKEN_FLOAT &&
+                          token != G_TOKEN_INT))
+                       {
+                         token = G_TOKEN_ERROR;
+                         value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+                         in_number = FALSE;
+                       }
+                     else
+                       {
+                         if (token != G_TOKEN_HEX)
+                           token = G_TOKEN_FLOAT;
+                         gstring = g_string_append_c (gstring, ch);
+                       }
+                     break;
+                     
+                   default:
+                     if (token != G_TOKEN_HEX)
+                       {
+                         token = G_TOKEN_ERROR;
+                         value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+                         in_number = FALSE;
+                       }
+                     else
+                       gstring = g_string_append_c (gstring, ch);
+                     break;
+                   }
+               }
+             else
+               in_number = FALSE;
+           }
+         while (in_number);
+         
+         endptr = NULL;
+         if (token == G_TOKEN_FLOAT)
+           value.v_float = g_strtod (gstring->str, &endptr);
+         else
+           {
+             guint64 ui64 = 0;
+             switch (token)
+               {
+               case G_TOKEN_BINARY:
+                 ui64 = g_ascii_strtoull (gstring->str, &endptr, 2);
+                 break;
+               case G_TOKEN_OCTAL:
+                 ui64 = g_ascii_strtoull (gstring->str, &endptr, 8);
+                 break;
+               case G_TOKEN_INT:
+                 ui64 = g_ascii_strtoull (gstring->str, &endptr, 10);
+                 break;
+               case G_TOKEN_HEX:
+                 ui64 = g_ascii_strtoull (gstring->str, &endptr, 16);
+                 break;
+               default: ;
+               }
+             if (scanner->config->store_int64)
+               value.v_int64 = ui64;
+             else
+               value.v_int = ui64;
+           }
+         if (endptr && *endptr)
+           {
+             token = G_TOKEN_ERROR;
+             if (*endptr == 'e' || *endptr == 'E')
+               value.v_error = G_ERR_NON_DIGIT_IN_CONST;
+             else
+               value.v_error = G_ERR_DIGIT_RADIX;
+           }
+         g_string_free (gstring, TRUE);
+         gstring = NULL;
+         ch = 0;
+       } /* number_parsing:... */
+       break;
+       
+       default:
+       default_case:
+       {
+         if (config->cpair_comment_single &&
+             ch == config->cpair_comment_single[0])
+           {
+             token = G_TOKEN_COMMENT_SINGLE;
+             in_comment_single = TRUE;
+             gstring = g_string_new (NULL);
+             ch = g_scanner_get_char (scanner, line_p, position_p);
+             while (ch != 0)
+               {
+                 if (ch == config->cpair_comment_single[1])
+                   {
+                     in_comment_single = FALSE;
+                     ch = 0;
+                     break;
+                   }
+                 
+                 gstring = g_string_append_c (gstring, ch);
+                 ch = g_scanner_get_char (scanner, line_p, position_p);
+               }
+             /* ignore a missing newline at EOF for single line comments */
+             if (in_comment_single &&
+                 config->cpair_comment_single[1] == '\n')
+               in_comment_single = FALSE;
+           }
+         else if (config->scan_identifier && ch &&
+                  strchr (config->cset_identifier_first, ch))
+           {
+           identifier_precedence:
+             
+             if (config->cset_identifier_nth && ch &&
+                 strchr (config->cset_identifier_nth,
+                         g_scanner_peek_next_char (scanner)))
+               {
+                 token = G_TOKEN_IDENTIFIER;
+                 gstring = g_string_new (NULL);
+                 gstring = g_string_append_c (gstring, ch);
+                 do
+                   {
+                     ch = g_scanner_get_char (scanner, line_p, position_p);
+                     gstring = g_string_append_c (gstring, ch);
+                     ch = g_scanner_peek_next_char (scanner);
+                   }
+                 while (ch && strchr (config->cset_identifier_nth, ch));
+                 ch = 0;
+               }
+             else if (config->scan_identifier_1char)
+               {
+                 token = G_TOKEN_IDENTIFIER;
+                 value.v_identifier = g_new0 (gchar, 2);
+                 value.v_identifier[0] = ch;
+                 ch = 0;
+               }
+           }
+         if (ch)
+           {
+             if (config->char_2_token)
+               token = ch;
+             else
+               {
+                 token = G_TOKEN_CHAR;
+                 value.v_char = ch;
+               }
+             ch = 0;
+           }
+       } /* default_case:... */
+       break;
+       }
+      g_assert (ch == 0 && token != G_TOKEN_NONE); /* paranoid */
+    }
+  while (ch != 0);
+  
+  if (in_comment_multi || in_comment_single ||
+      in_string_sq || in_string_dq)
+    {
+      token = G_TOKEN_ERROR;
+      if (gstring)
+       {
+         g_string_free (gstring, TRUE);
+         gstring = NULL;
+       }
+      (*position_p)++;
+      if (in_comment_multi || in_comment_single)
+       value.v_error = G_ERR_UNEXP_EOF_IN_COMMENT;
+      else /* (in_string_sq || in_string_dq) */
+       value.v_error = G_ERR_UNEXP_EOF_IN_STRING;
+    }
+  
+  if (gstring)
+    {
+      value.v_string = g_string_free (gstring, FALSE);
+      gstring = NULL;
+    }
+  
+  if (token == G_TOKEN_IDENTIFIER)
+    {
+      if (config->scan_symbols)
+       {
+         GScannerKey *key;
+         guint scope_id;
+         
+         scope_id = scanner->scope_id;
+         key = g_scanner_lookup_internal (scanner, scope_id, value.v_identifier);
+         if (!key && scope_id && scanner->config->scope_0_fallback)
+           key = g_scanner_lookup_internal (scanner, 0, value.v_identifier);
+         
+         if (key)
+           {
+             g_free (value.v_identifier);
+             token = G_TOKEN_SYMBOL;
+             value.v_symbol = key->value;
+           }
+       }
+      
+      if (token == G_TOKEN_IDENTIFIER &&
+         config->scan_identifier_NULL &&
+         strlen (value.v_identifier) == 4)
+       {
+         gchar *null_upper = "NULL";
+         gchar *null_lower = "null";
+         
+         if (scanner->config->case_sensitive)
+           {
+             if (value.v_identifier[0] == null_upper[0] &&
+                 value.v_identifier[1] == null_upper[1] &&
+                 value.v_identifier[2] == null_upper[2] &&
+                 value.v_identifier[3] == null_upper[3])
+               token = G_TOKEN_IDENTIFIER_NULL;
+           }
+         else
+           {
+             if ((value.v_identifier[0] == null_upper[0] ||
+                  value.v_identifier[0] == null_lower[0]) &&
+                 (value.v_identifier[1] == null_upper[1] ||
+                  value.v_identifier[1] == null_lower[1]) &&
+                 (value.v_identifier[2] == null_upper[2] ||
+                  value.v_identifier[2] == null_lower[2]) &&
+                 (value.v_identifier[3] == null_upper[3] ||
+                  value.v_identifier[3] == null_lower[3]))
+               token = G_TOKEN_IDENTIFIER_NULL;
+           }
+       }
+    }
+  
+  *token_p = token;
+  *value_p = value;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gscanner.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gscanner.h
new file mode 100644 (file)
index 0000000..3b7ad6f
--- /dev/null
@@ -0,0 +1,278 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_SCANNER_H__
+#define __G_SCANNER_H__
+
+#include <glib/gdataset.h>
+#include <glib/ghash.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GScanner       GScanner;
+typedef struct _GScannerConfig GScannerConfig;
+typedef union  _GTokenValue     GTokenValue;
+
+typedef void           (*GScannerMsgFunc)      (GScanner      *scanner,
+                                                gchar         *message,
+                                                gboolean       error);
+
+/* GScanner: Flexible lexical scanner for general purpose.
+ */
+
+/* Character sets */
+#define G_CSET_A_2_Z   "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
+#define G_CSET_a_2_z   "abcdefghijklmnopqrstuvwxyz"
+#define G_CSET_DIGITS  "0123456789"
+#define G_CSET_LATINC  "\300\301\302\303\304\305\306"\
+                       "\307\310\311\312\313\314\315\316\317\320"\
+                       "\321\322\323\324\325\326"\
+                       "\330\331\332\333\334\335\336"
+#define G_CSET_LATINS  "\337\340\341\342\343\344\345\346"\
+                       "\347\350\351\352\353\354\355\356\357\360"\
+                       "\361\362\363\364\365\366"\
+                       "\370\371\372\373\374\375\376\377"
+
+/* Error types */
+typedef enum
+{
+  G_ERR_UNKNOWN,
+  G_ERR_UNEXP_EOF,
+  G_ERR_UNEXP_EOF_IN_STRING,
+  G_ERR_UNEXP_EOF_IN_COMMENT,
+  G_ERR_NON_DIGIT_IN_CONST,
+  G_ERR_DIGIT_RADIX,
+  G_ERR_FLOAT_RADIX,
+  G_ERR_FLOAT_MALFORMED
+} GErrorType;
+
+/* Token types */
+typedef enum
+{
+  G_TOKEN_EOF                  =   0,
+  
+  G_TOKEN_LEFT_PAREN           = '(',
+  G_TOKEN_RIGHT_PAREN          = ')',
+  G_TOKEN_LEFT_CURLY           = '{',
+  G_TOKEN_RIGHT_CURLY          = '}',
+  G_TOKEN_LEFT_BRACE           = '[',
+  G_TOKEN_RIGHT_BRACE          = ']',
+  G_TOKEN_EQUAL_SIGN           = '=',
+  G_TOKEN_COMMA                        = ',',
+  
+  G_TOKEN_NONE                 = 256,
+  
+  G_TOKEN_ERROR,
+  
+  G_TOKEN_CHAR,
+  G_TOKEN_BINARY,
+  G_TOKEN_OCTAL,
+  G_TOKEN_INT,
+  G_TOKEN_HEX,
+  G_TOKEN_FLOAT,
+  G_TOKEN_STRING,
+  
+  G_TOKEN_SYMBOL,
+  G_TOKEN_IDENTIFIER,
+  G_TOKEN_IDENTIFIER_NULL,
+  
+  G_TOKEN_COMMENT_SINGLE,
+  G_TOKEN_COMMENT_MULTI,
+  G_TOKEN_LAST
+} GTokenType;
+
+union  _GTokenValue
+{
+  gpointer     v_symbol;
+  gchar                *v_identifier;
+  gulong       v_binary;
+  gulong       v_octal;
+  gulong       v_int;
+  guint64       v_int64;
+  gdouble      v_float;
+  gulong       v_hex;
+  gchar                *v_string;
+  gchar                *v_comment;
+  guchar       v_char;
+  guint                v_error;
+};
+
+struct _GScannerConfig
+{
+  /* Character sets
+   */
+  gchar                *cset_skip_characters;          /* default: " \t\n" */
+  gchar                *cset_identifier_first;
+  gchar                *cset_identifier_nth;
+  gchar                *cpair_comment_single;          /* default: "#\n" */
+  
+  /* Should symbol lookup work case sensitive?
+   */
+  guint                case_sensitive : 1;
+  
+  /* Boolean values to be adjusted "on the fly"
+   * to configure scanning behaviour.
+   */
+  guint                skip_comment_multi : 1;         /* C like comment */
+  guint                skip_comment_single : 1;        /* single line comment */
+  guint                scan_comment_multi : 1;         /* scan multi line comments? */
+  guint                scan_identifier : 1;
+  guint                scan_identifier_1char : 1;
+  guint                scan_identifier_NULL : 1;
+  guint                scan_symbols : 1;
+  guint                scan_binary : 1;
+  guint                scan_octal : 1;
+  guint                scan_float : 1;
+  guint                scan_hex : 1;                   /* `0x0ff0' */
+  guint                scan_hex_dollar : 1;            /* `$0ff0' */
+  guint                scan_string_sq : 1;             /* string: 'anything' */
+  guint                scan_string_dq : 1;             /* string: "\\-escapes!\n" */
+  guint                numbers_2_int : 1;              /* bin, octal, hex => int */
+  guint                int_2_float : 1;                /* int => G_TOKEN_FLOAT? */
+  guint                identifier_2_string : 1;
+  guint                char_2_token : 1;               /* return G_TOKEN_CHAR? */
+  guint                symbol_2_token : 1;
+  guint                scope_0_fallback : 1;           /* try scope 0 on lookups? */
+  guint                store_int64 : 1;                /* use value.v_int64 rather than v_int */
+  guint                padding_dummy;
+};
+
+struct _GScanner
+{
+  /* unused fields */
+  gpointer             user_data;
+  guint                        max_parse_errors;
+  
+  /* g_scanner_error() increments this field */
+  guint                        parse_errors;
+  
+  /* name of input stream, featured by the default message handler */
+  const gchar          *input_name;
+  
+  /* quarked data */
+  GData                        *qdata;
+  
+  /* link into the scanner configuration */
+  GScannerConfig       *config;
+  
+  /* fields filled in after g_scanner_get_next_token() */
+  GTokenType           token;
+  GTokenValue          value;
+  guint                        line;
+  guint                        position;
+  
+  /* fields filled in after g_scanner_peek_next_token() */
+  GTokenType           next_token;
+  GTokenValue          next_value;
+  guint                        next_line;
+  guint                        next_position;
+  
+  /* to be considered private */
+  GHashTable           *symbol_table;
+  gint                 input_fd;
+  const gchar          *text;
+  const gchar          *text_end;
+  gchar                        *buffer;
+  guint                        scope_id;
+  
+  /* handler function for _warn and _error */
+  GScannerMsgFunc      msg_handler;
+};
+
+GScanner*      g_scanner_new                   (const GScannerConfig *config_templ);
+void           g_scanner_destroy               (GScanner       *scanner);
+void           g_scanner_input_file            (GScanner       *scanner,
+                                                gint           input_fd);
+void           g_scanner_sync_file_offset      (GScanner       *scanner);
+void           g_scanner_input_text            (GScanner       *scanner,
+                                                const  gchar   *text,
+                                                guint          text_len);
+GTokenType     g_scanner_get_next_token        (GScanner       *scanner);
+GTokenType     g_scanner_peek_next_token       (GScanner       *scanner);
+GTokenType     g_scanner_cur_token             (GScanner       *scanner);
+GTokenValue    g_scanner_cur_value             (GScanner       *scanner);
+guint          g_scanner_cur_line              (GScanner       *scanner);
+guint          g_scanner_cur_position          (GScanner       *scanner);
+gboolean       g_scanner_eof                   (GScanner       *scanner);
+guint          g_scanner_set_scope             (GScanner       *scanner,
+                                                guint           scope_id);
+void           g_scanner_scope_add_symbol      (GScanner       *scanner,
+                                                guint           scope_id,
+                                                const gchar    *symbol,
+                                                gpointer       value);
+void           g_scanner_scope_remove_symbol   (GScanner       *scanner,
+                                                guint           scope_id,
+                                                const gchar    *symbol);
+gpointer       g_scanner_scope_lookup_symbol   (GScanner       *scanner,
+                                                guint           scope_id,
+                                                const gchar    *symbol);
+void           g_scanner_scope_foreach_symbol  (GScanner       *scanner,
+                                                guint           scope_id,
+                                                GHFunc          func,
+                                                gpointer        user_data);
+gpointer       g_scanner_lookup_symbol         (GScanner       *scanner,
+                                                const gchar    *symbol);
+void           g_scanner_unexp_token           (GScanner       *scanner,
+                                                GTokenType     expected_token,
+                                                const gchar    *identifier_spec,
+                                                const gchar    *symbol_spec,
+                                                const gchar    *symbol_name,
+                                                const gchar    *message,
+                                                gint            is_error);
+void           g_scanner_error                 (GScanner       *scanner,
+                                                const gchar    *format,
+                                                ...) G_GNUC_PRINTF (2,3);
+void           g_scanner_warn                  (GScanner       *scanner,
+                                                const gchar    *format,
+                                                ...) G_GNUC_PRINTF (2,3);
+
+#ifndef G_DISABLE_DEPRECATED
+
+/* keep downward source compatibility */
+#define                g_scanner_add_symbol( scanner, symbol, value )  G_STMT_START { \
+  g_scanner_scope_add_symbol ((scanner), 0, (symbol), (value)); \
+} G_STMT_END
+#define                g_scanner_remove_symbol( scanner, symbol )      G_STMT_START { \
+  g_scanner_scope_remove_symbol ((scanner), 0, (symbol)); \
+} G_STMT_END
+#define                g_scanner_foreach_symbol( scanner, func, data ) G_STMT_START { \
+  g_scanner_scope_foreach_symbol ((scanner), 0, (func), (data)); \
+} G_STMT_END
+
+/* The following two functions are deprecated and will be removed in
+ * the next major release. They do no good. */
+#define g_scanner_freeze_symbol_table(scanner) ((void)0)
+#define g_scanner_thaw_symbol_table(scanner) ((void)0)
+
+#endif /* G_DISABLE_DEPRECATED */
+
+G_END_DECLS
+
+#endif /* __G_SCANNER_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gscripttable.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gscripttable.h
new file mode 100644 (file)
index 0000000..b63e2da
--- /dev/null
@@ -0,0 +1,3012 @@
+/* gscripttable.h: Generated by gen-script-table.pl
+ *
+ *  Date: Mon Apr  7 23:17:02 2008
+ *  Source: Scripts-5.1.0.txt
+ *
+ * Do not edit.
+ */
+
+#define G_EASY_SCRIPTS_RANGE 8192
+
+static const guchar g_script_easy_table[8192] = {
+
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC,
+  G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC,
+  G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC,
+  G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC,
+  G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC, G_UNICODE_SCRIPT_COPTIC,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_ARMENIAN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_HEBREW,
+  G_UNICODE_SCRIPT_HEBREW, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC, G_UNICODE_SCRIPT_SYRIAC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC, G_UNICODE_SCRIPT_ARABIC,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA,
+  G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_THAANA, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO, G_UNICODE_SCRIPT_NKO,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI,
+  G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_DEVANAGARI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI,
+  G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_BENGALI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI,
+  G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_GURMUKHI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_GUJARATI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GUJARATI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA,
+  G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_ORIYA, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_TAMIL,
+  G_UNICODE_SCRIPT_TAMIL, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU,
+  G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_TELUGU, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA, G_UNICODE_SCRIPT_KANNADA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM, G_UNICODE_SCRIPT_MALAYALAM,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA, G_UNICODE_SCRIPT_SINHALA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_THAI,
+  G_UNICODE_SCRIPT_THAI, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_LAO, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN, G_UNICODE_SCRIPT_TIBETAN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_MYANMAR, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_GEORGIAN,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_GEORGIAN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL, G_UNICODE_SCRIPT_HANGUL,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC,
+  G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_ETHIOPIC, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE, G_UNICODE_SCRIPT_CHEROKEE,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM,
+  G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM,
+  G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM,
+  G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM,
+  G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM,
+  G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM,
+  G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM,
+  G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM,
+  G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM,
+  G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_OGHAM, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_RUNIC,
+  G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_RUNIC, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAGALOG,
+  G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG,
+  G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG,
+  G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG,
+  G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG,
+  G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG,
+  G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_TAGALOG, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO,
+  G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO,
+  G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO,
+  G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO,
+  G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO,
+  G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO,
+  G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_HANUNOO,
+  G_UNICODE_SCRIPT_HANUNOO, G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID,
+  G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID,
+  G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID,
+  G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID,
+  G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID,
+  G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID,
+  G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_BUHID, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAGBANWA,
+  G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA,
+  G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA,
+  G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA,
+  G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_TAGBANWA,
+  G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAGBANWA,
+  G_UNICODE_SCRIPT_TAGBANWA, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_COMMON, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_COMMON,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN, G_UNICODE_SCRIPT_MONGOLIAN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU, G_UNICODE_SCRIPT_LIMBU,
+  G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE,
+  G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE,
+  G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE,
+  G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE,
+  G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE,
+  G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE,
+  G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE,
+  G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE,
+  G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE,
+  G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_TAI_LE,
+  G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_TAI_LE,
+  G_UNICODE_SCRIPT_TAI_LE, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_NEW_TAI_LUE, G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER,
+  G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_KHMER, G_UNICODE_SCRIPT_BUGINESE,
+  G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE,
+  G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE,
+  G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE,
+  G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE,
+  G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE,
+  G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE,
+  G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE,
+  G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE,
+  G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_BUGINESE,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BUGINESE,
+  G_UNICODE_SCRIPT_BUGINESE, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE,
+  G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_BALINESE, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE, G_UNICODE_SCRIPT_SUNDANESE,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA, G_UNICODE_SCRIPT_LEPCHA,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI, G_UNICODE_SCRIPT_OL_CHIKI,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_CYRILLIC, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_CYRILLIC,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_INHERITED, G_UNICODE_SCRIPT_INHERITED,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_LATIN,
+  G_UNICODE_SCRIPT_LATIN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_UNKNOWN,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_UNKNOWN, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_GREEK,
+  G_UNICODE_SCRIPT_GREEK, G_UNICODE_SCRIPT_UNKNOWN,
+};
+
+static const struct {
+    gunichar    start;
+    guint16     chars;
+    guint16     script;
+} g_script_table[] = { 
+ { 0x2000,    12, G_UNICODE_SCRIPT_COMMON },
+ { 0x200c,     2, G_UNICODE_SCRIPT_INHERITED },
+ { 0x200e,    87, G_UNICODE_SCRIPT_COMMON },
+ { 0x206a,     7, G_UNICODE_SCRIPT_COMMON },
+ { 0x2071,     1, G_UNICODE_SCRIPT_LATIN },
+ { 0x2074,    11, G_UNICODE_SCRIPT_COMMON },
+ { 0x207f,     1, G_UNICODE_SCRIPT_LATIN },
+ { 0x2080,    15, G_UNICODE_SCRIPT_COMMON },
+ { 0x2090,     5, G_UNICODE_SCRIPT_LATIN },
+ { 0x20a0,    22, G_UNICODE_SCRIPT_COMMON },
+ { 0x20d0,    33, G_UNICODE_SCRIPT_INHERITED },
+ { 0x2100,    38, G_UNICODE_SCRIPT_COMMON },
+ { 0x2126,     1, G_UNICODE_SCRIPT_GREEK },
+ { 0x2127,     3, G_UNICODE_SCRIPT_COMMON },
+ { 0x212a,     2, G_UNICODE_SCRIPT_LATIN },
+ { 0x212c,     6, G_UNICODE_SCRIPT_COMMON },
+ { 0x2132,     1, G_UNICODE_SCRIPT_LATIN },
+ { 0x2133,    27, G_UNICODE_SCRIPT_COMMON },
+ { 0x214e,     1, G_UNICODE_SCRIPT_LATIN },
+ { 0x214f,     1, G_UNICODE_SCRIPT_COMMON },
+ { 0x2153,    13, G_UNICODE_SCRIPT_COMMON },
+ { 0x2160,    41, G_UNICODE_SCRIPT_LATIN },
+ { 0x2190,   600, G_UNICODE_SCRIPT_COMMON },
+ { 0x2400,    39, G_UNICODE_SCRIPT_COMMON },
+ { 0x2440,    11, G_UNICODE_SCRIPT_COMMON },
+ { 0x2460,   574, G_UNICODE_SCRIPT_COMMON },
+ { 0x26a0,    29, G_UNICODE_SCRIPT_COMMON },
+ { 0x26c0,     4, G_UNICODE_SCRIPT_COMMON },
+ { 0x2701,     4, G_UNICODE_SCRIPT_COMMON },
+ { 0x2706,     4, G_UNICODE_SCRIPT_COMMON },
+ { 0x270c,    28, G_UNICODE_SCRIPT_COMMON },
+ { 0x2729,    35, G_UNICODE_SCRIPT_COMMON },
+ { 0x274d,     1, G_UNICODE_SCRIPT_COMMON },
+ { 0x274f,     4, G_UNICODE_SCRIPT_COMMON },
+ { 0x2756,     1, G_UNICODE_SCRIPT_COMMON },
+ { 0x2758,     7, G_UNICODE_SCRIPT_COMMON },
+ { 0x2761,    52, G_UNICODE_SCRIPT_COMMON },
+ { 0x2798,    24, G_UNICODE_SCRIPT_COMMON },
+ { 0x27b1,    14, G_UNICODE_SCRIPT_COMMON },
+ { 0x27c0,    11, G_UNICODE_SCRIPT_COMMON },
+ { 0x27cc,     1, G_UNICODE_SCRIPT_COMMON },
+ { 0x27d0,    48, G_UNICODE_SCRIPT_COMMON },
+ { 0x2800,   256, G_UNICODE_SCRIPT_BRAILLE },
+ { 0x2900,   589, G_UNICODE_SCRIPT_COMMON },
+ { 0x2b50,     5, G_UNICODE_SCRIPT_COMMON },
+ { 0x2c00,    47, G_UNICODE_SCRIPT_GLAGOLITIC },
+ { 0x2c30,    47, G_UNICODE_SCRIPT_GLAGOLITIC },
+ { 0x2c60,    16, G_UNICODE_SCRIPT_LATIN },
+ { 0x2c71,    13, G_UNICODE_SCRIPT_LATIN },
+ { 0x2c80,   107, G_UNICODE_SCRIPT_COPTIC },
+ { 0x2cf9,     7, G_UNICODE_SCRIPT_COPTIC },
+ { 0x2d00,    38, G_UNICODE_SCRIPT_GEORGIAN },
+ { 0x2d30,    54, G_UNICODE_SCRIPT_TIFINAGH },
+ { 0x2d6f,     1, G_UNICODE_SCRIPT_TIFINAGH },
+ { 0x2d80,    23, G_UNICODE_SCRIPT_ETHIOPIC },
+ { 0x2da0,     7, G_UNICODE_SCRIPT_ETHIOPIC },
+ { 0x2da8,     7, G_UNICODE_SCRIPT_ETHIOPIC },
+ { 0x2db0,     7, G_UNICODE_SCRIPT_ETHIOPIC },
+ { 0x2db8,     7, G_UNICODE_SCRIPT_ETHIOPIC },
+ { 0x2dc0,     7, G_UNICODE_SCRIPT_ETHIOPIC },
+ { 0x2dc8,     7, G_UNICODE_SCRIPT_ETHIOPIC },
+ { 0x2dd0,     7, G_UNICODE_SCRIPT_ETHIOPIC },
+ { 0x2dd8,     7, G_UNICODE_SCRIPT_ETHIOPIC },
+ { 0x2de0,    32, G_UNICODE_SCRIPT_CYRILLIC },
+ { 0x2e00,    49, G_UNICODE_SCRIPT_COMMON },
+ { 0x2e80,    26, G_UNICODE_SCRIPT_HAN },
+ { 0x2e9b,    89, G_UNICODE_SCRIPT_HAN },
+ { 0x2f00,   214, G_UNICODE_SCRIPT_HAN },
+ { 0x2ff0,    12, G_UNICODE_SCRIPT_COMMON },
+ { 0x3000,     5, G_UNICODE_SCRIPT_COMMON },
+ { 0x3005,     1, G_UNICODE_SCRIPT_HAN },
+ { 0x3006,     1, G_UNICODE_SCRIPT_COMMON },
+ { 0x3007,     1, G_UNICODE_SCRIPT_HAN },
+ { 0x3008,    25, G_UNICODE_SCRIPT_COMMON },
+ { 0x3021,     9, G_UNICODE_SCRIPT_HAN },
+ { 0x302a,     6, G_UNICODE_SCRIPT_INHERITED },
+ { 0x3030,     8, G_UNICODE_SCRIPT_COMMON },
+ { 0x3038,     4, G_UNICODE_SCRIPT_HAN },
+ { 0x303c,     4, G_UNICODE_SCRIPT_COMMON },
+ { 0x3041,    86, G_UNICODE_SCRIPT_HIRAGANA },
+ { 0x3099,     2, G_UNICODE_SCRIPT_INHERITED },
+ { 0x309b,     2, G_UNICODE_SCRIPT_COMMON },
+ { 0x309d,     3, G_UNICODE_SCRIPT_HIRAGANA },
+ { 0x30a0,     1, G_UNICODE_SCRIPT_COMMON },
+ { 0x30a1,    90, G_UNICODE_SCRIPT_KATAKANA },
+ { 0x30fb,     2, G_UNICODE_SCRIPT_COMMON },
+ { 0x30fd,     3, G_UNICODE_SCRIPT_KATAKANA },
+ { 0x3105,    41, G_UNICODE_SCRIPT_BOPOMOFO },
+ { 0x3131,    94, G_UNICODE_SCRIPT_HANGUL },
+ { 0x3190,    16, G_UNICODE_SCRIPT_COMMON },
+ { 0x31a0,    24, G_UNICODE_SCRIPT_BOPOMOFO },
+ { 0x31c0,    36, G_UNICODE_SCRIPT_COMMON },
+ { 0x31f0,    16, G_UNICODE_SCRIPT_KATAKANA },
+ { 0x3200,    31, G_UNICODE_SCRIPT_HANGUL },
+ { 0x3220,    36, G_UNICODE_SCRIPT_COMMON },
+ { 0x3250,    16, G_UNICODE_SCRIPT_COMMON },
+ { 0x3260,    31, G_UNICODE_SCRIPT_HANGUL },
+ { 0x327f,    81, G_UNICODE_SCRIPT_COMMON },
+ { 0x32d0,    47, G_UNICODE_SCRIPT_KATAKANA },
+ { 0x3300,    88, G_UNICODE_SCRIPT_KATAKANA },
+ { 0x3358,   168, G_UNICODE_SCRIPT_COMMON },
+ { 0x3400,  6582, G_UNICODE_SCRIPT_HAN },
+ { 0x4dc0,    64, G_UNICODE_SCRIPT_COMMON },
+ { 0x4e00, 20932, G_UNICODE_SCRIPT_HAN },
+ { 0xa000,  1165, G_UNICODE_SCRIPT_YI },
+ { 0xa490,    55, G_UNICODE_SCRIPT_YI },
+ { 0xa500,   300, G_UNICODE_SCRIPT_VAI },
+ { 0xa640,    32, G_UNICODE_SCRIPT_CYRILLIC },
+ { 0xa662,    18, G_UNICODE_SCRIPT_CYRILLIC },
+ { 0xa67c,    28, G_UNICODE_SCRIPT_CYRILLIC },
+ { 0xa700,    34, G_UNICODE_SCRIPT_COMMON },
+ { 0xa722,   102, G_UNICODE_SCRIPT_LATIN },
+ { 0xa788,     3, G_UNICODE_SCRIPT_COMMON },
+ { 0xa78b,     2, G_UNICODE_SCRIPT_LATIN },
+ { 0xa7fb,     5, G_UNICODE_SCRIPT_LATIN },
+ { 0xa800,    44, G_UNICODE_SCRIPT_SYLOTI_NAGRI },
+ { 0xa840,    56, G_UNICODE_SCRIPT_PHAGS_PA },
+ { 0xa880,    69, G_UNICODE_SCRIPT_SAURASHTRA },
+ { 0xa8ce,    12, G_UNICODE_SCRIPT_SAURASHTRA },
+ { 0xa900,    48, G_UNICODE_SCRIPT_KAYAH_LI },
+ { 0xa930,    36, G_UNICODE_SCRIPT_REJANG },
+ { 0xa95f,     1, G_UNICODE_SCRIPT_REJANG },
+ { 0xaa00,    55, G_UNICODE_SCRIPT_CHAM },
+ { 0xaa40,    14, G_UNICODE_SCRIPT_CHAM },
+ { 0xaa50,    10, G_UNICODE_SCRIPT_CHAM },
+ { 0xaa5c,     4, G_UNICODE_SCRIPT_CHAM },
+ { 0xac00, 11172, G_UNICODE_SCRIPT_HANGUL },
+ { 0xf900,   302, G_UNICODE_SCRIPT_HAN },
+ { 0xfa30,    59, G_UNICODE_SCRIPT_HAN },
+ { 0xfa70,   106, G_UNICODE_SCRIPT_HAN },
+ { 0xfb00,     7, G_UNICODE_SCRIPT_LATIN },
+ { 0xfb13,     5, G_UNICODE_SCRIPT_ARMENIAN },
+ { 0xfb1d,    26, G_UNICODE_SCRIPT_HEBREW },
+ { 0xfb38,     5, G_UNICODE_SCRIPT_HEBREW },
+ { 0xfb3e,     1, G_UNICODE_SCRIPT_HEBREW },
+ { 0xfb40,     2, G_UNICODE_SCRIPT_HEBREW },
+ { 0xfb43,     2, G_UNICODE_SCRIPT_HEBREW },
+ { 0xfb46,    10, G_UNICODE_SCRIPT_HEBREW },
+ { 0xfb50,    98, G_UNICODE_SCRIPT_ARABIC },
+ { 0xfbd3,   363, G_UNICODE_SCRIPT_ARABIC },
+ { 0xfd3e,     2, G_UNICODE_SCRIPT_COMMON },
+ { 0xfd50,    64, G_UNICODE_SCRIPT_ARABIC },
+ { 0xfd92,    54, G_UNICODE_SCRIPT_ARABIC },
+ { 0xfdf0,    13, G_UNICODE_SCRIPT_ARABIC },
+ { 0xfdfd,     1, G_UNICODE_SCRIPT_COMMON },
+ { 0xfe00,    16, G_UNICODE_SCRIPT_INHERITED },
+ { 0xfe10,    10, G_UNICODE_SCRIPT_COMMON },
+ { 0xfe20,     7, G_UNICODE_SCRIPT_INHERITED },
+ { 0xfe30,    35, G_UNICODE_SCRIPT_COMMON },
+ { 0xfe54,    19, G_UNICODE_SCRIPT_COMMON },
+ { 0xfe68,     4, G_UNICODE_SCRIPT_COMMON },
+ { 0xfe70,     5, G_UNICODE_SCRIPT_ARABIC },
+ { 0xfe76,   135, G_UNICODE_SCRIPT_ARABIC },
+ { 0xfeff,     1, G_UNICODE_SCRIPT_COMMON },
+ { 0xff01,    32, G_UNICODE_SCRIPT_COMMON },
+ { 0xff21,    26, G_UNICODE_SCRIPT_LATIN },
+ { 0xff3b,     6, G_UNICODE_SCRIPT_COMMON },
+ { 0xff41,    26, G_UNICODE_SCRIPT_LATIN },
+ { 0xff5b,    11, G_UNICODE_SCRIPT_COMMON },
+ { 0xff66,    10, G_UNICODE_SCRIPT_KATAKANA },
+ { 0xff70,     1, G_UNICODE_SCRIPT_COMMON },
+ { 0xff71,    45, G_UNICODE_SCRIPT_KATAKANA },
+ { 0xff9e,     2, G_UNICODE_SCRIPT_COMMON },
+ { 0xffa0,    31, G_UNICODE_SCRIPT_HANGUL },
+ { 0xffc2,     6, G_UNICODE_SCRIPT_HANGUL },
+ { 0xffca,     6, G_UNICODE_SCRIPT_HANGUL },
+ { 0xffd2,     6, G_UNICODE_SCRIPT_HANGUL },
+ { 0xffda,     3, G_UNICODE_SCRIPT_HANGUL },
+ { 0xffe0,     7, G_UNICODE_SCRIPT_COMMON },
+ { 0xffe8,     7, G_UNICODE_SCRIPT_COMMON },
+ { 0xfff9,     5, G_UNICODE_SCRIPT_COMMON },
+ { 0x10000,    12, G_UNICODE_SCRIPT_LINEAR_B },
+ { 0x1000d,    26, G_UNICODE_SCRIPT_LINEAR_B },
+ { 0x10028,    19, G_UNICODE_SCRIPT_LINEAR_B },
+ { 0x1003c,     2, G_UNICODE_SCRIPT_LINEAR_B },
+ { 0x1003f,    15, G_UNICODE_SCRIPT_LINEAR_B },
+ { 0x10050,    14, G_UNICODE_SCRIPT_LINEAR_B },
+ { 0x10080,   123, G_UNICODE_SCRIPT_LINEAR_B },
+ { 0x10100,     3, G_UNICODE_SCRIPT_COMMON },
+ { 0x10107,    45, G_UNICODE_SCRIPT_COMMON },
+ { 0x10137,     9, G_UNICODE_SCRIPT_COMMON },
+ { 0x10140,    75, G_UNICODE_SCRIPT_GREEK },
+ { 0x10190,    12, G_UNICODE_SCRIPT_COMMON },
+ { 0x101d0,    45, G_UNICODE_SCRIPT_COMMON },
+ { 0x101fd,     1, G_UNICODE_SCRIPT_INHERITED },
+ { 0x10280,    29, G_UNICODE_SCRIPT_LYCIAN },
+ { 0x102a0,    49, G_UNICODE_SCRIPT_CARIAN },
+ { 0x10300,    31, G_UNICODE_SCRIPT_OLD_ITALIC },
+ { 0x10320,     4, G_UNICODE_SCRIPT_OLD_ITALIC },
+ { 0x10330,    27, G_UNICODE_SCRIPT_GOTHIC },
+ { 0x10380,    30, G_UNICODE_SCRIPT_UGARITIC },
+ { 0x1039f,     1, G_UNICODE_SCRIPT_UGARITIC },
+ { 0x103a0,    36, G_UNICODE_SCRIPT_OLD_PERSIAN },
+ { 0x103c8,    14, G_UNICODE_SCRIPT_OLD_PERSIAN },
+ { 0x10400,    80, G_UNICODE_SCRIPT_DESERET },
+ { 0x10450,    48, G_UNICODE_SCRIPT_SHAVIAN },
+ { 0x10480,    30, G_UNICODE_SCRIPT_OSMANYA },
+ { 0x104a0,    10, G_UNICODE_SCRIPT_OSMANYA },
+ { 0x10800,     6, G_UNICODE_SCRIPT_CYPRIOT },
+ { 0x10808,     1, G_UNICODE_SCRIPT_CYPRIOT },
+ { 0x1080a,    44, G_UNICODE_SCRIPT_CYPRIOT },
+ { 0x10837,     2, G_UNICODE_SCRIPT_CYPRIOT },
+ { 0x1083c,     1, G_UNICODE_SCRIPT_CYPRIOT },
+ { 0x1083f,     1, G_UNICODE_SCRIPT_CYPRIOT },
+ { 0x10900,    26, G_UNICODE_SCRIPT_PHOENICIAN },
+ { 0x1091f,     1, G_UNICODE_SCRIPT_PHOENICIAN },
+ { 0x10920,    26, G_UNICODE_SCRIPT_LYDIAN },
+ { 0x1093f,     1, G_UNICODE_SCRIPT_LYDIAN },
+ { 0x10a00,     4, G_UNICODE_SCRIPT_KHAROSHTHI },
+ { 0x10a05,     2, G_UNICODE_SCRIPT_KHAROSHTHI },
+ { 0x10a0c,     8, G_UNICODE_SCRIPT_KHAROSHTHI },
+ { 0x10a15,     3, G_UNICODE_SCRIPT_KHAROSHTHI },
+ { 0x10a19,    27, G_UNICODE_SCRIPT_KHAROSHTHI },
+ { 0x10a38,     3, G_UNICODE_SCRIPT_KHAROSHTHI },
+ { 0x10a3f,     9, G_UNICODE_SCRIPT_KHAROSHTHI },
+ { 0x10a50,     9, G_UNICODE_SCRIPT_KHAROSHTHI },
+ { 0x12000,   879, G_UNICODE_SCRIPT_CUNEIFORM },
+ { 0x12400,    99, G_UNICODE_SCRIPT_CUNEIFORM },
+ { 0x12470,     4, G_UNICODE_SCRIPT_CUNEIFORM },
+ { 0x1d000,   246, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d100,    39, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d129,    62, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d167,     3, G_UNICODE_SCRIPT_INHERITED },
+ { 0x1d16a,    17, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d17b,     8, G_UNICODE_SCRIPT_INHERITED },
+ { 0x1d183,     2, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d185,     7, G_UNICODE_SCRIPT_INHERITED },
+ { 0x1d18c,    30, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d1aa,     4, G_UNICODE_SCRIPT_INHERITED },
+ { 0x1d1ae,    48, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d200,    70, G_UNICODE_SCRIPT_GREEK },
+ { 0x1d300,    87, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d360,    18, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d400,    85, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d456,    71, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d49e,     2, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d4a2,     1, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d4a5,     2, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d4a9,     4, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d4ae,    12, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d4bb,     1, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d4bd,     7, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d4c5,    65, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d507,     4, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d50d,     8, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d516,     7, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d51e,    28, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d53b,     4, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d540,     5, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d546,     1, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d54a,     7, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d552,   340, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d6a8,   292, G_UNICODE_SCRIPT_COMMON },
+ { 0x1d7ce,    50, G_UNICODE_SCRIPT_COMMON },
+ { 0x1f000,    44, G_UNICODE_SCRIPT_COMMON },
+ { 0x1f030,   100, G_UNICODE_SCRIPT_COMMON },
+ { 0x20000, 42711, G_UNICODE_SCRIPT_HAN },
+ { 0x2f800,   542, G_UNICODE_SCRIPT_HAN },
+ { 0xe0001,     1, G_UNICODE_SCRIPT_COMMON },
+ { 0xe0020,    96, G_UNICODE_SCRIPT_COMMON },
+ { 0xe0100,   240, G_UNICODE_SCRIPT_INHERITED },
+};
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gsequence.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gsequence.c
new file mode 100644 (file)
index 0000000..8b28ce7
--- /dev/null
@@ -0,0 +1,1816 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+ * Soeren Sandmann (sandmann@daimi.au.dk)
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gsequence.h"
+
+#include "gmem.h"
+#include "gtestutils.h"
+/**
+ * SECTION: sequence
+ * @title: Sequences
+ * @short_description: scalable lists
+ *
+ * The #GSequence data structure has the API of a list, but is
+ * implemented internally with a balanced binary tree. This means that
+ * it is possible to maintain a sorted list of n elements in time O(n
+ * log n). The data contained in each element can be either integer
+ * values, by using of the <link
+ * linkend="glib-Type-Conversion-Macros">Type Conversion Macros</link>,
+ * or simply pointers to any type of data.
+ *
+ * A #GSequence is accessed through <firstterm>iterators</firstterm>,
+ * represented by a #GSequenceIter. An iterator represents a position
+ * between two elements of the sequence. For example, the
+ * <firstterm>begin</firstterm> iterator represents the gap immediately
+ * before the first element of the sequence, and the
+ * <firstterm>end</firstterm> iterator represents the gap immediately
+ * after the last element. In an empty sequence, the begin and end
+ * iterators are the same.
+ *
+ * Some methods on #GSequence operate on ranges of items. For example
+ * g_sequence_foreach_range() will call a user-specified function on
+ * each element with the given range. The range is delimited by the
+ * gaps represented by the passed-in iterators, so if you pass in the
+ * begin and end iterators, the range in question is the entire
+ * sequence.
+ *
+ * The function g_sequence_get() is used with an iterator to access the
+ * element immediately following the gap that the iterator represents.
+ * The iterator is said to <firstterm>point</firstterm> to that element.
+ *
+ * Iterators are stable across most operations on a #GSequence. For
+ * example an iterator pointing to some element of a sequence will
+ * continue to point to that element even after the sequence is sorted.
+ * Even moving an element to another sequence using for example
+ * g_sequence_move_range() will not invalidate the iterators pointing
+ * to it. The only operation that will invalidate an iterator is when
+ * the element it points to is removed from any sequence.
+ **/
+
+/**
+ * GSequenceIter:
+ *
+ * The #GSequenceIter struct is an opaque data type representing an
+ * iterator pointing into a #GSequence.
+ **/
+
+/**
+ * GSequenceIterCompareFunc:
+ * @a: a #GSequenceIter
+ * @b: a #GSequenceIter
+ * @data: user data
+ * @Returns: zero if the iterators are equal, a negative value if @a
+ *           comes before @b, and a positive value if @b comes before
+ *           @a.
+ *
+ * A #GSequenceIterCompareFunc is a function used to compare iterators.
+ * It must return zero if the iterators compare equal, a negative value
+ * if @a comes before @b, and a positive value if @b comes before @a.
+ **/
+
+typedef struct _GSequenceNode GSequenceNode;
+
+/**
+ * GSequence:
+ *
+ * The #GSequence struct is an opaque data type representing a
+ * <link linkend="glib-Sequences">Sequence</link> data type.
+ **/
+struct _GSequence
+{
+  GSequenceNode *       end_node;
+  GDestroyNotify        data_destroy_notify;
+  gboolean              access_prohibited;
+
+  /* The 'real_sequence' is used when temporary sequences are created
+   * to hold nodes that are being rearranged. The 'real_sequence' of such
+   * a temporary sequence points to the sequence that is actually being
+   * manipulated. The only reason we need this is so that when the
+   * sort/sort_changed/search_iter() functions call out to the application
+   * g_sequence_iter_get_sequence() will return the correct sequence.
+   */
+  GSequence *           real_sequence;
+};
+
+struct _GSequenceNode
+{
+  gint                  n_nodes;
+  GSequenceNode *       parent;
+  GSequenceNode *       left;
+  GSequenceNode *       right;
+  gpointer              data;   /* For the end node, this field points
+                                 * to the sequence
+                                 */
+};
+
+/*
+ * Declaration of GSequenceNode methods
+ */
+static GSequenceNode *node_new           (gpointer                  data);
+static GSequenceNode *node_get_first     (GSequenceNode            *node);
+static GSequenceNode *node_get_last      (GSequenceNode            *node);
+static GSequenceNode *node_get_prev      (GSequenceNode            *node);
+static GSequenceNode *node_get_next      (GSequenceNode            *node);
+static gint           node_get_pos       (GSequenceNode            *node);
+static GSequenceNode *node_get_by_pos    (GSequenceNode            *node,
+                                          gint                      pos);
+static GSequenceNode *node_find_closest  (GSequenceNode            *haystack,
+                                          GSequenceNode            *needle,
+                                          GSequenceNode            *end,
+                                          GSequenceIterCompareFunc  cmp,
+                                          gpointer                  user_data);
+static gint           node_get_length    (GSequenceNode            *node);
+static void           node_free          (GSequenceNode            *node,
+                                          GSequence                *seq);
+static void           node_cut           (GSequenceNode            *split);
+static void           node_insert_before (GSequenceNode            *node,
+                                          GSequenceNode            *new);
+static void           node_unlink        (GSequenceNode            *node);
+static void           node_join          (GSequenceNode            *left,
+                                          GSequenceNode            *right);
+static void           node_insert_sorted (GSequenceNode            *node,
+                                          GSequenceNode            *new,
+                                          GSequenceNode            *end,
+                                          GSequenceIterCompareFunc  cmp_func,
+                                          gpointer                  cmp_data);
+
+
+/*
+ * Various helper functions
+ */
+static void
+check_seq_access (GSequence *seq)
+{
+  if (G_UNLIKELY (seq->access_prohibited))
+    {
+      g_warning ("Accessing a sequence while it is "
+                 "being sorted or searched is not allowed");
+    }
+}
+
+static GSequence *
+get_sequence (GSequenceNode *node)
+{
+  return (GSequence *)node_get_last (node)->data;
+}
+
+static void
+check_iter_access (GSequenceIter *iter)
+{
+  check_seq_access (get_sequence (iter));
+}
+
+static gboolean
+is_end (GSequenceIter *iter)
+{
+  GSequence *seq;
+
+  if (iter->right)
+    return FALSE;
+
+  if (!iter->parent)
+    return TRUE;
+
+  if (iter->parent->right != iter)
+    return FALSE;
+
+  seq = get_sequence (iter);
+
+  return seq->end_node == iter;
+}
+
+typedef struct
+{
+  GCompareDataFunc  cmp_func;
+  gpointer          cmp_data;
+  GSequenceNode    *end_node;
+} SortInfo;
+
+/* This function compares two iters using a normal compare
+ * function and user_data passed in in a SortInfo struct
+ */
+static gint
+iter_compare (GSequenceIter *node1,
+              GSequenceIter *node2,
+              gpointer       data)
+{
+  const SortInfo *info = data;
+  gint retval;
+
+  if (node1 == info->end_node)
+    return 1;
+
+  if (node2 == info->end_node)
+    return -1;
+
+  retval = info->cmp_func (node1->data, node2->data, info->cmp_data);
+
+  return retval;
+}
+
+/*
+ * Public API
+ */
+
+/**
+ * g_sequence_new:
+ * @data_destroy: a #GDestroyNotify function, or %NULL
+ *
+ * Creates a new GSequence. The @data_destroy function, if non-%NULL will
+ * be called on all items when the sequence is destroyed and on items that
+ * are removed from the sequence.
+ *
+ * Return value: a new #GSequence
+ *
+ * Since: 2.14
+ **/
+GSequence *
+g_sequence_new (GDestroyNotify data_destroy)
+{
+  GSequence *seq = g_new (GSequence, 1);
+  seq->data_destroy_notify = data_destroy;
+
+  seq->end_node = node_new (seq);
+
+  seq->access_prohibited = FALSE;
+
+  seq->real_sequence = seq;
+
+  return seq;
+}
+
+/**
+ * g_sequence_free:
+ * @seq: a #GSequence
+ *
+ * Frees the memory allocated for @seq. If @seq has a data destroy
+ * function associated with it, that function is called on all items in
+ * @seq.
+ *
+ * Since: 2.14
+ **/
+void
+g_sequence_free (GSequence *seq)
+{
+  g_return_if_fail (seq != NULL);
+
+  check_seq_access (seq);
+
+  node_free (seq->end_node, seq);
+
+  g_free (seq);
+}
+
+/**
+ * g_sequence_foreach_range:
+ * @begin: a #GSequenceIter
+ * @end: a #GSequenceIter
+ * @func: a #GFunc
+ * @user_data: user data passed to @func
+ *
+ * Calls @func for each item in the range (@begin, @end) passing
+ * @user_data to the function.
+ *
+ * Since: 2.14
+ **/
+void
+g_sequence_foreach_range (GSequenceIter *begin,
+                          GSequenceIter *end,
+                          GFunc          func,
+                          gpointer       user_data)
+{
+  GSequence *seq;
+  GSequenceIter *iter;
+
+  g_return_if_fail (func != NULL);
+  g_return_if_fail (begin != NULL);
+  g_return_if_fail (end != NULL);
+
+  seq = get_sequence (begin);
+
+  seq->access_prohibited = TRUE;
+
+  iter = begin;
+  while (iter != end)
+    {
+      GSequenceIter *next = node_get_next (iter);
+
+      func (iter->data, user_data);
+
+      iter = next;
+    }
+
+  seq->access_prohibited = FALSE;
+}
+
+/**
+ * g_sequence_foreach:
+ * @seq: a #GSequence
+ * @func: the function to call for each item in @seq
+ * @user_data: user data passed to @func
+ *
+ * Calls @func for each item in the sequence passing @user_data
+ * to the function.
+ *
+ * Since: 2.14
+ **/
+void
+g_sequence_foreach (GSequence *seq,
+                    GFunc      func,
+                    gpointer   user_data)
+{
+  GSequenceIter *begin, *end;
+
+  check_seq_access (seq);
+
+  begin = g_sequence_get_begin_iter (seq);
+  end   = g_sequence_get_end_iter (seq);
+
+  g_sequence_foreach_range (begin, end, func, user_data);
+}
+
+/**
+ * g_sequence_range_get_midpoint:
+ * @begin: a #GSequenceIter
+ * @end: a #GSequenceIter
+ *
+ * Finds an iterator somewhere in the range (@begin, @end). This
+ * iterator will be close to the middle of the range, but is not
+ * guaranteed to be <emphasis>exactly</emphasis> in the middle.
+ *
+ * The @begin and @end iterators must both point to the same sequence and
+ * @begin must come before or be equal to @end in the sequence.
+ *
+ * Return value: A #GSequenceIter pointing somewhere in the
+ * (@begin, @end) range.
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_range_get_midpoint (GSequenceIter *begin,
+                               GSequenceIter *end)
+{
+  int begin_pos, end_pos, mid_pos;
+
+  g_return_val_if_fail (begin != NULL, NULL);
+  g_return_val_if_fail (end != NULL, NULL);
+  g_return_val_if_fail (get_sequence (begin) == get_sequence (end), NULL);
+
+  begin_pos = node_get_pos (begin);
+  end_pos = node_get_pos (end);
+
+  g_return_val_if_fail (end_pos >= begin_pos, NULL);
+
+  mid_pos = begin_pos + (end_pos - begin_pos) / 2;
+
+  return node_get_by_pos (begin, mid_pos);
+}
+
+/**
+ * g_sequence_iter_compare:
+ * @a: a #GSequenceIter
+ * @b: a #GSequenceIter
+ *
+ * Returns a negative number if @a comes before @b, 0 if they are equal,
+ * and a positive number if @a comes after @b.
+ *
+ * The @a and @b iterators must point into the same sequence.
+ *
+ * Return value: A negative number if @a comes before @b, 0 if they are
+ * equal, and a positive number if @a comes after @b.
+ *
+ * Since: 2.14
+ **/
+gint
+g_sequence_iter_compare (GSequenceIter *a,
+                         GSequenceIter *b)
+{
+  gint a_pos, b_pos;
+
+  g_return_val_if_fail (a != NULL, 0);
+  g_return_val_if_fail (b != NULL, 0);
+  g_return_val_if_fail (get_sequence (a) == get_sequence (b), 0);
+
+  check_iter_access (a);
+  check_iter_access (b);
+
+  a_pos = node_get_pos (a);
+  b_pos = node_get_pos (b);
+
+  if (a_pos == b_pos)
+    return 0;
+  else if (a_pos > b_pos)
+    return 1;
+  else
+    return -1;
+}
+
+/**
+ * g_sequence_append:
+ * @seq: a #GSequencePointer
+ * @data: the data for the new item
+ *
+ * Adds a new item to the end of @seq.
+ *
+ * Return value: an iterator pointing to the new item
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_append (GSequence *seq,
+                   gpointer   data)
+{
+  GSequenceNode *node;
+
+  g_return_val_if_fail (seq != NULL, NULL);
+
+  check_seq_access (seq);
+
+  node = node_new (data);
+  node_insert_before (seq->end_node, node);
+
+  return node;
+}
+
+/**
+ * g_sequence_prepend:
+ * @seq: a #GSequence
+ * @data: the data for the new item
+ *
+ * Adds a new item to the front of @seq
+ *
+ * Return value: an iterator pointing to the new item
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_prepend (GSequence *seq,
+                    gpointer   data)
+{
+  GSequenceNode *node, *first;
+
+  g_return_val_if_fail (seq != NULL, NULL);
+
+  check_seq_access (seq);
+
+  node = node_new (data);
+  first = node_get_first (seq->end_node);
+
+  node_insert_before (first, node);
+
+  return node;
+}
+
+/**
+ * g_sequence_insert_before:
+ * @iter: a #GSequenceIter
+ * @data: the data for the new item
+ *
+ * Inserts a new item just before the item pointed to by @iter.
+ *
+ * Return value: an iterator pointing to the new item
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_insert_before (GSequenceIter *iter,
+                          gpointer       data)
+{
+  GSequenceNode *node;
+
+  g_return_val_if_fail (iter != NULL, NULL);
+
+  check_iter_access (iter);
+
+  node = node_new (data);
+
+  node_insert_before (iter, node);
+
+  return node;
+}
+
+/**
+ * g_sequence_remove:
+ * @iter: a #GSequenceIter
+ *
+ * Removes the item pointed to by @iter. It is an error to pass the
+ * end iterator to this function.
+ *
+ * If the sequnce has a data destroy function associated with it, this
+ * function is called on the data for the removed item.
+ *
+ * Since: 2.14
+ **/
+void
+g_sequence_remove (GSequenceIter *iter)
+{
+  GSequence *seq;
+
+  g_return_if_fail (iter != NULL);
+  g_return_if_fail (!is_end (iter));
+
+  check_iter_access (iter);
+
+  seq = get_sequence (iter);
+
+  node_unlink (iter);
+  node_free (iter, seq);
+}
+
+/**
+ * g_sequence_remove_range:
+ * @begin: a #GSequenceIter
+ * @end: a #GSequenceIter
+ *
+ * Removes all items in the (@begin, @end) range.
+ *
+ * If the sequence has a data destroy function associated with it, this
+ * function is called on the data for the removed items.
+ *
+ * Since: 2.14
+ **/
+void
+g_sequence_remove_range (GSequenceIter *begin,
+                         GSequenceIter *end)
+{
+  g_return_if_fail (get_sequence (begin) == get_sequence (end));
+
+  check_iter_access (begin);
+  check_iter_access (end);
+
+  g_sequence_move_range (NULL, begin, end);
+}
+
+/**
+ * g_sequence_move_range:
+ * @dest: a #GSequenceIter
+ * @begin: a #GSequenceIter
+ * @end: a #GSequenceIter
+ *
+ * Inserts the (@begin, @end) range at the destination pointed to by ptr.
+ * The @begin and @end iters must point into the same sequence. It is
+ * allowed for @dest to point to a different sequence than the one pointed
+ * into by @begin and @end.
+ *
+ * If @dest is NULL, the range indicated by @begin and @end is
+ * removed from the sequence. If @dest iter points to a place within
+ * the (@begin, @end) range, the range does not move.
+ *
+ * Since: 2.14
+ **/
+void
+g_sequence_move_range (GSequenceIter *dest,
+                       GSequenceIter *begin,
+                       GSequenceIter *end)
+{
+  GSequence *src_seq;
+  GSequenceNode *first;
+
+  g_return_if_fail (begin != NULL);
+  g_return_if_fail (end != NULL);
+
+  check_iter_access (begin);
+  check_iter_access (end);
+  if (dest)
+    check_iter_access (dest);
+
+  src_seq = get_sequence (begin);
+
+  g_return_if_fail (src_seq == get_sequence (end));
+
+  /* Dest points to begin or end? */
+  if (dest == begin || dest == end)
+    return;
+
+  /* begin comes after end? */
+  if (g_sequence_iter_compare (begin, end) >= 0)
+    return;
+
+  /* dest points somewhere in the (begin, end) range? */
+  if (dest && get_sequence (dest) == src_seq &&
+      g_sequence_iter_compare (dest, begin) > 0 &&
+      g_sequence_iter_compare (dest, end) < 0)
+    {
+      return;
+    }
+
+  src_seq = get_sequence (begin);
+
+  first = node_get_first (begin);
+
+  node_cut (begin);
+
+  node_cut (end);
+
+  if (first != begin)
+    node_join (first, end);
+
+  if (dest)
+    {
+      first = node_get_first (dest);
+
+      node_cut (dest);
+
+      node_join (begin, dest);
+
+      if (dest != first)
+        node_join (first, begin);
+    }
+  else
+    {
+      node_free (begin, src_seq);
+    }
+}
+
+/**
+ * g_sequence_sort:
+ * @seq: a #GSequence
+ * @cmp_func: the #GCompareDataFunc used to sort @seq. This function is
+ *       passed two items of @seq and should return 0 if they are equal,
+ *       a negative value if the first comes before the second, and a
+ *       positive value if the second comes before the first.
+ * @cmp_data: user data passed to @cmp_func
+ *
+ * Sorts @seq using @cmp_func.
+ *
+ * Since: 2.14
+ **/
+void
+g_sequence_sort (GSequence        *seq,
+                 GCompareDataFunc  cmp_func,
+                 gpointer          cmp_data)
+{
+  SortInfo info;
+
+  info.cmp_func = cmp_func;
+  info.cmp_data = cmp_data;
+  info.end_node = seq->end_node;
+
+  check_seq_access (seq);
+
+  g_sequence_sort_iter (seq, iter_compare, &info);
+}
+
+/**
+ * g_sequence_insert_sorted:
+ * @seq: a #GSequence
+ * @data: the data to insert
+ * @cmp_func: the #GCompareDataFunc used to compare items in the sequence. It
+ *     is called with two items of the @seq and @user_data. It should
+ *     return 0 if the items are equal, a negative value if the first
+ *     item comes before the second, and a positive value if the second
+ *     item comes before the first.
+ * @cmp_data: user data passed to @cmp_func.
+ *
+ * Inserts @data into @sequence using @func to determine the new position.
+ * The sequence must already be sorted according to @cmp_func; otherwise the
+ * new position of @data is undefined.
+ *
+ * Return value: a #GSequenceIter pointing to the new item.
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_insert_sorted (GSequence        *seq,
+                          gpointer          data,
+                          GCompareDataFunc  cmp_func,
+                          gpointer          cmp_data)
+{
+  SortInfo info;
+
+  g_return_val_if_fail (seq != NULL, NULL);
+  g_return_val_if_fail (cmp_func != NULL, NULL);
+
+  info.cmp_func = cmp_func;
+  info.cmp_data = cmp_data;
+  info.end_node = seq->end_node;
+  check_seq_access (seq);
+
+  return g_sequence_insert_sorted_iter (seq, data, iter_compare, &info);
+}
+
+/**
+ * g_sequence_sort_changed:
+ * @iter: A #GSequenceIter
+ * @cmp_func: the #GCompareDataFunc used to compare items in the sequence. It
+ *     is called with two items of the @seq and @user_data. It should
+ *     return 0 if the items are equal, a negative value if the first
+ *     item comes before the second, and a positive value if the second
+ *     item comes before the first.
+ * @cmp_data: user data passed to @cmp_func.
+ *
+ * Moves the data pointed to a new position as indicated by @cmp_func. This
+ * function should be called for items in a sequence already sorted according
+ * to @cmp_func whenever some aspect of an item changes so that @cmp_func
+ * may return different values for that item.
+ *
+ * Since: 2.14
+ **/
+void
+g_sequence_sort_changed (GSequenceIter    *iter,
+                         GCompareDataFunc  cmp_func,
+                         gpointer          cmp_data)
+{
+  SortInfo info;
+
+  g_return_if_fail (!is_end (iter));
+
+  info.cmp_func = cmp_func;
+  info.cmp_data = cmp_data;
+  info.end_node = get_sequence (iter)->end_node;
+  check_iter_access (iter);
+
+  g_sequence_sort_changed_iter (iter, iter_compare, &info);
+}
+
+/**
+ * g_sequence_search:
+ * @seq: a #GSequence
+ * @data: data for the new item
+ * @cmp_func: the #GCompareDataFunc used to compare items in the sequence. It
+ *     is called with two items of the @seq and @user_data. It should
+ *     return 0 if the items are equal, a negative value if the first
+ *     item comes before the second, and a positive value if the second
+ *     item comes before the first.
+ * @cmp_data: user data passed to @cmp_func.
+ *
+ * Returns an iterator pointing to the position where @data would
+ * be inserted according to @cmp_func and @cmp_data.
+ *
+ * Return value: an #GSequenceIter pointing to the position where @data
+ * would have been inserted according to @cmp_func and @cmp_data.
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_search (GSequence        *seq,
+                   gpointer          data,
+                   GCompareDataFunc  cmp_func,
+                   gpointer          cmp_data)
+{
+  SortInfo info;
+
+  g_return_val_if_fail (seq != NULL, NULL);
+
+  info.cmp_func = cmp_func;
+  info.cmp_data = cmp_data;
+  info.end_node = seq->end_node;
+  check_seq_access (seq);
+
+  return g_sequence_search_iter (seq, data, iter_compare, &info);
+}
+
+/**
+ * g_sequence_sort_iter:
+ * @seq: a #GSequence
+ * @cmp_func: the #GSequenceItercompare used to compare iterators in the
+ *     sequence. It is called with two iterators pointing into @seq. It should
+ *     return 0 if the iterators are equal, a negative value if the first
+ *     iterator comes before the second, and a positive value if the second
+ *     iterator comes before the first.
+ * @cmp_data: user data passed to @cmp_func
+ *
+ * Like g_sequence_sort(), but uses a #GSequenceIterCompareFunc instead
+ * of a GCompareDataFunc as the compare function
+ *
+ * Since: 2.14
+ **/
+void
+g_sequence_sort_iter (GSequence                *seq,
+                      GSequenceIterCompareFunc  cmp_func,
+                      gpointer                  cmp_data)
+{
+  GSequence *tmp;
+  GSequenceNode *begin, *end;
+
+  g_return_if_fail (seq != NULL);
+  g_return_if_fail (cmp_func != NULL);
+
+  check_seq_access (seq);
+
+  begin = g_sequence_get_begin_iter (seq);
+  end   = g_sequence_get_end_iter (seq);
+
+  tmp = g_sequence_new (NULL);
+  tmp->real_sequence = seq;
+
+  g_sequence_move_range (g_sequence_get_begin_iter (tmp), begin, end);
+
+  seq->access_prohibited = TRUE;
+  tmp->access_prohibited = TRUE;
+
+  while (g_sequence_get_length (tmp) > 0)
+    {
+      GSequenceNode *node = g_sequence_get_begin_iter (tmp);
+
+      node_insert_sorted (seq->end_node, node, seq->end_node,
+                          cmp_func, cmp_data);
+    }
+
+  tmp->access_prohibited = FALSE;
+  seq->access_prohibited = FALSE;
+
+  g_sequence_free (tmp);
+}
+
+/**
+ * g_sequence_sort_changed_iter:
+ * @iter: a #GSequenceIter
+ * @iter_cmp: the #GSequenceItercompare used to compare iterators in the
+ *     sequence. It is called with two iterators pointing into @seq. It should
+ *     return 0 if the iterators are equal, a negative value if the first
+ *     iterator comes before the second, and a positive value if the second
+ *     iterator comes before the first.
+ * @cmp_data: user data passed to @cmp_func
+ *
+ * Like g_sequence_sort_changed(), but uses
+ * a #GSequenceIterCompareFunc instead of a #GCompareDataFunc as
+ * the compare function.
+ *
+ * Since: 2.14
+ **/
+void
+g_sequence_sort_changed_iter (GSequenceIter            *iter,
+                              GSequenceIterCompareFunc  iter_cmp,
+                              gpointer                  cmp_data)
+{
+  GSequence *seq, *tmp_seq;
+  GSequenceIter *next, *prev;
+
+  g_return_if_fail (iter != NULL);
+  g_return_if_fail (!is_end (iter));
+  g_return_if_fail (iter_cmp != NULL);
+  check_iter_access (iter);
+
+  /* If one of the neighbours is equal to iter, then
+   * don't move it. This ensures that sort_changed() is
+   * a stable operation.
+   */
+
+  next = node_get_next (iter);
+  prev = node_get_prev (iter);
+
+  if (prev != iter && iter_cmp (prev, iter, cmp_data) == 0)
+    return;
+
+  if (!is_end (next) && iter_cmp (next, iter, cmp_data) == 0)
+    return;
+
+  seq = get_sequence (iter);
+
+  seq->access_prohibited = TRUE;
+
+  tmp_seq = g_sequence_new (NULL);
+  tmp_seq->real_sequence = seq;
+
+  node_unlink (iter);
+  node_insert_before (tmp_seq->end_node, iter);
+
+  node_insert_sorted (seq->end_node, iter, seq->end_node,
+                      iter_cmp, cmp_data);
+
+  g_sequence_free (tmp_seq);
+
+  seq->access_prohibited = FALSE;
+}
+
+/**
+ * g_sequence_insert_sorted_iter:
+ * @seq: a #GSequence
+ * @data: data for the new item
+ * @iter_cmp: the #GSequenceItercompare used to compare iterators in the
+ *     sequence. It is called with two iterators pointing into @seq. It should
+ *     return 0 if the iterators are equal, a negative value if the first
+ *     iterator comes before the second, and a positive value if the second
+ *     iterator comes before the first.
+ * @cmp_data: user data passed to @cmp_func
+ *
+ * Like g_sequence_insert_sorted(), but uses
+ * a #GSequenceIterCompareFunc instead of a #GCompareDataFunc as
+ * the compare function.
+ *
+ * Return value: a #GSequenceIter pointing to the new item
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_insert_sorted_iter (GSequence                *seq,
+                               gpointer                  data,
+                               GSequenceIterCompareFunc  iter_cmp,
+                               gpointer                  cmp_data)
+{
+  GSequenceNode *new_node;
+  GSequence *tmp_seq;
+
+  g_return_val_if_fail (seq != NULL, NULL);
+  g_return_val_if_fail (iter_cmp != NULL, NULL);
+
+  check_seq_access (seq);
+
+  seq->access_prohibited = TRUE;
+
+  /* Create a new temporary sequence and put the new node into
+   * that. The reason for this is that the user compare function
+   * will be called with the new node, and if it dereferences,
+   * "is_end" will be called on it. But that will crash if the
+   * node is not actually in a sequence.
+   *
+   * node_insert_sorted() makes sure the node is unlinked before
+   * it is inserted.
+   *
+   * The reason we need the "iter" versions at all is that that
+   * is the only kind of compare functions GtkTreeView can use.
+   */
+  tmp_seq = g_sequence_new (NULL);
+  tmp_seq->real_sequence = seq;
+
+  new_node = g_sequence_append (tmp_seq, data);
+
+  node_insert_sorted (seq->end_node, new_node,
+                      seq->end_node, iter_cmp, cmp_data);
+
+  g_sequence_free (tmp_seq);
+
+  seq->access_prohibited = FALSE;
+
+  return new_node;
+}
+
+/**
+ * g_sequence_search_iter:
+ * @seq: a #GSequence
+ * @data: data for the new item
+ * @iter_cmp: the #GSequenceIterCompare function used to compare iterators
+ *     in the sequence. It is called with two iterators pointing into @seq.
+ *     It should return 0 if the iterators are equal, a negative value if the
+ *     first iterator comes before the second, and a positive value if the
+ *     second iterator comes before the first.
+ * @cmp_data: user data passed to @iter_cmp
+ *
+ * Like g_sequence_search(), but uses
+ * a #GSequenceIterCompareFunc instead of a #GCompareDataFunc as
+ * the compare function.
+ *
+ * Return value: a #GSequenceIter pointing to the position in @seq
+ * where @data would have been inserted according to @iter_cmp and @cmp_data.
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_search_iter (GSequence                *seq,
+                        gpointer                  data,
+                        GSequenceIterCompareFunc  iter_cmp,
+                        gpointer                  cmp_data)
+{
+  GSequenceNode *node;
+  GSequenceNode *dummy;
+  GSequence *tmp_seq;
+
+  g_return_val_if_fail (seq != NULL, NULL);
+
+  check_seq_access (seq);
+
+  seq->access_prohibited = TRUE;
+
+  tmp_seq = g_sequence_new (NULL);
+  tmp_seq->real_sequence = seq;
+
+  dummy = g_sequence_append (tmp_seq, data);
+
+  node = node_find_closest (seq->end_node, dummy,
+                            seq->end_node, iter_cmp, cmp_data);
+
+  g_sequence_free (tmp_seq);
+
+  seq->access_prohibited = FALSE;
+
+  return node;
+}
+
+/**
+ * g_sequence_iter_get_sequence:
+ * @iter: a #GSequenceIter
+ *
+ * Returns the #GSequence that @iter points into.
+ *
+ * Return value: the #GSequence that @iter points into.
+ *
+ * Since: 2.14
+ **/
+GSequence *
+g_sequence_iter_get_sequence (GSequenceIter *iter)
+{
+  GSequence *seq;
+
+  g_return_val_if_fail (iter != NULL, NULL);
+
+  seq = get_sequence (iter);
+
+  /* For temporary sequences, this points to the sequence that
+   * is actually being manipulated
+   */
+  return seq->real_sequence;
+}
+
+/**
+ * g_sequence_get:
+ * @iter: a #GSequenceIter
+ *
+ * Returns the data that @iter points to.
+ *
+ * Return value: the data that @iter points to
+ *
+ * Since: 2.14
+ **/
+gpointer
+g_sequence_get (GSequenceIter *iter)
+{
+  g_return_val_if_fail (iter != NULL, NULL);
+  g_return_val_if_fail (!is_end (iter), NULL);
+
+  return iter->data;
+}
+
+/**
+ * g_sequence_set:
+ * @iter: a #GSequenceIter
+ * @data: new data for the item
+ *
+ * Changes the data for the item pointed to by @iter to be @data. If
+ * the sequence has a data destroy function associated with it, that
+ * function is called on the existing data that @iter pointed to.
+ *
+ * Since: 2.14
+ **/
+void
+g_sequence_set (GSequenceIter *iter,
+                gpointer       data)
+{
+  GSequence *seq;
+
+  g_return_if_fail (iter != NULL);
+  g_return_if_fail (!is_end (iter));
+
+  seq = get_sequence (iter);
+
+  /* If @data is identical to iter->data, it is destroyed
+   * here. This will work right in case of ref-counted objects. Also
+   * it is similar to what ghashtables do.
+   *
+   * For non-refcounted data it's a little less convenient, but
+   * code relying on self-setting not destroying would be
+   * pretty dubious anyway ...
+   */
+
+  if (seq->data_destroy_notify)
+    seq->data_destroy_notify (iter->data);
+
+  iter->data = data;
+}
+
+/**
+ * g_sequence_get_length:
+ * @seq: a #GSequence
+ *
+ * Returns the length of @seq
+ *
+ * Return value: the length of @seq
+ *
+ * Since: 2.14
+ **/
+gint
+g_sequence_get_length (GSequence *seq)
+{
+  return node_get_length (seq->end_node) - 1;
+}
+
+/**
+ * g_sequence_get_end_iter:
+ * @seq: a #GSequence
+ *
+ * Returns the end iterator for @seg
+ *
+ * Return value: the end iterator for @seq
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_get_end_iter (GSequence *seq)
+{
+  g_return_val_if_fail (seq != NULL, NULL);
+
+  return seq->end_node;
+}
+
+/**
+ * g_sequence_get_begin_iter:
+ * @seq: a #GSequence
+ *
+ * Returns the begin iterator for @seq.
+ *
+ * Return value: the begin iterator for @seq.
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_get_begin_iter (GSequence *seq)
+{
+  g_return_val_if_fail (seq != NULL, NULL);
+
+  return node_get_first (seq->end_node);
+}
+
+static int
+clamp_position (GSequence *seq,
+                int        pos)
+{
+  gint len = g_sequence_get_length (seq);
+
+  if (pos > len || pos < 0)
+    pos = len;
+
+  return pos;
+}
+
+/*
+ * if pos > number of items or -1, will return end pointer
+ */
+/**
+ * g_sequence_get_iter_at_pos:
+ * @seq: a #GSequence
+ * @pos: a position in @seq, or -1 for the end.
+ *
+ * Returns the iterator at position @pos. If @pos is negative or larger
+ * than the number of items in @seq, the end iterator is returned.
+ *
+ * Return value: The #GSequenceIter at position @pos
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_get_iter_at_pos (GSequence *seq,
+                            gint       pos)
+{
+  g_return_val_if_fail (seq != NULL, NULL);
+
+  pos = clamp_position (seq, pos);
+
+  return node_get_by_pos (seq->end_node, pos);
+}
+
+/**
+ * g_sequence_move:
+ * @src: a #GSequenceIter pointing to the item to move
+ * @dest: a #GSequenceIter pointing to the position to which
+ *        the item is moved.
+ *
+ * Moves the item pointed to by @src to the position indicated by @dest.
+ * After calling this function @dest will point to the position immediately
+ * after @src. It is allowed for @src and @dest to point into different
+ * sequences.
+ *
+ * Since: 2.14
+ **/
+void
+g_sequence_move (GSequenceIter *src,
+                 GSequenceIter *dest)
+{
+  g_return_if_fail (src != NULL);
+  g_return_if_fail (dest != NULL);
+  g_return_if_fail (!is_end (src));
+
+  if (src == dest)
+    return;
+
+  node_unlink (src);
+  node_insert_before (dest, src);
+}
+
+/* GSequenceIter */
+
+/**
+ * g_sequence_iter_is_end:
+ * @iter: a #GSequenceIter
+ *
+ * Returns whether @iter is the end iterator
+ *
+ * Return value: Whether @iter is the end iterator.
+ *
+ * Since: 2.14
+ **/
+gboolean
+g_sequence_iter_is_end (GSequenceIter *iter)
+{
+  g_return_val_if_fail (iter != NULL, FALSE);
+
+  return is_end (iter);
+}
+
+/**
+ * g_sequence_iter_is_begin:
+ * @iter: a #GSequenceIter
+ *
+ * Returns whether @iter is the begin iterator
+ *
+ * Return value: whether @iter is the begin iterator
+ *
+ * Since: 2.14
+ **/
+gboolean
+g_sequence_iter_is_begin (GSequenceIter *iter)
+{
+  g_return_val_if_fail (iter != NULL, FALSE);
+
+  return (node_get_prev (iter) == iter);
+}
+
+/**
+ * g_sequence_iter_get_position:
+ * @iter: a #GSequenceIter
+ *
+ * Returns the position of @iter
+ *
+ * Return value: the position of @iter
+ *
+ * Since: 2.14
+ **/
+gint
+g_sequence_iter_get_position (GSequenceIter *iter)
+{
+  g_return_val_if_fail (iter != NULL, -1);
+
+  return node_get_pos (iter);
+}
+
+/**
+ * g_sequence_iter_next:
+ * @iter: a #GSequenceIter
+ *
+ * Returns an iterator pointing to the next position after @iter. If
+ * @iter is the end iterator, the end iterator is returned.
+ *
+ * Return value: a #GSequenceIter pointing to the next position after @iter.
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_iter_next (GSequenceIter *iter)
+{
+  g_return_val_if_fail (iter != NULL, NULL);
+
+  return node_get_next (iter);
+}
+
+/**
+ * g_sequence_iter_prev:
+ * @iter: a #GSequenceIter
+ *
+ * Returns an iterator pointing to the previous position before @iter. If
+ * @iter is the begin iterator, the begin iterator is returned.
+ *
+ * Return value: a #GSequenceIter pointing to the previous position before
+ * @iter.
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_iter_prev (GSequenceIter *iter)
+{
+  g_return_val_if_fail (iter != NULL, NULL);
+
+  return node_get_prev (iter);
+}
+
+/**
+ * g_sequence_iter_move:
+ * @iter: a #GSequenceIter
+ * @delta: A positive or negative number indicating how many positions away
+ *    from @iter the returned #GSequenceIter will be.
+ *
+ * Returns the #GSequenceIter which is @delta positions away from @iter.
+ * If @iter is closer than -@delta positions to the beginning of the sequence,
+ * the begin iterator is returned. If @iter is closer than @delta positions
+ * to the end of the sequence, the end iterator is returned.
+ *
+ * Return value: a #GSequenceIter which is @delta positions away from @iter.
+ *
+ * Since: 2.14
+ **/
+GSequenceIter *
+g_sequence_iter_move (GSequenceIter *iter,
+                      gint           delta)
+{
+  gint new_pos;
+
+  g_return_val_if_fail (iter != NULL, NULL);
+
+  new_pos = node_get_pos (iter) + delta;
+
+  new_pos = clamp_position (get_sequence (iter), new_pos);
+
+  return node_get_by_pos (iter, new_pos);
+}
+
+/**
+ * g_sequence_swap:
+ * @a: a #GSequenceIter
+ * @b: a #GSequenceIter
+ *
+ * Swaps the items pointed to by @a and @b. It is allowed for @a and @b
+ * to point into difference sequences.
+ *
+ * Since: 2.14
+ **/
+void
+g_sequence_swap (GSequenceIter *a,
+                 GSequenceIter *b)
+{
+  GSequenceNode *leftmost, *rightmost, *rightmost_next;
+  int a_pos, b_pos;
+
+  g_return_if_fail (!g_sequence_iter_is_end (a));
+  g_return_if_fail (!g_sequence_iter_is_end (b));
+
+  if (a == b)
+    return;
+
+  a_pos = g_sequence_iter_get_position (a);
+  b_pos = g_sequence_iter_get_position (b);
+
+  if (a_pos > b_pos)
+    {
+      leftmost = b;
+      rightmost = a;
+    }
+  else
+    {
+      leftmost = a;
+      rightmost = b;
+    }
+
+  rightmost_next = node_get_next (rightmost);
+
+  /* The situation is now like this:
+   *
+   *     ..., leftmost, ......., rightmost, rightmost_next, ...
+   *
+   */
+  g_sequence_move (rightmost, leftmost);
+  g_sequence_move (leftmost, rightmost_next);
+}
+
+/*
+ * Implementation of a treap
+ *
+ *
+ */
+static guint
+get_priority (GSequenceNode *node)
+{
+  guint key = GPOINTER_TO_UINT (node);
+
+  /* This hash function is based on one found on Thomas Wang's
+   * web page at
+   *
+   *    http://www.concentric.net/~Ttwang/tech/inthash.htm
+   *
+   */
+  key = (key << 15) - key - 1;
+  key = key ^ (key >> 12);
+  key = key + (key << 2);
+  key = key ^ (key >> 4);
+  key = key + (key << 3) + (key << 11);
+  key = key ^ (key >> 16);
+
+  /* We rely on 0 being less than all other priorities */
+  return key? key : 1;
+}
+
+static GSequenceNode *
+find_root (GSequenceNode *node)
+{
+  while (node->parent)
+    node = node->parent;
+
+  return node;
+}
+
+static GSequenceNode *
+node_new (gpointer data)
+{
+  GSequenceNode *node = g_slice_new0 (GSequenceNode);
+
+  node->n_nodes = 1;
+  node->data = data;
+  node->left = NULL;
+  node->right = NULL;
+  node->parent = NULL;
+
+  return node;
+}
+
+static GSequenceNode *
+node_get_first (GSequenceNode *node)
+{
+  node = find_root (node);
+
+  while (node->left)
+    node = node->left;
+
+  return node;
+}
+
+static GSequenceNode *
+node_get_last (GSequenceNode *node)
+{
+  node = find_root (node);
+
+  while (node->right)
+    node = node->right;
+
+  return node;
+}
+
+#define NODE_LEFT_CHILD(n)  (((n)->parent) && ((n)->parent->left) == (n))
+#define NODE_RIGHT_CHILD(n) (((n)->parent) && ((n)->parent->right) == (n))
+
+static GSequenceNode *
+node_get_next (GSequenceNode *node)
+{
+  GSequenceNode *n = node;
+
+  if (n->right)
+    {
+      n = n->right;
+      while (n->left)
+        n = n->left;
+    }
+  else
+    {
+      while (NODE_RIGHT_CHILD (n))
+        n = n->parent;
+
+      if (n->parent)
+        n = n->parent;
+      else
+        n = node;
+    }
+
+  return n;
+}
+
+static GSequenceNode *
+node_get_prev (GSequenceNode *node)
+{
+  GSequenceNode *n = node;
+
+  if (n->left)
+    {
+      n = n->left;
+      while (n->right)
+        n = n->right;
+    }
+  else
+    {
+      while (NODE_LEFT_CHILD (n))
+        n = n->parent;
+
+      if (n->parent)
+        n = n->parent;
+      else
+        n = node;
+    }
+
+  return n;
+}
+
+#define N_NODES(n) ((n)? (n)->n_nodes : 0)
+
+static gint
+node_get_pos (GSequenceNode *node)
+{
+  int n_smaller = 0;
+
+  if (node->left)
+    n_smaller = node->left->n_nodes;
+
+  while (node)
+    {
+      if (NODE_RIGHT_CHILD (node))
+        n_smaller += N_NODES (node->parent->left) + 1;
+
+      node = node->parent;
+    }
+
+  return n_smaller;
+}
+
+static GSequenceNode *
+node_get_by_pos (GSequenceNode *node,
+                 gint           pos)
+{
+  int i;
+
+  node = find_root (node);
+
+  while ((i = N_NODES (node->left)) != pos)
+    {
+      if (i < pos)
+        {
+          node = node->right;
+          pos -= (i + 1);
+        }
+      else
+        {
+          node = node->left;
+        }
+    }
+
+  return node;
+}
+
+static GSequenceNode *
+node_find_closest (GSequenceNode            *haystack,
+                   GSequenceNode            *needle,
+                   GSequenceNode            *end,
+                   GSequenceIterCompareFunc  iter_cmp,
+                   gpointer                  cmp_data)
+{
+  GSequenceNode *best;
+  gint c;
+
+  haystack = find_root (haystack);
+
+  do
+    {
+      best = haystack;
+
+      /* iter_cmp can't be passed the end node, since the function may
+       * be user-supplied
+       */
+      if (haystack == end)
+        c = 1;
+      else
+        c = iter_cmp (haystack, needle, cmp_data);
+
+      /* In the following we don't break even if c == 0. Instaed we go on
+       * searching along the 'bigger' nodes, so that we find the last one
+       * that is equal to the needle.
+       */
+      if (c > 0)
+        haystack = haystack->left;
+      else
+        haystack = haystack->right;
+    }
+  while (haystack != NULL);
+
+  /* If the best node is smaller or equal to the data, then move one step
+   * to the right to make sure the best one is strictly bigger than the data
+   */
+  if (best != end && c <= 0)
+    best = node_get_next (best);
+
+  return best;
+}
+
+static gint
+node_get_length    (GSequenceNode            *node)
+{
+  node = find_root (node);
+
+  return node->n_nodes;
+}
+
+static void
+real_node_free (GSequenceNode *node,
+                GSequence     *seq)
+{
+  if (node)
+    {
+      real_node_free (node->left, seq);
+      real_node_free (node->right, seq);
+
+      if (seq && seq->data_destroy_notify && node != seq->end_node)
+        seq->data_destroy_notify (node->data);
+
+      g_slice_free (GSequenceNode, node);
+    }
+}
+
+static void
+node_free (GSequenceNode *node,
+           GSequence *seq)
+{
+  node = find_root (node);
+
+  real_node_free (node, seq);
+}
+
+static void
+node_update_fields (GSequenceNode *node)
+{
+  int n_nodes = 1;
+
+  n_nodes += N_NODES (node->left);
+  n_nodes += N_NODES (node->right);
+
+  node->n_nodes = n_nodes;
+}
+
+static void
+node_rotate (GSequenceNode *node)
+{
+  GSequenceNode *tmp, *old;
+
+  g_assert (node->parent);
+  g_assert (node->parent != node);
+
+  if (NODE_LEFT_CHILD (node))
+    {
+      /* rotate right */
+      tmp = node->right;
+
+      node->right = node->parent;
+      node->parent = node->parent->parent;
+      if (node->parent)
+        {
+          if (node->parent->left == node->right)
+            node->parent->left = node;
+          else
+            node->parent->right = node;
+        }
+
+      g_assert (node->right);
+
+      node->right->parent = node;
+      node->right->left = tmp;
+
+      if (node->right->left)
+        node->right->left->parent = node->right;
+
+      old = node->right;
+    }
+  else
+    {
+      /* rotate left */
+      tmp = node->left;
+
+      node->left = node->parent;
+      node->parent = node->parent->parent;
+      if (node->parent)
+        {
+          if (node->parent->right == node->left)
+            node->parent->right = node;
+          else
+            node->parent->left = node;
+        }
+
+      g_assert (node->left);
+
+      node->left->parent = node;
+      node->left->right = tmp;
+
+      if (node->left->right)
+        node->left->right->parent = node->left;
+
+      old = node->left;
+    }
+
+  node_update_fields (old);
+  node_update_fields (node);
+}
+
+static void
+node_update_fields_deep (GSequenceNode *node)
+{
+  if (node)
+    {
+      node_update_fields (node);
+
+      node_update_fields_deep (node->parent);
+    }
+}
+
+static void
+rotate_down (GSequenceNode *node,
+             guint          priority)
+{
+  guint left, right;
+
+  left = node->left ? get_priority (node->left)  : 0;
+  right = node->right ? get_priority (node->right) : 0;
+
+  while (priority < left || priority < right)
+    {
+      if (left > right)
+        node_rotate (node->left);
+      else
+        node_rotate (node->right);
+
+      left = node->left ? get_priority (node->left)  : 0;
+      right = node->right ? get_priority (node->right) : 0;
+    }
+}
+
+static void
+node_cut (GSequenceNode *node)
+{
+  while (node->parent)
+    node_rotate (node);
+
+  if (node->left)
+    node->left->parent = NULL;
+
+  node->left = NULL;
+  node_update_fields (node);
+
+  rotate_down (node, get_priority (node));
+}
+
+static void
+node_join (GSequenceNode *left,
+           GSequenceNode *right)
+{
+  GSequenceNode *fake = node_new (NULL);
+
+  fake->left = find_root (left);
+  fake->right = find_root (right);
+  fake->left->parent = fake;
+  fake->right->parent = fake;
+
+  node_update_fields (fake);
+
+  node_unlink (fake);
+
+  node_free (fake, NULL);
+}
+
+static void
+node_insert_before (GSequenceNode *node,
+                    GSequenceNode *new)
+{
+  new->left = node->left;
+  if (new->left)
+    new->left->parent = new;
+
+  new->parent = node;
+  node->left = new;
+
+  node_update_fields_deep (new);
+
+  while (new->parent && get_priority (new) > get_priority (new->parent))
+    node_rotate (new);
+
+  rotate_down (new, get_priority (new));
+}
+
+static void
+node_unlink (GSequenceNode *node)
+{
+  rotate_down (node, 0);
+
+  if (NODE_RIGHT_CHILD (node))
+    node->parent->right = NULL;
+  else if (NODE_LEFT_CHILD (node))
+    node->parent->left = NULL;
+
+  if (node->parent)
+    node_update_fields_deep (node->parent);
+
+  node->parent = NULL;
+}
+
+static void
+node_insert_sorted (GSequenceNode            *node,
+                    GSequenceNode            *new,
+                    GSequenceNode            *end,
+                    GSequenceIterCompareFunc  iter_cmp,
+                    gpointer                  cmp_data)
+{
+  GSequenceNode *closest;
+
+  closest = node_find_closest (node, new, end, iter_cmp, cmp_data);
+
+  node_unlink (new);
+
+  node_insert_before (closest, new);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gsequence.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gsequence.h
new file mode 100644 (file)
index 0000000..fa79066
--- /dev/null
@@ -0,0 +1,128 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 2002, 2003, 2004, 2005, 2006, 2007
+ * Soeren Sandmann (sandmann@daimi.au.dk)
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_SEQUENCE_H__
+#define __G_SEQUENCE_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GSequence      GSequence;
+typedef struct _GSequenceNode  GSequenceIter;
+
+typedef gint (* GSequenceIterCompareFunc) (GSequenceIter *a,
+                                           GSequenceIter *b,
+                                           gpointer       data);
+
+
+/* GSequence */
+GSequence *    g_sequence_new                (GDestroyNotify            data_destroy);
+void           g_sequence_free               (GSequence                *seq);
+gint           g_sequence_get_length         (GSequence                *seq);
+void           g_sequence_foreach            (GSequence                *seq,
+                                              GFunc                     func,
+                                              gpointer                  user_data);
+void           g_sequence_foreach_range      (GSequenceIter            *begin,
+                                              GSequenceIter            *end,
+                                              GFunc                     func,
+                                              gpointer                  user_data);
+void           g_sequence_sort               (GSequence                *seq,
+                                              GCompareDataFunc          cmp_func,
+                                              gpointer                  cmp_data);
+void           g_sequence_sort_iter          (GSequence                *seq,
+                                              GSequenceIterCompareFunc  cmp_func,
+                                              gpointer                  cmp_data);
+
+
+/* Getting iters */
+GSequenceIter *g_sequence_get_begin_iter     (GSequence                *seq);
+GSequenceIter *g_sequence_get_end_iter       (GSequence                *seq);
+GSequenceIter *g_sequence_get_iter_at_pos    (GSequence                *seq,
+                                              gint                      pos);
+GSequenceIter *g_sequence_append             (GSequence                *seq,
+                                              gpointer                  data);
+GSequenceIter *g_sequence_prepend            (GSequence                *seq,
+                                              gpointer                  data);
+GSequenceIter *g_sequence_insert_before      (GSequenceIter            *iter,
+                                              gpointer                  data);
+void           g_sequence_move               (GSequenceIter            *src,
+                                              GSequenceIter            *dest);
+void           g_sequence_swap               (GSequenceIter            *a,
+                                              GSequenceIter            *b);
+GSequenceIter *g_sequence_insert_sorted      (GSequence                *seq,
+                                              gpointer                  data,
+                                              GCompareDataFunc          cmp_func,
+                                              gpointer                  cmp_data);
+GSequenceIter *g_sequence_insert_sorted_iter (GSequence                *seq,
+                                              gpointer                  data,
+                                              GSequenceIterCompareFunc  iter_cmp,
+                                              gpointer                  cmp_data);
+void           g_sequence_sort_changed       (GSequenceIter            *iter,
+                                              GCompareDataFunc          cmp_func,
+                                              gpointer                  cmp_data);
+void           g_sequence_sort_changed_iter  (GSequenceIter            *iter,
+                                              GSequenceIterCompareFunc  iter_cmp,
+                                              gpointer                  cmp_data);
+void           g_sequence_remove             (GSequenceIter            *iter);
+void           g_sequence_remove_range       (GSequenceIter            *begin,
+                                              GSequenceIter            *end);
+void           g_sequence_move_range         (GSequenceIter            *dest,
+                                              GSequenceIter            *begin,
+                                              GSequenceIter            *end);
+GSequenceIter *g_sequence_search             (GSequence                *seq,
+                                              gpointer                  data,
+                                              GCompareDataFunc          cmp_func,
+                                              gpointer                  cmp_data);
+GSequenceIter *g_sequence_search_iter        (GSequence                *seq,
+                                              gpointer                  data,
+                                              GSequenceIterCompareFunc  iter_cmp,
+                                              gpointer                  cmp_data);
+
+
+/* Dereferencing */
+gpointer       g_sequence_get                (GSequenceIter            *iter);
+void           g_sequence_set                (GSequenceIter            *iter,
+                                              gpointer                  data);
+
+/* Operations on GSequenceIter * */
+gboolean       g_sequence_iter_is_begin      (GSequenceIter            *iter);
+gboolean       g_sequence_iter_is_end        (GSequenceIter            *iter);
+GSequenceIter *g_sequence_iter_next          (GSequenceIter            *iter);
+GSequenceIter *g_sequence_iter_prev          (GSequenceIter            *iter);
+gint           g_sequence_iter_get_position  (GSequenceIter            *iter);
+GSequenceIter *g_sequence_iter_move          (GSequenceIter            *iter,
+                                              gint                      delta);
+GSequence *    g_sequence_iter_get_sequence  (GSequenceIter            *iter);
+
+
+/* Search */
+gint           g_sequence_iter_compare       (GSequenceIter            *a,
+                                              GSequenceIter            *b);
+GSequenceIter *g_sequence_range_get_midpoint (GSequenceIter            *begin,
+                                              GSequenceIter            *end);
+
+G_END_DECLS
+
+#endif /* __G_SEQUENCE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gshell.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gshell.c
new file mode 100644 (file)
index 0000000..1461f29
--- /dev/null
@@ -0,0 +1,691 @@
+/* gshell.c - Shell-related utilities
+ *
+ *  Copyright 2000 Red Hat, Inc.
+ *  g_execvpe implementation based on GNU libc execvp:
+ *   Copyright 1991, 92, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not, write
+ * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <string.h>
+
+#include "gshell.h"
+
+#include "gslist.h"
+#include "gstrfuncs.h"
+#include "gstring.h"
+#include "gtestutils.h"
+#include "glibintl.h"
+
+/**
+ * SECTION: shell
+ * @title: Shell-related Utilities
+ * @short_description: shell-like commandline handling
+ **/
+
+/**
+ * G_SHELL_ERROR:
+ *
+ * Error domain for shell functions. Errors in this domain will be from
+ * the #GShellError enumeration. See #GError for information on error
+ * domains.
+ **/
+
+/**
+ * GShellError:
+ * @G_SHELL_ERROR_BAD_QUOTING: Mismatched or otherwise mangled quoting.
+ * @G_SHELL_ERROR_EMPTY_STRING: String to be parsed was empty.
+ * @G_SHELL_ERROR_FAILED: Some other error.
+ *
+ * Error codes returned by shell functions.
+ **/
+GQuark
+g_shell_error_quark (void)
+{
+  return g_quark_from_static_string ("g-shell-error-quark");
+}
+
+/* Single quotes preserve the literal string exactly. escape
+ * sequences are not allowed; not even \' - if you want a '
+ * in the quoted text, you have to do something like 'foo'\''bar'
+ *
+ * Double quotes allow $ ` " \ and newline to be escaped with backslash.
+ * Otherwise double quotes preserve things literally.
+ */
+
+static gboolean 
+unquote_string_inplace (gchar* str, gchar** end, GError** err)
+{
+  gchar* dest;
+  gchar* s;
+  gchar quote_char;
+  
+  g_return_val_if_fail(end != NULL, FALSE);
+  g_return_val_if_fail(err == NULL || *err == NULL, FALSE);
+  g_return_val_if_fail(str != NULL, FALSE);
+  
+  dest = s = str;
+
+  quote_char = *s;
+  
+  if (!(*s == '"' || *s == '\''))
+    {
+      g_set_error_literal (err,
+                           G_SHELL_ERROR,
+                           G_SHELL_ERROR_BAD_QUOTING,
+                           _("Quoted text doesn't begin with a quotation mark"));
+      *end = str;
+      return FALSE;
+    }
+
+  /* Skip the initial quote mark */
+  ++s;
+
+  if (quote_char == '"')
+    {
+      while (*s)
+        {
+          g_assert(s > dest); /* loop invariant */
+      
+          switch (*s)
+            {
+            case '"':
+              /* End of the string, return now */
+              *dest = '\0';
+              ++s;
+              *end = s;
+              return TRUE;
+              break;
+
+            case '\\':
+              /* Possible escaped quote or \ */
+              ++s;
+              switch (*s)
+                {
+                case '"':
+                case '\\':
+                case '`':
+                case '$':
+                case '\n':
+                  *dest = *s;
+                  ++s;
+                  ++dest;
+                  break;
+
+                default:
+                  /* not an escaped char */
+                  *dest = '\\';
+                  ++dest;
+                  /* ++s already done. */
+                  break;
+                }
+              break;
+
+            default:
+              *dest = *s;
+              ++dest;
+              ++s;
+              break;
+            }
+
+          g_assert(s > dest); /* loop invariant */
+        }
+    }
+  else
+    {
+      while (*s)
+        {
+          g_assert(s > dest); /* loop invariant */
+          
+          if (*s == '\'')
+            {
+              /* End of the string, return now */
+              *dest = '\0';
+              ++s;
+              *end = s;
+              return TRUE;
+            }
+          else
+            {
+              *dest = *s;
+              ++dest;
+              ++s;
+            }
+
+          g_assert(s > dest); /* loop invariant */
+        }
+    }
+  
+  /* If we reach here this means the close quote was never encountered */
+
+  *dest = '\0';
+  
+  g_set_error_literal (err,
+                       G_SHELL_ERROR,
+                       G_SHELL_ERROR_BAD_QUOTING,
+                       _("Unmatched quotation mark in command line or other shell-quoted text"));
+  *end = s;
+  return FALSE;
+}
+
+/**
+ * g_shell_quote:
+ * @unquoted_string: a literal string
+ * 
+ * Quotes a string so that the shell (/bin/sh) will interpret the
+ * quoted string to mean @unquoted_string. If you pass a filename to
+ * the shell, for example, you should first quote it with this
+ * function.  The return value must be freed with g_free(). The
+ * quoting style used is undefined (single or double quotes may be
+ * used).
+ * 
+ * Return value: quoted string
+ **/
+gchar*
+g_shell_quote (const gchar *unquoted_string)
+{
+  /* We always use single quotes, because the algorithm is cheesier.
+   * We could use double if we felt like it, that might be more
+   * human-readable.
+   */
+
+  const gchar *p;
+  GString *dest;
+
+  g_return_val_if_fail (unquoted_string != NULL, NULL);
+  
+  dest = g_string_new ("'");
+
+  p = unquoted_string;
+
+  /* could speed this up a lot by appending chunks of text at a
+   * time.
+   */
+  while (*p)
+    {
+      /* Replace literal ' with a close ', a \', and a open ' */
+      if (*p == '\'')
+        g_string_append (dest, "'\\''");
+      else
+        g_string_append_c (dest, *p);
+
+      ++p;
+    }
+
+  /* close the quote */
+  g_string_append_c (dest, '\'');
+  
+  return g_string_free (dest, FALSE);
+}
+
+/**
+ * g_shell_unquote:
+ * @quoted_string: shell-quoted string
+ * @error: error return location or NULL
+ * 
+ * Unquotes a string as the shell (/bin/sh) would. Only handles
+ * quotes; if a string contains file globs, arithmetic operators,
+ * variables, backticks, redirections, or other special-to-the-shell
+ * features, the result will be different from the result a real shell
+ * would produce (the variables, backticks, etc. will be passed
+ * through literally instead of being expanded). This function is
+ * guaranteed to succeed if applied to the result of
+ * g_shell_quote(). If it fails, it returns %NULL and sets the
+ * error. The @quoted_string need not actually contain quoted or
+ * escaped text; g_shell_unquote() simply goes through the string and
+ * unquotes/unescapes anything that the shell would. Both single and
+ * double quotes are handled, as are escapes including escaped
+ * newlines. The return value must be freed with g_free(). Possible
+ * errors are in the #G_SHELL_ERROR domain.
+ * 
+ * Shell quoting rules are a bit strange. Single quotes preserve the
+ * literal string exactly. escape sequences are not allowed; not even
+ * \' - if you want a ' in the quoted text, you have to do something
+ * like 'foo'\''bar'.  Double quotes allow $, `, ", \, and newline to
+ * be escaped with backslash. Otherwise double quotes preserve things
+ * literally.
+ *
+ * Return value: an unquoted string
+ **/
+gchar*
+g_shell_unquote (const gchar *quoted_string,
+                 GError     **error)
+{
+  gchar *unquoted;
+  gchar *end;
+  gchar *start;
+  GString *retval;
+  
+  g_return_val_if_fail (quoted_string != NULL, NULL);
+  
+  unquoted = g_strdup (quoted_string);
+
+  start = unquoted;
+  end = unquoted;
+  retval = g_string_new (NULL);
+
+  /* The loop allows cases such as
+   * "foo"blah blah'bar'woo foo"baz"la la la\'\''foo'
+   */
+  while (*start)
+    {
+      /* Append all non-quoted chars, honoring backslash escape
+       */
+      
+      while (*start && !(*start == '"' || *start == '\''))
+        {
+          if (*start == '\\')
+            {
+              /* all characters can get escaped by backslash,
+               * except newline, which is removed if it follows
+               * a backslash outside of quotes
+               */
+              
+              ++start;
+              if (*start)
+                {
+                  if (*start != '\n')
+                    g_string_append_c (retval, *start);
+                  ++start;
+                }
+            }
+          else
+            {
+              g_string_append_c (retval, *start);
+              ++start;
+            }
+        }
+
+      if (*start)
+        {
+          if (!unquote_string_inplace (start, &end, error))
+            {
+              goto error;
+            }
+          else
+            {
+              g_string_append (retval, start);
+              start = end;
+            }
+        }
+    }
+
+  g_free (unquoted);
+  return g_string_free (retval, FALSE);
+  
+ error:
+  g_assert (error == NULL || *error != NULL);
+  
+  g_free (unquoted);
+  g_string_free (retval, TRUE);
+  return NULL;
+}
+
+/* g_parse_argv() does a semi-arbitrary weird subset of the way
+ * the shell parses a command line. We don't do variable expansion,
+ * don't understand that operators are tokens, don't do tilde expansion,
+ * don't do command substitution, no arithmetic expansion, IFS gets ignored,
+ * don't do filename globs, don't remove redirection stuff, etc.
+ *
+ * READ THE UNIX98 SPEC on "Shell Command Language" before changing
+ * the behavior of this code.
+ *
+ * Steps to parsing the argv string:
+ *
+ *  - tokenize the string (but since we ignore operators,
+ *    our tokenization may diverge from what the shell would do)
+ *    note that tokenization ignores the internals of a quoted
+ *    word and it always splits on spaces, not on IFS even
+ *    if we used IFS. We also ignore "end of input indicator"
+ *    (I guess this is control-D?)
+ *
+ *    Tokenization steps, from UNIX98 with operator stuff removed,
+ *    are:
+ * 
+ *    1) "If the current character is backslash, single-quote or
+ *        double-quote (\, ' or ") and it is not quoted, it will affect
+ *        quoting for subsequent characters up to the end of the quoted
+ *        text. The rules for quoting are as described in Quoting
+ *        . During token recognition no substitutions will be actually
+ *        performed, and the result token will contain exactly the
+ *        characters that appear in the input (except for newline
+ *        character joining), unmodified, including any embedded or
+ *        enclosing quotes or substitution operators, between the quote
+ *        mark and the end of the quoted text. The token will not be
+ *        delimited by the end of the quoted field."
+ *
+ *    2) "If the current character is an unquoted newline character,
+ *        the current token will be delimited."
+ *
+ *    3) "If the current character is an unquoted blank character, any
+ *        token containing the previous character is delimited and the
+ *        current character will be discarded."
+ *
+ *    4) "If the previous character was part of a word, the current
+ *        character will be appended to that word."
+ *
+ *    5) "If the current character is a "#", it and all subsequent
+ *        characters up to, but excluding, the next newline character
+ *        will be discarded as a comment. The newline character that
+ *        ends the line is not considered part of the comment. The
+ *        "#" starts a comment only when it is at the beginning of a
+ *        token. Since the search for the end-of-comment does not
+ *        consider an escaped newline character specially, a comment
+ *        cannot be continued to the next line."
+ *
+ *    6) "The current character will be used as the start of a new word."
+ *
+ *
+ *  - for each token (word), perform portions of word expansion, namely
+ *    field splitting (using default whitespace IFS) and quote
+ *    removal.  Field splitting may increase the number of words.
+ *    Quote removal does not increase the number of words.
+ *
+ *   "If the complete expansion appropriate for a word results in an
+ *   empty field, that empty field will be deleted from the list of
+ *   fields that form the completely expanded command, unless the
+ *   original word contained single-quote or double-quote characters."
+ *    - UNIX98 spec
+ *
+ *
+ */
+
+static inline void
+ensure_token (GString **token)
+{
+  if (*token == NULL)
+    *token = g_string_new (NULL);
+}
+
+static void
+delimit_token (GString **token,
+               GSList **retval)
+{
+  if (*token == NULL)
+    return;
+
+  *retval = g_slist_prepend (*retval, g_string_free (*token, FALSE));
+
+  *token = NULL;
+}
+
+static GSList*
+tokenize_command_line (const gchar *command_line,
+                       GError **error)
+{
+  gchar current_quote;
+  const gchar *p;
+  GString *current_token = NULL;
+  GSList *retval = NULL;
+  gboolean quoted;
+
+  current_quote = '\0';
+  quoted = FALSE;
+  p = command_line;
+  while (*p)
+    {
+      if (current_quote == '\\')
+        {
+          if (*p == '\n')
+            {
+              /* we append nothing; backslash-newline become nothing */
+            }
+          else
+            {
+              /* we append the backslash and the current char,
+               * to be interpreted later after tokenization
+               */
+              ensure_token (&current_token);
+              g_string_append_c (current_token, '\\');
+              g_string_append_c (current_token, *p);
+            }
+
+          current_quote = '\0';
+        }
+      else if (current_quote == '#')
+        {
+          /* Discard up to and including next newline */
+          while (*p && *p != '\n')
+            ++p;
+
+          current_quote = '\0';
+          
+          if (*p == '\0')
+            break;
+        }
+      else if (current_quote)
+        {
+          if (*p == current_quote &&
+              /* check that it isn't an escaped double quote */
+              !(current_quote == '"' && quoted))
+            {
+              /* close the quote */
+              current_quote = '\0';
+            }
+
+          /* Everything inside quotes, and the close quote,
+           * gets appended literally.
+           */
+
+          ensure_token (&current_token);
+          g_string_append_c (current_token, *p);
+        }
+      else
+        {
+          switch (*p)
+            {
+            case '\n':
+              delimit_token (&current_token, &retval);
+              break;
+
+            case ' ':
+            case '\t':
+              /* If the current token contains the previous char, delimit
+               * the current token. A nonzero length
+               * token should always contain the previous char.
+               */
+              if (current_token &&
+                  current_token->len > 0)
+                {
+                  delimit_token (&current_token, &retval);
+                }
+              
+              /* discard all unquoted blanks (don't add them to a token) */
+              break;
+
+
+              /* single/double quotes are appended to the token,
+               * escapes are maybe appended next time through the loop,
+               * comment chars are never appended.
+               */
+              
+            case '\'':
+            case '"':
+              ensure_token (&current_token);
+              g_string_append_c (current_token, *p);
+
+              /* FALL THRU */
+              
+            case '#':
+            case '\\':
+              current_quote = *p;
+              break;
+
+            default:
+              /* Combines rules 4) and 6) - if we have a token, append to it,
+               * otherwise create a new token.
+               */
+              ensure_token (&current_token);
+              g_string_append_c (current_token, *p);
+              break;
+            }
+        }
+
+      /* We need to count consecutive backslashes mod 2, 
+       * to detect escaped doublequotes.
+       */
+      if (*p != '\\')
+       quoted = FALSE;
+      else
+       quoted = !quoted;
+
+      ++p;
+    }
+
+  delimit_token (&current_token, &retval);
+
+  if (current_quote)
+    {
+      if (current_quote == '\\')
+        g_set_error (error,
+                     G_SHELL_ERROR,
+                     G_SHELL_ERROR_BAD_QUOTING,
+                     _("Text ended just after a '\\' character."
+                       " (The text was '%s')"),
+                     command_line);
+      else
+        g_set_error (error,
+                     G_SHELL_ERROR,
+                     G_SHELL_ERROR_BAD_QUOTING,
+                     _("Text ended before matching quote was found for %c."
+                       " (The text was '%s')"),
+                     current_quote, command_line);
+      
+      goto error;
+    }
+
+  if (retval == NULL)
+    {
+      g_set_error_literal (error,
+                           G_SHELL_ERROR,
+                           G_SHELL_ERROR_EMPTY_STRING,
+                           _("Text was empty (or contained only whitespace)"));
+
+      goto error;
+    }
+  
+  /* we appended backward */
+  retval = g_slist_reverse (retval);
+
+  return retval;
+
+ error:
+  g_assert (error == NULL || *error != NULL);
+  
+  if (retval)
+    {
+      g_slist_foreach (retval, (GFunc)g_free, NULL);
+      g_slist_free (retval);
+    }
+
+  return NULL;
+}
+
+/**
+ * g_shell_parse_argv:
+ * @command_line: command line to parse
+ * @argcp: return location for number of args
+ * @argvp: return location for array of args
+ * @error: return location for error
+ * 
+ * Parses a command line into an argument vector, in much the same way
+ * the shell would, but without many of the expansions the shell would
+ * perform (variable expansion, globs, operators, filename expansion,
+ * etc. are not supported). The results are defined to be the same as
+ * those you would get from a UNIX98 /bin/sh, as long as the input
+ * contains none of the unsupported shell expansions. If the input
+ * does contain such expansions, they are passed through
+ * literally. Possible errors are those from the #G_SHELL_ERROR
+ * domain. Free the returned vector with g_strfreev().
+ * 
+ * Return value: %TRUE on success, %FALSE if error set
+ **/
+gboolean
+g_shell_parse_argv (const gchar *command_line,
+                    gint        *argcp,
+                    gchar     ***argvp,
+                    GError     **error)
+{
+  /* Code based on poptParseArgvString() from libpopt */
+  gint argc = 0;
+  gchar **argv = NULL;
+  GSList *tokens = NULL;
+  gint i;
+  GSList *tmp_list;
+  
+  g_return_val_if_fail (command_line != NULL, FALSE);
+
+  tokens = tokenize_command_line (command_line, error);
+  if (tokens == NULL)
+    return FALSE;
+
+  /* Because we can't have introduced any new blank space into the
+   * tokens (we didn't do any new expansions), we don't need to
+   * perform field splitting. If we were going to honor IFS or do any
+   * expansions, we would have to do field splitting on each word
+   * here. Also, if we were going to do any expansion we would need to
+   * remove any zero-length words that didn't contain quotes
+   * originally; but since there's no expansion we know all words have
+   * nonzero length, unless they contain quotes.
+   * 
+   * So, we simply remove quotes, and don't do any field splitting or
+   * empty word removal, since we know there was no way to introduce
+   * such things.
+   */
+
+  argc = g_slist_length (tokens);
+  argv = g_new0 (gchar*, argc + 1);
+  i = 0;
+  tmp_list = tokens;
+  while (tmp_list)
+    {
+      argv[i] = g_shell_unquote (tmp_list->data, error);
+
+      /* Since we already checked that quotes matched up in the
+       * tokenizer, this shouldn't be possible to reach I guess.
+       */
+      if (argv[i] == NULL)
+        goto failed;
+
+      tmp_list = g_slist_next (tmp_list);
+      ++i;
+    }
+  
+  g_slist_foreach (tokens, (GFunc)g_free, NULL);
+  g_slist_free (tokens);
+  
+  if (argcp)
+    *argcp = argc;
+
+  if (argvp)
+    *argvp = argv;
+  else
+    g_strfreev (argv);
+
+  return TRUE;
+
+ failed:
+
+  g_assert (error == NULL || *error != NULL);
+  g_strfreev (argv);
+  g_slist_foreach (tokens, (GFunc) g_free, NULL);
+  g_slist_free (tokens);
+  
+  return FALSE;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gshell.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gshell.h
new file mode 100644 (file)
index 0000000..130f100
--- /dev/null
@@ -0,0 +1,55 @@
+/* gshell.h - Shell-related utilities
+ *
+ *  Copyright 2000 Red Hat, Inc.
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not, write
+ * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_SHELL_H__
+#define __G_SHELL_H__
+
+#include <glib/gerror.h>
+
+G_BEGIN_DECLS
+
+#define G_SHELL_ERROR g_shell_error_quark ()
+
+typedef enum
+{
+  /* mismatched or otherwise mangled quoting */
+  G_SHELL_ERROR_BAD_QUOTING,
+  /* string to be parsed was empty */
+  G_SHELL_ERROR_EMPTY_STRING,
+  G_SHELL_ERROR_FAILED
+} GShellError;
+
+GQuark g_shell_error_quark (void);
+
+gchar*   g_shell_quote      (const gchar   *unquoted_string);
+gchar*   g_shell_unquote    (const gchar   *quoted_string,
+                             GError       **error);
+gboolean g_shell_parse_argv (const gchar   *command_line,
+                             gint          *argcp,
+                             gchar       ***argvp,
+                             GError       **error);
+
+G_END_DECLS
+
+#endif /* __G_SHELL_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gslice.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gslice.c
new file mode 100644 (file)
index 0000000..05de6b3
--- /dev/null
@@ -0,0 +1,1495 @@
+/* GLIB sliced memory - fast concurrent memory chunk allocator
+ * Copyright (C) 2005 Tim Janik
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+/* MT safe */
+
+#include "config.h"
+#include "glibconfig.h"
+
+#if     defined HAVE_POSIX_MEMALIGN && defined POSIX_MEMALIGN_WITH_COMPLIANT_ALLOCS
+#  define HAVE_COMPLIANT_POSIX_MEMALIGN 1
+#endif
+
+#ifdef HAVE_COMPLIANT_POSIX_MEMALIGN
+#define _XOPEN_SOURCE 600       /* posix_memalign() */
+#endif
+#include <stdlib.h>             /* posix_memalign() */
+#include <string.h>
+#include <errno.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>             /* sysconf() */
+#endif
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include <process.h>
+#endif
+
+#include <stdio.h>              /* fputs/fprintf */
+
+#include "gslice.h"
+
+#include "gmain.h"
+#include "gmem.h"               /* gslice.h */
+#include "gstrfuncs.h"
+#include "gutils.h"
+#include "gtestutils.h"
+#include "gthread.h"
+#include "gthreadprivate.h"
+#include "glib_trace.h"
+
+/* the GSlice allocator is split up into 4 layers, roughly modelled after the slab
+ * allocator and magazine extensions as outlined in:
+ * + [Bonwick94] Jeff Bonwick, The slab allocator: An object-caching kernel
+ *   memory allocator. USENIX 1994, http://citeseer.ist.psu.edu/bonwick94slab.html
+ * + [Bonwick01] Bonwick and Jonathan Adams, Magazines and vmem: Extending the
+ *   slab allocator to many cpu's and arbitrary resources.
+ *   USENIX 2001, http://citeseer.ist.psu.edu/bonwick01magazines.html
+ * the layers are:
+ * - the thread magazines. for each (aligned) chunk size, a magazine (a list)
+ *   of recently freed and soon to be allocated chunks is maintained per thread.
+ *   this way, most alloc/free requests can be quickly satisfied from per-thread
+ *   free lists which only require one g_private_get() call to retrive the
+ *   thread handle.
+ * - the magazine cache. allocating and freeing chunks to/from threads only
+ *   occours at magazine sizes from a global depot of magazines. the depot
+ *   maintaines a 15 second working set of allocated magazines, so full
+ *   magazines are not allocated and released too often.
+ *   the chunk size dependent magazine sizes automatically adapt (within limits,
+ *   see [3]) to lock contention to properly scale performance across a variety
+ *   of SMP systems.
+ * - the slab allocator. this allocator allocates slabs (blocks of memory) close
+ *   to the system page size or multiples thereof which have to be page aligned.
+ *   the blocks are divided into smaller chunks which are used to satisfy
+ *   allocations from the upper layers. the space provided by the reminder of
+ *   the chunk size division is used for cache colorization (random distribution
+ *   of chunk addresses) to improve processor cache utilization. multiple slabs
+ *   with the same chunk size are kept in a partially sorted ring to allow O(1)
+ *   freeing and allocation of chunks (as long as the allocation of an entirely
+ *   new slab can be avoided).
+ * - the page allocator. on most modern systems, posix_memalign(3) or
+ *   memalign(3) should be available, so this is used to allocate blocks with
+ *   system page size based alignments and sizes or multiples thereof.
+ *   if no memalign variant is provided, valloc() is used instead and
+ *   block sizes are limited to the system page size (no multiples thereof).
+ *   as a fallback, on system without even valloc(), a malloc(3)-based page
+ *   allocator with alloc-only behaviour is used.
+ *
+ * NOTES:
+ * [1] some systems memalign(3) implementations may rely on boundary tagging for
+ *     the handed out memory chunks. to avoid excessive page-wise fragmentation,
+ *     we reserve 2 * sizeof (void*) per block size for the systems memalign(3),
+ *     specified in NATIVE_MALLOC_PADDING.
+ * [2] using the slab allocator alone already provides for a fast and efficient
+ *     allocator, it doesn't properly scale beyond single-threaded uses though.
+ *     also, the slab allocator implements eager free(3)-ing, i.e. does not
+ *     provide any form of caching or working set maintenance. so if used alone,
+ *     it's vulnerable to trashing for sequences of balanced (alloc, free) pairs
+ *     at certain thresholds.
+ * [3] magazine sizes are bound by an implementation specific minimum size and
+ *     a chunk size specific maximum to limit magazine storage sizes to roughly
+ *     16KB.
+ * [4] allocating ca. 8 chunks per block/page keeps a good balance between
+ *     external and internal fragmentation (<= 12.5%). [Bonwick94]
+ */
+
+/* --- macros and constants --- */
+#define LARGEALIGNMENT          (256)
+#define P2ALIGNMENT             (2 * sizeof (gsize))                            /* fits 2 pointers (assumed to be 2 * GLIB_SIZEOF_SIZE_T below) */
+#define ALIGN(size, base)       ((base) * (gsize) (((size) + (base) - 1) / (base)))
+#define NATIVE_MALLOC_PADDING   P2ALIGNMENT                                     /* per-page padding left for native malloc(3) see [1] */
+#define SLAB_INFO_SIZE          P2ALIGN (sizeof (SlabInfo) + NATIVE_MALLOC_PADDING)
+#define MAX_MAGAZINE_SIZE       (256)                                           /* see [3] and allocator_get_magazine_threshold() for this */
+#define MIN_MAGAZINE_SIZE       (4)
+#define MAX_STAMP_COUNTER       (7)                                             /* distributes the load of gettimeofday() */
+#define MAX_SLAB_CHUNK_SIZE(al) (((al)->max_page_size - SLAB_INFO_SIZE) / 8)    /* we want at last 8 chunks per page, see [4] */
+#define MAX_SLAB_INDEX(al)      (SLAB_INDEX (al, MAX_SLAB_CHUNK_SIZE (al)) + 1)
+#define SLAB_INDEX(al, asize)   ((asize) / P2ALIGNMENT - 1)                     /* asize must be P2ALIGNMENT aligned */
+#define SLAB_CHUNK_SIZE(al, ix) (((ix) + 1) * P2ALIGNMENT)
+#define SLAB_BPAGE_SIZE(al,csz) (8 * (csz) + SLAB_INFO_SIZE)
+
+/* optimized version of ALIGN (size, P2ALIGNMENT) */
+#if     GLIB_SIZEOF_SIZE_T * 2 == 8  /* P2ALIGNMENT */
+#define P2ALIGN(size)   (((size) + 0x7) & ~(gsize) 0x7)
+#elif   GLIB_SIZEOF_SIZE_T * 2 == 16 /* P2ALIGNMENT */
+#define P2ALIGN(size)   (((size) + 0xf) & ~(gsize) 0xf)
+#else
+#define P2ALIGN(size)   ALIGN (size, P2ALIGNMENT)
+#endif
+
+/* special helpers to avoid gmessage.c dependency */
+static void mem_error (const char *format, ...) G_GNUC_PRINTF (1,2);
+#define mem_assert(cond)    do { if (G_LIKELY (cond)) ; else mem_error ("assertion failed: %s", #cond); } while (0)
+
+/* --- structures --- */
+typedef struct _ChunkLink      ChunkLink;
+typedef struct _SlabInfo       SlabInfo;
+typedef struct _CachedMagazine CachedMagazine;
+struct _ChunkLink {
+  ChunkLink *next;
+  ChunkLink *data;
+};
+struct _SlabInfo {
+  ChunkLink *chunks;
+  guint n_allocated;
+  SlabInfo *next, *prev;
+};
+typedef struct {
+  ChunkLink *chunks;
+  gsize      count;                     /* approximative chunks list length */
+} Magazine;
+typedef struct {
+  Magazine   *magazine1;                /* array of MAX_SLAB_INDEX (allocator) */
+  Magazine   *magazine2;                /* array of MAX_SLAB_INDEX (allocator) */
+} ThreadMemory;
+typedef struct {
+  gboolean always_malloc;
+  gboolean bypass_magazines;
+  gboolean debug_blocks;
+  gsize    working_set_msecs;
+  guint    color_increment;
+} SliceConfig;
+typedef struct {
+  /* const after initialization */
+  gsize         min_page_size, max_page_size;
+  SliceConfig   config;
+  gsize         max_slab_chunk_size_for_magazine_cache;
+  /* magazine cache */
+  GMutex       *magazine_mutex;
+  ChunkLink   **magazines;                /* array of MAX_SLAB_INDEX (allocator) */
+  guint        *contention_counters;      /* array of MAX_SLAB_INDEX (allocator) */
+  gint          mutex_counter;
+  guint         stamp_counter;
+  guint         last_stamp;
+  /* slab allocator */
+  GMutex       *slab_mutex;
+  SlabInfo    **slab_stack;                /* array of MAX_SLAB_INDEX (allocator) */
+  guint        color_accu;
+} Allocator;
+
+/* --- g-slice prototypes --- */
+static gpointer     slab_allocator_alloc_chunk       (gsize      chunk_size);
+static void         slab_allocator_free_chunk        (gsize      chunk_size,
+                                                      gpointer   mem);
+static void         private_thread_memory_cleanup    (gpointer   data);
+static gpointer     allocator_memalign               (gsize      alignment,
+                                                      gsize      memsize);
+static void         allocator_memfree                (gsize      memsize,
+                                                      gpointer   mem);
+static inline void  magazine_cache_update_stamp      (void);
+static inline gsize allocator_get_magazine_threshold (Allocator *allocator,
+                                                      guint      ix);
+
+/* --- g-slice memory checker --- */
+static void     smc_notify_alloc  (void   *pointer,
+                                   size_t  size);
+static int      smc_notify_free   (void   *pointer,
+                                   size_t  size);
+
+/* --- variables --- */
+static GPrivate   *private_thread_memory = NULL;
+static gsize       sys_page_size = 0;
+static Allocator   allocator[1] = { { 0, }, };
+static SliceConfig slice_config = {
+  FALSE,        /* always_malloc */
+  FALSE,        /* bypass_magazines */
+  FALSE,        /* debug_blocks */
+  15 * 1000,    /* working_set_msecs */
+  1,            /* color increment, alt: 0x7fffffff */
+};
+static GMutex     *smc_tree_mutex = NULL; /* mutex for G_SLICE=debug-blocks */
+
+/* --- auxillary funcitons --- */
+void
+g_slice_set_config (GSliceConfig ckey,
+                    gint64       value)
+{
+  g_return_if_fail (sys_page_size == 0);
+  switch (ckey)
+    {
+    case G_SLICE_CONFIG_ALWAYS_MALLOC:
+      slice_config.always_malloc = value != 0;
+      break;
+    case G_SLICE_CONFIG_BYPASS_MAGAZINES:
+      slice_config.bypass_magazines = value != 0;
+      break;
+    case G_SLICE_CONFIG_WORKING_SET_MSECS:
+      slice_config.working_set_msecs = value;
+      break;
+    case G_SLICE_CONFIG_COLOR_INCREMENT:
+      slice_config.color_increment = value;
+    default: ;
+    }
+}
+
+gint64
+g_slice_get_config (GSliceConfig ckey)
+{
+  switch (ckey)
+    {
+    case G_SLICE_CONFIG_ALWAYS_MALLOC:
+      return slice_config.always_malloc;
+    case G_SLICE_CONFIG_BYPASS_MAGAZINES:
+      return slice_config.bypass_magazines;
+    case G_SLICE_CONFIG_WORKING_SET_MSECS:
+      return slice_config.working_set_msecs;
+    case G_SLICE_CONFIG_CHUNK_SIZES:
+      return MAX_SLAB_INDEX (allocator);
+    case G_SLICE_CONFIG_COLOR_INCREMENT:
+      return slice_config.color_increment;
+    default:
+      return 0;
+    }
+}
+
+gint64*
+g_slice_get_config_state (GSliceConfig ckey,
+                          gint64       address,
+                          guint       *n_values)
+{
+  guint i = 0;
+  g_return_val_if_fail (n_values != NULL, NULL);
+  *n_values = 0;
+  switch (ckey)
+    {
+      gint64 array[64];
+    case G_SLICE_CONFIG_CONTENTION_COUNTER:
+      array[i++] = SLAB_CHUNK_SIZE (allocator, address);
+      array[i++] = allocator->contention_counters[address];
+      array[i++] = allocator_get_magazine_threshold (allocator, address);
+      *n_values = i;
+      return g_memdup (array, sizeof (array[0]) * *n_values);
+    default:
+      return NULL;
+    }
+}
+
+static void
+slice_config_init (SliceConfig *config)
+{
+  /* don't use g_malloc/g_message here */
+  gchar buffer[1024];
+  const gchar *val = _g_getenv_nomalloc ("G_SLICE", buffer);
+  const GDebugKey keys[] = {
+    { "always-malloc", 1 << 0 },
+    { "debug-blocks",  1 << 1 },
+  };
+  gint flags = !val ? 0 : g_parse_debug_string (val, keys, G_N_ELEMENTS (keys));
+  *config = slice_config;
+  if (flags & (1 << 0))         /* always-malloc */
+    config->always_malloc = TRUE;
+  if (flags & (1 << 1))         /* debug-blocks */
+    config->debug_blocks = TRUE;
+}
+
+static void
+g_slice_init_nomessage (void)
+{
+  /* we may not use g_error() or friends here */
+  mem_assert (sys_page_size == 0);
+  mem_assert (MIN_MAGAZINE_SIZE >= 4);
+
+#ifdef G_OS_WIN32
+  {
+    SYSTEM_INFO system_info;
+    GetSystemInfo (&system_info);
+    sys_page_size = system_info.dwPageSize;
+  }
+#else
+  sys_page_size = sysconf (_SC_PAGESIZE); /* = sysconf (_SC_PAGE_SIZE); = getpagesize(); */
+#endif
+  mem_assert (sys_page_size >= 2 * LARGEALIGNMENT);
+  mem_assert ((sys_page_size & (sys_page_size - 1)) == 0);
+  slice_config_init (&allocator->config);
+  allocator->min_page_size = sys_page_size;
+#if HAVE_COMPLIANT_POSIX_MEMALIGN || HAVE_MEMALIGN
+  /* allow allocation of pages up to 8KB (with 8KB alignment).
+   * this is useful because many medium to large sized structures
+   * fit less than 8 times (see [4]) into 4KB pages.
+   * we allow very small page sizes here, to reduce wastage in
+   * threads if only small allocations are required (this does
+   * bear the risk of incresing allocation times and fragmentation
+   * though).
+   */
+  allocator->min_page_size = MAX (allocator->min_page_size, 4096);
+  allocator->max_page_size = MAX (allocator->min_page_size, 8192);
+  allocator->min_page_size = MIN (allocator->min_page_size, 128);
+#else
+  /* we can only align to system page size */
+  allocator->max_page_size = sys_page_size;
+#endif
+  if (allocator->config.always_malloc)
+    {
+      allocator->contention_counters = NULL;
+      allocator->magazines = NULL;
+      allocator->slab_stack = NULL;
+    }
+  else
+    {
+      allocator->contention_counters = g_new0 (guint, MAX_SLAB_INDEX (allocator));
+      allocator->magazines = g_new0 (ChunkLink*, MAX_SLAB_INDEX (allocator));
+      allocator->slab_stack = g_new0 (SlabInfo*, MAX_SLAB_INDEX (allocator));
+    }
+
+  allocator->magazine_mutex = NULL;     /* _g_slice_thread_init_nomessage() */
+  allocator->mutex_counter = 0;
+  allocator->stamp_counter = MAX_STAMP_COUNTER; /* force initial update */
+  allocator->last_stamp = 0;
+  allocator->slab_mutex = NULL;         /* _g_slice_thread_init_nomessage() */
+  allocator->color_accu = 0;
+  magazine_cache_update_stamp();
+  /* values cached for performance reasons */
+  allocator->max_slab_chunk_size_for_magazine_cache = MAX_SLAB_CHUNK_SIZE (allocator);
+  if (allocator->config.always_malloc || allocator->config.bypass_magazines)
+    allocator->max_slab_chunk_size_for_magazine_cache = 0;      /* non-optimized cases */
+  /* at this point, g_mem_gc_friendly() should be initialized, this
+   * should have been accomplished by the above g_malloc/g_new calls
+   */
+}
+
+static inline guint
+allocator_categorize (gsize aligned_chunk_size)
+{
+  /* speed up the likely path */
+  if (G_LIKELY (aligned_chunk_size && aligned_chunk_size <= allocator->max_slab_chunk_size_for_magazine_cache))
+    return 1;           /* use magazine cache */
+
+  /* the above will fail (max_slab_chunk_size_for_magazine_cache == 0) if the
+   * allocator is still uninitialized, or if we are not configured to use the
+   * magazine cache.
+   */
+  if (!sys_page_size)
+    g_slice_init_nomessage ();
+  if (!allocator->config.always_malloc &&
+      aligned_chunk_size &&
+      aligned_chunk_size <= MAX_SLAB_CHUNK_SIZE (allocator))
+    {
+      if (allocator->config.bypass_magazines)
+        return 2;       /* use slab allocator, see [2] */
+      return 1;         /* use magazine cache */
+    }
+  return 0;             /* use malloc() */
+}
+
+void
+_g_slice_thread_init_nomessage (void)
+{
+  /* we may not use g_error() or friends here */
+  if (!sys_page_size)
+    g_slice_init_nomessage();
+  else
+    {
+      /* g_slice_init_nomessage() has been called already, probably due
+       * to a g_slice_alloc1() before g_thread_init().
+       */
+    }
+  private_thread_memory = g_private_new (private_thread_memory_cleanup);
+  allocator->magazine_mutex = g_mutex_new();
+  allocator->slab_mutex = g_mutex_new();
+  if (allocator->config.debug_blocks)
+    smc_tree_mutex = g_mutex_new();
+}
+
+static inline void
+g_mutex_lock_a (GMutex *mutex,
+                guint  *contention_counter)
+{
+  gboolean contention = FALSE;
+  if (!g_mutex_trylock (mutex))
+    {
+      g_mutex_lock (mutex);
+      contention = TRUE;
+    }
+  if (contention)
+    {
+      allocator->mutex_counter++;
+      if (allocator->mutex_counter >= 1)        /* quickly adapt to contention */
+        {
+          allocator->mutex_counter = 0;
+          *contention_counter = MIN (*contention_counter + 1, MAX_MAGAZINE_SIZE);
+        }
+    }
+  else /* !contention */
+    {
+      allocator->mutex_counter--;
+      if (allocator->mutex_counter < -11)       /* moderately recover magazine sizes */
+        {
+          allocator->mutex_counter = 0;
+          *contention_counter = MAX (*contention_counter, 1) - 1;
+        }
+    }
+}
+
+static inline ThreadMemory*
+thread_memory_from_self (void)
+{
+  ThreadMemory *tmem = g_private_get (private_thread_memory);
+  if (G_UNLIKELY (!tmem))
+    {
+      static ThreadMemory *single_thread_memory = NULL;   /* remember single-thread info for multi-threaded case */
+      if (single_thread_memory && g_thread_supported ())
+        {
+          g_mutex_lock (allocator->slab_mutex);
+          if (single_thread_memory)
+            {
+              /* GSlice has been used before g_thread_init(), and now
+               * we are running threaded. to cope with it, use the saved
+               * thread memory structure from when we weren't threaded.
+               */
+              tmem = single_thread_memory;
+              single_thread_memory = NULL;      /* slab_mutex protected when multi-threaded */
+            }
+          g_mutex_unlock (allocator->slab_mutex);
+        }
+      if (!tmem)
+       {
+          const guint n_magazines = MAX_SLAB_INDEX (allocator);
+         tmem = g_malloc0 (sizeof (ThreadMemory) + sizeof (Magazine) * 2 * n_magazines);
+         tmem->magazine1 = (Magazine*) (tmem + 1);
+         tmem->magazine2 = &tmem->magazine1[n_magazines];
+       }
+      /* g_private_get/g_private_set works in the single-threaded xor the multi-
+       * threaded case. but not *across* g_thread_init(), after multi-thread
+       * initialization it returns NULL for previously set single-thread data.
+       */
+      g_private_set (private_thread_memory, tmem);
+      /* save single-thread thread memory structure, in case we need to
+       * pick it up again after multi-thread initialization happened.
+       */
+      if (!single_thread_memory && !g_thread_supported ())
+        single_thread_memory = tmem;            /* no slab_mutex created yet */
+    }
+  return tmem;
+}
+
+static inline ChunkLink*
+magazine_chain_pop_head (ChunkLink **magazine_chunks)
+{
+  /* magazine chains are linked via ChunkLink->next.
+   * each ChunkLink->data of the toplevel chain may point to a subchain,
+   * linked via ChunkLink->next. ChunkLink->data of the subchains just
+   * contains uninitialized junk.
+   */
+  ChunkLink *chunk = (*magazine_chunks)->data;
+  if (G_UNLIKELY (chunk))
+    {
+      /* allocating from freed list */
+      (*magazine_chunks)->data = chunk->next;
+    }
+  else
+    {
+      chunk = *magazine_chunks;
+      *magazine_chunks = chunk->next;
+    }
+  return chunk;
+}
+
+#if 0 /* useful for debugging */
+static guint
+magazine_count (ChunkLink *head)
+{
+  guint count = 0;
+  if (!head)
+    return 0;
+  while (head)
+    {
+      ChunkLink *child = head->data;
+      count += 1;
+      for (child = head->data; child; child = child->next)
+        count += 1;
+      head = head->next;
+    }
+  return count;
+}
+#endif
+
+static inline gsize
+allocator_get_magazine_threshold (Allocator *allocator,
+                                  guint      ix)
+{
+  /* the magazine size calculated here has a lower bound of MIN_MAGAZINE_SIZE,
+   * which is required by the implementation. also, for moderately sized chunks
+   * (say >= 64 bytes), magazine sizes shouldn't be much smaller then the number
+   * of chunks available per page/2 to avoid excessive traffic in the magazine
+   * cache for small to medium sized structures.
+   * the upper bound of the magazine size is effectively provided by
+   * MAX_MAGAZINE_SIZE. for larger chunks, this number is scaled down so that
+   * the content of a single magazine doesn't exceed ca. 16KB.
+   */
+  gsize chunk_size = SLAB_CHUNK_SIZE (allocator, ix);
+  guint threshold = MAX (MIN_MAGAZINE_SIZE, allocator->max_page_size / MAX (5 * chunk_size, 5 * 32));
+  guint contention_counter = allocator->contention_counters[ix];
+  if (G_UNLIKELY (contention_counter))  /* single CPU bias */
+    {
+      /* adapt contention counter thresholds to chunk sizes */
+      contention_counter = contention_counter * 64 / chunk_size;
+      threshold = MAX (threshold, contention_counter);
+    }
+  return threshold;
+}
+
+/* --- magazine cache --- */
+static inline void
+magazine_cache_update_stamp (void)
+{
+  if (allocator->stamp_counter >= MAX_STAMP_COUNTER)
+    {
+      GTimeVal tv;
+      g_get_current_time (&tv);
+      allocator->last_stamp = tv.tv_sec * 1000 + tv.tv_usec / 1000; /* milli seconds */
+      allocator->stamp_counter = 0;
+    }
+  else
+    allocator->stamp_counter++;
+}
+
+static inline ChunkLink*
+magazine_chain_prepare_fields (ChunkLink *magazine_chunks)
+{
+  ChunkLink *chunk1;
+  ChunkLink *chunk2;
+  ChunkLink *chunk3;
+  ChunkLink *chunk4;
+  /* checked upon initialization: mem_assert (MIN_MAGAZINE_SIZE >= 4); */
+  /* ensure a magazine with at least 4 unused data pointers */
+  chunk1 = magazine_chain_pop_head (&magazine_chunks);
+  chunk2 = magazine_chain_pop_head (&magazine_chunks);
+  chunk3 = magazine_chain_pop_head (&magazine_chunks);
+  chunk4 = magazine_chain_pop_head (&magazine_chunks);
+  chunk4->next = magazine_chunks;
+  chunk3->next = chunk4;
+  chunk2->next = chunk3;
+  chunk1->next = chunk2;
+  return chunk1;
+}
+
+/* access the first 3 fields of a specially prepared magazine chain */
+#define magazine_chain_prev(mc)         ((mc)->data)
+#define magazine_chain_stamp(mc)        ((mc)->next->data)
+#define magazine_chain_uint_stamp(mc)   GPOINTER_TO_UINT ((mc)->next->data)
+#define magazine_chain_next(mc)         ((mc)->next->next->data)
+#define magazine_chain_count(mc)        ((mc)->next->next->next->data)
+
+static void
+magazine_cache_trim (Allocator *allocator,
+                     guint      ix,
+                     guint      stamp)
+{
+  /* g_mutex_lock (allocator->mutex); done by caller */
+  /* trim magazine cache from tail */
+  ChunkLink *current = magazine_chain_prev (allocator->magazines[ix]);
+  ChunkLink *trash = NULL;
+  while (ABS (stamp - magazine_chain_uint_stamp (current)) >= allocator->config.working_set_msecs)
+    {
+      /* unlink */
+      ChunkLink *prev = magazine_chain_prev (current);
+      ChunkLink *next = magazine_chain_next (current);
+      magazine_chain_next (prev) = next;
+      magazine_chain_prev (next) = prev;
+      /* clear special fields, put on trash stack */
+      magazine_chain_next (current) = NULL;
+      magazine_chain_count (current) = NULL;
+      magazine_chain_stamp (current) = NULL;
+      magazine_chain_prev (current) = trash;
+      trash = current;
+      /* fixup list head if required */
+      if (current == allocator->magazines[ix])
+        {
+          allocator->magazines[ix] = NULL;
+          break;
+        }
+      current = prev;
+    }
+  g_mutex_unlock (allocator->magazine_mutex);
+  /* free trash */
+  if (trash)
+    {
+      const gsize chunk_size = SLAB_CHUNK_SIZE (allocator, ix);
+      g_mutex_lock (allocator->slab_mutex);
+      while (trash)
+        {
+          current = trash;
+          trash = magazine_chain_prev (current);
+          magazine_chain_prev (current) = NULL; /* clear special field */
+          while (current)
+            {
+              ChunkLink *chunk = magazine_chain_pop_head (&current);
+              slab_allocator_free_chunk (chunk_size, chunk);
+            }
+        }
+      g_mutex_unlock (allocator->slab_mutex);
+    }
+}
+
+static void
+magazine_cache_push_magazine (guint      ix,
+                              ChunkLink *magazine_chunks,
+                              gsize      count) /* must be >= MIN_MAGAZINE_SIZE */
+{
+  ChunkLink *current = magazine_chain_prepare_fields (magazine_chunks);
+  ChunkLink *next, *prev;
+  g_mutex_lock (allocator->magazine_mutex);
+  /* add magazine at head */
+  next = allocator->magazines[ix];
+  if (next)
+    prev = magazine_chain_prev (next);
+  else
+    next = prev = current;
+  magazine_chain_next (prev) = current;
+  magazine_chain_prev (next) = current;
+  magazine_chain_prev (current) = prev;
+  magazine_chain_next (current) = next;
+  magazine_chain_count (current) = (gpointer) count;
+  /* stamp magazine */
+  magazine_cache_update_stamp();
+  magazine_chain_stamp (current) = GUINT_TO_POINTER (allocator->last_stamp);
+  allocator->magazines[ix] = current;
+  /* free old magazines beyond a certain threshold */
+  magazine_cache_trim (allocator, ix, allocator->last_stamp);
+  /* g_mutex_unlock (allocator->mutex); was done by magazine_cache_trim() */
+}
+
+static ChunkLink*
+magazine_cache_pop_magazine (guint  ix,
+                             gsize *countp)
+{
+  g_mutex_lock_a (allocator->magazine_mutex, &allocator->contention_counters[ix]);
+  if (!allocator->magazines[ix])
+    {
+      guint magazine_threshold = allocator_get_magazine_threshold (allocator, ix);
+      gsize i, chunk_size = SLAB_CHUNK_SIZE (allocator, ix);
+      ChunkLink *chunk, *head;
+      g_mutex_unlock (allocator->magazine_mutex);
+      g_mutex_lock (allocator->slab_mutex);
+      head = slab_allocator_alloc_chunk (chunk_size);
+      head->data = NULL;
+      chunk = head;
+      for (i = 1; i < magazine_threshold; i++)
+        {
+          chunk->next = slab_allocator_alloc_chunk (chunk_size);
+          chunk = chunk->next;
+          chunk->data = NULL;
+        }
+      chunk->next = NULL;
+      g_mutex_unlock (allocator->slab_mutex);
+      *countp = i;
+      return head;
+    }
+  else
+    {
+      ChunkLink *current = allocator->magazines[ix];
+      ChunkLink *prev = magazine_chain_prev (current);
+      ChunkLink *next = magazine_chain_next (current);
+      /* unlink */
+      magazine_chain_next (prev) = next;
+      magazine_chain_prev (next) = prev;
+      allocator->magazines[ix] = next == current ? NULL : next;
+      g_mutex_unlock (allocator->magazine_mutex);
+      /* clear special fields and hand out */
+      *countp = (gsize) magazine_chain_count (current);
+      magazine_chain_prev (current) = NULL;
+      magazine_chain_next (current) = NULL;
+      magazine_chain_count (current) = NULL;
+      magazine_chain_stamp (current) = NULL;
+      return current;
+    }
+}
+
+/* --- thread magazines --- */
+static void
+private_thread_memory_cleanup (gpointer data)
+{
+  ThreadMemory *tmem = data;
+  const guint n_magazines = MAX_SLAB_INDEX (allocator);
+  guint ix;
+  for (ix = 0; ix < n_magazines; ix++)
+    {
+      Magazine *mags[2];
+      guint j;
+      mags[0] = &tmem->magazine1[ix];
+      mags[1] = &tmem->magazine2[ix];
+      for (j = 0; j < 2; j++)
+        {
+          Magazine *mag = mags[j];
+          if (mag->count >= MIN_MAGAZINE_SIZE)
+            magazine_cache_push_magazine (ix, mag->chunks, mag->count);
+          else
+            {
+              const gsize chunk_size = SLAB_CHUNK_SIZE (allocator, ix);
+              g_mutex_lock (allocator->slab_mutex);
+              while (mag->chunks)
+                {
+                  ChunkLink *chunk = magazine_chain_pop_head (&mag->chunks);
+                  slab_allocator_free_chunk (chunk_size, chunk);
+                }
+              g_mutex_unlock (allocator->slab_mutex);
+            }
+        }
+    }
+  g_free (tmem);
+}
+
+static void
+thread_memory_magazine1_reload (ThreadMemory *tmem,
+                                guint         ix)
+{
+  Magazine *mag = &tmem->magazine1[ix];
+  mem_assert (mag->chunks == NULL); /* ensure that we may reset mag->count */
+  mag->count = 0;
+  mag->chunks = magazine_cache_pop_magazine (ix, &mag->count);
+}
+
+static void
+thread_memory_magazine2_unload (ThreadMemory *tmem,
+                                guint         ix)
+{
+  Magazine *mag = &tmem->magazine2[ix];
+  magazine_cache_push_magazine (ix, mag->chunks, mag->count);
+  mag->chunks = NULL;
+  mag->count = 0;
+}
+
+static inline void
+thread_memory_swap_magazines (ThreadMemory *tmem,
+                              guint         ix)
+{
+  Magazine xmag = tmem->magazine1[ix];
+  tmem->magazine1[ix] = tmem->magazine2[ix];
+  tmem->magazine2[ix] = xmag;
+}
+
+static inline gboolean
+thread_memory_magazine1_is_empty (ThreadMemory *tmem,
+                                  guint         ix)
+{
+  return tmem->magazine1[ix].chunks == NULL;
+}
+
+static inline gboolean
+thread_memory_magazine2_is_full (ThreadMemory *tmem,
+                                 guint         ix)
+{
+  return tmem->magazine2[ix].count >= allocator_get_magazine_threshold (allocator, ix);
+}
+
+static inline gpointer
+thread_memory_magazine1_alloc (ThreadMemory *tmem,
+                               guint         ix)
+{
+  Magazine *mag = &tmem->magazine1[ix];
+  ChunkLink *chunk = magazine_chain_pop_head (&mag->chunks);
+  if (G_LIKELY (mag->count > 0))
+    mag->count--;
+  return chunk;
+}
+
+static inline void
+thread_memory_magazine2_free (ThreadMemory *tmem,
+                              guint         ix,
+                              gpointer      mem)
+{
+  Magazine *mag = &tmem->magazine2[ix];
+  ChunkLink *chunk = mem;
+  chunk->data = NULL;
+  chunk->next = mag->chunks;
+  mag->chunks = chunk;
+  mag->count++;
+}
+
+/* --- API functions --- */
+gpointer
+g_slice_alloc (gsize mem_size)
+{
+  gsize chunk_size;
+  gpointer mem;
+  guint acat;
+  chunk_size = P2ALIGN (mem_size);
+  acat = allocator_categorize (chunk_size);
+  if (G_LIKELY (acat == 1))     /* allocate through magazine layer */
+    {
+      ThreadMemory *tmem = thread_memory_from_self();
+      guint ix = SLAB_INDEX (allocator, chunk_size);
+      if (G_UNLIKELY (thread_memory_magazine1_is_empty (tmem, ix)))
+        {
+          thread_memory_swap_magazines (tmem, ix);
+          if (G_UNLIKELY (thread_memory_magazine1_is_empty (tmem, ix)))
+            thread_memory_magazine1_reload (tmem, ix);
+        }
+      mem = thread_memory_magazine1_alloc (tmem, ix);
+    }
+  else if (acat == 2)           /* allocate through slab allocator */
+    {
+      g_mutex_lock (allocator->slab_mutex);
+      mem = slab_allocator_alloc_chunk (chunk_size);
+      g_mutex_unlock (allocator->slab_mutex);
+    }
+  else                          /* delegate to system malloc */
+    mem = g_malloc (mem_size);
+  if (G_UNLIKELY (allocator->config.debug_blocks))
+    smc_notify_alloc (mem, mem_size);
+
+  TRACE (GLIB_SLICE_ALLOC((void*)mem, mem_size));
+
+  return mem;
+}
+
+gpointer
+g_slice_alloc0 (gsize mem_size)
+{
+  gpointer mem = g_slice_alloc (mem_size);
+  if (mem)
+    memset (mem, 0, mem_size);
+  return mem;
+}
+
+gpointer
+g_slice_copy (gsize         mem_size,
+              gconstpointer mem_block)
+{
+  gpointer mem = g_slice_alloc (mem_size);
+  if (mem)
+    memcpy (mem, mem_block, mem_size);
+  return mem;
+}
+
+void
+g_slice_free1 (gsize    mem_size,
+               gpointer mem_block)
+{
+  gsize chunk_size = P2ALIGN (mem_size);
+  guint acat = allocator_categorize (chunk_size);
+  if (G_UNLIKELY (!mem_block))
+    return;
+  if (G_UNLIKELY (allocator->config.debug_blocks) &&
+      !smc_notify_free (mem_block, mem_size))
+    abort();
+  if (G_LIKELY (acat == 1))             /* allocate through magazine layer */
+    {
+      ThreadMemory *tmem = thread_memory_from_self();
+      guint ix = SLAB_INDEX (allocator, chunk_size);
+      if (G_UNLIKELY (thread_memory_magazine2_is_full (tmem, ix)))
+        {
+          thread_memory_swap_magazines (tmem, ix);
+          if (G_UNLIKELY (thread_memory_magazine2_is_full (tmem, ix)))
+            thread_memory_magazine2_unload (tmem, ix);
+        }
+      if (G_UNLIKELY (g_mem_gc_friendly))
+        memset (mem_block, 0, chunk_size);
+      thread_memory_magazine2_free (tmem, ix, mem_block);
+    }
+  else if (acat == 2)                   /* allocate through slab allocator */
+    {
+      if (G_UNLIKELY (g_mem_gc_friendly))
+        memset (mem_block, 0, chunk_size);
+      g_mutex_lock (allocator->slab_mutex);
+      slab_allocator_free_chunk (chunk_size, mem_block);
+      g_mutex_unlock (allocator->slab_mutex);
+    }
+  else                                  /* delegate to system malloc */
+    {
+      if (G_UNLIKELY (g_mem_gc_friendly))
+        memset (mem_block, 0, mem_size);
+      g_free (mem_block);
+    }
+  TRACE (GLIB_SLICE_FREE((void*)mem_block, mem_size));
+}
+
+void
+g_slice_free_chain_with_offset (gsize    mem_size,
+                                gpointer mem_chain,
+                                gsize    next_offset)
+{
+  gpointer slice = mem_chain;
+  /* while the thread magazines and the magazine cache are implemented so that
+   * they can easily be extended to allow for free lists containing more free
+   * lists for the first level nodes, which would allow O(1) freeing in this
+   * function, the benefit of such an extension is questionable, because:
+   * - the magazine size counts will become mere lower bounds which confuses
+   *   the code adapting to lock contention;
+   * - freeing a single node to the thread magazines is very fast, so this
+   *   O(list_length) operation is multiplied by a fairly small factor;
+   * - memory usage histograms on larger applications seem to indicate that
+   *   the amount of released multi node lists is negligible in comparison
+   *   to single node releases.
+   * - the major performance bottle neck, namely g_private_get() or
+   *   g_mutex_lock()/g_mutex_unlock() has already been moved out of the
+   *   inner loop for freeing chained slices.
+   */
+  gsize chunk_size = P2ALIGN (mem_size);
+  guint acat = allocator_categorize (chunk_size);
+  if (G_LIKELY (acat == 1))             /* allocate through magazine layer */
+    {
+      ThreadMemory *tmem = thread_memory_from_self();
+      guint ix = SLAB_INDEX (allocator, chunk_size);
+      while (slice)
+        {
+          guint8 *current = slice;
+          slice = *(gpointer*) (current + next_offset);
+          if (G_UNLIKELY (allocator->config.debug_blocks) &&
+              !smc_notify_free (current, mem_size))
+            abort();
+          if (G_UNLIKELY (thread_memory_magazine2_is_full (tmem, ix)))
+            {
+              thread_memory_swap_magazines (tmem, ix);
+              if (G_UNLIKELY (thread_memory_magazine2_is_full (tmem, ix)))
+                thread_memory_magazine2_unload (tmem, ix);
+            }
+          if (G_UNLIKELY (g_mem_gc_friendly))
+            memset (current, 0, chunk_size);
+          thread_memory_magazine2_free (tmem, ix, current);
+        }
+    }
+  else if (acat == 2)                   /* allocate through slab allocator */
+    {
+      g_mutex_lock (allocator->slab_mutex);
+      while (slice)
+        {
+          guint8 *current = slice;
+          slice = *(gpointer*) (current + next_offset);
+          if (G_UNLIKELY (allocator->config.debug_blocks) &&
+              !smc_notify_free (current, mem_size))
+            abort();
+          if (G_UNLIKELY (g_mem_gc_friendly))
+            memset (current, 0, chunk_size);
+          slab_allocator_free_chunk (chunk_size, current);
+        }
+      g_mutex_unlock (allocator->slab_mutex);
+    }
+  else                                  /* delegate to system malloc */
+    while (slice)
+      {
+        guint8 *current = slice;
+        slice = *(gpointer*) (current + next_offset);
+        if (G_UNLIKELY (allocator->config.debug_blocks) &&
+            !smc_notify_free (current, mem_size))
+          abort();
+        if (G_UNLIKELY (g_mem_gc_friendly))
+          memset (current, 0, mem_size);
+        g_free (current);
+      }
+}
+
+/* --- single page allocator --- */
+static void
+allocator_slab_stack_push (Allocator *allocator,
+                           guint      ix,
+                           SlabInfo  *sinfo)
+{
+  /* insert slab at slab ring head */
+  if (!allocator->slab_stack[ix])
+    {
+      sinfo->next = sinfo;
+      sinfo->prev = sinfo;
+    }
+  else
+    {
+      SlabInfo *next = allocator->slab_stack[ix], *prev = next->prev;
+      next->prev = sinfo;
+      prev->next = sinfo;
+      sinfo->next = next;
+      sinfo->prev = prev;
+    }
+  allocator->slab_stack[ix] = sinfo;
+}
+
+static gsize
+allocator_aligned_page_size (Allocator *allocator,
+                             gsize      n_bytes)
+{
+  gsize val = 1 << g_bit_storage (n_bytes - 1);
+  val = MAX (val, allocator->min_page_size);
+  return val;
+}
+
+static void
+allocator_add_slab (Allocator *allocator,
+                    guint      ix,
+                    gsize      chunk_size)
+{
+  ChunkLink *chunk;
+  SlabInfo *sinfo;
+  gsize addr, padding, n_chunks, color = 0;
+  gsize page_size = allocator_aligned_page_size (allocator, SLAB_BPAGE_SIZE (allocator, chunk_size));
+  /* allocate 1 page for the chunks and the slab */
+  gpointer aligned_memory = allocator_memalign (page_size, page_size - NATIVE_MALLOC_PADDING);
+  guint8 *mem = aligned_memory;
+  guint i;
+  if (!mem)
+    {
+      const gchar *syserr = "unknown error";
+#if HAVE_STRERROR
+      syserr = strerror (errno);
+#endif
+      mem_error ("failed to allocate %u bytes (alignment: %u): %s\n",
+                 (guint) (page_size - NATIVE_MALLOC_PADDING), (guint) page_size, syserr);
+    }
+  /* mask page adress */
+  addr = ((gsize) mem / page_size) * page_size;
+  /* assert alignment */
+  mem_assert (aligned_memory == (gpointer) addr);
+  /* basic slab info setup */
+  sinfo = (SlabInfo*) (mem + page_size - SLAB_INFO_SIZE);
+  sinfo->n_allocated = 0;
+  sinfo->chunks = NULL;
+  /* figure cache colorization */
+  n_chunks = ((guint8*) sinfo - mem) / chunk_size;
+  padding = ((guint8*) sinfo - mem) - n_chunks * chunk_size;
+  if (padding)
+    {
+      color = (allocator->color_accu * P2ALIGNMENT) % padding;
+      allocator->color_accu += allocator->config.color_increment;
+    }
+  /* add chunks to free list */
+  chunk = (ChunkLink*) (mem + color);
+  sinfo->chunks = chunk;
+  for (i = 0; i < n_chunks - 1; i++)
+    {
+      chunk->next = (ChunkLink*) ((guint8*) chunk + chunk_size);
+      chunk = chunk->next;
+    }
+  chunk->next = NULL;   /* last chunk */
+  /* add slab to slab ring */
+  allocator_slab_stack_push (allocator, ix, sinfo);
+}
+
+static gpointer
+slab_allocator_alloc_chunk (gsize chunk_size)
+{
+  ChunkLink *chunk;
+  guint ix = SLAB_INDEX (allocator, chunk_size);
+  /* ensure non-empty slab */
+  if (!allocator->slab_stack[ix] || !allocator->slab_stack[ix]->chunks)
+    allocator_add_slab (allocator, ix, chunk_size);
+  /* allocate chunk */
+  chunk = allocator->slab_stack[ix]->chunks;
+  allocator->slab_stack[ix]->chunks = chunk->next;
+  allocator->slab_stack[ix]->n_allocated++;
+  /* rotate empty slabs */
+  if (!allocator->slab_stack[ix]->chunks)
+    allocator->slab_stack[ix] = allocator->slab_stack[ix]->next;
+  return chunk;
+}
+
+static void
+slab_allocator_free_chunk (gsize    chunk_size,
+                           gpointer mem)
+{
+  ChunkLink *chunk;
+  gboolean was_empty;
+  guint ix = SLAB_INDEX (allocator, chunk_size);
+  gsize page_size = allocator_aligned_page_size (allocator, SLAB_BPAGE_SIZE (allocator, chunk_size));
+  gsize addr = ((gsize) mem / page_size) * page_size;
+  /* mask page adress */
+  guint8 *page = (guint8*) addr;
+  SlabInfo *sinfo = (SlabInfo*) (page + page_size - SLAB_INFO_SIZE);
+  /* assert valid chunk count */
+  mem_assert (sinfo->n_allocated > 0);
+  /* add chunk to free list */
+  was_empty = sinfo->chunks == NULL;
+  chunk = (ChunkLink*) mem;
+  chunk->next = sinfo->chunks;
+  sinfo->chunks = chunk;
+  sinfo->n_allocated--;
+  /* keep slab ring partially sorted, empty slabs at end */
+  if (was_empty)
+    {
+      /* unlink slab */
+      SlabInfo *next = sinfo->next, *prev = sinfo->prev;
+      next->prev = prev;
+      prev->next = next;
+      if (allocator->slab_stack[ix] == sinfo)
+        allocator->slab_stack[ix] = next == sinfo ? NULL : next;
+      /* insert slab at head */
+      allocator_slab_stack_push (allocator, ix, sinfo);
+    }
+  /* eagerly free complete unused slabs */
+  if (!sinfo->n_allocated)
+    {
+      /* unlink slab */
+      SlabInfo *next = sinfo->next, *prev = sinfo->prev;
+      next->prev = prev;
+      prev->next = next;
+      if (allocator->slab_stack[ix] == sinfo)
+        allocator->slab_stack[ix] = next == sinfo ? NULL : next;
+      /* free slab */
+      allocator_memfree (page_size, page);
+    }
+}
+
+/* --- memalign implementation --- */
+#ifdef HAVE_MALLOC_H
+#include <malloc.h>             /* memalign() */
+#endif
+
+/* from config.h:
+ * define HAVE_POSIX_MEMALIGN           1 // if free(posix_memalign(3)) works, <stdlib.h>
+ * define HAVE_COMPLIANT_POSIX_MEMALIGN 1 // if free(posix_memalign(3)) works for sizes != 2^n, <stdlib.h>
+ * define HAVE_MEMALIGN                 1 // if free(memalign(3)) works, <malloc.h>
+ * define HAVE_VALLOC                   1 // if free(valloc(3)) works, <stdlib.h> or <malloc.h>
+ * if none is provided, we implement malloc(3)-based alloc-only page alignment
+ */
+
+#if !(HAVE_COMPLIANT_POSIX_MEMALIGN || HAVE_MEMALIGN || HAVE_VALLOC)
+static GTrashStack *compat_valloc_trash = NULL;
+#endif
+
+static gpointer
+allocator_memalign (gsize alignment,
+                    gsize memsize)
+{
+  gpointer aligned_memory = NULL;
+  gint err = ENOMEM;
+#if     HAVE_COMPLIANT_POSIX_MEMALIGN
+  err = posix_memalign (&aligned_memory, alignment, memsize);
+#elif   HAVE_MEMALIGN
+  errno = 0;
+  aligned_memory = memalign (alignment, memsize);
+  err = errno;
+#elif   HAVE_VALLOC
+  errno = 0;
+  aligned_memory = valloc (memsize);
+  err = errno;
+#else
+  /* simplistic non-freeing page allocator */
+  mem_assert (alignment == sys_page_size);
+  mem_assert (memsize <= sys_page_size);
+  if (!compat_valloc_trash)
+    {
+      const guint n_pages = 16;
+      guint8 *mem = malloc (n_pages * sys_page_size);
+      err = errno;
+      if (mem)
+        {
+          gint i = n_pages;
+          guint8 *amem = (guint8*) ALIGN ((gsize) mem, sys_page_size);
+          if (amem != mem)
+            i--;        /* mem wasn't page aligned */
+          while (--i >= 0)
+            g_trash_stack_push (&compat_valloc_trash, amem + i * sys_page_size);
+        }
+    }
+  aligned_memory = g_trash_stack_pop (&compat_valloc_trash);
+#endif
+  if (!aligned_memory)
+    errno = err;
+  return aligned_memory;
+}
+
+static void
+allocator_memfree (gsize    memsize,
+                   gpointer mem)
+{
+#if     HAVE_COMPLIANT_POSIX_MEMALIGN || HAVE_MEMALIGN || HAVE_VALLOC
+  free (mem);
+#else
+  mem_assert (memsize <= sys_page_size);
+  g_trash_stack_push (&compat_valloc_trash, mem);
+#endif
+}
+
+static void
+mem_error (const char *format,
+           ...)
+{
+  const char *pname;
+  va_list args;
+  /* at least, put out "MEMORY-ERROR", in case we segfault during the rest of the function */
+  fputs ("\n***MEMORY-ERROR***: ", stderr);
+  pname = g_get_prgname();
+  fprintf (stderr, "%s[%ld]: GSlice: ", pname ? pname : "", (long)getpid());
+  va_start (args, format);
+  vfprintf (stderr, format, args);
+  va_end (args);
+  fputs ("\n", stderr);
+  abort();
+  _exit (1);
+}
+
+/* --- g-slice memory checker tree --- */
+typedef size_t SmcKType;                /* key type */
+typedef size_t SmcVType;                /* value type */
+typedef struct {
+  SmcKType key;
+  SmcVType value;
+} SmcEntry;
+static void             smc_tree_insert      (SmcKType  key,
+                                              SmcVType  value);
+static gboolean         smc_tree_lookup      (SmcKType  key,
+                                              SmcVType *value_p);
+static gboolean         smc_tree_remove      (SmcKType  key);
+
+
+/* --- g-slice memory checker implementation --- */
+static void
+smc_notify_alloc (void   *pointer,
+                  size_t  size)
+{
+  size_t adress = (size_t) pointer;
+  if (pointer)
+    smc_tree_insert (adress, size);
+}
+
+#if 0
+static void
+smc_notify_ignore (void *pointer)
+{
+  size_t adress = (size_t) pointer;
+  if (pointer)
+    smc_tree_remove (adress);
+}
+#endif
+
+static int
+smc_notify_free (void   *pointer,
+                 size_t  size)
+{
+  size_t adress = (size_t) pointer;
+  SmcVType real_size;
+  gboolean found_one;
+
+  if (!pointer)
+    return 1; /* ignore */
+  found_one = smc_tree_lookup (adress, &real_size);
+  if (!found_one)
+    {
+      fprintf (stderr, "GSlice: MemChecker: attempt to release non-allocated block: %p size=%" G_GSIZE_FORMAT "\n", pointer, size);
+      return 0;
+    }
+  if (real_size != size && (real_size || size))
+    {
+      fprintf (stderr, "GSlice: MemChecker: attempt to release block with invalid size: %p size=%" G_GSIZE_FORMAT " invalid-size=%" G_GSIZE_FORMAT "\n", pointer, real_size, size);
+      return 0;
+    }
+  if (!smc_tree_remove (adress))
+    {
+      fprintf (stderr, "GSlice: MemChecker: attempt to release non-allocated block: %p size=%" G_GSIZE_FORMAT "\n", pointer, size);
+      return 0;
+    }
+  return 1; /* all fine */
+}
+
+/* --- g-slice memory checker tree implementation --- */
+#define SMC_TRUNK_COUNT     (4093 /* 16381 */)          /* prime, to distribute trunk collisions (big, allocated just once) */
+#define SMC_BRANCH_COUNT    (511)                       /* prime, to distribute branch collisions */
+#define SMC_TRUNK_EXTENT    (SMC_BRANCH_COUNT * 2039)   /* key adress space per trunk, should distribute uniformly across BRANCH_COUNT */
+#define SMC_TRUNK_HASH(k)   ((k / SMC_TRUNK_EXTENT) % SMC_TRUNK_COUNT)  /* generate new trunk hash per megabyte (roughly) */
+#define SMC_BRANCH_HASH(k)  (k % SMC_BRANCH_COUNT)
+
+typedef struct {
+  SmcEntry    *entries;
+  unsigned int n_entries;
+} SmcBranch;
+
+static SmcBranch     **smc_tree_root = NULL;
+
+static void
+smc_tree_abort (int errval)
+{
+  const char *syserr = "unknown error";
+#if HAVE_STRERROR
+  syserr = strerror (errval);
+#endif
+  mem_error ("MemChecker: failure in debugging tree: %s", syserr);
+}
+
+static inline SmcEntry*
+smc_tree_branch_grow_L (SmcBranch   *branch,
+                        unsigned int index)
+{
+  unsigned int old_size = branch->n_entries * sizeof (branch->entries[0]);
+  unsigned int new_size = old_size + sizeof (branch->entries[0]);
+  SmcEntry *entry;
+  mem_assert (index <= branch->n_entries);
+  branch->entries = (SmcEntry*) realloc (branch->entries, new_size);
+  if (!branch->entries)
+    smc_tree_abort (errno);
+  entry = branch->entries + index;
+  g_memmove (entry + 1, entry, (branch->n_entries - index) * sizeof (entry[0]));
+  branch->n_entries += 1;
+  return entry;
+}
+
+static inline SmcEntry*
+smc_tree_branch_lookup_nearest_L (SmcBranch *branch,
+                                  SmcKType   key)
+{
+  unsigned int n_nodes = branch->n_entries, offs = 0;
+  SmcEntry *check = branch->entries;
+  int cmp = 0;
+  while (offs < n_nodes)
+    {
+      unsigned int i = (offs + n_nodes) >> 1;
+      check = branch->entries + i;
+      cmp = key < check->key ? -1 : key != check->key;
+      if (cmp == 0)
+        return check;                   /* return exact match */
+      else if (cmp < 0)
+        n_nodes = i;
+      else /* (cmp > 0) */
+        offs = i + 1;
+    }
+  /* check points at last mismatch, cmp > 0 indicates greater key */
+  return cmp > 0 ? check + 1 : check;   /* return insertion position for inexact match */
+}
+
+static void
+smc_tree_insert (SmcKType key,
+                 SmcVType value)
+{
+  unsigned int ix0, ix1;
+  SmcEntry *entry;
+
+  g_mutex_lock (smc_tree_mutex);
+  ix0 = SMC_TRUNK_HASH (key);
+  ix1 = SMC_BRANCH_HASH (key);
+  if (!smc_tree_root)
+    {
+      smc_tree_root = calloc (SMC_TRUNK_COUNT, sizeof (smc_tree_root[0]));
+      if (!smc_tree_root)
+        smc_tree_abort (errno);
+    }
+  if (!smc_tree_root[ix0])
+    {
+      smc_tree_root[ix0] = calloc (SMC_BRANCH_COUNT, sizeof (smc_tree_root[0][0]));
+      if (!smc_tree_root[ix0])
+        smc_tree_abort (errno);
+    }
+  entry = smc_tree_branch_lookup_nearest_L (&smc_tree_root[ix0][ix1], key);
+  if (!entry ||                                                                         /* need create */
+      entry >= smc_tree_root[ix0][ix1].entries + smc_tree_root[ix0][ix1].n_entries ||   /* need append */
+      entry->key != key)                                                                /* need insert */
+    entry = smc_tree_branch_grow_L (&smc_tree_root[ix0][ix1], entry - smc_tree_root[ix0][ix1].entries);
+  entry->key = key;
+  entry->value = value;
+  g_mutex_unlock (smc_tree_mutex);
+}
+
+static gboolean
+smc_tree_lookup (SmcKType  key,
+                 SmcVType *value_p)
+{
+  SmcEntry *entry = NULL;
+  unsigned int ix0 = SMC_TRUNK_HASH (key), ix1 = SMC_BRANCH_HASH (key);
+  gboolean found_one = FALSE;
+  *value_p = 0;
+  g_mutex_lock (smc_tree_mutex);
+  if (smc_tree_root && smc_tree_root[ix0])
+    {
+      entry = smc_tree_branch_lookup_nearest_L (&smc_tree_root[ix0][ix1], key);
+      if (entry &&
+          entry < smc_tree_root[ix0][ix1].entries + smc_tree_root[ix0][ix1].n_entries &&
+          entry->key == key)
+        {
+          found_one = TRUE;
+          *value_p = entry->value;
+        }
+    }
+  g_mutex_unlock (smc_tree_mutex);
+  return found_one;
+}
+
+static gboolean
+smc_tree_remove (SmcKType key)
+{
+  unsigned int ix0 = SMC_TRUNK_HASH (key), ix1 = SMC_BRANCH_HASH (key);
+  gboolean found_one = FALSE;
+  g_mutex_lock (smc_tree_mutex);
+  if (smc_tree_root && smc_tree_root[ix0])
+    {
+      SmcEntry *entry = smc_tree_branch_lookup_nearest_L (&smc_tree_root[ix0][ix1], key);
+      if (entry &&
+          entry < smc_tree_root[ix0][ix1].entries + smc_tree_root[ix0][ix1].n_entries &&
+          entry->key == key)
+        {
+          unsigned int i = entry - smc_tree_root[ix0][ix1].entries;
+          smc_tree_root[ix0][ix1].n_entries -= 1;
+          g_memmove (entry, entry + 1, (smc_tree_root[ix0][ix1].n_entries - i) * sizeof (entry[0]));
+          if (!smc_tree_root[ix0][ix1].n_entries)
+            {
+              /* avoid useless pressure on the memory system */
+              free (smc_tree_root[ix0][ix1].entries);
+              smc_tree_root[ix0][ix1].entries = NULL;
+            }
+          found_one = TRUE;
+        }
+    }
+  g_mutex_unlock (smc_tree_mutex);
+  return found_one;
+}
+
+#ifdef G_ENABLE_DEBUG
+void
+g_slice_debug_tree_statistics (void)
+{
+  g_mutex_lock (smc_tree_mutex);
+  if (smc_tree_root)
+    {
+      unsigned int i, j, t = 0, o = 0, b = 0, su = 0, ex = 0, en = 4294967295u;
+      double tf, bf;
+      for (i = 0; i < SMC_TRUNK_COUNT; i++)
+        if (smc_tree_root[i])
+          {
+            t++;
+            for (j = 0; j < SMC_BRANCH_COUNT; j++)
+              if (smc_tree_root[i][j].n_entries)
+                {
+                  b++;
+                  su += smc_tree_root[i][j].n_entries;
+                  en = MIN (en, smc_tree_root[i][j].n_entries);
+                  ex = MAX (ex, smc_tree_root[i][j].n_entries);
+                }
+              else if (smc_tree_root[i][j].entries)
+                o++; /* formerly used, now empty */
+          }
+      en = b ? en : 0;
+      tf = MAX (t, 1.0); /* max(1) to be a valid divisor */
+      bf = MAX (b, 1.0); /* max(1) to be a valid divisor */
+      fprintf (stderr, "GSlice: MemChecker: %u trunks, %u branches, %u old branches\n", t, b, o);
+      fprintf (stderr, "GSlice: MemChecker: %f branches per trunk, %.2f%% utilization\n",
+               b / tf,
+               100.0 - (SMC_BRANCH_COUNT - b / tf) / (0.01 * SMC_BRANCH_COUNT));
+      fprintf (stderr, "GSlice: MemChecker: %f entries per branch, %u minimum, %u maximum\n",
+               su / bf, en, ex);
+    }
+  else
+    fprintf (stderr, "GSlice: MemChecker: root=NULL\n");
+  g_mutex_unlock (smc_tree_mutex);
+  
+  /* sample statistics (beast + GSLice + 24h scripted core & GUI activity):
+   *  PID %CPU %MEM   VSZ  RSS      COMMAND
+   * 8887 30.3 45.8 456068 414856   beast-0.7.1 empty.bse
+   * $ cat /proc/8887/statm # total-program-size resident-set-size shared-pages text/code data/stack library dirty-pages
+   * 114017 103714 2354 344 0 108676 0
+   * $ cat /proc/8887/status 
+   * Name:   beast-0.7.1
+   * VmSize:   456068 kB
+   * VmLck:         0 kB
+   * VmRSS:    414856 kB
+   * VmData:   434620 kB
+   * VmStk:        84 kB
+   * VmExe:      1376 kB
+   * VmLib:     13036 kB
+   * VmPTE:       456 kB
+   * Threads:        3
+   * (gdb) print g_slice_debug_tree_statistics ()
+   * GSlice: MemChecker: 422 trunks, 213068 branches, 0 old branches
+   * GSlice: MemChecker: 504.900474 branches per trunk, 98.81% utilization
+   * GSlice: MemChecker: 4.965039 entries per branch, 1 minimum, 37 maximum
+   */
+}
+#endif /* G_ENABLE_DEBUG */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gslice.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gslice.h
new file mode 100644 (file)
index 0000000..962199e
--- /dev/null
@@ -0,0 +1,86 @@
+/* GLIB sliced memory - fast threaded memory chunk allocator
+ * Copyright (C) 2005 Tim Janik
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_SLICE_H__
+#define __G_SLICE_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+/* slices - fast allocation/release of small memory blocks
+ */
+gpointer g_slice_alloc                 (gsize         block_size) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1);
+gpointer g_slice_alloc0                (gsize         block_size) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1);
+gpointer g_slice_copy                   (gsize         block_size,
+                                         gconstpointer mem_block) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(1);
+void     g_slice_free1                 (gsize         block_size,
+                                        gpointer      mem_block);
+void     g_slice_free_chain_with_offset (gsize         block_size,
+                                        gpointer      mem_chain,
+                                        gsize         next_offset);
+#define  g_slice_new(type)      ((type*) g_slice_alloc (sizeof (type)))
+#define  g_slice_new0(type)     ((type*) g_slice_alloc0 (sizeof (type)))
+/* MemoryBlockType *
+ *       g_slice_dup                    (MemoryBlockType,
+ *                                      MemoryBlockType *mem_block);
+ *       g_slice_free                   (MemoryBlockType,
+ *                                      MemoryBlockType *mem_block);
+ *       g_slice_free_chain             (MemoryBlockType,
+ *                                       MemoryBlockType *first_chain_block,
+ *                                       memory_block_next_field);
+ * pseudo prototypes for the macro
+ * definitions following below.
+ */
+
+/* we go through extra hoops to ensure type safety */
+#define g_slice_dup(type, mem)                                  \
+  (1 ? (type*) g_slice_copy (sizeof (type), (mem))              \
+     : ((void) ((type*) 0 == (mem)), (type*) 0))
+#define g_slice_free(type, mem)                                do {    \
+  if (1) g_slice_free1 (sizeof (type), (mem));                 \
+  else   (void) ((type*) 0 == (mem));                          \
+} while (0)
+#define g_slice_free_chain(type, mem_chain, next)      do {    \
+  if (1) g_slice_free_chain_with_offset (sizeof (type),                \
+                 (mem_chain), G_STRUCT_OFFSET (type, next));   \
+  else   (void) ((type*) 0 == (mem_chain));                    \
+} while (0)
+
+
+/* --- internal debugging API --- */
+typedef enum {
+  G_SLICE_CONFIG_ALWAYS_MALLOC = 1,
+  G_SLICE_CONFIG_BYPASS_MAGAZINES,
+  G_SLICE_CONFIG_WORKING_SET_MSECS,
+  G_SLICE_CONFIG_COLOR_INCREMENT,
+  G_SLICE_CONFIG_CHUNK_SIZES,
+  G_SLICE_CONFIG_CONTENTION_COUNTER
+} GSliceConfig;
+void     g_slice_set_config       (GSliceConfig ckey, gint64 value);
+gint64   g_slice_get_config       (GSliceConfig ckey);
+gint64*  g_slice_get_config_state  (GSliceConfig ckey, gint64 address, guint *n_values);
+
+G_END_DECLS
+
+#endif /* __G_SLICE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gslist.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gslist.c
new file mode 100644 (file)
index 0000000..dfbd354
--- /dev/null
@@ -0,0 +1,1058 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "gslist.h"
+#include "gtestutils.h"
+
+/**
+ * SECTION: linked_lists_single
+ * @title: Singly-Linked Lists
+ * @short_description: linked lists containing integer values or
+ *                     pointers to data, limited to iterating over the
+ *                     list in one direction
+ *
+ * The #GSList structure and its associated functions provide a
+ * standard singly-linked list data structure.
+ *
+ * Each element in the list contains a piece of data, together with a
+ * pointer which links to the next element in the list. Using this
+ * pointer it is possible to move through the list in one direction
+ * only (unlike the <link
+ * linkend="glib-Doubly-Linked-lists">Doubly-Linked Lists</link> which
+ * allow movement in both directions).
+ *
+ * The data contained in each element can be either integer values, by
+ * using one of the <link linkend="glib-Type-Conversion-Macros">Type
+ * Conversion Macros</link>, or simply pointers to any type of data.
+ *
+ * List elements are allocated from the <link
+ * linkend="glib-Memory-Slices">slice allocator</link>, which is more
+ * efficient than allocating elements individually.
+ *
+ * Note that most of the #GSList functions expect to be passed a
+ * pointer to the first element in the list. The functions which insert
+ * elements return the new start of the list, which may have changed.
+ *
+ * There is no function to create a #GSList. %NULL is considered to be
+ * the empty list so you simply set a #GSList* to %NULL.
+ *
+ * To add elements, use g_slist_append(), g_slist_prepend(),
+ * g_slist_insert() and g_slist_insert_sorted().
+ *
+ * To remove elements, use g_slist_remove().
+ *
+ * To find elements in the list use g_slist_last(), g_slist_next(),
+ * g_slist_nth(), g_slist_nth_data(), g_slist_find() and
+ * g_slist_find_custom().
+ *
+ * To find the index of an element use g_slist_position() and
+ * g_slist_index().
+ *
+ * To call a function for each element in the list use
+ * g_slist_foreach().
+ *
+ * To free the entire list, use g_slist_free().
+ **/
+
+/**
+ * GSList:
+ * @data: holds the element's data, which can be a pointer to any kind
+ *        of data, or any integer value using the <link
+ *        linkend="glib-Type-Conversion-Macros">Type Conversion
+ *        Macros</link>.
+ * @next: contains the link to the next element in the list.
+ *
+ * The #GSList struct is used for each element in the singly-linked
+ * list.
+ **/
+
+/**
+ * g_slist_next:
+ * @slist: an element in a #GSList.
+ * @Returns: the next element, or %NULL if there are no more elements.
+ *
+ * A convenience macro to get the next element in a #GSList.
+ **/
+
+
+/**
+ * g_slist_push_allocator:
+ * @dummy: the #GAllocator to use when allocating #GSList elements.
+ *
+ * Sets the allocator to use to allocate #GSList elements. Use
+ * g_slist_pop_allocator() to restore the previous allocator.
+ *
+ * Note that this function is not available if GLib has been compiled
+ * with <option>--disable-mem-pools</option>
+ *
+ * Deprecated: 2.10: It does nothing, since #GSList has been converted
+ *                   to the <link linkend="glib-Memory-Slices">slice
+ *                   allocator</link>
+ **/
+void g_slist_push_allocator (gpointer dummy) { /* present for binary compat only */ }
+
+/**
+ * g_slist_pop_allocator:
+ *
+ * Restores the previous #GAllocator, used when allocating #GSList
+ * elements.
+ *
+ * Note that this function is not available if GLib has been compiled
+ * with <option>--disable-mem-pools</option>
+ *
+ * Deprecated: 2.10: It does nothing, since #GSList has been converted
+ *                   to the <link linkend="glib-Memory-Slices">slice
+ *                   allocator</link>
+ **/
+void g_slist_pop_allocator  (void)           { /* present for binary compat only */ }
+
+#define _g_slist_alloc0()       g_slice_new0 (GSList)
+#define _g_slist_alloc()        g_slice_new (GSList)
+#define _g_slist_free1(slist)   g_slice_free (GSList, slist)
+
+/**
+ * g_slist_alloc:
+ * @Returns: a pointer to the newly-allocated #GSList element.
+ *
+ * Allocates space for one #GSList element. It is called by the
+ * g_slist_append(), g_slist_prepend(), g_slist_insert() and
+ * g_slist_insert_sorted() functions and so is rarely used on its own.
+ **/
+GSList*
+g_slist_alloc (void)
+{
+  return _g_slist_alloc0 ();
+}
+
+/**
+ * g_slist_free:
+ * @list: a #GSList
+ *
+ * Frees all of the memory used by a #GSList.
+ * The freed elements are returned to the slice allocator.
+ */
+void
+g_slist_free (GSList *list)
+{
+  g_slice_free_chain (GSList, list, next);
+}
+
+/**
+ * g_slist_free_1:
+ * @list: a #GSList element
+ *
+ * Frees one #GSList element.
+ * It is usually used after g_slist_remove_link().
+ */
+/**
+ * g_slist_free1:
+ *
+ * A macro which does the same as g_slist_free_1().
+ *
+ * Since: 2.10
+ **/
+void
+g_slist_free_1 (GSList *list)
+{
+  _g_slist_free1 (list);
+}
+
+/**
+ * g_slist_append:
+ * @list: a #GSList
+ * @data: the data for the new element
+ *
+ * Adds a new element on to the end of the list.
+ *
+ * <note><para>
+ * The return value is the new start of the list, which may
+ * have changed, so make sure you store the new value.
+ * </para></note>
+ *
+ * <note><para>
+ * Note that g_slist_append() has to traverse the entire list
+ * to find the end, which is inefficient when adding multiple
+ * elements. A common idiom to avoid the inefficiency is to prepend
+ * the elements and reverse the list when all elements have been added.
+ * </para></note>
+ *
+ * |[
+ * /&ast; Notice that these are initialized to the empty list. &ast;/
+ * GSList *list = NULL, *number_list = NULL;
+ *
+ * /&ast; This is a list of strings. &ast;/
+ * list = g_slist_append (list, "first");
+ * list = g_slist_append (list, "second");
+ *
+ * /&ast; This is a list of integers. &ast;/
+ * number_list = g_slist_append (number_list, GINT_TO_POINTER (27));
+ * number_list = g_slist_append (number_list, GINT_TO_POINTER (14));
+ * ]|
+ *
+ * Returns: the new start of the #GSList
+ */
+GSList*
+g_slist_append (GSList   *list,
+                gpointer  data)
+{
+  GSList *new_list;
+  GSList *last;
+
+  new_list = _g_slist_alloc ();
+  new_list->data = data;
+  new_list->next = NULL;
+
+  if (list)
+    {
+      last = g_slist_last (list);
+      /* g_assert (last != NULL); */
+      last->next = new_list;
+
+      return list;
+    }
+  else
+    return new_list;
+}
+
+/**
+ * g_slist_prepend:
+ * @list: a #GSList
+ * @data: the data for the new element
+ *
+ * Adds a new element on to the start of the list.
+ *
+ * <note><para>
+ * The return value is the new start of the list, which
+ * may have changed, so make sure you store the new value.
+ * </para></note>
+ *
+ * |[
+ * /&ast; Notice that it is initialized to the empty list. &ast;/
+ * GSList *list = NULL;
+ * list = g_slist_prepend (list, "last");
+ * list = g_slist_prepend (list, "first");
+ * ]|
+ *
+ * Returns: the new start of the #GSList
+ */
+GSList*
+g_slist_prepend (GSList   *list,
+                 gpointer  data)
+{
+  GSList *new_list;
+
+  new_list = _g_slist_alloc ();
+  new_list->data = data;
+  new_list->next = list;
+
+  return new_list;
+}
+
+/**
+ * g_slist_insert:
+ * @list: a #GSList
+ * @data: the data for the new element
+ * @position: the position to insert the element.
+ *     If this is negative, or is larger than the number
+ *     of elements in the list, the new element is added on
+ *     to the end of the list.
+ *
+ * Inserts a new element into the list at the given position.
+ *
+ * Returns: the new start of the #GSList
+ */
+GSList*
+g_slist_insert (GSList   *list,
+                gpointer  data,
+                gint      position)
+{
+  GSList *prev_list;
+  GSList *tmp_list;
+  GSList *new_list;
+
+  if (position < 0)
+    return g_slist_append (list, data);
+  else if (position == 0)
+    return g_slist_prepend (list, data);
+
+  new_list = _g_slist_alloc ();
+  new_list->data = data;
+
+  if (!list)
+    {
+      new_list->next = NULL;
+      return new_list;
+    }
+
+  prev_list = NULL;
+  tmp_list = list;
+
+  while ((position-- > 0) && tmp_list)
+    {
+      prev_list = tmp_list;
+      tmp_list = tmp_list->next;
+    }
+
+  if (prev_list)
+    {
+      new_list->next = prev_list->next;
+      prev_list->next = new_list;
+    }
+  else
+    {
+      new_list->next = list;
+      list = new_list;
+    }
+
+  return list;
+}
+
+/**
+ * g_slist_insert_before:
+ * @slist: a #GSList
+ * @sibling: node to insert @data before
+ * @data: data to put in the newly-inserted node
+ *
+ * Inserts a node before @sibling containing @data.
+ *
+ * Returns: the new head of the list.
+ */
+GSList*
+g_slist_insert_before (GSList  *slist,
+                       GSList  *sibling,
+                       gpointer data)
+{
+  if (!slist)
+    {
+      slist = _g_slist_alloc ();
+      slist->data = data;
+      slist->next = NULL;
+      g_return_val_if_fail (sibling == NULL, slist);
+      return slist;
+    }
+  else
+    {
+      GSList *node, *last = NULL;
+
+      for (node = slist; node; last = node, node = last->next)
+        if (node == sibling)
+          break;
+      if (!last)
+        {
+          node = _g_slist_alloc ();
+          node->data = data;
+          node->next = slist;
+
+          return node;
+        }
+      else
+        {
+          node = _g_slist_alloc ();
+          node->data = data;
+          node->next = last->next;
+          last->next = node;
+
+          return slist;
+        }
+    }
+}
+
+/**
+ * g_slist_concat:
+ * @list1: a #GSList
+ * @list2: the #GSList to add to the end of the first #GSList
+ *
+ * Adds the second #GSList onto the end of the first #GSList.
+ * Note that the elements of the second #GSList are not copied.
+ * They are used directly.
+ *
+ * Returns: the start of the new #GSList
+ */
+GSList *
+g_slist_concat (GSList *list1, GSList *list2)
+{
+  if (list2)
+    {
+      if (list1)
+        g_slist_last (list1)->next = list2;
+      else
+        list1 = list2;
+    }
+
+  return list1;
+}
+
+/**
+ * g_slist_remove:
+ * @list: a #GSList
+ * @data: the data of the element to remove
+ *
+ * Removes an element from a #GSList.
+ * If two elements contain the same data, only the first is removed.
+ * If none of the elements contain the data, the #GSList is unchanged.
+ *
+ * Returns: the new start of the #GSList
+ */
+GSList*
+g_slist_remove (GSList        *list,
+                gconstpointer  data)
+{
+  GSList *tmp, *prev = NULL;
+
+  tmp = list;
+  while (tmp)
+    {
+      if (tmp->data == data)
+        {
+          if (prev)
+            prev->next = tmp->next;
+          else
+            list = tmp->next;
+
+          g_slist_free_1 (tmp);
+          break;
+        }
+      prev = tmp;
+      tmp = prev->next;
+    }
+
+  return list;
+}
+
+/**
+ * g_slist_remove_all:
+ * @list: a #GSList
+ * @data: data to remove
+ *
+ * Removes all list nodes with data equal to @data.
+ * Returns the new head of the list. Contrast with
+ * g_slist_remove() which removes only the first node
+ * matching the given data.
+ *
+ * Returns: new head of @list
+ */
+GSList*
+g_slist_remove_all (GSList        *list,
+                    gconstpointer  data)
+{
+  GSList *tmp, *prev = NULL;
+
+  tmp = list;
+  while (tmp)
+    {
+      if (tmp->data == data)
+        {
+          GSList *next = tmp->next;
+
+          if (prev)
+            prev->next = next;
+          else
+            list = next;
+
+          g_slist_free_1 (tmp);
+          tmp = next;
+        }
+      else
+        {
+          prev = tmp;
+          tmp = prev->next;
+        }
+    }
+
+  return list;
+}
+
+static inline GSList*
+_g_slist_remove_link (GSList *list,
+                      GSList *link)
+{
+  GSList *tmp;
+  GSList *prev;
+
+  prev = NULL;
+  tmp = list;
+
+  while (tmp)
+    {
+      if (tmp == link)
+        {
+          if (prev)
+            prev->next = tmp->next;
+          if (list == tmp)
+            list = list->next;
+
+          tmp->next = NULL;
+          break;
+        }
+
+      prev = tmp;
+      tmp = tmp->next;
+    }
+
+  return list;
+}
+
+/**
+ * g_slist_remove_link:
+ * @list: a #GSList
+ * @link_: an element in the #GSList
+ *
+ * Removes an element from a #GSList, without
+ * freeing the element. The removed element's next
+ * link is set to %NULL, so that it becomes a
+ * self-contained list with one element.
+ *
+ * Returns: the new start of the #GSList, without the element
+ */
+GSList*
+g_slist_remove_link (GSList *list,
+                     GSList *link_)
+{
+  return _g_slist_remove_link (list, link_);
+}
+
+/**
+ * g_slist_delete_link:
+ * @list: a #GSList
+ * @link_: node to delete
+ *
+ * Removes the node link_ from the list and frees it.
+ * Compare this to g_slist_remove_link() which removes the node
+ * without freeing it.
+ *
+ * Returns: the new head of @list
+ */
+GSList*
+g_slist_delete_link (GSList *list,
+                     GSList *link_)
+{
+  list = _g_slist_remove_link (list, link_);
+  _g_slist_free1 (link_);
+
+  return list;
+}
+
+/**
+ * g_slist_copy:
+ * @list: a #GSList
+ *
+ * Copies a #GSList.
+ *
+ * <note><para>
+ * Note that this is a "shallow" copy. If the list elements
+ * consist of pointers to data, the pointers are copied but
+ * the actual data isn't.
+ * </para></note>
+ *
+ * Returns: a copy of @list
+ */
+GSList*
+g_slist_copy (GSList *list)
+{
+  GSList *new_list = NULL;
+
+  if (list)
+    {
+      GSList *last;
+
+      new_list = _g_slist_alloc ();
+      new_list->data = list->data;
+      last = new_list;
+      list = list->next;
+      while (list)
+        {
+          last->next = _g_slist_alloc ();
+          last = last->next;
+          last->data = list->data;
+          list = list->next;
+        }
+      last->next = NULL;
+    }
+
+  return new_list;
+}
+
+/**
+ * g_slist_reverse:
+ * @list: a #GSList
+ *
+ * Reverses a #GSList.
+ *
+ * Returns: the start of the reversed #GSList
+ */
+GSList*
+g_slist_reverse (GSList *list)
+{
+  GSList *prev = NULL;
+
+  while (list)
+    {
+      GSList *next = list->next;
+
+      list->next = prev;
+
+      prev = list;
+      list = next;
+    }
+
+  return prev;
+}
+
+/**
+ * g_slist_nth:
+ * @list: a #GSList
+ * @n: the position of the element, counting from 0
+ *
+ * Gets the element at the given position in a #GSList.
+ *
+ * Returns: the element, or %NULL if the position is off
+ *     the end of the #GSList
+ */
+GSList*
+g_slist_nth (GSList *list,
+             guint   n)
+{
+  while (n-- > 0 && list)
+    list = list->next;
+
+  return list;
+}
+
+/**
+ * g_slist_nth_data:
+ * @list: a #GSList
+ * @n: the position of the element
+ *
+ * Gets the data of the element at the given position.
+ *
+ * Returns: the element's data, or %NULL if the position
+ *     is off the end of the #GSList
+ */
+gpointer
+g_slist_nth_data (GSList   *list,
+                  guint     n)
+{
+  while (n-- > 0 && list)
+    list = list->next;
+
+  return list ? list->data : NULL;
+}
+
+/**
+ * g_slist_find:
+ * @list: a #GSList
+ * @data: the element data to find
+ *
+ * Finds the element in a #GSList which
+ * contains the given data.
+ *
+ * Returns: the found #GSList element,
+ *     or %NULL if it is not found
+ */
+GSList*
+g_slist_find (GSList        *list,
+              gconstpointer  data)
+{
+  while (list)
+    {
+      if (list->data == data)
+        break;
+      list = list->next;
+    }
+
+  return list;
+}
+
+
+/**
+ * g_slist_find_custom:
+ * @list: a #GSList
+ * @data: user data passed to the function
+ * @func: the function to call for each element.
+ *     It should return 0 when the desired element is found
+ *
+ * Finds an element in a #GSList, using a supplied function to
+ * find the desired element. It iterates over the list, calling
+ * the given function which should return 0 when the desired
+ * element is found. The function takes two #gconstpointer arguments,
+ * the #GSList element's data as the first argument and the
+ * given user data.
+ *
+ * Returns: the found #GSList element, or %NULL if it is not found
+ */
+GSList*
+g_slist_find_custom (GSList        *list,
+                     gconstpointer  data,
+                     GCompareFunc   func)
+{
+  g_return_val_if_fail (func != NULL, list);
+
+  while (list)
+    {
+      if (! func (list->data, data))
+        return list;
+      list = list->next;
+    }
+
+  return NULL;
+}
+
+/**
+ * g_slist_position:
+ * @list: a #GSList
+ * @llink: an element in the #GSList
+ *
+ * Gets the position of the given element
+ * in the #GSList (starting from 0).
+ *
+ * Returns: the position of the element in the #GSList,
+ *     or -1 if the element is not found
+ */
+gint
+g_slist_position (GSList *list,
+                  GSList *llink)
+{
+  gint i;
+
+  i = 0;
+  while (list)
+    {
+      if (list == llink)
+        return i;
+      i++;
+      list = list->next;
+    }
+
+  return -1;
+}
+
+/**
+ * g_slist_index:
+ * @list: a #GSList
+ * @data: the data to find
+ *
+ * Gets the position of the element containing
+ * the given data (starting from 0).
+ *
+ * Returns: the index of the element containing the data,
+ *     or -1 if the data is not found
+ */
+gint
+g_slist_index (GSList        *list,
+               gconstpointer  data)
+{
+  gint i;
+
+  i = 0;
+  while (list)
+    {
+      if (list->data == data)
+        return i;
+      i++;
+      list = list->next;
+    }
+
+  return -1;
+}
+
+/**
+ * g_slist_last:
+ * @list: a #GSList
+ *
+ * Gets the last element in a #GSList.
+ *
+ * <note><para>
+ * This function iterates over the whole list.
+ * </para></note>
+ *
+ * Returns: the last element in the #GSList,
+ *     or %NULL if the #GSList has no elements
+ */
+GSList*
+g_slist_last (GSList *list)
+{
+  if (list)
+    {
+      while (list->next)
+        list = list->next;
+    }
+
+  return list;
+}
+
+/**
+ * g_slist_length:
+ * @list: a #GSList
+ *
+ * Gets the number of elements in a #GSList.
+ *
+ * <note><para>
+ * This function iterates over the whole list to
+ * count its elements.
+ * </para></note>
+ *
+ * Returns: the number of elements in the #GSList
+ */
+guint
+g_slist_length (GSList *list)
+{
+  guint length;
+
+  length = 0;
+  while (list)
+    {
+      length++;
+      list = list->next;
+    }
+
+  return length;
+}
+
+/**
+ * g_slist_foreach:
+ * @list: a #GSList
+ * @func: the function to call with each element's data
+ * @user_data: user data to pass to the function
+ *
+ * Calls a function for each element of a #GSList.
+ */
+void
+g_slist_foreach (GSList   *list,
+                 GFunc     func,
+                 gpointer  user_data)
+{
+  while (list)
+    {
+      GSList *next = list->next;
+      (*func) (list->data, user_data);
+      list = next;
+    }
+}
+
+static GSList*
+g_slist_insert_sorted_real (GSList   *list,
+                            gpointer  data,
+                            GFunc     func,
+                            gpointer  user_data)
+{
+  GSList *tmp_list = list;
+  GSList *prev_list = NULL;
+  GSList *new_list;
+  gint cmp;
+
+  g_return_val_if_fail (func != NULL, list);
+
+  if (!list)
+    {
+      new_list = _g_slist_alloc ();
+      new_list->data = data;
+      new_list->next = NULL;
+      return new_list;
+    }
+
+  cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
+
+  while ((tmp_list->next) && (cmp > 0))
+    {
+      prev_list = tmp_list;
+      tmp_list = tmp_list->next;
+
+      cmp = ((GCompareDataFunc) func) (data, tmp_list->data, user_data);
+    }
+
+  new_list = _g_slist_alloc ();
+  new_list->data = data;
+
+  if ((!tmp_list->next) && (cmp > 0))
+    {
+      tmp_list->next = new_list;
+      new_list->next = NULL;
+      return list;
+    }
+
+  if (prev_list)
+    {
+      prev_list->next = new_list;
+      new_list->next = tmp_list;
+      return list;
+    }
+  else
+    {
+      new_list->next = list;
+      return new_list;
+    }
+}
+
+/**
+ * g_slist_insert_sorted:
+ * @list: a #GSList
+ * @data: the data for the new element
+ * @func: the function to compare elements in the list.
+ *     It should return a number > 0 if the first parameter
+ *     comes after the second parameter in the sort order.
+ *
+ * Inserts a new element into the list, using the given
+ * comparison function to determine its position.
+ *
+ * Returns: the new start of the #GSList
+ */
+GSList*
+g_slist_insert_sorted (GSList       *list,
+                       gpointer      data,
+                       GCompareFunc  func)
+{
+  return g_slist_insert_sorted_real (list, data, (GFunc) func, NULL);
+}
+
+/**
+ * g_slist_insert_sorted_with_data:
+ * @list: a #GSList
+ * @data: the data for the new element
+ * @func: the function to compare elements in the list.
+ *     It should return a number > 0 if the first parameter
+ *     comes after the second parameter in the sort order.
+ * @user_data: data to pass to comparison function
+ *
+ * Inserts a new element into the list, using the given
+ * comparison function to determine its position.
+ *
+ * Returns: the new start of the #GSList
+ *
+ * Since: 2.10
+ */
+GSList*
+g_slist_insert_sorted_with_data (GSList           *list,
+                                 gpointer          data,
+                                 GCompareDataFunc  func,
+                                 gpointer          user_data)
+{
+  return g_slist_insert_sorted_real (list, data, (GFunc) func, user_data);
+}
+
+static GSList *
+g_slist_sort_merge (GSList   *l1,
+                    GSList   *l2,
+                    GFunc     compare_func,
+                    gpointer  user_data)
+{
+  GSList list, *l;
+  gint cmp;
+
+  l=&list;
+
+  while (l1 && l2)
+    {
+      cmp = ((GCompareDataFunc) compare_func) (l1->data, l2->data, user_data);
+
+      if (cmp <= 0)
+        {
+          l=l->next=l1;
+          l1=l1->next;
+        }
+      else
+        {
+          l=l->next=l2;
+          l2=l2->next;
+        }
+    }
+  l->next= l1 ? l1 : l2;
+
+  return list.next;
+}
+
+static GSList *
+g_slist_sort_real (GSList   *list,
+                   GFunc     compare_func,
+                   gpointer  user_data)
+{
+  GSList *l1, *l2;
+
+  if (!list)
+    return NULL;
+  if (!list->next)
+    return list;
+
+  l1 = list;
+  l2 = list->next;
+
+  while ((l2 = l2->next) != NULL)
+    {
+      if ((l2 = l2->next) == NULL)
+        break;
+      l1=l1->next;
+    }
+  l2 = l1->next;
+  l1->next = NULL;
+
+  return g_slist_sort_merge (g_slist_sort_real (list, compare_func, user_data),
+                             g_slist_sort_real (l2, compare_func, user_data),
+                             compare_func,
+                             user_data);
+}
+
+/**
+ * g_slist_sort:
+ * @list: a #GSList
+ * @compare_func: the comparison function used to sort the #GSList.
+ *     This function is passed the data from 2 elements of the #GSList
+ *     and should return 0 if they are equal, a negative value if the
+ *     first element comes before the second, or a positive value if
+ *     the first element comes after the second.
+ *
+ * Sorts a #GSList using the given comparison function.
+ *
+ * Returns: the start of the sorted #GSList
+ */
+GSList *
+g_slist_sort (GSList       *list,
+              GCompareFunc  compare_func)
+{
+  return g_slist_sort_real (list, (GFunc) compare_func, NULL);
+}
+
+/**
+ * g_slist_sort_with_data:
+ * @list: a #GSList
+ * @compare_func: comparison function
+ * @user_data: data to pass to comparison function
+ *
+ * Like g_slist_sort(), but the sort function accepts a user data argument.
+ *
+ * Returns: new head of the list
+ */
+GSList *
+g_slist_sort_with_data (GSList           *list,
+                        GCompareDataFunc  compare_func,
+                        gpointer          user_data)
+{
+  return g_slist_sort_real (list, (GFunc) compare_func, user_data);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gslist.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gslist.h
new file mode 100644 (file)
index 0000000..8b01faf
--- /dev/null
@@ -0,0 +1,114 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_SLIST_H__
+#define __G_SLIST_H__
+
+#include <glib/gmem.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GSList GSList;
+
+struct _GSList
+{
+  gpointer data;
+  GSList *next;
+};
+
+/* Singly linked lists
+ */
+GSList*  g_slist_alloc                   (void) G_GNUC_WARN_UNUSED_RESULT;
+void     g_slist_free                    (GSList           *list);
+void     g_slist_free_1                  (GSList           *list);
+#define         g_slist_free1                   g_slist_free_1
+GSList*  g_slist_append                  (GSList           *list,
+                                         gpointer          data) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_prepend                 (GSList           *list,
+                                         gpointer          data) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_insert                  (GSList           *list,
+                                         gpointer          data,
+                                         gint              position) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_insert_sorted           (GSList           *list,
+                                         gpointer          data,
+                                         GCompareFunc      func) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_insert_sorted_with_data (GSList           *list,
+                                         gpointer          data,
+                                         GCompareDataFunc  func,
+                                         gpointer          user_data) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_insert_before           (GSList           *slist,
+                                         GSList           *sibling,
+                                         gpointer          data) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_concat                  (GSList           *list1,
+                                         GSList           *list2) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_remove                  (GSList           *list,
+                                         gconstpointer     data) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_remove_all              (GSList           *list,
+                                         gconstpointer     data) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_remove_link             (GSList           *list,
+                                         GSList           *link_) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_delete_link             (GSList           *list,
+                                         GSList           *link_) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_reverse                 (GSList           *list) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_copy                    (GSList           *list) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_nth                     (GSList           *list,
+                                         guint             n);
+GSList*  g_slist_find                    (GSList           *list,
+                                         gconstpointer     data);
+GSList*  g_slist_find_custom             (GSList           *list,
+                                         gconstpointer     data,
+                                         GCompareFunc      func);
+gint     g_slist_position                (GSList           *list,
+                                         GSList           *llink);
+gint     g_slist_index                   (GSList           *list,
+                                         gconstpointer     data);
+GSList*  g_slist_last                    (GSList           *list);
+guint    g_slist_length                  (GSList           *list);
+void     g_slist_foreach                 (GSList           *list,
+                                         GFunc             func,
+                                         gpointer          user_data);
+GSList*  g_slist_sort                    (GSList           *list,
+                                         GCompareFunc      compare_func) G_GNUC_WARN_UNUSED_RESULT;
+GSList*  g_slist_sort_with_data          (GSList           *list,
+                                         GCompareDataFunc  compare_func,
+                                         gpointer          user_data) G_GNUC_WARN_UNUSED_RESULT;
+gpointer g_slist_nth_data                (GSList           *list,
+                                         guint             n);
+
+#define  g_slist_next(slist)            ((slist) ? (((GSList *)(slist))->next) : NULL)
+
+#ifndef G_DISABLE_DEPRECATED
+void     g_slist_push_allocator          (gpointer        dummy);
+void     g_slist_pop_allocator           (void);
+#endif
+
+G_END_DECLS
+
+#endif /* __G_SLIST_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gspawn-win32-helper.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gspawn-win32-helper.c
new file mode 100644 (file)
index 0000000..40108bb
--- /dev/null
@@ -0,0 +1,333 @@
+/* gspawn-win32-helper.c - Helper program for process launching on Win32.
+ *
+ *  Copyright 2000 Red Hat, Inc.
+ *  Copyright 2000 Tor Lillqvist
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not, write
+ * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <fcntl.h>
+
+#undef G_LOG_DOMAIN
+#include "glib.h"
+#define GSPAWN_HELPER
+#include "gspawn-win32.c"      /* For shared definitions */
+
+
+static void
+write_err_and_exit (gint    fd,
+                   gintptr msg)
+{
+  gintptr en = errno;
+  
+  write (fd, &msg, sizeof(gintptr));
+  write (fd, &en, sizeof(gintptr));
+  
+  _exit (1);
+}
+
+#ifdef __GNUC__
+#  ifndef _stdcall
+#    define _stdcall  __attribute__((stdcall))
+#  endif
+#endif
+
+/* We build gspawn-win32-helper.exe as a Windows GUI application
+ * to avoid any temporarily flashing console windows in case
+ * the gspawn function is invoked by a GUI program. Thus, no main()
+ * but a WinMain(). We do, however, still use argc and argv tucked
+ * away in the global __argc and __argv by the C runtime startup code.
+ */
+
+/* Info peeked from mingw runtime's source code. __wgetmainargs() is a
+ * function to get the program's argv in wide char format.
+ */
+
+typedef struct {
+  int newmode;
+} _startupinfo;
+
+extern void __wgetmainargs(int *argc,
+                          wchar_t ***wargv,
+                          wchar_t ***wenviron,
+                          int expand_wildcards,
+                          _startupinfo *startupinfo);
+
+/* Copy of protect_argv that handles wchar_t strings */
+
+static gint
+protect_wargv (wchar_t  **wargv,
+              wchar_t ***new_wargv)
+{
+  gint i;
+  gint argc = 0;
+  
+  while (wargv[argc])
+    ++argc;
+  *new_wargv = g_new (wchar_t *, argc+1);
+
+  /* Quote each argv element if necessary, so that it will get
+   * reconstructed correctly in the C runtime startup code.  Note that
+   * the unquoting algorithm in the C runtime is really weird, and
+   * rather different than what Unix shells do. See stdargv.c in the C
+   * runtime sources (in the Platform SDK, in src/crt).
+   *
+   * Note that an new_wargv[0] constructed by this function should
+   * *not* be passed as the filename argument to a _wspawn* or _wexec*
+   * family function. That argument should be the real file name
+   * without any quoting.
+   */
+  for (i = 0; i < argc; i++)
+    {
+      wchar_t *p = wargv[i];
+      wchar_t *q;
+      gint len = 0;
+      gboolean need_dblquotes = FALSE;
+      while (*p)
+       {
+         if (*p == ' ' || *p == '\t')
+           need_dblquotes = TRUE;
+         else if (*p == '"')
+           len++;
+         else if (*p == '\\')
+           {
+             wchar_t *pp = p;
+             while (*pp && *pp == '\\')
+               pp++;
+             if (*pp == '"')
+               len++;
+           }
+         len++;
+         p++;
+       }
+
+      q = (*new_wargv)[i] = g_new (wchar_t, len + need_dblquotes*2 + 1);
+      p = wargv[i];
+
+      if (need_dblquotes)
+       *q++ = '"';
+
+      while (*p)
+       {
+         if (*p == '"')
+           *q++ = '\\';
+         else if (*p == '\\')
+           {
+             wchar_t *pp = p;
+             while (*pp && *pp == '\\')
+               pp++;
+             if (*pp == '"')
+               *q++ = '\\';
+           }
+         *q++ = *p;
+         p++;
+       }
+
+      if (need_dblquotes)
+       *q++ = '"';
+      *q++ = '\0';
+    }
+  (*new_wargv)[argc] = NULL;
+
+  return argc;
+}
+
+#ifndef HELPER_CONSOLE
+int _stdcall
+WinMain (struct HINSTANCE__ *hInstance,
+        struct HINSTANCE__ *hPrevInstance,
+        char               *lpszCmdLine,
+        int                 nCmdShow)
+#else
+int
+main (int ignored_argc, char **ignored_argv)
+#endif
+{
+  int child_err_report_fd = -1;
+  int helper_sync_fd = -1;
+  int i;
+  int fd;
+  int mode;
+  gintptr handle;
+  int saved_errno;
+  gintptr no_error = CHILD_NO_ERROR;
+  gint argv_zero_offset = ARG_PROGRAM;
+  wchar_t **new_wargv;
+  int argc;
+  wchar_t **wargv, **wenvp;
+  _startupinfo si = { 0 };
+  char c;
+
+  g_assert (__argc >= ARG_COUNT);
+
+  /* Fetch the wide-char argument vector */
+  __wgetmainargs (&argc, &wargv, &wenvp, 0, &si);
+
+  /* We still have the system codepage args in __argv. We can look
+   * at the first args in which gspawn-win32.c passes us flags and
+   * fd numbers in __argv, as we know those are just ASCII anyway.
+   */
+  g_assert (argc == __argc);
+
+  /* argv[ARG_CHILD_ERR_REPORT] is the file descriptor number onto
+   * which write error messages.
+   */
+  child_err_report_fd = atoi (__argv[ARG_CHILD_ERR_REPORT]);
+
+  /* Hack to implement G_SPAWN_FILE_AND_ARGV_ZERO. If
+   * argv[ARG_CHILD_ERR_REPORT] is suffixed with a '#' it means we get
+   * the program to run and its argv[0] separately.
+   */
+  if (__argv[ARG_CHILD_ERR_REPORT][strlen (__argv[ARG_CHILD_ERR_REPORT]) - 1] == '#')
+    argv_zero_offset++;
+
+  /* argv[ARG_HELPER_SYNC] is the file descriptor number we read a
+   * byte that tells us it is OK to exit. We have to wait until the
+   * parent allows us to exit, so that the parent has had time to
+   * duplicate the process handle we sent it. Duplicating a handle
+   * from another process works only if that other process exists.
+   */
+  helper_sync_fd = atoi (__argv[ARG_HELPER_SYNC]);
+
+  /* argv[ARG_STDIN..ARG_STDERR] are the file descriptor numbers that
+   * should be dup2'd to 0, 1 and 2. '-' if the corresponding fd
+   * should be left alone, and 'z' if it should be connected to the
+   * bit bucket NUL:.
+   */
+  if (__argv[ARG_STDIN][0] == '-')
+    ; /* Nothing */
+  else if (__argv[ARG_STDIN][0] == 'z')
+    {
+      fd = open ("NUL:", O_RDONLY);
+      if (fd != 0)
+       {
+         dup2 (fd, 0);
+         close (fd);
+       }
+    }
+  else
+    {
+      fd = atoi (__argv[ARG_STDIN]);
+      if (fd != 0)
+       {
+         dup2 (fd, 0);
+         close (fd);
+       }
+    }
+
+  if (__argv[ARG_STDOUT][0] == '-')
+    ; /* Nothing */
+  else if (__argv[ARG_STDOUT][0] == 'z')
+    {
+      fd = open ("NUL:", O_WRONLY);
+      if (fd != 1)
+       {
+         dup2 (fd, 1);
+         close (fd);
+       }
+    }
+  else
+    {
+      fd = atoi (__argv[ARG_STDOUT]);
+      if (fd != 1)
+       {
+         dup2 (fd, 1);
+         close (fd);
+       }
+    }
+
+  if (__argv[ARG_STDERR][0] == '-')
+    ; /* Nothing */
+  else if (__argv[ARG_STDERR][0] == 'z')
+    {
+      fd = open ("NUL:", O_WRONLY);
+      if (fd != 2)
+       {
+         dup2 (fd, 2);
+         close (fd);
+       }
+    }
+  else
+    {
+      fd = atoi (__argv[ARG_STDERR]);
+      if (fd != 2)
+       {
+         dup2 (fd, 2);
+         close (fd);
+       }
+    }
+
+  /* __argv[ARG_WORKING_DIRECTORY] is the directory in which to run the
+   * process.  If "-", don't change directory.
+   */
+  if (__argv[ARG_WORKING_DIRECTORY][0] == '-' &&
+      __argv[ARG_WORKING_DIRECTORY][1] == 0)
+    ; /* Nothing */
+  else if (_wchdir (wargv[ARG_WORKING_DIRECTORY]) < 0)
+    write_err_and_exit (child_err_report_fd, CHILD_CHDIR_FAILED);
+
+  /* __argv[ARG_CLOSE_DESCRIPTORS] is "y" if file descriptors from 3
+   *  upwards should be closed
+   */
+  if (__argv[ARG_CLOSE_DESCRIPTORS][0] == 'y')
+    for (i = 3; i < 1000; i++) /* FIXME real limit? */
+      if (i != child_err_report_fd && i != helper_sync_fd)
+       close (i);
+
+  /* We don't want our child to inherit the error report and
+   * helper sync fds.
+   */
+  child_err_report_fd = dup_noninherited (child_err_report_fd, _O_WRONLY);
+  helper_sync_fd = dup_noninherited (helper_sync_fd, _O_RDONLY);
+
+  /* __argv[ARG_WAIT] is "w" to wait for the program to exit */
+  if (__argv[ARG_WAIT][0] == 'w')
+    mode = P_WAIT;
+  else
+    mode = P_NOWAIT;
+
+  /* __argv[ARG_USE_PATH] is "y" to use PATH, otherwise not */
+
+  /* __argv[ARG_PROGRAM] is executable file to run,
+   * __argv[argv_zero_offset]... is its argv. argv_zero_offset equals
+   * ARG_PROGRAM unless G_SPAWN_FILE_AND_ARGV_ZERO was used, in which
+   * case we have a separate executable name and argv[0].
+   */
+
+  /* For the program name passed to spawnv(), don't use the quoted
+   * version.
+   */
+  protect_wargv (wargv + argv_zero_offset, &new_wargv);
+
+  if (__argv[ARG_USE_PATH][0] == 'y')
+    handle = _wspawnvp (mode, wargv[ARG_PROGRAM], (const wchar_t **) new_wargv);
+  else
+    handle = _wspawnv (mode, wargv[ARG_PROGRAM], (const wchar_t **) new_wargv);
+
+  saved_errno = errno;
+
+  if (handle == -1 && saved_errno != 0)
+    write_err_and_exit (child_err_report_fd, CHILD_SPAWN_FAILED);
+
+  write (child_err_report_fd, &no_error, sizeof (no_error));
+  write (child_err_report_fd, &handle, sizeof (handle));
+
+  read (helper_sync_fd, &c, 1);
+
+  return 0;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gspawn-win32.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gspawn-win32.c
new file mode 100644 (file)
index 0000000..44ae907
--- /dev/null
@@ -0,0 +1,1493 @@
+/* gspawn-win32.c - Process launching on Win32
+ *
+ *  Copyright 2000 Red Hat, Inc.
+ *  Copyright 2003 Tor Lillqvist
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not, write
+ * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Implementation details on Win32.
+ *
+ * - There is no way to set the no-inherit flag for
+ *   a "file descriptor" in the MS C runtime. The flag is there,
+ *   and the dospawn() function uses it, but unfortunately
+ *   this flag can only be set when opening the file.
+ * - As there is no fork(), we cannot reliably change directory
+ *   before starting the child process. (There might be several threads
+ *   running, and the current directory is common for all threads.)
+ *
+ * Thus, we must in many cases use a helper program to handle closing
+ * of (inherited) file descriptors and changing of directory. The
+ * helper process is also needed if the standard input, standard
+ * output, or standard error of the process to be run are supposed to
+ * be redirected somewhere.
+ *
+ * The structure of the source code in this file is a mess, I know.
+ */
+
+/* Define this to get some logging all the time */
+/* #define G_SPAWN_WIN32_DEBUG */
+
+#include "config.h"
+
+#include "glib.h"
+#include "gprintfint.h"
+#include "glibintl.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <windows.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <io.h>
+#include <process.h>
+#include <direct.h>
+#include <wchar.h>
+
+#ifdef G_SPAWN_WIN32_DEBUG
+  static int debug = 1;
+  #define SETUP_DEBUG() /* empty */
+#else
+  static int debug = -1;
+  #define SETUP_DEBUG()                                        \
+    G_STMT_START                                       \
+      {                                                        \
+       if (debug == -1)                                \
+         {                                             \
+           if (getenv ("G_SPAWN_WIN32_DEBUG") != NULL) \
+             debug = 1;                                \
+           else                                        \
+             debug = 0;                                \
+         }                                             \
+      }                                                        \
+    G_STMT_END
+#endif
+
+enum
+{
+  CHILD_NO_ERROR,
+  CHILD_CHDIR_FAILED,
+  CHILD_SPAWN_FAILED,
+};
+
+enum {
+  ARG_CHILD_ERR_REPORT = 1,
+  ARG_HELPER_SYNC,
+  ARG_STDIN,
+  ARG_STDOUT,
+  ARG_STDERR,
+  ARG_WORKING_DIRECTORY,
+  ARG_CLOSE_DESCRIPTORS,
+  ARG_USE_PATH,
+  ARG_WAIT,
+  ARG_PROGRAM,
+  ARG_COUNT = ARG_PROGRAM
+};
+
+static int
+dup_noninherited (int fd,
+                 int mode)
+{
+  HANDLE filehandle;
+
+  DuplicateHandle (GetCurrentProcess (), (LPHANDLE) _get_osfhandle (fd),
+                  GetCurrentProcess (), &filehandle,
+                  0, FALSE, DUPLICATE_SAME_ACCESS);
+  close (fd);
+  return _open_osfhandle ((gintptr) filehandle, mode | _O_NOINHERIT);
+}
+
+#ifndef GSPAWN_HELPER
+
+#ifdef _WIN64
+#define HELPER_PROCESS "gspawn-win64-helper"
+#else
+#define HELPER_PROCESS "gspawn-win32-helper"
+#endif
+
+static gchar *
+protect_argv_string (const gchar *string)
+{
+  const gchar *p = string;
+  gchar *retval, *q;
+  gint len = 0;
+  gboolean need_dblquotes = FALSE;
+  while (*p)
+    {
+      if (*p == ' ' || *p == '\t')
+       need_dblquotes = TRUE;
+      else if (*p == '"')
+       len++;
+      else if (*p == '\\')
+       {
+         const gchar *pp = p;
+         while (*pp && *pp == '\\')
+           pp++;
+         if (*pp == '"')
+           len++;
+       }
+      len++;
+      p++;
+    }
+  
+  q = retval = g_malloc (len + need_dblquotes*2 + 1);
+  p = string;
+
+  if (need_dblquotes)
+    *q++ = '"';
+  
+  while (*p)
+    {
+      if (*p == '"')
+       *q++ = '\\';
+      else if (*p == '\\')
+       {
+         const gchar *pp = p;
+         while (*pp && *pp == '\\')
+           pp++;
+         if (*pp == '"')
+           *q++ = '\\';
+       }
+      *q++ = *p;
+      p++;
+    }
+  
+  if (need_dblquotes)
+    *q++ = '"';
+  *q++ = '\0';
+
+  return retval;
+}
+
+static gint
+protect_argv (gchar  **argv,
+             gchar ***new_argv)
+{
+  gint i;
+  gint argc = 0;
+  
+  while (argv[argc])
+    ++argc;
+  *new_argv = g_new (gchar *, argc+1);
+
+  /* Quote each argv element if necessary, so that it will get
+   * reconstructed correctly in the C runtime startup code.  Note that
+   * the unquoting algorithm in the C runtime is really weird, and
+   * rather different than what Unix shells do. See stdargv.c in the C
+   * runtime sources (in the Platform SDK, in src/crt).
+   *
+   * Note that an new_argv[0] constructed by this function should
+   * *not* be passed as the filename argument to a spawn* or exec*
+   * family function. That argument should be the real file name
+   * without any quoting.
+   */
+  for (i = 0; i < argc; i++)
+    (*new_argv)[i] = protect_argv_string (argv[i]);
+
+  (*new_argv)[argc] = NULL;
+
+  return argc;
+}
+
+GQuark
+g_spawn_error_quark (void)
+{
+  return g_quark_from_static_string ("g-exec-error-quark");
+}
+
+gboolean
+g_spawn_async_utf8 (const gchar          *working_directory,
+                   gchar               **argv,
+                   gchar               **envp,
+                   GSpawnFlags           flags,
+                   GSpawnChildSetupFunc  child_setup,
+                   gpointer              user_data,
+                   GPid                 *child_handle,
+                   GError              **error)
+{
+  g_return_val_if_fail (argv != NULL, FALSE);
+  
+  return g_spawn_async_with_pipes_utf8 (working_directory,
+                                       argv, envp,
+                                       flags,
+                                       child_setup,
+                                       user_data,
+                                       child_handle,
+                                       NULL, NULL, NULL,
+                                       error);
+}
+
+/* Avoids a danger in threaded situations (calling close()
+ * on a file descriptor twice, and another thread has
+ * re-opened it since the first close)
+ */
+static void
+close_and_invalidate (gint *fd)
+{
+  if (*fd < 0)
+    return;
+
+  close (*fd);
+  *fd = -1;
+}
+
+typedef enum
+{
+  READ_FAILED = 0, /* FALSE */
+  READ_OK,
+  READ_EOF
+} ReadResult;
+
+static ReadResult
+read_data (GString     *str,
+           GIOChannel  *iochannel,
+           GError     **error)
+{
+  GIOStatus giostatus;
+  gsize bytes;
+  gchar buf[4096];
+
+ again:
+  
+  giostatus = g_io_channel_read_chars (iochannel, buf, sizeof (buf), &bytes, NULL);
+
+  if (bytes == 0)
+    return READ_EOF;
+  else if (bytes > 0)
+    {
+      g_string_append_len (str, buf, bytes);
+      return READ_OK;
+    }
+  else if (giostatus == G_IO_STATUS_AGAIN)
+    goto again;
+  else if (giostatus == G_IO_STATUS_ERROR)
+    {
+      g_set_error_literal (error, G_SPAWN_ERROR, G_SPAWN_ERROR_READ,
+                           _("Failed to read data from child process"));
+      
+      return READ_FAILED;
+    }
+  else
+    return READ_OK;
+}
+
+static gboolean
+make_pipe (gint     p[2],
+           GError **error)
+{
+  if (_pipe (p, 4096, _O_BINARY) < 0)
+    {
+      int errsv = errno;
+
+      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+                   _("Failed to create pipe for communicating with child process (%s)"),
+                   g_strerror (errsv));
+      return FALSE;
+    }
+  else
+    return TRUE;
+}
+
+/* The helper process writes a status report back to us, through a
+ * pipe, consisting of two ints.
+ */
+static gboolean
+read_helper_report (int      fd,
+                   gintptr  report[2],
+                   GError **error)
+{
+  gint bytes = 0;
+  
+  while (bytes < sizeof(gintptr)*2)
+    {
+      gint chunk;
+
+      if (debug)
+       g_print ("%s:read_helper_report: read %" G_GSIZE_FORMAT "...\n",
+                __FILE__,
+                sizeof(gintptr)*2 - bytes);
+
+      chunk = read (fd, ((gchar*)report) + bytes,
+                   sizeof(gintptr)*2 - bytes);
+
+      if (debug)
+       g_print ("...got %d bytes\n", chunk);
+          
+      if (chunk < 0)
+        {
+          int errsv = errno;
+
+          /* Some weird shit happened, bail out */
+          g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+                       _("Failed to read from child pipe (%s)"),
+                       g_strerror (errsv));
+
+          return FALSE;
+        }
+      else if (chunk == 0)
+       {
+         g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+                      _("Failed to read from child pipe (%s)"),
+                      "EOF");
+         break; /* EOF */
+       }
+      else
+       bytes += chunk;
+    }
+
+  if (bytes < sizeof(gintptr)*2)
+    return FALSE;
+
+  return TRUE;
+}
+
+static void
+set_child_error (gintptr      report[2],
+                const gchar *working_directory,
+                GError     **error)
+{
+  switch (report[0])
+    {
+    case CHILD_CHDIR_FAILED:
+      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR,
+                  _("Failed to change to directory '%s' (%s)"),
+                  working_directory,
+                  g_strerror (report[1]));
+      break;
+    case CHILD_SPAWN_FAILED:
+      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+                  _("Failed to execute child process (%s)"),
+                  g_strerror (report[1]));
+      break;
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static gboolean
+utf8_charv_to_wcharv (char     **utf8_charv,
+                     wchar_t ***wcharv,
+                     int       *error_index,
+                     GError   **error)
+{
+  wchar_t **retval = NULL;
+
+  *wcharv = NULL;
+  if (utf8_charv != NULL)
+    {
+      int n = 0, i;
+
+      while (utf8_charv[n])
+       n++;
+      retval = g_new (wchar_t *, n + 1);
+
+      for (i = 0; i < n; i++)
+       {
+         retval[i] = g_utf8_to_utf16 (utf8_charv[i], -1, NULL, NULL, error);
+         if (retval[i] == NULL)
+           {
+             if (error_index)
+               *error_index = i;
+             while (i)
+               g_free (retval[--i]);
+             g_free (retval);
+             return FALSE;
+           }
+       }
+           
+      retval[n] = NULL;
+    }
+  *wcharv = retval;
+  return TRUE;
+}
+
+static gboolean
+do_spawn_directly (gint                 *exit_status,
+                  gboolean              do_return_handle,
+                  GSpawnFlags           flags,
+                  gchar               **argv,
+                  char                **envp,
+                  char                **protected_argv,
+                  GPid                 *child_handle,
+                  GError              **error)     
+{
+  const int mode = (exit_status == NULL) ? P_NOWAIT : P_WAIT;
+  char **new_argv;
+  gintptr rc = -1;
+  int saved_errno;
+  GError *conv_error = NULL;
+  gint conv_error_index;
+  wchar_t *wargv0, **wargv, **wenvp;
+
+  new_argv = (flags & G_SPAWN_FILE_AND_ARGV_ZERO) ? protected_argv + 1 : protected_argv;
+      
+  wargv0 = g_utf8_to_utf16 (argv[0], -1, NULL, NULL, &conv_error);
+  if (wargv0 == NULL)
+    {
+      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+                  _("Invalid program name: %s"),
+                  conv_error->message);
+      g_error_free (conv_error);
+      
+      return FALSE;
+    }
+  
+  if (!utf8_charv_to_wcharv (new_argv, &wargv, &conv_error_index, &conv_error))
+    {
+      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+                  _("Invalid string in argument vector at %d: %s"),
+                  conv_error_index, conv_error->message);
+      g_error_free (conv_error);
+      g_free (wargv0);
+
+      return FALSE;
+    }
+
+  if (!utf8_charv_to_wcharv (envp, &wenvp, NULL, &conv_error))
+    {
+      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+                  _("Invalid string in environment: %s"),
+                  conv_error->message);
+      g_error_free (conv_error);
+      g_free (wargv0);
+      g_strfreev ((gchar **) wargv);
+
+      return FALSE;
+    }
+
+  if (flags & G_SPAWN_SEARCH_PATH)
+    if (wenvp != NULL)
+      rc = _wspawnvpe (mode, wargv0, (const wchar_t **) wargv, (const wchar_t **) wenvp);
+    else
+      rc = _wspawnvp (mode, wargv0, (const wchar_t **) wargv);
+  else
+    if (wenvp != NULL)
+      rc = _wspawnve (mode, wargv0, (const wchar_t **) wargv, (const wchar_t **) wenvp);
+    else
+      rc = _wspawnv (mode, wargv0, (const wchar_t **) wargv);
+
+  g_free (wargv0);
+  g_strfreev ((gchar **) wargv);
+  g_strfreev ((gchar **) wenvp);
+
+  saved_errno = errno;
+
+  if (rc == -1 && saved_errno != 0)
+    {
+      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+                  _("Failed to execute child process (%s)"),
+                  g_strerror (saved_errno));
+      return FALSE;
+    }
+
+  if (exit_status == NULL)
+    {
+      if (child_handle && do_return_handle)
+       *child_handle = (GPid) rc;
+      else
+       {
+         CloseHandle ((HANDLE) rc);
+         if (child_handle)
+           *child_handle = 0;
+       }
+    }
+  else
+    *exit_status = rc;
+
+  return TRUE;
+}
+
+static gboolean
+do_spawn_with_pipes (gint                 *exit_status,
+                    gboolean              do_return_handle,
+                    const gchar          *working_directory,
+                    gchar               **argv,
+                    char                **envp,
+                    GSpawnFlags           flags,
+                    GSpawnChildSetupFunc  child_setup,
+                    GPid                 *child_handle,
+                    gint                 *standard_input,
+                    gint                 *standard_output,
+                    gint                 *standard_error,
+                    gint                 *err_report,
+                    GError              **error)     
+{
+  char **protected_argv;
+  char args[ARG_COUNT][10];
+  char **new_argv;
+  int i;
+  gintptr rc = -1;
+  int saved_errno;
+  int argc;
+  int stdin_pipe[2] = { -1, -1 };
+  int stdout_pipe[2] = { -1, -1 };
+  int stderr_pipe[2] = { -1, -1 };
+  int child_err_report_pipe[2] = { -1, -1 };
+  int helper_sync_pipe[2] = { -1, -1 };
+  gintptr helper_report[2];
+  static gboolean warned_about_child_setup = FALSE;
+  GError *conv_error = NULL;
+  gint conv_error_index;
+  gchar *helper_process;
+  CONSOLE_CURSOR_INFO cursor_info;
+  wchar_t *whelper, **wargv, **wenvp;
+  extern gchar *_glib_get_dll_directory (void);
+  gchar *glib_dll_directory;
+
+  if (child_setup && !warned_about_child_setup)
+    {
+      warned_about_child_setup = TRUE;
+      g_warning ("passing a child setup function to the g_spawn functions is pointless on Windows and it is ignored");
+    }
+
+  argc = protect_argv (argv, &protected_argv);
+
+  if (!standard_input && !standard_output && !standard_error &&
+      (flags & G_SPAWN_CHILD_INHERITS_STDIN) &&
+      !(flags & G_SPAWN_STDOUT_TO_DEV_NULL) &&
+      !(flags & G_SPAWN_STDERR_TO_DEV_NULL) &&
+      (working_directory == NULL || !*working_directory) &&
+      (flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN))
+    {
+      /* We can do without the helper process */
+      gboolean retval =
+       do_spawn_directly (exit_status, do_return_handle, flags,
+                          argv, envp, protected_argv,
+                          child_handle, error);
+      g_strfreev (protected_argv);
+      return retval;
+    }
+
+  if (standard_input && !make_pipe (stdin_pipe, error))
+    goto cleanup_and_fail;
+  
+  if (standard_output && !make_pipe (stdout_pipe, error))
+    goto cleanup_and_fail;
+  
+  if (standard_error && !make_pipe (stderr_pipe, error))
+    goto cleanup_and_fail;
+  
+  if (!make_pipe (child_err_report_pipe, error))
+    goto cleanup_and_fail;
+  
+  if (!make_pipe (helper_sync_pipe, error))
+    goto cleanup_and_fail;
+  
+  new_argv = g_new (char *, argc + 1 + ARG_COUNT);
+  if (GetConsoleCursorInfo (GetStdHandle (STD_OUTPUT_HANDLE), &cursor_info))
+    helper_process = HELPER_PROCESS "-console.exe";
+  else
+    helper_process = HELPER_PROCESS ".exe";
+  
+  glib_dll_directory = _glib_get_dll_directory ();
+  if (glib_dll_directory != NULL)
+    {
+      helper_process = g_build_filename (glib_dll_directory, helper_process, NULL);
+      g_free (glib_dll_directory);
+    }
+  else
+    helper_process = g_strdup (helper_process);
+
+  new_argv[0] = protect_argv_string (helper_process);
+
+  _g_sprintf (args[ARG_CHILD_ERR_REPORT], "%d", child_err_report_pipe[1]);
+  new_argv[ARG_CHILD_ERR_REPORT] = args[ARG_CHILD_ERR_REPORT];
+  
+  /* Make the read end of the child error report pipe
+   * noninherited. Otherwise it will needlessly be inherited by the
+   * helper process, and the started actual user process. As such that
+   * shouldn't harm, but it is unnecessary.
+   */
+  child_err_report_pipe[0] = dup_noninherited (child_err_report_pipe[0], _O_RDONLY);
+
+  if (flags & G_SPAWN_FILE_AND_ARGV_ZERO)
+    {
+      /* Overload ARG_CHILD_ERR_REPORT to also encode the
+       * G_SPAWN_FILE_AND_ARGV_ZERO functionality.
+       */
+      strcat (args[ARG_CHILD_ERR_REPORT], "#");
+    }
+  
+  _g_sprintf (args[ARG_HELPER_SYNC], "%d", helper_sync_pipe[0]);
+  new_argv[ARG_HELPER_SYNC] = args[ARG_HELPER_SYNC];
+  
+  /* Make the write end of the sync pipe noninherited. Otherwise the
+   * helper process will inherit it, and thus if this process happens
+   * to crash before writing the sync byte to the pipe, the helper
+   * process won't read but won't get any EOF either, as it has the
+   * write end open itself.
+   */
+  helper_sync_pipe[1] = dup_noninherited (helper_sync_pipe[1], _O_WRONLY);
+
+  if (standard_input)
+    {
+      _g_sprintf (args[ARG_STDIN], "%d", stdin_pipe[0]);
+      new_argv[ARG_STDIN] = args[ARG_STDIN];
+    }
+  else if (flags & G_SPAWN_CHILD_INHERITS_STDIN)
+    {
+      /* Let stdin be alone */
+      new_argv[ARG_STDIN] = "-";
+    }
+  else
+    {
+      /* Keep process from blocking on a read of stdin */
+      new_argv[ARG_STDIN] = "z";
+    }
+  
+  if (standard_output)
+    {
+      _g_sprintf (args[ARG_STDOUT], "%d", stdout_pipe[1]);
+      new_argv[ARG_STDOUT] = args[ARG_STDOUT];
+    }
+  else if (flags & G_SPAWN_STDOUT_TO_DEV_NULL)
+    {
+      new_argv[ARG_STDOUT] = "z";
+    }
+  else
+    {
+      new_argv[ARG_STDOUT] = "-";
+    }
+  
+  if (standard_error)
+    {
+      _g_sprintf (args[ARG_STDERR], "%d", stderr_pipe[1]);
+      new_argv[ARG_STDERR] = args[ARG_STDERR];
+    }
+  else if (flags & G_SPAWN_STDERR_TO_DEV_NULL)
+    {
+      new_argv[ARG_STDERR] = "z";
+    }
+  else
+    {
+      new_argv[ARG_STDERR] = "-";
+    }
+  
+  if (working_directory && *working_directory)
+    new_argv[ARG_WORKING_DIRECTORY] = protect_argv_string (working_directory);
+  else
+    new_argv[ARG_WORKING_DIRECTORY] = g_strdup ("-");
+  
+  if (!(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN))
+    new_argv[ARG_CLOSE_DESCRIPTORS] = "y";
+  else
+    new_argv[ARG_CLOSE_DESCRIPTORS] = "-";
+
+  if (flags & G_SPAWN_SEARCH_PATH)
+    new_argv[ARG_USE_PATH] = "y";
+  else
+    new_argv[ARG_USE_PATH] = "-";
+
+  if (exit_status == NULL)
+    new_argv[ARG_WAIT] = "-";
+  else
+    new_argv[ARG_WAIT] = "w";
+
+  for (i = 0; i <= argc; i++)
+    new_argv[ARG_PROGRAM + i] = protected_argv[i];
+
+  SETUP_DEBUG();
+
+  if (debug)
+    {
+      g_print ("calling %s with argv:\n", helper_process);
+      for (i = 0; i < argc + 1 + ARG_COUNT; i++)
+       g_print ("argv[%d]: %s\n", i, (new_argv[i] ? new_argv[i] : "NULL"));
+    }
+
+  if (!utf8_charv_to_wcharv (new_argv, &wargv, &conv_error_index, &conv_error))
+    {
+      if (conv_error_index == ARG_WORKING_DIRECTORY)
+       g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR,
+                    _("Invalid working directory: %s"),
+                    conv_error->message);
+      else
+       g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+                    _("Invalid string in argument vector at %d: %s"),
+                    conv_error_index - ARG_PROGRAM, conv_error->message);
+      g_error_free (conv_error);
+      g_strfreev (protected_argv);
+      g_free (new_argv[0]);
+      g_free (new_argv[ARG_WORKING_DIRECTORY]);
+      g_free (new_argv);
+      g_free (helper_process);
+
+      goto cleanup_and_fail;
+    }
+
+  if (!utf8_charv_to_wcharv (envp, &wenvp, NULL, &conv_error))
+    {
+      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+                  _("Invalid string in environment: %s"),
+                  conv_error->message);
+      g_error_free (conv_error);
+      g_strfreev (protected_argv);
+      g_free (new_argv[0]);
+      g_free (new_argv[ARG_WORKING_DIRECTORY]);
+      g_free (new_argv);
+      g_free (helper_process);
+      g_strfreev ((gchar **) wargv);
+      goto cleanup_and_fail;
+    }
+
+  whelper = g_utf8_to_utf16 (helper_process, -1, NULL, NULL, NULL);
+  g_free (helper_process);
+
+  if (wenvp != NULL)
+    rc = _wspawnvpe (P_NOWAIT, whelper, (const wchar_t **) wargv, (const wchar_t **) wenvp);
+  else
+    rc = _wspawnvp (P_NOWAIT, whelper, (const wchar_t **) wargv);
+
+  saved_errno = errno;
+
+  g_free (whelper);
+  g_strfreev ((gchar **) wargv);
+  g_strfreev ((gchar **) wenvp);
+
+  /* Close the other process's ends of the pipes in this process,
+   * otherwise the reader will never get EOF.
+   */
+  close_and_invalidate (&child_err_report_pipe[1]);
+  close_and_invalidate (&helper_sync_pipe[0]);
+  close_and_invalidate (&stdin_pipe[0]);
+  close_and_invalidate (&stdout_pipe[1]);
+  close_and_invalidate (&stderr_pipe[1]);
+
+  g_strfreev (protected_argv);
+
+  g_free (new_argv[0]);
+  g_free (new_argv[ARG_WORKING_DIRECTORY]);
+  g_free (new_argv);
+
+  /* Check if gspawn-win32-helper couldn't be run */
+  if (rc == -1 && saved_errno != 0)
+    {
+      g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+                  _("Failed to execute helper program (%s)"),
+                  g_strerror (saved_errno));
+      goto cleanup_and_fail;
+    }
+
+  if (exit_status != NULL)
+    {
+      /* Synchronous case. Pass helper's report pipe back to caller,
+       * which takes care of reading it after the grandchild has
+       * finished.
+       */
+      g_assert (err_report != NULL);
+      *err_report = child_err_report_pipe[0];
+      write (helper_sync_pipe[1], " ", 1);
+      close_and_invalidate (&helper_sync_pipe[1]);
+    }
+  else
+    {
+      /* Asynchronous case. We read the helper's report right away. */
+      if (!read_helper_report (child_err_report_pipe[0], helper_report, error))
+       goto cleanup_and_fail;
+        
+      close_and_invalidate (&child_err_report_pipe[0]);
+
+      switch (helper_report[0])
+       {
+       case CHILD_NO_ERROR:
+         if (child_handle && do_return_handle)
+           {
+             /* rc is our HANDLE for gspawn-win32-helper. It has
+              * told us the HANDLE of its child. Duplicate that into
+              * a HANDLE valid in this process.
+              */
+             if (!DuplicateHandle ((HANDLE) rc, (HANDLE) helper_report[1],
+                                   GetCurrentProcess (), (LPHANDLE) child_handle,
+                                   0, TRUE, DUPLICATE_SAME_ACCESS))
+               {
+                 char *emsg = g_win32_error_message (GetLastError ());
+                 g_print("%s\n", emsg);
+                 *child_handle = 0;
+               }
+           }
+         else if (child_handle)
+           *child_handle = 0;
+         write (helper_sync_pipe[1], " ", 1);
+         close_and_invalidate (&helper_sync_pipe[1]);
+         break;
+         
+       default:
+         write (helper_sync_pipe[1], " ", 1);
+         close_and_invalidate (&helper_sync_pipe[1]);
+         set_child_error (helper_report, working_directory, error);
+         goto cleanup_and_fail;
+       }
+    }
+
+  /* Success against all odds! return the information */
+      
+  if (standard_input)
+    *standard_input = stdin_pipe[1];
+  if (standard_output)
+    *standard_output = stdout_pipe[0];
+  if (standard_error)
+    *standard_error = stderr_pipe[0];
+  if (rc != -1)
+    CloseHandle ((HANDLE) rc);
+  
+  return TRUE;
+
+ cleanup_and_fail:
+
+  if (rc != -1)
+    CloseHandle ((HANDLE) rc);
+  if (child_err_report_pipe[0] != -1)
+    close (child_err_report_pipe[0]);
+  if (child_err_report_pipe[1] != -1)
+    close (child_err_report_pipe[1]);
+  if (helper_sync_pipe[0] != -1)
+    close (helper_sync_pipe[0]);
+  if (helper_sync_pipe[1] != -1)
+    close (helper_sync_pipe[1]);
+  if (stdin_pipe[0] != -1)
+    close (stdin_pipe[0]);
+  if (stdin_pipe[1] != -1)
+    close (stdin_pipe[1]);
+  if (stdout_pipe[0] != -1)
+    close (stdout_pipe[0]);
+  if (stdout_pipe[1] != -1)
+    close (stdout_pipe[1]);
+  if (stderr_pipe[0] != -1)
+    close (stderr_pipe[0]);
+  if (stderr_pipe[1] != -1)
+    close (stderr_pipe[1]);
+
+  return FALSE;
+}
+
+gboolean
+g_spawn_sync_utf8 (const gchar          *working_directory,
+                  gchar               **argv,
+                  gchar               **envp,
+                  GSpawnFlags           flags,
+                  GSpawnChildSetupFunc  child_setup,
+                  gpointer              user_data,
+                  gchar               **standard_output,
+                  gchar               **standard_error,
+                  gint                 *exit_status,
+                  GError              **error)     
+{
+  gint outpipe = -1;
+  gint errpipe = -1;
+  gint reportpipe = -1;
+  GIOChannel *outchannel = NULL;
+  GIOChannel *errchannel = NULL;
+  GPollFD outfd, errfd;
+  GPollFD fds[2];
+  gint nfds;
+  gint outindex = -1;
+  gint errindex = -1;
+  gint ret;
+  GString *outstr = NULL;
+  GString *errstr = NULL;
+  gboolean failed;
+  gint status;
+  
+  g_return_val_if_fail (argv != NULL, FALSE);
+  g_return_val_if_fail (!(flags & G_SPAWN_DO_NOT_REAP_CHILD), FALSE);
+  g_return_val_if_fail (standard_output == NULL ||
+                        !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
+  g_return_val_if_fail (standard_error == NULL ||
+                        !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
+  
+  /* Just to ensure segfaults if callers try to use
+   * these when an error is reported.
+   */
+  if (standard_output)
+    *standard_output = NULL;
+
+  if (standard_error)
+    *standard_error = NULL;
+  
+  if (!do_spawn_with_pipes (&status,
+                           FALSE,
+                           working_directory,
+                           argv,
+                           envp,
+                           flags,
+                           child_setup,
+                           NULL,
+                           NULL,
+                           standard_output ? &outpipe : NULL,
+                           standard_error ? &errpipe : NULL,
+                           &reportpipe,
+                           error))
+    return FALSE;
+
+  /* Read data from child. */
+  
+  failed = FALSE;
+
+  if (outpipe >= 0)
+    {
+      outstr = g_string_new (NULL);
+      outchannel = g_io_channel_win32_new_fd (outpipe);
+      g_io_channel_set_encoding (outchannel, NULL, NULL);
+      g_io_channel_set_buffered (outchannel, FALSE);
+      g_io_channel_win32_make_pollfd (outchannel,
+                                     G_IO_IN | G_IO_ERR | G_IO_HUP,
+                                     &outfd);
+      if (debug)
+       g_print ("outfd=%p\n", (HANDLE) outfd.fd);
+    }
+      
+  if (errpipe >= 0)
+    {
+      errstr = g_string_new (NULL);
+      errchannel = g_io_channel_win32_new_fd (errpipe);
+      g_io_channel_set_encoding (errchannel, NULL, NULL);
+      g_io_channel_set_buffered (errchannel, FALSE);
+      g_io_channel_win32_make_pollfd (errchannel,
+                                     G_IO_IN | G_IO_ERR | G_IO_HUP,
+                                     &errfd);
+      if (debug)
+       g_print ("errfd=%p\n", (HANDLE) errfd.fd);
+    }
+
+  /* Read data until we get EOF on all pipes. */
+  while (!failed && (outpipe >= 0 || errpipe >= 0))
+    {
+      nfds = 0;
+      if (outpipe >= 0)
+       {
+         fds[nfds] = outfd;
+         outindex = nfds;
+         nfds++;
+       }
+      if (errpipe >= 0)
+       {
+         fds[nfds] = errfd;
+         errindex = nfds;
+         nfds++;
+       }
+
+      if (debug)
+       g_print ("g_spawn_sync: calling g_io_channel_win32_poll, nfds=%d\n",
+                nfds);
+
+      ret = g_io_channel_win32_poll (fds, nfds, -1);
+
+      if (ret < 0)
+        {
+          failed = TRUE;
+
+          g_set_error_literal (error, G_SPAWN_ERROR, G_SPAWN_ERROR_READ,
+                               _("Unexpected error in g_io_channel_win32_poll() reading data from a child process"));
+         
+          break;
+        }
+
+      if (outpipe >= 0 && (fds[outindex].revents & G_IO_IN))
+        {
+          switch (read_data (outstr, outchannel, error))
+            {
+            case READ_FAILED:
+             if (debug)
+               g_print ("g_spawn_sync: outchannel: READ_FAILED\n");
+              failed = TRUE;
+              break;
+            case READ_EOF:
+             if (debug)
+               g_print ("g_spawn_sync: outchannel: READ_EOF\n");
+              g_io_channel_unref (outchannel);
+             outchannel = NULL;
+              close_and_invalidate (&outpipe);
+              break;
+            default:
+             if (debug)
+               g_print ("g_spawn_sync: outchannel: OK\n");
+              break;
+            }
+
+          if (failed)
+            break;
+        }
+
+      if (errpipe >= 0 && (fds[errindex].revents & G_IO_IN))
+        {
+          switch (read_data (errstr, errchannel, error))
+            {
+            case READ_FAILED:
+             if (debug)
+               g_print ("g_spawn_sync: errchannel: READ_FAILED\n");
+              failed = TRUE;
+              break;
+            case READ_EOF:
+             if (debug)
+               g_print ("g_spawn_sync: errchannel: READ_EOF\n");
+             g_io_channel_unref (errchannel);
+             errchannel = NULL;
+              close_and_invalidate (&errpipe);
+              break;
+            default:
+             if (debug)
+               g_print ("g_spawn_sync: errchannel: OK\n");
+              break;
+            }
+
+          if (failed)
+            break;
+        }
+    }
+
+  if (reportpipe == -1)
+    {
+      /* No helper process, exit status of actual spawned process
+       * already available.
+       */
+      if (exit_status)
+        *exit_status = status;
+    }
+  else
+    {
+      /* Helper process was involved. Read its report now after the
+       * grandchild has finished.
+       */
+      gintptr helper_report[2];
+
+      if (!read_helper_report (reportpipe, helper_report, error))
+       failed = TRUE;
+      else
+       {
+         switch (helper_report[0])
+           {
+           case CHILD_NO_ERROR:
+             if (exit_status)
+               *exit_status = helper_report[1];
+             break;
+           default:
+             set_child_error (helper_report, working_directory, error);
+             failed = TRUE;
+             break;
+           }
+       }
+      close_and_invalidate (&reportpipe);
+    }
+
+
+  /* These should only be open still if we had an error.  */
+  
+  if (outchannel != NULL)
+    g_io_channel_unref (outchannel);
+  if (errchannel != NULL)
+    g_io_channel_unref (errchannel);
+  if (outpipe >= 0)
+    close_and_invalidate (&outpipe);
+  if (errpipe >= 0)
+    close_and_invalidate (&errpipe);
+  
+  if (failed)
+    {
+      if (outstr)
+        g_string_free (outstr, TRUE);
+      if (errstr)
+        g_string_free (errstr, TRUE);
+
+      return FALSE;
+    }
+  else
+    {
+      if (standard_output)        
+        *standard_output = g_string_free (outstr, FALSE);
+
+      if (standard_error)
+        *standard_error = g_string_free (errstr, FALSE);
+
+      return TRUE;
+    }
+}
+
+gboolean
+g_spawn_async_with_pipes_utf8 (const gchar          *working_directory,
+                              gchar               **argv,
+                              gchar               **envp,
+                              GSpawnFlags           flags,
+                              GSpawnChildSetupFunc  child_setup,
+                              gpointer              user_data,
+                              GPid                 *child_handle,
+                              gint                 *standard_input,
+                              gint                 *standard_output,
+                              gint                 *standard_error,
+                              GError              **error)
+{
+  g_return_val_if_fail (argv != NULL, FALSE);
+  g_return_val_if_fail (standard_output == NULL ||
+                        !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
+  g_return_val_if_fail (standard_error == NULL ||
+                        !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
+  /* can't inherit stdin if we have an input pipe. */
+  g_return_val_if_fail (standard_input == NULL ||
+                        !(flags & G_SPAWN_CHILD_INHERITS_STDIN), FALSE);
+  
+  return do_spawn_with_pipes (NULL,
+                             (flags & G_SPAWN_DO_NOT_REAP_CHILD),
+                             working_directory,
+                             argv,
+                             envp,
+                             flags,
+                             child_setup,
+                             child_handle,
+                             standard_input,
+                             standard_output,
+                             standard_error,
+                             NULL,
+                             error);
+}
+
+gboolean
+g_spawn_command_line_sync_utf8 (const gchar  *command_line,
+                               gchar       **standard_output,
+                               gchar       **standard_error,
+                               gint         *exit_status,
+                               GError      **error)
+{
+  gboolean retval;
+  gchar **argv = 0;
+
+  g_return_val_if_fail (command_line != NULL, FALSE);
+  
+  if (!g_shell_parse_argv (command_line,
+                           NULL, &argv,
+                           error))
+    return FALSE;
+  
+  retval = g_spawn_sync_utf8 (NULL,
+                             argv,
+                             NULL,
+                             G_SPAWN_SEARCH_PATH,
+                             NULL,
+                             NULL,
+                             standard_output,
+                             standard_error,
+                             exit_status,
+                             error);
+  g_strfreev (argv);
+
+  return retval;
+}
+
+gboolean
+g_spawn_command_line_async_utf8 (const gchar *command_line,
+                                GError     **error)
+{
+  gboolean retval;
+  gchar **argv = 0;
+
+  g_return_val_if_fail (command_line != NULL, FALSE);
+
+  if (!g_shell_parse_argv (command_line,
+                           NULL, &argv,
+                           error))
+    return FALSE;
+  
+  retval = g_spawn_async_utf8 (NULL,
+                              argv,
+                              NULL,
+                              G_SPAWN_SEARCH_PATH,
+                              NULL,
+                              NULL,
+                              NULL,
+                              error);
+  g_strfreev (argv);
+
+  return retval;
+}
+
+void
+g_spawn_close_pid (GPid pid)
+{
+    CloseHandle (pid);
+}
+
+#if !defined (_WIN64)
+
+/* Binary compatibility versions that take system codepage pathnames,
+ * argument vectors and environments. These get used only by code
+ * built against 2.8.1 or earlier. Code built against 2.8.2 or later
+ * will use the _utf8 versions above (see the #defines in gspawn.h).
+ */
+
+#undef g_spawn_async
+#undef g_spawn_async_with_pipes
+#undef g_spawn_sync
+#undef g_spawn_command_line_sync
+#undef g_spawn_command_line_async
+
+static gboolean
+setup_utf8_copies (const gchar *working_directory,
+                  gchar      **utf8_working_directory,
+                  gchar      **argv,
+                  gchar     ***utf8_argv,
+                  gchar      **envp,
+                  gchar     ***utf8_envp,
+                  GError     **error)
+{
+  gint i, argc, envc;
+
+  if (working_directory == NULL)
+    *utf8_working_directory = NULL;
+  else
+    {
+      GError *conv_error = NULL;
+      
+      *utf8_working_directory = g_locale_to_utf8 (working_directory, -1, NULL, NULL, &conv_error);
+      if (*utf8_working_directory == NULL)
+       {
+         g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_CHDIR,
+                      _("Invalid working directory: %s"),
+                      conv_error->message);
+         g_error_free (conv_error);
+         return FALSE;
+       }
+    }
+
+  argc = 0;
+  while (argv[argc])
+    ++argc;
+  *utf8_argv = g_new (gchar *, argc + 1);
+  for (i = 0; i < argc; i++)
+    {
+      GError *conv_error = NULL;
+
+      (*utf8_argv)[i] = g_locale_to_utf8 (argv[i], -1, NULL, NULL, &conv_error);
+      if ((*utf8_argv)[i] == NULL)
+       {
+         g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+                      _("Invalid string in argument vector at %d: %s"),
+                      i, conv_error->message);
+         g_error_free (conv_error);
+         
+         g_strfreev (*utf8_argv);
+         *utf8_argv = NULL;
+
+         g_free (*utf8_working_directory);
+         *utf8_working_directory = NULL;
+
+         return FALSE;
+       }
+    }
+  (*utf8_argv)[argc] = NULL;
+
+  if (envp == NULL)
+    {
+      *utf8_envp = NULL;
+    }
+  else
+    {
+      envc = 0;
+      while (envp[envc])
+       ++envc;
+      *utf8_envp = g_new (gchar *, envc + 1);
+      for (i = 0; i < envc; i++)
+       {
+         GError *conv_error = NULL;
+
+         (*utf8_envp)[i] = g_locale_to_utf8 (envp[i], -1, NULL, NULL, &conv_error);
+         if ((*utf8_envp)[i] == NULL)
+           {   
+             g_set_error (error, G_SPAWN_ERROR, G_SPAWN_ERROR_FAILED,
+                          _("Invalid string in environment: %s"),
+                          conv_error->message);
+             g_error_free (conv_error);
+
+             g_strfreev (*utf8_envp);
+             *utf8_envp = NULL;
+
+             g_strfreev (*utf8_argv);
+             *utf8_argv = NULL;
+
+             g_free (*utf8_working_directory);
+             *utf8_working_directory = NULL;
+
+             return FALSE;
+           }
+       }
+      (*utf8_envp)[envc] = NULL;
+    }
+  return TRUE;
+}
+
+static void
+free_utf8_copies (gchar  *utf8_working_directory,
+                 gchar **utf8_argv,
+                 gchar **utf8_envp)
+{
+  g_free (utf8_working_directory);
+  g_strfreev (utf8_argv);
+  g_strfreev (utf8_envp);
+}
+
+gboolean
+g_spawn_async_with_pipes (const gchar          *working_directory,
+                          gchar               **argv,
+                          gchar               **envp,
+                          GSpawnFlags           flags,
+                          GSpawnChildSetupFunc  child_setup,
+                          gpointer              user_data,
+                          GPid                 *child_handle,
+                          gint                 *standard_input,
+                          gint                 *standard_output,
+                          gint                 *standard_error,
+                          GError              **error)
+{
+  gchar *utf8_working_directory;
+  gchar **utf8_argv;
+  gchar **utf8_envp;
+  gboolean retval;
+
+  if (!setup_utf8_copies (working_directory, &utf8_working_directory,
+                         argv, &utf8_argv,
+                         envp, &utf8_envp,
+                         error))
+    return FALSE;
+
+  retval = g_spawn_async_with_pipes_utf8 (utf8_working_directory,
+                                         utf8_argv, utf8_envp,
+                                         flags, child_setup, user_data,
+                                         child_handle,
+                                         standard_input, standard_output, standard_error,
+                                         error);
+
+  free_utf8_copies (utf8_working_directory, utf8_argv, utf8_envp);
+
+  return retval;
+}
+
+gboolean
+g_spawn_async (const gchar          *working_directory,
+              gchar               **argv,
+              gchar               **envp,
+              GSpawnFlags           flags,
+              GSpawnChildSetupFunc  child_setup,
+              gpointer              user_data,
+              GPid                 *child_handle,
+              GError              **error)
+{
+  return g_spawn_async_with_pipes (working_directory,
+                                  argv, envp,
+                                  flags,
+                                  child_setup,
+                                  user_data,
+                                  child_handle,
+                                  NULL, NULL, NULL,
+                                  error);
+}
+
+gboolean
+g_spawn_sync (const gchar          *working_directory,
+             gchar               **argv,
+             gchar               **envp,
+             GSpawnFlags           flags,
+             GSpawnChildSetupFunc  child_setup,
+             gpointer              user_data,
+             gchar               **standard_output,
+             gchar               **standard_error,
+             gint                 *exit_status,
+             GError              **error)     
+{
+  gchar *utf8_working_directory;
+  gchar **utf8_argv;
+  gchar **utf8_envp;
+  gboolean retval;
+
+  if (!setup_utf8_copies (working_directory, &utf8_working_directory,
+                         argv, &utf8_argv,
+                         envp, &utf8_envp,
+                         error))
+    return FALSE;
+
+  retval = g_spawn_sync_utf8 (utf8_working_directory,
+                             utf8_argv, utf8_envp,
+                             flags, child_setup, user_data,
+                             standard_output, standard_error, exit_status,
+                             error);
+
+  free_utf8_copies (utf8_working_directory, utf8_argv, utf8_envp);
+
+  return retval;
+}
+
+gboolean
+g_spawn_command_line_sync (const gchar  *command_line,
+                          gchar       **standard_output,
+                          gchar       **standard_error,
+                          gint         *exit_status,
+                          GError      **error)
+{
+  gboolean retval;
+  gchar **argv = 0;
+
+  g_return_val_if_fail (command_line != NULL, FALSE);
+  
+  if (!g_shell_parse_argv (command_line,
+                           NULL, &argv,
+                           error))
+    return FALSE;
+  
+  retval = g_spawn_sync (NULL,
+                         argv,
+                         NULL,
+                         G_SPAWN_SEARCH_PATH,
+                         NULL,
+                         NULL,
+                         standard_output,
+                         standard_error,
+                         exit_status,
+                         error);
+  g_strfreev (argv);
+
+  return retval;
+}
+
+gboolean
+g_spawn_command_line_async (const gchar *command_line,
+                           GError     **error)
+{
+  gboolean retval;
+  gchar **argv = 0;
+
+  g_return_val_if_fail (command_line != NULL, FALSE);
+
+  if (!g_shell_parse_argv (command_line,
+                           NULL, &argv,
+                           error))
+    return FALSE;
+  
+  retval = g_spawn_async (NULL,
+                          argv,
+                          NULL,
+                          G_SPAWN_SEARCH_PATH,
+                          NULL,
+                          NULL,
+                          NULL,
+                          error);
+  g_strfreev (argv);
+
+  return retval;
+}
+
+#endif /* !_WIN64 */
+
+#endif /* !GSPAWN_HELPER */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gspawn.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gspawn.c
new file mode 100644 (file)
index 0000000..149d337
--- /dev/null
@@ -0,0 +1,1685 @@
+/* gspawn.c - Process launching
+ *
+ *  Copyright 2000 Red Hat, Inc.
+ *  g_execvpe implementation based on GNU libc execvp:
+ *   Copyright 1991, 92, 95, 96, 97, 98, 99 Free Software Foundation, Inc.
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not, write
+ * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <sys/time.h>
+#include <sys/types.h>
+#include <sys/wait.h>
+#include <unistd.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <signal.h>
+#include <string.h>
+#include <stdlib.h>   /* for fdwalk */
+#include <dirent.h>
+
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H */
+
+#ifdef HAVE_SYS_RESOURCE_H
+#include <sys/resource.h>
+#endif /* HAVE_SYS_RESOURCE_H */
+
+#include "gspawn.h"
+
+#include "gmem.h"
+#include "gshell.h"
+#include "gstring.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "gutils.h"
+#include "glibintl.h"
+
+static gint g_execute (const gchar  *file,
+                       gchar **argv,
+                       gchar **envp,
+                       gboolean search_path);
+
+static gboolean make_pipe            (gint                  p[2],
+                                      GError              **error);
+static gboolean fork_exec_with_pipes (gboolean              intermediate_child,
+                                      const gchar          *working_directory,
+                                      gchar               **argv,
+                                      gchar               **envp,
+                                      gboolean              close_descriptors,
+                                      gboolean              search_path,
+                                      gboolean              stdout_to_null,
+                                      gboolean              stderr_to_null,
+                                      gboolean              child_inherits_stdin,
+                                      gboolean              file_and_argv_zero,
+                                      GSpawnChildSetupFunc  child_setup,
+                                      gpointer              user_data,
+                                      GPid                 *child_pid,
+                                      gint                 *standard_input,
+                                      gint                 *standard_output,
+                                      gint                 *standard_error,
+                                      GError              **error);
+
+GQuark
+g_spawn_error_quark (void)
+{
+  return g_quark_from_static_string ("g-exec-error-quark");
+}
+
+/**
+ * g_spawn_async:
+ * @working_directory: child's current working directory, or %NULL to inherit parent's
+ * @argv: child's argument vector
+ * @envp: child's environment, or %NULL to inherit parent's
+ * @flags: flags from #GSpawnFlags
+ * @child_setup: function to run in the child just before exec()
+ * @user_data: user data for @child_setup
+ * @child_pid: return location for child process reference, or %NULL
+ * @error: return location for error
+ * 
+ * See g_spawn_async_with_pipes() for a full description; this function
+ * simply calls the g_spawn_async_with_pipes() without any pipes.
+ *
+ * You should call g_spawn_close_pid() on the returned child process
+ * reference when you don't need it any more.
+ * 
+ * <note><para>
+ * If you are writing a GTK+ application, and the program you 
+ * are spawning is a graphical application, too, then you may
+ * want to use gdk_spawn_on_screen() instead to ensure that 
+ * the spawned program opens its windows on the right screen.
+ * </para></note>
+ *
+ * <note><para> Note that the returned @child_pid on Windows is a
+ * handle to the child process and not its identifier. Process handles
+ * and process identifiers are different concepts on Windows.
+ * </para></note>
+ *
+ * Return value: %TRUE on success, %FALSE if error is set
+ **/
+gboolean
+g_spawn_async (const gchar          *working_directory,
+               gchar               **argv,
+               gchar               **envp,
+               GSpawnFlags           flags,
+               GSpawnChildSetupFunc  child_setup,
+               gpointer              user_data,
+               GPid                 *child_pid,
+               GError              **error)
+{
+  g_return_val_if_fail (argv != NULL, FALSE);
+  
+  return g_spawn_async_with_pipes (working_directory,
+                                   argv, envp,
+                                   flags,
+                                   child_setup,
+                                   user_data,
+                                   child_pid,
+                                   NULL, NULL, NULL,
+                                   error);
+}
+
+/* Avoids a danger in threaded situations (calling close()
+ * on a file descriptor twice, and another thread has
+ * re-opened it since the first close)
+ */
+static gint
+close_and_invalidate (gint *fd)
+{
+  gint ret;
+
+  if (*fd < 0)
+    return -1;
+  else
+    {
+      ret = close (*fd);
+      *fd = -1;
+    }
+
+  return ret;
+}
+
+/* Some versions of OS X define READ_OK in public headers */
+#undef READ_OK
+
+typedef enum
+{
+  READ_FAILED = 0, /* FALSE */
+  READ_OK,
+  READ_EOF
+} ReadResult;
+
+static ReadResult
+read_data (GString *str,
+           gint     fd,
+           GError **error)
+{
+  gssize bytes;        
+  gchar buf[4096];    
+
+ again:
+  
+  bytes = read (fd, buf, 4096);
+
+  if (bytes == 0)
+    return READ_EOF;
+  else if (bytes > 0)
+    {
+      g_string_append_len (str, buf, bytes);
+      return READ_OK;
+    }
+  else if (bytes < 0 && errno == EINTR)
+    goto again;
+  else if (bytes < 0)
+    {
+      int errsv = errno;
+
+      g_set_error (error,
+                   G_SPAWN_ERROR,
+                   G_SPAWN_ERROR_READ,
+                   _("Failed to read data from child process (%s)"),
+                   g_strerror (errsv));
+      
+      return READ_FAILED;
+    }
+  else
+    return READ_OK;
+}
+
+/**
+ * g_spawn_sync:
+ * @working_directory: child's current working directory, or %NULL to inherit parent's
+ * @argv: child's argument vector
+ * @envp: child's environment, or %NULL to inherit parent's
+ * @flags: flags from #GSpawnFlags 
+ * @child_setup: function to run in the child just before exec()
+ * @user_data: user data for @child_setup
+ * @standard_output: return location for child output, or %NULL
+ * @standard_error: return location for child error messages, or %NULL
+ * @exit_status: return location for child exit status, as returned by waitpid(), or %NULL
+ * @error: return location for error, or %NULL
+ *
+ * Executes a child synchronously (waits for the child to exit before returning).
+ * All output from the child is stored in @standard_output and @standard_error,
+ * if those parameters are non-%NULL. Note that you must set the  
+ * %G_SPAWN_STDOUT_TO_DEV_NULL and %G_SPAWN_STDERR_TO_DEV_NULL flags when
+ * passing %NULL for @standard_output and @standard_error.
+ * If @exit_status is non-%NULL, the exit status of the child is stored
+ * there as it would be returned by waitpid(); standard UNIX macros such 
+ * as WIFEXITED() and WEXITSTATUS() must be used to evaluate the exit status.
+ * Note that this function call waitpid() even if @exit_status is %NULL, and
+ * does not accept the %G_SPAWN_DO_NOT_REAP_CHILD flag.
+ * If an error occurs, no data is returned in @standard_output, 
+ * @standard_error, or @exit_status. 
+ *
+ * This function calls g_spawn_async_with_pipes() internally; see that
+ * function for full details on the other parameters and details on
+ * how these functions work on Windows.
+ * 
+ * Return value: %TRUE on success, %FALSE if an error was set.
+ **/
+gboolean
+g_spawn_sync (const gchar          *working_directory,
+              gchar               **argv,
+              gchar               **envp,
+              GSpawnFlags           flags,
+              GSpawnChildSetupFunc  child_setup,
+              gpointer              user_data,
+              gchar               **standard_output,
+              gchar               **standard_error,
+              gint                 *exit_status,
+              GError              **error)     
+{
+  gint outpipe = -1;
+  gint errpipe = -1;
+  GPid pid;
+  fd_set fds;
+  gint ret;
+  GString *outstr = NULL;
+  GString *errstr = NULL;
+  gboolean failed;
+  gint status;
+  
+  g_return_val_if_fail (argv != NULL, FALSE);
+  g_return_val_if_fail (!(flags & G_SPAWN_DO_NOT_REAP_CHILD), FALSE);
+  g_return_val_if_fail (standard_output == NULL ||
+                        !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
+  g_return_val_if_fail (standard_error == NULL ||
+                        !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
+  
+  /* Just to ensure segfaults if callers try to use
+   * these when an error is reported.
+   */
+  if (standard_output)
+    *standard_output = NULL;
+
+  if (standard_error)
+    *standard_error = NULL;
+  
+  if (!fork_exec_with_pipes (FALSE,
+                             working_directory,
+                             argv,
+                             envp,
+                             !(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN),
+                             (flags & G_SPAWN_SEARCH_PATH) != 0,
+                             (flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0,
+                             (flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
+                             (flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
+                             (flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0,
+                             child_setup,
+                             user_data,
+                             &pid,
+                             NULL,
+                             standard_output ? &outpipe : NULL,
+                             standard_error ? &errpipe : NULL,
+                             error))
+    return FALSE;
+
+  /* Read data from child. */
+  
+  failed = FALSE;
+
+  if (outpipe >= 0)
+    {
+      outstr = g_string_new (NULL);
+    }
+      
+  if (errpipe >= 0)
+    {
+      errstr = g_string_new (NULL);
+    }
+
+  /* Read data until we get EOF on both pipes. */
+  while (!failed &&
+         (outpipe >= 0 ||
+          errpipe >= 0))
+    {
+      ret = 0;
+          
+      FD_ZERO (&fds);
+      if (outpipe >= 0)
+        FD_SET (outpipe, &fds);
+      if (errpipe >= 0)
+        FD_SET (errpipe, &fds);
+          
+      ret = select (MAX (outpipe, errpipe) + 1,
+                    &fds,
+                    NULL, NULL,
+                    NULL /* no timeout */);
+
+      if (ret < 0 && errno != EINTR)
+        {
+          int errsv = errno;
+
+          failed = TRUE;
+
+          g_set_error (error,
+                       G_SPAWN_ERROR,
+                       G_SPAWN_ERROR_READ,
+                       _("Unexpected error in select() reading data from a child process (%s)"),
+                       g_strerror (errsv));
+              
+          break;
+        }
+
+      if (outpipe >= 0 && FD_ISSET (outpipe, &fds))
+        {
+          switch (read_data (outstr, outpipe, error))
+            {
+            case READ_FAILED:
+              failed = TRUE;
+              break;
+            case READ_EOF:
+              close_and_invalidate (&outpipe);
+              outpipe = -1;
+              break;
+            default:
+              break;
+            }
+
+          if (failed)
+            break;
+        }
+
+      if (errpipe >= 0 && FD_ISSET (errpipe, &fds))
+        {
+          switch (read_data (errstr, errpipe, error))
+            {
+            case READ_FAILED:
+              failed = TRUE;
+              break;
+            case READ_EOF:
+              close_and_invalidate (&errpipe);
+              errpipe = -1;
+              break;
+            default:
+              break;
+            }
+
+          if (failed)
+            break;
+        }
+    }
+
+  /* These should only be open still if we had an error.  */
+  
+  if (outpipe >= 0)
+    close_and_invalidate (&outpipe);
+  if (errpipe >= 0)
+    close_and_invalidate (&errpipe);
+  
+  /* Wait for child to exit, even if we have
+   * an error pending.
+   */
+ again:
+      
+  ret = waitpid (pid, &status, 0);
+
+  if (ret < 0)
+    {
+      if (errno == EINTR)
+        goto again;
+      else if (errno == ECHILD)
+        {
+          if (exit_status)
+            {
+              g_warning ("In call to g_spawn_sync(), exit status of a child process was requested but SIGCHLD action was set to SIG_IGN and ECHILD was received by waitpid(), so exit status can't be returned. This is a bug in the program calling g_spawn_sync(); either don't request the exit status, or don't set the SIGCHLD action.");
+            }
+          else
+            {
+              /* We don't need the exit status. */
+            }
+        }
+      else
+        {
+          if (!failed) /* avoid error pileups */
+            {
+              int errsv = errno;
+
+              failed = TRUE;
+                  
+              g_set_error (error,
+                           G_SPAWN_ERROR,
+                           G_SPAWN_ERROR_READ,
+                           _("Unexpected error in waitpid() (%s)"),
+                           g_strerror (errsv));
+            }
+        }
+    }
+  
+  if (failed)
+    {
+      if (outstr)
+        g_string_free (outstr, TRUE);
+      if (errstr)
+        g_string_free (errstr, TRUE);
+
+      return FALSE;
+    }
+  else
+    {
+      if (exit_status)
+        *exit_status = status;
+      
+      if (standard_output)        
+        *standard_output = g_string_free (outstr, FALSE);
+
+      if (standard_error)
+        *standard_error = g_string_free (errstr, FALSE);
+
+      return TRUE;
+    }
+}
+
+/**
+ * g_spawn_async_with_pipes:
+ * @working_directory: child's current working directory, or %NULL to inherit parent's, in the GLib file name encoding
+ * @argv: child's argument vector, in the GLib file name encoding
+ * @envp: child's environment, or %NULL to inherit parent's, in the GLib file name encoding
+ * @flags: flags from #GSpawnFlags
+ * @child_setup: function to run in the child just before exec()
+ * @user_data: user data for @child_setup
+ * @child_pid: return location for child process ID, or %NULL
+ * @standard_input: return location for file descriptor to write to child's stdin, or %NULL
+ * @standard_output: return location for file descriptor to read child's stdout, or %NULL
+ * @standard_error: return location for file descriptor to read child's stderr, or %NULL
+ * @error: return location for error
+ *
+ * Executes a child program asynchronously (your program will not
+ * block waiting for the child to exit). The child program is
+ * specified by the only argument that must be provided, @argv. @argv
+ * should be a %NULL-terminated array of strings, to be passed as the
+ * argument vector for the child. The first string in @argv is of
+ * course the name of the program to execute. By default, the name of
+ * the program must be a full path; the <envar>PATH</envar> shell variable 
+ * will only be searched if you pass the %G_SPAWN_SEARCH_PATH flag.
+ *
+ * On Windows, note that all the string or string vector arguments to
+ * this function and the other g_spawn*() functions are in UTF-8, the
+ * GLib file name encoding. Unicode characters that are not part of
+ * the system codepage passed in these arguments will be correctly
+ * available in the spawned program only if it uses wide character API
+ * to retrieve its command line. For C programs built with Microsoft's
+ * tools it is enough to make the program have a wmain() instead of
+ * main(). wmain() has a wide character argument vector as parameter.
+ *
+ * At least currently, mingw doesn't support wmain(), so if you use
+ * mingw to develop the spawned program, it will have to call the
+ * undocumented function __wgetmainargs() to get the wide character
+ * argument vector and environment. See gspawn-win32-helper.c in the
+ * GLib sources or init.c in the mingw runtime sources for a prototype
+ * for that function. Alternatively, you can retrieve the Win32 system
+ * level wide character command line passed to the spawned program
+ * using the GetCommandLineW() function.
+ *
+ * On Windows the low-level child process creation API
+ * <function>CreateProcess()</function> doesn't use argument vectors,
+ * but a command line. The C runtime library's
+ * <function>spawn*()</function> family of functions (which
+ * g_spawn_async_with_pipes() eventually calls) paste the argument
+ * vector elements together into a command line, and the C runtime startup code
+ * does a corresponding reconstruction of an argument vector from the
+ * command line, to be passed to main(). Complications arise when you have
+ * argument vector elements that contain spaces of double quotes. The
+ * <function>spawn*()</function> functions don't do any quoting or
+ * escaping, but on the other hand the startup code does do unquoting
+ * and unescaping in order to enable receiving arguments with embedded
+ * spaces or double quotes. To work around this asymmetry,
+ * g_spawn_async_with_pipes() will do quoting and escaping on argument
+ * vector elements that need it before calling the C runtime
+ * spawn() function.
+ *
+ * The returned @child_pid on Windows is a handle to the child
+ * process, not its identifier. Process handles and process
+ * identifiers are different concepts on Windows.
+ *
+ * @envp is a %NULL-terminated array of strings, where each string
+ * has the form <literal>KEY=VALUE</literal>. This will become
+ * the child's environment. If @envp is %NULL, the child inherits its
+ * parent's environment.
+ *
+ * @flags should be the bitwise OR of any flags you want to affect the
+ * function's behaviour. The %G_SPAWN_DO_NOT_REAP_CHILD means that 
+ * the child will not automatically be reaped; you must use a
+ * #GChildWatch source to be notified about the death of the child 
+ * process. Eventually you must call g_spawn_close_pid() on the
+ * @child_pid, in order to free resources which may be associated
+ * with the child process. (On Unix, using a #GChildWatch source is
+ * equivalent to calling waitpid() or handling the %SIGCHLD signal 
+ * manually. On Windows, calling g_spawn_close_pid() is equivalent
+ * to calling CloseHandle() on the process handle returned in 
+ * @child_pid).
+ *
+ * %G_SPAWN_LEAVE_DESCRIPTORS_OPEN means that the parent's open file
+ * descriptors will be inherited by the child; otherwise all
+ * descriptors except stdin/stdout/stderr will be closed before
+ * calling exec() in the child. %G_SPAWN_SEARCH_PATH 
+ * means that <literal>argv[0]</literal> need not be an absolute path, it
+ * will be looked for in the user's <envar>PATH</envar>. 
+ * %G_SPAWN_STDOUT_TO_DEV_NULL means that the child's standard output will 
+ * be discarded, instead of going to the same location as the parent's 
+ * standard output. If you use this flag, @standard_output must be %NULL.
+ * %G_SPAWN_STDERR_TO_DEV_NULL means that the child's standard error
+ * will be discarded, instead of going to the same location as the parent's
+ * standard error. If you use this flag, @standard_error must be %NULL.
+ * %G_SPAWN_CHILD_INHERITS_STDIN means that the child will inherit the parent's
+ * standard input (by default, the child's standard input is attached to
+ * /dev/null). If you use this flag, @standard_input must be %NULL.
+ * %G_SPAWN_FILE_AND_ARGV_ZERO means that the first element of @argv is
+ * the file to execute, while the remaining elements are the
+ * actual argument vector to pass to the file. Normally
+ * g_spawn_async_with_pipes() uses @argv[0] as the file to execute, and
+ * passes all of @argv to the child.
+ *
+ * @child_setup and @user_data are a function and user data. On POSIX
+ * platforms, the function is called in the child after GLib has
+ * performed all the setup it plans to perform (including creating
+ * pipes, closing file descriptors, etc.) but before calling
+ * exec(). That is, @child_setup is called just
+ * before calling exec() in the child. Obviously
+ * actions taken in this function will only affect the child, not the
+ * parent.
+ *
+ * On Windows, there is no separate fork() and exec()
+ * functionality. Child processes are created and run with a single
+ * API call, CreateProcess(). There is no sensible thing @child_setup
+ * could be used for on Windows so it is ignored and not called.
+ *
+ * If non-%NULL, @child_pid will on Unix be filled with the child's
+ * process ID. You can use the process ID to send signals to the
+ * child, or to use g_child_watch_add() (or waitpid()) if you specified the
+ * %G_SPAWN_DO_NOT_REAP_CHILD flag. On Windows, @child_pid will be
+ * filled with a handle to the child process only if you specified the
+ * %G_SPAWN_DO_NOT_REAP_CHILD flag. You can then access the child
+ * process using the Win32 API, for example wait for its termination
+ * with the <function>WaitFor*()</function> functions, or examine its
+ * exit code with GetExitCodeProcess(). You should close the handle 
+ * with CloseHandle() or g_spawn_close_pid() when you no longer need it.
+ *
+ * If non-%NULL, the @standard_input, @standard_output, @standard_error
+ * locations will be filled with file descriptors for writing to the child's
+ * standard input or reading from its standard output or standard error.
+ * The caller of g_spawn_async_with_pipes() must close these file descriptors
+ * when they are no longer in use. If these parameters are %NULL, the corresponding
+ * pipe won't be created.
+ *
+ * If @standard_input is NULL, the child's standard input is attached to 
+ * /dev/null unless %G_SPAWN_CHILD_INHERITS_STDIN is set.
+ *
+ * If @standard_error is NULL, the child's standard error goes to the same 
+ * location as the parent's standard error unless %G_SPAWN_STDERR_TO_DEV_NULL 
+ * is set.
+ *
+ * If @standard_output is NULL, the child's standard output goes to the same 
+ * location as the parent's standard output unless %G_SPAWN_STDOUT_TO_DEV_NULL 
+ * is set.
+ *
+ * @error can be %NULL to ignore errors, or non-%NULL to report errors.
+ * If an error is set, the function returns %FALSE. Errors
+ * are reported even if they occur in the child (for example if the
+ * executable in <literal>argv[0]</literal> is not found). Typically
+ * the <literal>message</literal> field of returned errors should be displayed
+ * to users. Possible errors are those from the #G_SPAWN_ERROR domain.
+ *
+ * If an error occurs, @child_pid, @standard_input, @standard_output,
+ * and @standard_error will not be filled with valid values.
+ *
+ * If @child_pid is not %NULL and an error does not occur then the returned
+ * process reference must be closed using g_spawn_close_pid().
+ *
+ * <note><para>
+ * If you are writing a GTK+ application, and the program you 
+ * are spawning is a graphical application, too, then you may
+ * want to use gdk_spawn_on_screen_with_pipes() instead to ensure that 
+ * the spawned program opens its windows on the right screen.
+ * </para></note>
+ * 
+ * Return value: %TRUE on success, %FALSE if an error was set
+ **/
+gboolean
+g_spawn_async_with_pipes (const gchar          *working_directory,
+                          gchar               **argv,
+                          gchar               **envp,
+                          GSpawnFlags           flags,
+                          GSpawnChildSetupFunc  child_setup,
+                          gpointer              user_data,
+                          GPid                 *child_pid,
+                          gint                 *standard_input,
+                          gint                 *standard_output,
+                          gint                 *standard_error,
+                          GError              **error)
+{
+  g_return_val_if_fail (argv != NULL, FALSE);
+  g_return_val_if_fail (standard_output == NULL ||
+                        !(flags & G_SPAWN_STDOUT_TO_DEV_NULL), FALSE);
+  g_return_val_if_fail (standard_error == NULL ||
+                        !(flags & G_SPAWN_STDERR_TO_DEV_NULL), FALSE);
+  /* can't inherit stdin if we have an input pipe. */
+  g_return_val_if_fail (standard_input == NULL ||
+                        !(flags & G_SPAWN_CHILD_INHERITS_STDIN), FALSE);
+  
+  return fork_exec_with_pipes (!(flags & G_SPAWN_DO_NOT_REAP_CHILD),
+                               working_directory,
+                               argv,
+                               envp,
+                               !(flags & G_SPAWN_LEAVE_DESCRIPTORS_OPEN),
+                               (flags & G_SPAWN_SEARCH_PATH) != 0,
+                               (flags & G_SPAWN_STDOUT_TO_DEV_NULL) != 0,
+                               (flags & G_SPAWN_STDERR_TO_DEV_NULL) != 0,
+                               (flags & G_SPAWN_CHILD_INHERITS_STDIN) != 0,
+                               (flags & G_SPAWN_FILE_AND_ARGV_ZERO) != 0,
+                               child_setup,
+                               user_data,
+                               child_pid,
+                               standard_input,
+                               standard_output,
+                               standard_error,
+                               error);
+}
+
+/**
+ * g_spawn_command_line_sync:
+ * @command_line: a command line 
+ * @standard_output: return location for child output
+ * @standard_error: return location for child errors
+ * @exit_status: return location for child exit status, as returned by waitpid()
+ * @error: return location for errors
+ *
+ * A simple version of g_spawn_sync() with little-used parameters
+ * removed, taking a command line instead of an argument vector.  See
+ * g_spawn_sync() for full details. @command_line will be parsed by
+ * g_shell_parse_argv(). Unlike g_spawn_sync(), the %G_SPAWN_SEARCH_PATH flag
+ * is enabled. Note that %G_SPAWN_SEARCH_PATH can have security
+ * implications, so consider using g_spawn_sync() directly if
+ * appropriate. Possible errors are those from g_spawn_sync() and those
+ * from g_shell_parse_argv().
+ *
+ * If @exit_status is non-%NULL, the exit status of the child is stored there as
+ * it would be returned by waitpid(); standard UNIX macros such as WIFEXITED()
+ * and WEXITSTATUS() must be used to evaluate the exit status.
+ * 
+ * On Windows, please note the implications of g_shell_parse_argv()
+ * parsing @command_line. Parsing is done according to Unix shell rules, not 
+ * Windows command interpreter rules.
+ * Space is a separator, and backslashes are
+ * special. Thus you cannot simply pass a @command_line containing
+ * canonical Windows paths, like "c:\\program files\\app\\app.exe", as
+ * the backslashes will be eaten, and the space will act as a
+ * separator. You need to enclose such paths with single quotes, like
+ * "'c:\\program files\\app\\app.exe' 'e:\\folder\\argument.txt'".
+ *
+ * Return value: %TRUE on success, %FALSE if an error was set
+ **/
+gboolean
+g_spawn_command_line_sync (const gchar  *command_line,
+                           gchar       **standard_output,
+                           gchar       **standard_error,
+                           gint         *exit_status,
+                           GError      **error)
+{
+  gboolean retval;
+  gchar **argv = NULL;
+
+  g_return_val_if_fail (command_line != NULL, FALSE);
+  
+  if (!g_shell_parse_argv (command_line,
+                           NULL, &argv,
+                           error))
+    return FALSE;
+  
+  retval = g_spawn_sync (NULL,
+                         argv,
+                         NULL,
+                         G_SPAWN_SEARCH_PATH,
+                         NULL,
+                         NULL,
+                         standard_output,
+                         standard_error,
+                         exit_status,
+                         error);
+  g_strfreev (argv);
+
+  return retval;
+}
+
+/**
+ * g_spawn_command_line_async:
+ * @command_line: a command line
+ * @error: return location for errors
+ * 
+ * A simple version of g_spawn_async() that parses a command line with
+ * g_shell_parse_argv() and passes it to g_spawn_async(). Runs a
+ * command line in the background. Unlike g_spawn_async(), the
+ * %G_SPAWN_SEARCH_PATH flag is enabled, other flags are not. Note
+ * that %G_SPAWN_SEARCH_PATH can have security implications, so
+ * consider using g_spawn_async() directly if appropriate. Possible
+ * errors are those from g_shell_parse_argv() and g_spawn_async().
+ * 
+ * The same concerns on Windows apply as for g_spawn_command_line_sync().
+ *
+ * Return value: %TRUE on success, %FALSE if error is set.
+ **/
+gboolean
+g_spawn_command_line_async (const gchar *command_line,
+                            GError     **error)
+{
+  gboolean retval;
+  gchar **argv = NULL;
+
+  g_return_val_if_fail (command_line != NULL, FALSE);
+
+  if (!g_shell_parse_argv (command_line,
+                           NULL, &argv,
+                           error))
+    return FALSE;
+  
+  retval = g_spawn_async (NULL,
+                          argv,
+                          NULL,
+                          G_SPAWN_SEARCH_PATH,
+                          NULL,
+                          NULL,
+                          NULL,
+                          error);
+  g_strfreev (argv);
+
+  return retval;
+}
+
+static gint
+exec_err_to_g_error (gint en)
+{
+  switch (en)
+    {
+#ifdef EACCES
+    case EACCES:
+      return G_SPAWN_ERROR_ACCES;
+      break;
+#endif
+
+#ifdef EPERM
+    case EPERM:
+      return G_SPAWN_ERROR_PERM;
+      break;
+#endif
+
+#ifdef E2BIG
+    case E2BIG:
+      return G_SPAWN_ERROR_2BIG;
+      break;
+#endif
+
+#ifdef ENOEXEC
+    case ENOEXEC:
+      return G_SPAWN_ERROR_NOEXEC;
+      break;
+#endif
+
+#ifdef ENAMETOOLONG
+    case ENAMETOOLONG:
+      return G_SPAWN_ERROR_NAMETOOLONG;
+      break;
+#endif
+
+#ifdef ENOENT
+    case ENOENT:
+      return G_SPAWN_ERROR_NOENT;
+      break;
+#endif
+
+#ifdef ENOMEM
+    case ENOMEM:
+      return G_SPAWN_ERROR_NOMEM;
+      break;
+#endif
+
+#ifdef ENOTDIR
+    case ENOTDIR:
+      return G_SPAWN_ERROR_NOTDIR;
+      break;
+#endif
+
+#ifdef ELOOP
+    case ELOOP:
+      return G_SPAWN_ERROR_LOOP;
+      break;
+#endif
+      
+#ifdef ETXTBUSY
+    case ETXTBUSY:
+      return G_SPAWN_ERROR_TXTBUSY;
+      break;
+#endif
+
+#ifdef EIO
+    case EIO:
+      return G_SPAWN_ERROR_IO;
+      break;
+#endif
+
+#ifdef ENFILE
+    case ENFILE:
+      return G_SPAWN_ERROR_NFILE;
+      break;
+#endif
+
+#ifdef EMFILE
+    case EMFILE:
+      return G_SPAWN_ERROR_MFILE;
+      break;
+#endif
+
+#ifdef EINVAL
+    case EINVAL:
+      return G_SPAWN_ERROR_INVAL;
+      break;
+#endif
+
+#ifdef EISDIR
+    case EISDIR:
+      return G_SPAWN_ERROR_ISDIR;
+      break;
+#endif
+
+#ifdef ELIBBAD
+    case ELIBBAD:
+      return G_SPAWN_ERROR_LIBBAD;
+      break;
+#endif
+      
+    default:
+      return G_SPAWN_ERROR_FAILED;
+      break;
+    }
+}
+
+static gssize
+write_all (gint fd, gconstpointer vbuf, gsize to_write)
+{
+  gchar *buf = (gchar *) vbuf;
+  
+  while (to_write > 0)
+    {
+      gssize count = write (fd, buf, to_write);
+      if (count < 0)
+        {
+          if (errno != EINTR)
+            return FALSE;
+        }
+      else
+        {
+          to_write -= count;
+          buf += count;
+        }
+    }
+  
+  return TRUE;
+}
+
+G_GNUC_NORETURN
+static void
+write_err_and_exit (gint fd, gint msg)
+{
+  gint en = errno;
+  
+  write_all (fd, &msg, sizeof(msg));
+  write_all (fd, &en, sizeof(en));
+  
+  _exit (1);
+}
+
+static int
+set_cloexec (void *data, gint fd)
+{
+  if (fd >= GPOINTER_TO_INT (data))
+    fcntl (fd, F_SETFD, FD_CLOEXEC);
+
+  return 0;
+}
+
+#ifndef HAVE_FDWALK
+static int
+fdwalk (int (*cb)(void *data, int fd), void *data)
+{
+  gint open_max;
+  gint fd;
+  gint res = 0;
+  
+#ifdef HAVE_SYS_RESOURCE_H
+  struct rlimit rl;
+#endif
+
+#ifdef __linux__  
+  DIR *d;
+
+  if ((d = opendir("/proc/self/fd"))) {
+      struct dirent *de;
+
+      while ((de = readdir(d))) {
+          glong l;
+          gchar *e = NULL;
+
+          if (de->d_name[0] == '.')
+              continue;
+            
+          errno = 0;
+          l = strtol(de->d_name, &e, 10);
+          if (errno != 0 || !e || *e)
+              continue;
+
+          fd = (gint) l;
+
+          if ((glong) fd != l)
+              continue;
+
+          if (fd == dirfd(d))
+              continue;
+
+          if ((res = cb (data, fd)) != 0)
+              break;
+        }
+      
+      closedir(d);
+      return res;
+  }
+
+  /* If /proc is not mounted or not accessible we fall back to the old
+   * rlimit trick */
+
+#endif
+  
+#ifdef HAVE_SYS_RESOURCE_H
+      
+  if (getrlimit(RLIMIT_NOFILE, &rl) == 0 && rl.rlim_max != RLIM_INFINITY)
+      open_max = rl.rlim_max;
+  else
+#endif
+      open_max = sysconf (_SC_OPEN_MAX);
+
+  for (fd = 0; fd < open_max; fd++)
+      if ((res = cb (data, fd)) != 0)
+          break;
+
+  return res;
+}
+#endif
+
+static gint
+sane_dup2 (gint fd1, gint fd2)
+{
+  gint ret;
+
+ retry:
+  ret = dup2 (fd1, fd2);
+  if (ret < 0 && errno == EINTR)
+    goto retry;
+
+  return ret;
+}
+
+enum
+{
+  CHILD_CHDIR_FAILED,
+  CHILD_EXEC_FAILED,
+  CHILD_DUP2_FAILED,
+  CHILD_FORK_FAILED
+};
+
+static void
+do_exec (gint                  child_err_report_fd,
+         gint                  stdin_fd,
+         gint                  stdout_fd,
+         gint                  stderr_fd,
+         const gchar          *working_directory,
+         gchar               **argv,
+         gchar               **envp,
+         gboolean              close_descriptors,
+         gboolean              search_path,
+         gboolean              stdout_to_null,
+         gboolean              stderr_to_null,
+         gboolean              child_inherits_stdin,
+         gboolean              file_and_argv_zero,
+         GSpawnChildSetupFunc  child_setup,
+         gpointer              user_data)
+{
+  if (working_directory && chdir (working_directory) < 0)
+    write_err_and_exit (child_err_report_fd,
+                        CHILD_CHDIR_FAILED);
+
+  /* Close all file descriptors but stdin stdout and stderr as
+   * soon as we exec. Note that this includes
+   * child_err_report_fd, which keeps the parent from blocking
+   * forever on the other end of that pipe.
+   */
+  if (close_descriptors)
+    {
+      fdwalk (set_cloexec, GINT_TO_POINTER(3));
+    }
+  else
+    {
+      /* We need to do child_err_report_fd anyway */
+      set_cloexec (GINT_TO_POINTER(0), child_err_report_fd);
+    }
+  
+  /* Redirect pipes as required */
+  
+  if (stdin_fd >= 0)
+    {
+      /* dup2 can't actually fail here I don't think */
+          
+      if (sane_dup2 (stdin_fd, 0) < 0)
+        write_err_and_exit (child_err_report_fd,
+                            CHILD_DUP2_FAILED);
+
+      /* ignore this if it doesn't work */
+      close_and_invalidate (&stdin_fd);
+    }
+  else if (!child_inherits_stdin)
+    {
+      /* Keep process from blocking on a read of stdin */
+      gint read_null = open ("/dev/null", O_RDONLY);
+      sane_dup2 (read_null, 0);
+      close_and_invalidate (&read_null);
+    }
+
+  if (stdout_fd >= 0)
+    {
+      /* dup2 can't actually fail here I don't think */
+          
+      if (sane_dup2 (stdout_fd, 1) < 0)
+        write_err_and_exit (child_err_report_fd,
+                            CHILD_DUP2_FAILED);
+
+      /* ignore this if it doesn't work */
+      close_and_invalidate (&stdout_fd);
+    }
+  else if (stdout_to_null)
+    {
+      gint write_null = open ("/dev/null", O_WRONLY);
+      sane_dup2 (write_null, 1);
+      close_and_invalidate (&write_null);
+    }
+
+  if (stderr_fd >= 0)
+    {
+      /* dup2 can't actually fail here I don't think */
+          
+      if (sane_dup2 (stderr_fd, 2) < 0)
+        write_err_and_exit (child_err_report_fd,
+                            CHILD_DUP2_FAILED);
+
+      /* ignore this if it doesn't work */
+      close_and_invalidate (&stderr_fd);
+    }
+  else if (stderr_to_null)
+    {
+      gint write_null = open ("/dev/null", O_WRONLY);
+      sane_dup2 (write_null, 2);
+      close_and_invalidate (&write_null);
+    }
+  
+  /* Call user function just before we exec */
+  if (child_setup)
+    {
+      (* child_setup) (user_data);
+    }
+
+  g_execute (argv[0],
+             file_and_argv_zero ? argv + 1 : argv,
+             envp, search_path);
+
+  /* Exec failed */
+  write_err_and_exit (child_err_report_fd,
+                      CHILD_EXEC_FAILED);
+}
+
+static gboolean
+read_ints (int      fd,
+           gint*    buf,
+           gint     n_ints_in_buf,    
+           gint    *n_ints_read,      
+           GError **error)
+{
+  gsize bytes = 0;    
+  
+  while (TRUE)
+    {
+      gssize chunk;    
+
+      if (bytes >= sizeof(gint)*2)
+        break; /* give up, who knows what happened, should not be
+                * possible.
+                */
+          
+    again:
+      chunk = read (fd,
+                    ((gchar*)buf) + bytes,
+                    sizeof(gint) * n_ints_in_buf - bytes);
+      if (chunk < 0 && errno == EINTR)
+        goto again;
+          
+      if (chunk < 0)
+        {
+          int errsv = errno;
+
+          /* Some weird shit happened, bail out */
+          g_set_error (error,
+                       G_SPAWN_ERROR,
+                       G_SPAWN_ERROR_FAILED,
+                       _("Failed to read from child pipe (%s)"),
+                       g_strerror (errsv));
+
+          return FALSE;
+        }
+      else if (chunk == 0)
+        break; /* EOF */
+      else /* chunk > 0 */
+       bytes += chunk;
+    }
+
+  *n_ints_read = (gint)(bytes / sizeof(gint));
+
+  return TRUE;
+}
+
+static gboolean
+fork_exec_with_pipes (gboolean              intermediate_child,
+                      const gchar          *working_directory,
+                      gchar               **argv,
+                      gchar               **envp,
+                      gboolean              close_descriptors,
+                      gboolean              search_path,
+                      gboolean              stdout_to_null,
+                      gboolean              stderr_to_null,
+                      gboolean              child_inherits_stdin,
+                      gboolean              file_and_argv_zero,
+                      GSpawnChildSetupFunc  child_setup,
+                      gpointer              user_data,
+                      GPid                 *child_pid,
+                      gint                 *standard_input,
+                      gint                 *standard_output,
+                      gint                 *standard_error,
+                      GError              **error)     
+{
+  GPid pid = -1;
+  gint stdin_pipe[2] = { -1, -1 };
+  gint stdout_pipe[2] = { -1, -1 };
+  gint stderr_pipe[2] = { -1, -1 };
+  gint child_err_report_pipe[2] = { -1, -1 };
+  gint child_pid_report_pipe[2] = { -1, -1 };
+  gint status;
+  
+  if (!make_pipe (child_err_report_pipe, error))
+    return FALSE;
+
+  if (intermediate_child && !make_pipe (child_pid_report_pipe, error))
+    goto cleanup_and_fail;
+  
+  if (standard_input && !make_pipe (stdin_pipe, error))
+    goto cleanup_and_fail;
+  
+  if (standard_output && !make_pipe (stdout_pipe, error))
+    goto cleanup_and_fail;
+
+  if (standard_error && !make_pipe (stderr_pipe, error))
+    goto cleanup_and_fail;
+
+  pid = fork ();
+
+  if (pid < 0)
+    {
+      int errsv = errno;
+
+      g_set_error (error,
+                   G_SPAWN_ERROR,
+                   G_SPAWN_ERROR_FORK,
+                   _("Failed to fork (%s)"),
+                   g_strerror (errsv));
+
+      goto cleanup_and_fail;
+    }
+  else if (pid == 0)
+    {
+      /* Immediate child. This may or may not be the child that
+       * actually execs the new process.
+       */
+      
+      /* Be sure we crash if the parent exits
+       * and we write to the err_report_pipe
+       */
+      signal (SIGPIPE, SIG_DFL);
+
+      /* Close the parent's end of the pipes;
+       * not needed in the close_descriptors case,
+       * though
+       */
+      close_and_invalidate (&child_err_report_pipe[0]);
+      close_and_invalidate (&child_pid_report_pipe[0]);
+      close_and_invalidate (&stdin_pipe[1]);
+      close_and_invalidate (&stdout_pipe[0]);
+      close_and_invalidate (&stderr_pipe[0]);
+      
+      if (intermediate_child)
+        {
+          /* We need to fork an intermediate child that launches the
+           * final child. The purpose of the intermediate child
+           * is to exit, so we can waitpid() it immediately.
+           * Then the grandchild will not become a zombie.
+           */
+          GPid grandchild_pid;
+
+          grandchild_pid = fork ();
+
+          if (grandchild_pid < 0)
+            {
+              /* report -1 as child PID */
+              write_all (child_pid_report_pipe[1], &grandchild_pid,
+                         sizeof(grandchild_pid));
+              
+              write_err_and_exit (child_err_report_pipe[1],
+                                  CHILD_FORK_FAILED);              
+            }
+          else if (grandchild_pid == 0)
+            {
+              do_exec (child_err_report_pipe[1],
+                       stdin_pipe[0],
+                       stdout_pipe[1],
+                       stderr_pipe[1],
+                       working_directory,
+                       argv,
+                       envp,
+                       close_descriptors,
+                       search_path,
+                       stdout_to_null,
+                       stderr_to_null,
+                       child_inherits_stdin,
+                       file_and_argv_zero,
+                       child_setup,
+                       user_data);
+            }
+          else
+            {
+              write_all (child_pid_report_pipe[1], &grandchild_pid, sizeof(grandchild_pid));
+              close_and_invalidate (&child_pid_report_pipe[1]);
+              
+              _exit (0);
+            }
+        }
+      else
+        {
+          /* Just run the child.
+           */
+
+          do_exec (child_err_report_pipe[1],
+                   stdin_pipe[0],
+                   stdout_pipe[1],
+                   stderr_pipe[1],
+                   working_directory,
+                   argv,
+                   envp,
+                   close_descriptors,
+                   search_path,
+                   stdout_to_null,
+                   stderr_to_null,
+                   child_inherits_stdin,
+                   file_and_argv_zero,
+                   child_setup,
+                   user_data);
+        }
+    }
+  else
+    {
+      /* Parent */
+      
+      gint buf[2];
+      gint n_ints = 0;    
+
+      /* Close the uncared-about ends of the pipes */
+      close_and_invalidate (&child_err_report_pipe[1]);
+      close_and_invalidate (&child_pid_report_pipe[1]);
+      close_and_invalidate (&stdin_pipe[0]);
+      close_and_invalidate (&stdout_pipe[1]);
+      close_and_invalidate (&stderr_pipe[1]);
+
+      /* If we had an intermediate child, reap it */
+      if (intermediate_child)
+        {
+        wait_again:
+          if (waitpid (pid, &status, 0) < 0)
+            {
+              if (errno == EINTR)
+                goto wait_again;
+              else if (errno == ECHILD)
+                ; /* do nothing, child already reaped */
+              else
+                g_warning ("waitpid() should not fail in "
+                          "'fork_exec_with_pipes'");
+            }
+        }
+      
+
+      if (!read_ints (child_err_report_pipe[0],
+                      buf, 2, &n_ints,
+                      error))
+        goto cleanup_and_fail;
+        
+      if (n_ints >= 2)
+        {
+          /* Error from the child. */
+
+          switch (buf[0])
+            {
+            case CHILD_CHDIR_FAILED:
+              g_set_error (error,
+                           G_SPAWN_ERROR,
+                           G_SPAWN_ERROR_CHDIR,
+                           _("Failed to change to directory '%s' (%s)"),
+                           working_directory,
+                           g_strerror (buf[1]));
+
+              break;
+              
+            case CHILD_EXEC_FAILED:
+              g_set_error (error,
+                           G_SPAWN_ERROR,
+                           exec_err_to_g_error (buf[1]),
+                           _("Failed to execute child process \"%s\" (%s)"),
+                           argv[0],
+                           g_strerror (buf[1]));
+
+              break;
+              
+            case CHILD_DUP2_FAILED:
+              g_set_error (error,
+                           G_SPAWN_ERROR,
+                           G_SPAWN_ERROR_FAILED,
+                           _("Failed to redirect output or input of child process (%s)"),
+                           g_strerror (buf[1]));
+
+              break;
+
+            case CHILD_FORK_FAILED:
+              g_set_error (error,
+                           G_SPAWN_ERROR,
+                           G_SPAWN_ERROR_FORK,
+                           _("Failed to fork child process (%s)"),
+                           g_strerror (buf[1]));
+              break;
+              
+            default:
+              g_set_error (error,
+                           G_SPAWN_ERROR,
+                           G_SPAWN_ERROR_FAILED,
+                           _("Unknown error executing child process \"%s\""),
+                           argv[0]);
+              break;
+            }
+
+          goto cleanup_and_fail;
+        }
+
+      /* Get child pid from intermediate child pipe. */
+      if (intermediate_child)
+        {
+          n_ints = 0;
+          
+          if (!read_ints (child_pid_report_pipe[0],
+                          buf, 1, &n_ints, error))
+            goto cleanup_and_fail;
+
+          if (n_ints < 1)
+            {
+              int errsv = errno;
+
+              g_set_error (error,
+                           G_SPAWN_ERROR,
+                           G_SPAWN_ERROR_FAILED,
+                           _("Failed to read enough data from child pid pipe (%s)"),
+                           g_strerror (errsv));
+              goto cleanup_and_fail;
+            }
+          else
+            {
+              /* we have the child pid */
+              pid = buf[0];
+            }
+        }
+      
+      /* Success against all odds! return the information */
+      close_and_invalidate (&child_err_report_pipe[0]);
+      close_and_invalidate (&child_pid_report_pipe[0]);
+      if (child_pid)
+        *child_pid = pid;
+
+      if (standard_input)
+        *standard_input = stdin_pipe[1];
+      if (standard_output)
+        *standard_output = stdout_pipe[0];
+      if (standard_error)
+        *standard_error = stderr_pipe[0];
+      
+      return TRUE;
+    }
+
+ cleanup_and_fail:
+
+  /* There was an error from the Child, reap the child to avoid it being
+     a zombie.
+   */
+
+  if (pid > 0)
+  {
+    wait_failed:
+     if (waitpid (pid, NULL, 0) < 0)
+       {
+          if (errno == EINTR)
+            goto wait_failed;
+          else if (errno == ECHILD)
+            ; /* do nothing, child already reaped */
+          else
+            g_warning ("waitpid() should not fail in "
+                       "'fork_exec_with_pipes'");
+       }
+   }
+
+  close_and_invalidate (&child_err_report_pipe[0]);
+  close_and_invalidate (&child_err_report_pipe[1]);
+  close_and_invalidate (&child_pid_report_pipe[0]);
+  close_and_invalidate (&child_pid_report_pipe[1]);
+  close_and_invalidate (&stdin_pipe[0]);
+  close_and_invalidate (&stdin_pipe[1]);
+  close_and_invalidate (&stdout_pipe[0]);
+  close_and_invalidate (&stdout_pipe[1]);
+  close_and_invalidate (&stderr_pipe[0]);
+  close_and_invalidate (&stderr_pipe[1]);
+
+  return FALSE;
+}
+
+static gboolean
+make_pipe (gint     p[2],
+           GError **error)
+{
+  if (pipe (p) < 0)
+    {
+      gint errsv = errno;
+      g_set_error (error,
+                   G_SPAWN_ERROR,
+                   G_SPAWN_ERROR_FAILED,
+                   _("Failed to create pipe for communicating with child process (%s)"),
+                   g_strerror (errsv));
+      return FALSE;
+    }
+  else
+    return TRUE;
+}
+
+/* Based on execvp from GNU C Library */
+
+static void
+script_execute (const gchar *file,
+                gchar      **argv,
+                gchar      **envp,
+                gboolean     search_path)
+{
+  /* Count the arguments.  */
+  int argc = 0;
+  while (argv[argc])
+    ++argc;
+  
+  /* Construct an argument list for the shell.  */
+  {
+    gchar **new_argv;
+
+    new_argv = g_new0 (gchar*, argc + 2); /* /bin/sh and NULL */
+    
+    new_argv[0] = (char *) "/bin/sh";
+    new_argv[1] = (char *) file;
+    while (argc > 0)
+      {
+       new_argv[argc + 1] = argv[argc];
+       --argc;
+      }
+
+    /* Execute the shell. */
+    if (envp)
+      execve (new_argv[0], new_argv, envp);
+    else
+      execv (new_argv[0], new_argv);
+    
+    g_free (new_argv);
+  }
+}
+
+static gchar*
+my_strchrnul (const gchar *str, gchar c)
+{
+  gchar *p = (gchar*) str;
+  while (*p && (*p != c))
+    ++p;
+
+  return p;
+}
+
+static gint
+g_execute (const gchar *file,
+           gchar      **argv,
+           gchar      **envp,
+           gboolean     search_path)
+{
+  if (*file == '\0')
+    {
+      /* We check the simple case first. */
+      errno = ENOENT;
+      return -1;
+    }
+
+  if (!search_path || strchr (file, '/') != NULL)
+    {
+      /* Don't search when it contains a slash. */
+      if (envp)
+        execve (file, argv, envp);
+      else
+        execv (file, argv);
+      
+      if (errno == ENOEXEC)
+       script_execute (file, argv, envp, FALSE);
+    }
+  else
+    {
+      gboolean got_eacces = 0;
+      const gchar *path, *p;
+      gchar *name, *freeme;
+      gsize len;
+      gsize pathlen;
+
+      path = g_getenv ("PATH");
+      if (path == NULL)
+       {
+         /* There is no `PATH' in the environment.  The default
+          * search path in libc is the current directory followed by
+          * the path `confstr' returns for `_CS_PATH'.
+           */
+
+          /* In GLib we put . last, for security, and don't use the
+           * unportable confstr(); UNIX98 does not actually specify
+           * what to search if PATH is unset. POSIX may, dunno.
+           */
+          
+          path = "/bin:/usr/bin:.";
+       }
+
+      len = strlen (file) + 1;
+      pathlen = strlen (path);
+      freeme = name = g_malloc (pathlen + len + 1);
+      
+      /* Copy the file name at the top, including '\0'  */
+      memcpy (name + pathlen + 1, file, len);
+      name = name + pathlen;
+      /* And add the slash before the filename  */
+      *name = '/';
+
+      p = path;
+      do
+       {
+         char *startp;
+
+         path = p;
+         p = my_strchrnul (path, ':');
+
+         if (p == path)
+           /* Two adjacent colons, or a colon at the beginning or the end
+             * of `PATH' means to search the current directory.
+             */
+           startp = name + 1;
+         else
+           startp = memcpy (name - (p - path), path, p - path);
+
+         /* Try to execute this name.  If it works, execv will not return.  */
+          if (envp)
+            execve (startp, argv, envp);
+          else
+            execv (startp, argv);
+          
+         if (errno == ENOEXEC)
+           script_execute (startp, argv, envp, search_path);
+
+         switch (errno)
+           {
+           case EACCES:
+             /* Record the we got a `Permission denied' error.  If we end
+               * up finding no executable we can use, we want to diagnose
+               * that we did find one but were denied access.
+               */
+             got_eacces = TRUE;
+
+              /* FALL THRU */
+              
+           case ENOENT:
+#ifdef ESTALE
+           case ESTALE:
+#endif
+#ifdef ENOTDIR
+           case ENOTDIR:
+#endif
+             /* Those errors indicate the file is missing or not executable
+               * by us, in which case we want to just try the next path
+               * directory.
+               */
+             break;
+
+           default:
+             /* Some other error means we found an executable file, but
+               * something went wrong executing it; return the error to our
+               * caller.
+               */
+              g_free (freeme);
+             return -1;
+           }
+       }
+      while (*p++ != '\0');
+
+      /* We tried every element and none of them worked.  */
+      if (got_eacces)
+       /* At least one failure was due to permissions, so report that
+         * error.
+         */
+        errno = EACCES;
+
+      g_free (freeme);
+    }
+
+  /* Return the error from the last attempt (probably ENOENT).  */
+  return -1;
+}
+
+/**
+ * g_spawn_close_pid:
+ * @pid: The process reference to close
+ *
+ * On some platforms, notably Windows, the #GPid type represents a resource
+ * which must be closed to prevent resource leaking. g_spawn_close_pid()
+ * is provided for this purpose. It should be used on all platforms, even
+ * though it doesn't do anything under UNIX.
+ **/
+void
+g_spawn_close_pid (GPid pid)
+{
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gspawn.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gspawn.h
new file mode 100644 (file)
index 0000000..9836b34
--- /dev/null
@@ -0,0 +1,139 @@
+/* gspawn.h - Process launching
+ *
+ *  Copyright 2000 Red Hat, Inc.
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not, write
+ * to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_SPAWN_H__
+#define __G_SPAWN_H__
+
+#include <glib/gerror.h>
+
+G_BEGIN_DECLS
+
+/* I'm not sure I remember our proposed naming convention here. */
+#define G_SPAWN_ERROR g_spawn_error_quark ()
+
+typedef enum
+{
+  G_SPAWN_ERROR_FORK,   /* fork failed due to lack of memory */
+  G_SPAWN_ERROR_READ,   /* read or select on pipes failed */
+  G_SPAWN_ERROR_CHDIR,  /* changing to working dir failed */
+  G_SPAWN_ERROR_ACCES,  /* execv() returned EACCES */
+  G_SPAWN_ERROR_PERM,   /* execv() returned EPERM */
+  G_SPAWN_ERROR_2BIG,   /* execv() returned E2BIG */
+  G_SPAWN_ERROR_NOEXEC, /* execv() returned ENOEXEC */
+  G_SPAWN_ERROR_NAMETOOLONG, /* ""  "" ENAMETOOLONG */
+  G_SPAWN_ERROR_NOENT,       /* ""  "" ENOENT */
+  G_SPAWN_ERROR_NOMEM,       /* ""  "" ENOMEM */
+  G_SPAWN_ERROR_NOTDIR,      /* ""  "" ENOTDIR */
+  G_SPAWN_ERROR_LOOP,        /* ""  "" ELOOP   */
+  G_SPAWN_ERROR_TXTBUSY,     /* ""  "" ETXTBUSY */
+  G_SPAWN_ERROR_IO,          /* ""  "" EIO */
+  G_SPAWN_ERROR_NFILE,       /* ""  "" ENFILE */
+  G_SPAWN_ERROR_MFILE,       /* ""  "" EMFLE */
+  G_SPAWN_ERROR_INVAL,       /* ""  "" EINVAL */
+  G_SPAWN_ERROR_ISDIR,       /* ""  "" EISDIR */
+  G_SPAWN_ERROR_LIBBAD,      /* ""  "" ELIBBAD */
+  G_SPAWN_ERROR_FAILED       /* other fatal failure, error->message
+                              * should explain
+                              */
+} GSpawnError;
+
+typedef void (* GSpawnChildSetupFunc) (gpointer user_data);
+
+typedef enum
+{
+  G_SPAWN_LEAVE_DESCRIPTORS_OPEN = 1 << 0,
+  G_SPAWN_DO_NOT_REAP_CHILD      = 1 << 1,
+  /* look for argv[0] in the path i.e. use execvp() */
+  G_SPAWN_SEARCH_PATH            = 1 << 2,
+  /* Dump output to /dev/null */
+  G_SPAWN_STDOUT_TO_DEV_NULL     = 1 << 3,
+  G_SPAWN_STDERR_TO_DEV_NULL     = 1 << 4,
+  G_SPAWN_CHILD_INHERITS_STDIN   = 1 << 5,
+  G_SPAWN_FILE_AND_ARGV_ZERO     = 1 << 6
+} GSpawnFlags;
+
+GQuark g_spawn_error_quark (void);
+
+#ifdef G_OS_WIN32
+#define g_spawn_async g_spawn_async_utf8
+#define g_spawn_async_with_pipes g_spawn_async_with_pipes_utf8
+#define g_spawn_sync g_spawn_sync_utf8
+#define g_spawn_command_line_sync g_spawn_command_line_sync_utf8
+#define g_spawn_command_line_async g_spawn_command_line_async_utf8
+#endif
+
+gboolean g_spawn_async (const gchar           *working_directory,
+                        gchar                **argv,
+                        gchar                **envp,
+                        GSpawnFlags            flags,
+                        GSpawnChildSetupFunc   child_setup,
+                        gpointer               user_data,
+                        GPid                  *child_pid,
+                        GError               **error);
+
+
+/* Opens pipes for non-NULL standard_output, standard_input, standard_error,
+ * and returns the parent's end of the pipes.
+ */
+gboolean g_spawn_async_with_pipes (const gchar          *working_directory,
+                                   gchar               **argv,
+                                   gchar               **envp,
+                                   GSpawnFlags           flags,
+                                   GSpawnChildSetupFunc  child_setup,
+                                   gpointer              user_data,
+                                   GPid                 *child_pid,
+                                   gint                 *standard_input,
+                                   gint                 *standard_output,
+                                   gint                 *standard_error,
+                                   GError              **error);
+
+
+/* If standard_output or standard_error are non-NULL, the full
+ * standard output or error of the command will be placed there.
+ */
+
+gboolean g_spawn_sync         (const gchar          *working_directory,
+                               gchar               **argv,
+                               gchar               **envp,
+                               GSpawnFlags           flags,
+                               GSpawnChildSetupFunc  child_setup,
+                               gpointer              user_data,
+                               gchar               **standard_output,
+                               gchar               **standard_error,
+                               gint                 *exit_status,
+                               GError              **error);
+
+gboolean g_spawn_command_line_sync  (const gchar          *command_line,
+                                     gchar               **standard_output,
+                                     gchar               **standard_error,
+                                     gint                 *exit_status,
+                                     GError              **error);
+gboolean g_spawn_command_line_async (const gchar          *command_line,
+                                     GError              **error);
+
+void g_spawn_close_pid (GPid pid);
+
+G_END_DECLS
+
+#endif /* __G_SPAWN_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gstdio.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gstdio.c
new file mode 100644 (file)
index 0000000..fb5a9fb
--- /dev/null
@@ -0,0 +1,832 @@
+/* gstdio.c - wrappers for C library functions
+ *
+ * Copyright 2004 Tor Lillqvist
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+#include "glibconfig.h"
+
+#define G_STDIO_NO_WRAP_ON_UNIX
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#include <errno.h>
+#include <wchar.h>
+#include <direct.h>
+#include <io.h>
+#include <sys/utime.h>
+#else
+#include <utime.h>
+#endif
+
+#include "gstdio.h"
+
+
+#if !defined (G_OS_UNIX) && !defined (G_OS_WIN32) && !defined (G_OS_BEOS)
+#error Please port this to your operating system
+#endif
+
+#if defined (_MSC_VER) && !defined(_WIN64)
+#undef _wstat
+#define _wstat _wstat32
+#endif
+
+/**
+ * g_access:
+ * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ * @mode: as in access()
+ *
+ * A wrapper for the POSIX access() function. This function is used to
+ * test a pathname for one or several of read, write or execute
+ * permissions, or just existence.
+ *
+ * On Windows, the file protection mechanism is not at all POSIX-like,
+ * and the underlying function in the C library only checks the
+ * FAT-style READONLY attribute, and does not look at the ACL of a
+ * file at all. This function is this in practise almost useless on
+ * Windows. Software that needs to handle file permissions on Windows
+ * more exactly should use the Win32 API.
+ *
+ * See your C library manual for more details about access().
+ *
+ * Returns: zero if the pathname refers to an existing file system
+ * object that has all the tested permissions, or -1 otherwise or on
+ * error.
+ * 
+ * Since: 2.8
+ */
+int
+g_access (const gchar *filename,
+         int          mode)
+{
+#ifdef G_OS_WIN32
+  wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+  int retval;
+  int save_errno;
+    
+  if (wfilename == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+#ifndef X_OK
+#define X_OK 1
+#endif
+
+  retval = _waccess (wfilename, mode & ~X_OK);
+  save_errno = errno;
+
+  g_free (wfilename);
+
+  errno = save_errno;
+  return retval;
+#else
+  return access (filename, mode);
+#endif
+}
+
+/**
+ * g_chmod:
+ * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ * @mode: as in chmod()
+ *
+ * A wrapper for the POSIX chmod() function. The chmod() function is
+ * used to set the permissions of a file system object.
+ * 
+ * On Windows the file protection mechanism is not at all POSIX-like,
+ * and the underlying chmod() function in the C library just sets or
+ * clears the FAT-style READONLY attribute. It does not touch any
+ * ACL. Software that needs to manage file permissions on Windows
+ * exactly should use the Win32 API.
+ *
+ * See your C library manual for more details about chmod().
+ *
+ * Returns: zero if the operation succeeded, -1 on error.
+ * 
+ * Since: 2.8
+ */
+int
+g_chmod (const gchar *filename,
+        int          mode)
+{
+#ifdef G_OS_WIN32
+  wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+  int retval;
+  int save_errno;
+    
+  if (wfilename == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  retval = _wchmod (wfilename, mode);
+  save_errno = errno;
+
+  g_free (wfilename);
+
+  errno = save_errno;
+  return retval;
+#else
+  return chmod (filename, mode);
+#endif
+}
+/**
+ * g_open:
+ * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ * @flags: as in open()
+ * @mode: as in open()
+ *
+ * A wrapper for the POSIX open() function. The open() function is
+ * used to convert a pathname into a file descriptor.
+ *
+ * On POSIX systems file descriptors are implemented by the operating
+ * system. On Windows, it's the C library that implements open() and
+ * file descriptors. The actual Win32 API for opening files is quite
+ * different, see MSDN documentation for CreateFile(). The Win32 API
+ * uses file handles, which are more randomish integers, not small
+ * integers like file descriptors.
+ *
+ * Because file descriptors are specific to the C library on Windows,
+ * the file descriptor returned by this function makes sense only to
+ * functions in the same C library. Thus if the GLib-using code uses a
+ * different C library than GLib does, the file descriptor returned by
+ * this function cannot be passed to C library functions like write()
+ * or read().
+ *
+ * See your C library manual for more details about open().
+ *
+ * Returns: a new file descriptor, or -1 if an error occurred. The
+ * return value can be used exactly like the return value from open().
+ * 
+ * Since: 2.6
+ */
+int
+g_open (const gchar *filename,
+       int          flags,
+       int          mode)
+{
+#ifdef G_OS_WIN32
+  wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+  int retval;
+  int save_errno;
+    
+  if (wfilename == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  retval = _wopen (wfilename, flags, mode);
+  save_errno = errno;
+
+  g_free (wfilename);
+
+  errno = save_errno;
+  return retval;
+#else
+  return open (filename, flags, mode);
+#endif
+}
+
+/**
+ * g_creat:
+ * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ * @mode: as in creat()
+ *
+ * A wrapper for the POSIX creat() function. The creat() function is
+ * used to convert a pathname into a file descriptor, creating a file
+ * if necessary.
+
+ * On POSIX systems file descriptors are implemented by the operating
+ * system. On Windows, it's the C library that implements creat() and
+ * file descriptors. The actual Windows API for opening files is
+ * different, see MSDN documentation for CreateFile(). The Win32 API
+ * uses file handles, which are more randomish integers, not small
+ * integers like file descriptors.
+ *
+ * Because file descriptors are specific to the C library on Windows,
+ * the file descriptor returned by this function makes sense only to
+ * functions in the same C library. Thus if the GLib-using code uses a
+ * different C library than GLib does, the file descriptor returned by
+ * this function cannot be passed to C library functions like write()
+ * or read().
+ *
+ * See your C library manual for more details about creat().
+ *
+ * Returns: a new file descriptor, or -1 if an error occurred. The
+ * return value can be used exactly like the return value from creat().
+ * 
+ * Since: 2.8
+ */
+int
+g_creat (const gchar *filename,
+        int          mode)
+{
+#ifdef G_OS_WIN32
+  wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+  int retval;
+  int save_errno;
+    
+  if (wfilename == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  retval = _wcreat (wfilename, mode);
+  save_errno = errno;
+
+  g_free (wfilename);
+
+  errno = save_errno;
+  return retval;
+#else
+  return creat (filename, mode);
+#endif
+}
+
+/**
+ * g_rename:
+ * @oldfilename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ * @newfilename: a pathname in the GLib file name encoding
+ *
+ * A wrapper for the POSIX rename() function. The rename() function 
+ * renames a file, moving it between directories if required.
+ * 
+ * See your C library manual for more details about how rename() works
+ * on your system. It is not possible in general on Windows to rename
+ * a file that is open to some process.
+ *
+ * Returns: 0 if the renaming succeeded, -1 if an error occurred
+ * 
+ * Since: 2.6
+ */
+int
+g_rename (const gchar *oldfilename,
+         const gchar *newfilename)
+{
+#ifdef G_OS_WIN32
+  wchar_t *woldfilename = g_utf8_to_utf16 (oldfilename, -1, NULL, NULL, NULL);
+  wchar_t *wnewfilename;
+  int retval;
+  int save_errno = 0;
+
+  if (woldfilename == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  wnewfilename = g_utf8_to_utf16 (newfilename, -1, NULL, NULL, NULL);
+
+  if (wnewfilename == NULL)
+    {
+      g_free (woldfilename);
+      errno = EINVAL;
+      return -1;
+    }
+
+  if (MoveFileExW (woldfilename, wnewfilename, MOVEFILE_REPLACE_EXISTING))
+    retval = 0;
+  else
+    {
+      retval = -1;
+      switch (GetLastError ())
+       {
+#define CASE(a,b) case ERROR_##a: save_errno = b; break
+         CASE (FILE_NOT_FOUND, ENOENT);
+         CASE (PATH_NOT_FOUND, ENOENT);
+         CASE (ACCESS_DENIED, EACCES);
+         CASE (NOT_SAME_DEVICE, EXDEV);
+         CASE (LOCK_VIOLATION, EACCES);
+         CASE (SHARING_VIOLATION, EACCES);
+         CASE (FILE_EXISTS, EEXIST);
+         CASE (ALREADY_EXISTS, EEXIST);
+#undef CASE
+       default: save_errno = EIO;
+       }
+    }
+
+  g_free (woldfilename);
+  g_free (wnewfilename);
+    
+  errno = save_errno;
+  return retval;
+#else
+  return rename (oldfilename, newfilename);
+#endif
+}
+
+/**
+ * g_mkdir: 
+ * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ * @mode: permissions to use for the newly created directory
+ *
+ * A wrapper for the POSIX mkdir() function. The mkdir() function 
+ * attempts to create a directory with the given name and permissions.
+ * The mode argument is ignored on Windows.
+ * 
+ * See your C library manual for more details about mkdir().
+ *
+ * Returns: 0 if the directory was successfully created, -1 if an error 
+ *    occurred
+ * 
+ * Since: 2.6
+ */
+int
+g_mkdir (const gchar *filename,
+        int          mode)
+{
+#ifdef G_OS_WIN32
+  wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+  int retval;
+  int save_errno;
+
+  if (wfilename == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  retval = _wmkdir (wfilename);
+  save_errno = errno;
+
+  g_free (wfilename);
+    
+  errno = save_errno;
+  return retval;
+#else
+  return mkdir (filename, mode);
+#endif
+}
+
+/**
+ * g_chdir: 
+ * @path: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ *
+ * A wrapper for the POSIX chdir() function. The function changes the
+ * current directory of the process to @path.
+ * 
+ * See your C library manual for more details about chdir().
+ *
+ * Returns: 0 on success, -1 if an error occurred.
+ * 
+ * Since: 2.8
+ */
+int
+g_chdir (const gchar *path)
+{
+#ifdef G_OS_WIN32
+  wchar_t *wpath = g_utf8_to_utf16 (path, -1, NULL, NULL, NULL);
+  int retval;
+  int save_errno;
+
+  if (wpath == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  retval = _wchdir (wpath);
+  save_errno = errno;
+
+  g_free (wpath);
+    
+  errno = save_errno;
+  return retval;
+#else
+  return chdir (path);
+#endif
+}
+
+/**
+ * GStatBuf:
+ *
+ * A type corresponding to the appropriate struct type for the stat
+ * system call, depending on the platform and/or compiler being used.
+ *
+ * See g_stat() for more information.
+ **/
+/**
+ * g_stat: 
+ * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ * @buf: a pointer to a <structname>stat</structname> struct, which
+ *    will be filled with the file information
+ *
+ * A wrapper for the POSIX stat() function. The stat() function
+ * returns information about a file. On Windows the stat() function in
+ * the C library checks only the FAT-style READONLY attribute and does
+ * not look at the ACL at all. Thus on Windows the protection bits in
+ * the st_mode field are a fabrication of little use.
+ * 
+ * On Windows the Microsoft C libraries have several variants of the
+ * <structname>stat</structname> struct and stat() function with names
+ * like "_stat", "_stat32", "_stat32i64" and "_stat64i32". The one
+ * used here is for 32-bit code the one with 32-bit size and time
+ * fields, specifically called "_stat32".
+ *
+ * In Microsoft's compiler, by default "struct stat" means one with
+ * 64-bit time fields while in MinGW "struct stat" is the legacy one
+ * with 32-bit fields. To hopefully clear up this messs, the gstdio.h
+ * header defines a type GStatBuf which is the appropriate struct type
+ * depending on the platform and/or compiler being used. On POSIX it
+ * is just "struct stat", but note that even on POSIX platforms,
+ * "stat" might be a macro.
+ *
+ * See your C library manual for more details about stat().
+ *
+ * Returns: 0 if the information was successfully retrieved, -1 if an error 
+ *    occurred
+ * 
+ * Since: 2.6
+ */
+int
+g_stat (const gchar *filename,
+       GStatBuf    *buf)
+{
+#ifdef G_OS_WIN32
+  wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+  int retval;
+  int save_errno;
+  int len;
+
+  if (wfilename == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  len = wcslen (wfilename);
+  while (len > 0 && G_IS_DIR_SEPARATOR (wfilename[len-1]))
+    len--;
+  if (len > 0 &&
+      (!g_path_is_absolute (filename) || len > g_path_skip_root (filename) - filename))
+    wfilename[len] = '\0';
+
+  retval = _wstat (wfilename, buf);
+  save_errno = errno;
+
+  g_free (wfilename);
+
+  errno = save_errno;
+  return retval;
+#else
+  return stat (filename, buf);
+#endif
+}
+
+/**
+ * g_lstat: 
+ * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ * @buf: a pointer to a <structname>stat</structname> struct, which
+ *    will be filled with the file information
+ *
+ * A wrapper for the POSIX lstat() function. The lstat() function is
+ * like stat() except that in the case of symbolic links, it returns
+ * information about the symbolic link itself and not the file that it
+ * refers to. If the system does not support symbolic links g_lstat()
+ * is identical to g_stat().
+ * 
+ * See your C library manual for more details about lstat().
+ *
+ * Returns: 0 if the information was successfully retrieved, -1 if an error 
+ *    occurred
+ * 
+ * Since: 2.6
+ */
+int
+g_lstat (const gchar *filename,
+        GStatBuf    *buf)
+{
+#ifdef HAVE_LSTAT
+  /* This can't be Win32, so don't do the widechar dance. */
+  return lstat (filename, buf);
+#else
+  return g_stat (filename, buf);
+#endif
+}
+
+/**
+ * g_unlink:
+ * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ *
+ * A wrapper for the POSIX unlink() function. The unlink() function 
+ * deletes a name from the filesystem. If this was the last link to the 
+ * file and no processes have it opened, the diskspace occupied by the
+ * file is freed.
+ * 
+ * See your C library manual for more details about unlink(). Note
+ * that on Windows, it is in general not possible to delete files that
+ * are open to some process, or mapped into memory.
+ *
+ * Returns: 0 if the name was successfully deleted, -1 if an error 
+ *    occurred
+ * 
+ * Since: 2.6
+ */
+int
+g_unlink (const gchar *filename)
+{
+#ifdef G_OS_WIN32
+  wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+  int retval;
+  int save_errno;
+
+  if (wfilename == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  retval = _wunlink (wfilename);
+  save_errno = errno;
+
+  g_free (wfilename);
+
+  errno = save_errno;
+  return retval;
+#else
+  return unlink (filename);
+#endif
+}
+
+/**
+ * g_remove:
+ * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ *
+ * A wrapper for the POSIX remove() function. The remove() function
+ * deletes a name from the filesystem.
+ * 
+ * See your C library manual for more details about how remove() works
+ * on your system. On Unix, remove() removes also directories, as it
+ * calls unlink() for files and rmdir() for directories. On Windows,
+ * although remove() in the C library only works for files, this
+ * function tries first remove() and then if that fails rmdir(), and
+ * thus works for both files and directories. Note however, that on
+ * Windows, it is in general not possible to remove a file that is
+ * open to some process, or mapped into memory.
+ *
+ * If this function fails on Windows you can't infer too much from the
+ * errno value. rmdir() is tried regardless of what caused remove() to
+ * fail. Any errno value set by remove() will be overwritten by that
+ * set by rmdir().
+ *
+ * Returns: 0 if the file was successfully removed, -1 if an error 
+ *    occurred
+ * 
+ * Since: 2.6
+ */
+int
+g_remove (const gchar *filename)
+{
+#ifdef G_OS_WIN32
+  wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+  int retval;
+  int save_errno;
+
+  if (wfilename == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+
+  retval = _wremove (wfilename);
+  if (retval == -1)
+    retval = _wrmdir (wfilename);
+  save_errno = errno;
+
+  g_free (wfilename);
+
+  errno = save_errno;
+  return retval;
+#else
+  return remove (filename);
+#endif
+}
+
+/**
+ * g_rmdir:
+ * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ *
+ * A wrapper for the POSIX rmdir() function. The rmdir() function
+ * deletes a directory from the filesystem.
+ * 
+ * See your C library manual for more details about how rmdir() works
+ * on your system.
+ *
+ * Returns: 0 if the directory was successfully removed, -1 if an error 
+ *    occurred
+ * 
+ * Since: 2.6
+ */
+int
+g_rmdir (const gchar *filename)
+{
+#ifdef G_OS_WIN32
+  wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+  int retval;
+  int save_errno;
+
+  if (wfilename == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+  
+  retval = _wrmdir (wfilename);
+  save_errno = errno;
+
+  g_free (wfilename);
+
+  errno = save_errno;
+  return retval;
+#else
+  return rmdir (filename);
+#endif
+}
+
+/**
+ * g_fopen:
+ * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ * @mode: a string describing the mode in which the file should be 
+ *   opened
+ *
+ * A wrapper for the stdio fopen() function. The fopen() function
+ * opens a file and associates a new stream with it.
+ * 
+ * Because file descriptors are specific to the C library on Windows,
+ * and a file descriptor is partof the <type>FILE</type> struct, the
+ * <type>FILE</type> pointer returned by this function makes sense
+ * only to functions in the same C library. Thus if the GLib-using
+ * code uses a different C library than GLib does, the
+ * <type>FILE</type> pointer returned by this function cannot be
+ * passed to C library functions like fprintf() or fread().
+ *
+ * See your C library manual for more details about fopen().
+ *
+ * Returns: A <type>FILE</type> pointer if the file was successfully
+ *    opened, or %NULL if an error occurred
+ * 
+ * Since: 2.6
+ */
+FILE *
+g_fopen (const gchar *filename,
+        const gchar *mode)
+{
+#ifdef G_OS_WIN32
+  wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+  wchar_t *wmode;
+  FILE *retval;
+  int save_errno;
+
+  if (wfilename == NULL)
+    {
+      errno = EINVAL;
+      return NULL;
+    }
+
+  wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
+
+  if (wmode == NULL)
+    {
+      g_free (wfilename);
+      errno = EINVAL;
+      return NULL;
+    }
+
+  retval = _wfopen (wfilename, wmode);
+  save_errno = errno;
+
+  g_free (wfilename);
+  g_free (wmode);
+
+  errno = save_errno;
+  return retval;
+#else
+  return fopen (filename, mode);
+#endif
+}
+
+/**
+ * g_freopen:
+ * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ * @mode: a string describing the mode in which the file should be 
+ *   opened
+ * @stream: an existing stream which will be reused, or %NULL
+ *
+ * A wrapper for the POSIX freopen() function. The freopen() function
+ * opens a file and associates it with an existing stream.
+ * 
+ * See your C library manual for more details about freopen().
+ *
+ * Returns: A <type>FILE</type> pointer if the file was successfully
+ *    opened, or %NULL if an error occurred.
+ * 
+ * Since: 2.6
+ */
+FILE *
+g_freopen (const gchar *filename,
+          const gchar *mode,
+          FILE        *stream)
+{
+#ifdef G_OS_WIN32
+  wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+  wchar_t *wmode;
+  FILE *retval;
+  int save_errno;
+
+  if (wfilename == NULL)
+    {
+      errno = EINVAL;
+      return NULL;
+    }
+  
+  wmode = g_utf8_to_utf16 (mode, -1, NULL, NULL, NULL);
+
+  if (wmode == NULL)
+    {
+      g_free (wfilename);
+      errno = EINVAL;
+      return NULL;
+    }
+  
+  retval = _wfreopen (wfilename, wmode, stream);
+  save_errno = errno;
+
+  g_free (wfilename);
+  g_free (wmode);
+
+  errno = save_errno;
+  return retval;
+#else
+  return freopen (filename, mode, stream);
+#endif
+}
+
+/**
+ * g_utime:
+ * @filename: a pathname in the GLib file name encoding (UTF-8 on Windows)
+ * @utb: a pointer to a struct utimbuf.
+ *
+ * A wrapper for the POSIX utime() function. The utime() function
+ * sets the access and modification timestamps of a file.
+ * 
+ * See your C library manual for more details about how utime() works
+ * on your system.
+ *
+ * Returns: 0 if the operation was successful, -1 if an error 
+ *    occurred
+ * 
+ * Since: 2.18
+ */
+int
+g_utime (const gchar    *filename,
+        struct utimbuf *utb)
+{
+#ifdef G_OS_WIN32
+  wchar_t *wfilename = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+  int retval;
+  int save_errno;
+
+  if (wfilename == NULL)
+    {
+      errno = EINVAL;
+      return -1;
+    }
+  
+  retval = _wutime (wfilename, (struct _utimbuf*) utb);
+  save_errno = errno;
+
+  g_free (wfilename);
+
+  errno = save_errno;
+  return retval;
+#else
+  return utime (filename, utb);
+#endif
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gstdio.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gstdio.h
new file mode 100644 (file)
index 0000000..b92eb6c
--- /dev/null
@@ -0,0 +1,147 @@
+/* gstdio.h - GFilename wrappers for C library functions
+ *
+ * Copyright 2004 Tor Lillqvist
+ *
+ * GLib 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 of the
+ * License, or (at your option) any later version.
+ *
+ * GLib 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 GLib; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_STDIO_H__
+#define __G_STDIO_H__
+
+#include <glib/gprintf.h>
+
+#include <sys/stat.h>
+
+G_BEGIN_DECLS
+
+#if defined (_MSC_VER) && !defined(_WIN64)
+
+/* Make it clear that we mean the struct with 32-bit st_size and
+ * 32-bit st_*time fields as that is how the 32-bit GLib DLL normally
+ * has been compiled. If you get a compiler warning when calling
+ * g_stat(), do take it seriously and make sure that the type of
+ * struct stat the code in GLib fills in matches the struct the type
+ * of struct stat you pass to g_stat(). To avoid hassle, to get file
+ * attributes just use the GIO API instead which doesn't use struct
+ * stat.
+ *
+ * Sure, it would be nicer to use a struct with 64-bit st_size and
+ * 64-bit st_*time fields, but changing that now would break ABI. And
+ * in MinGW, a plain "struct stat" is the one with 32-bit st_size and
+ * st_*time fields.
+ */
+
+typedef struct _stat32 GStatBuf;
+
+#else
+
+typedef struct stat GStatBuf;
+
+#endif
+
+#if defined(G_OS_UNIX) && !defined(G_STDIO_NO_WRAP_ON_UNIX)
+
+/* Just pass on to the system functions, so there's no potential for data
+ * format mismatches, especially with large file interfaces. 
+ * A few functions can't be handled in this way, since they are not defined
+ * in a portable system header that we could include here.
+ */
+
+#define g_chmod   chmod
+#define g_open    open
+#define g_creat   creat
+#define g_rename  rename
+#define g_mkdir   mkdir
+#define g_stat    stat
+#define g_lstat   lstat
+#define g_remove  remove
+#define g_fopen   fopen
+#define g_freopen freopen
+#define g_utime   utime
+
+int g_access (const gchar *filename,
+             int          mode);
+
+int g_chdir  (const gchar *path);
+
+int g_unlink (const gchar *filename);
+
+int g_rmdir  (const gchar *filename);
+
+#else /* ! G_OS_UNIX */
+
+/* Wrappers for C library functions that take pathname arguments. On
+ * Unix, the pathname is a file name as it literally is in the file
+ * system. On well-maintained systems with consistent users who know
+ * what they are doing and no exchange of files with others this would
+ * be a well-defined encoding, preferrably UTF-8. On Windows, the
+ * pathname is always in UTF-8, even if that is not the on-disk
+ * encoding, and not the encoding accepted by the C library or Win32
+ * API.
+ */
+
+int g_access    (const gchar *filename,
+                int          mode);
+
+int g_chmod     (const gchar *filename,
+                int          mode);
+
+int g_open      (const gchar *filename,
+                 int          flags,
+                 int          mode);
+
+int g_creat     (const gchar *filename,
+                 int          mode);
+
+int g_rename    (const gchar *oldfilename,
+                 const gchar *newfilename);
+
+int g_mkdir     (const gchar *filename,
+                 int          mode);
+
+int g_chdir     (const gchar *path);
+
+int g_stat      (const gchar *filename,
+                 GStatBuf    *buf);
+
+int g_lstat     (const gchar *filename,
+                 GStatBuf    *buf);
+
+int g_unlink    (const gchar *filename);
+
+int g_remove    (const gchar *filename);
+
+int g_rmdir     (const gchar *filename);
+
+FILE *g_fopen   (const gchar *filename,
+                 const gchar *mode);
+
+FILE *g_freopen (const gchar *filename,
+                 const gchar *mode,
+                 FILE        *stream);
+
+struct utimbuf;                        /* Don't need the real definition of struct utimbuf when just
+                                * including this header.
+                                */
+
+int g_utime     (const gchar    *filename,
+                struct utimbuf *utb);
+
+#endif /* G_OS_UNIX */
+
+G_END_DECLS
+
+#endif /* __G_STDIO_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gstrfuncs.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gstrfuncs.c
new file mode 100644 (file)
index 0000000..56a5d3b
--- /dev/null
@@ -0,0 +1,3297 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#define _GNU_SOURCE             /* For stpcpy */
+
+#include <stdarg.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <locale.h>
+#include <errno.h>
+#include <ctype.h>              /* For tolower() */
+#if !defined (HAVE_STRSIGNAL) || !defined(NO_SYS_SIGLIST_DECL)
+#include <signal.h>
+#endif
+
+#include "gstrfuncs.h"
+
+#include "gprintf.h"
+#include "gprintfint.h"
+#include "glibintl.h"
+
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#endif
+
+/* do not include <unistd.h> in this place since it
+ * interferes with g_strsignal() on some OSes
+ */
+
+static const guint16 ascii_table_data[256] = {
+  0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
+  0x004, 0x104, 0x104, 0x004, 0x104, 0x104, 0x004, 0x004,
+  0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
+  0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004, 0x004,
+  0x140, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
+  0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
+  0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459, 0x459,
+  0x459, 0x459, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
+  0x0d0, 0x653, 0x653, 0x653, 0x653, 0x653, 0x653, 0x253,
+  0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
+  0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253, 0x253,
+  0x253, 0x253, 0x253, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x0d0,
+  0x0d0, 0x473, 0x473, 0x473, 0x473, 0x473, 0x473, 0x073,
+  0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
+  0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073, 0x073,
+  0x073, 0x073, 0x073, 0x0d0, 0x0d0, 0x0d0, 0x0d0, 0x004
+  /* the upper 128 are all zeroes */
+};
+
+const guint16 * const g_ascii_table = ascii_table_data;
+
+/**
+ * g_strdup:
+ * @str: the string to duplicate
+ *
+ * Duplicates a string. If @str is %NULL it returns %NULL.
+ * The returned string should be freed with g_free()
+ * when no longer needed.
+ *
+ * Returns: a newly-allocated copy of @str
+ */
+gchar*
+g_strdup (const gchar *str)
+{
+  gchar *new_str;
+  gsize length;
+
+  if (str)
+    {
+      length = strlen (str) + 1;
+      new_str = g_new (char, length);
+      memcpy (new_str, str, length);
+    }
+  else
+    new_str = NULL;
+
+  return new_str;
+}
+
+/**
+ * g_memdup:
+ * @mem: the memory to copy.
+ * @byte_size: the number of bytes to copy.
+ *
+ * Allocates @byte_size bytes of memory, and copies @byte_size bytes into it
+ * from @mem. If @mem is %NULL it returns %NULL.
+ *
+ * Returns: a pointer to the newly-allocated copy of the memory, or %NULL if @mem
+ *  is %NULL.
+ */
+gpointer
+g_memdup (gconstpointer mem,
+          guint         byte_size)
+{
+  gpointer new_mem;
+
+  if (mem)
+    {
+      new_mem = g_malloc (byte_size);
+      memcpy (new_mem, mem, byte_size);
+    }
+  else
+    new_mem = NULL;
+
+  return new_mem;
+}
+
+/**
+ * g_strndup:
+ * @str: the string to duplicate
+ * @n: the maximum number of bytes to copy from @str
+ *
+ * Duplicates the first @n bytes of a string, returning a newly-allocated
+ * buffer @n + 1 bytes long which will always be nul-terminated.
+ * If @str is less than @n bytes long the buffer is padded with nuls.
+ * If @str is %NULL it returns %NULL.
+ * The returned value should be freed when no longer needed.
+ *
+ * <note><para>
+ * To copy a number of characters from a UTF-8 encoded string, use
+ * g_utf8_strncpy() instead.
+ * </para></note>
+ *
+ * Returns: a newly-allocated buffer containing the first @n bytes
+ *          of @str, nul-terminated
+ */
+gchar*
+g_strndup (const gchar *str,
+           gsize        n)
+{
+  gchar *new_str;
+
+  if (str)
+    {
+      new_str = g_new (gchar, n + 1);
+      strncpy (new_str, str, n);
+      new_str[n] = '\0';
+    }
+  else
+    new_str = NULL;
+
+  return new_str;
+}
+
+/**
+ * g_strnfill:
+ * @length: the length of the new string
+ * @fill_char: the byte to fill the string with
+ *
+ * Creates a new string @length bytes long filled with @fill_char.
+ * The returned string should be freed when no longer needed.
+ *
+ * Returns: a newly-allocated string filled the @fill_char
+ */
+gchar*
+g_strnfill (gsize length,
+            gchar fill_char)
+{
+  gchar *str;
+
+  str = g_new (gchar, length + 1);
+  memset (str, (guchar)fill_char, length);
+  str[length] = '\0';
+
+  return str;
+}
+
+/**
+ * g_stpcpy:
+ * @dest: destination buffer.
+ * @src: source string.
+ *
+ * Copies a nul-terminated string into the dest buffer, include the
+ * trailing nul, and return a pointer to the trailing nul byte.
+ * This is useful for concatenating multiple strings together
+ * without having to repeatedly scan for the end.
+ *
+ * Return value: a pointer to trailing nul byte.
+ **/
+gchar *
+g_stpcpy (gchar       *dest,
+          const gchar *src)
+{
+#ifdef HAVE_STPCPY
+  g_return_val_if_fail (dest != NULL, NULL);
+  g_return_val_if_fail (src != NULL, NULL);
+  return stpcpy (dest, src);
+#else
+  register gchar *d = dest;
+  register const gchar *s = src;
+
+  g_return_val_if_fail (dest != NULL, NULL);
+  g_return_val_if_fail (src != NULL, NULL);
+  do
+    *d++ = *s;
+  while (*s++ != '\0');
+
+  return d - 1;
+#endif
+}
+
+/**
+ * g_strdup_vprintf:
+ * @format: a standard printf() format string, but notice
+ *     <link linkend="string-precision">string precision pitfalls</link>
+ * @args: the list of parameters to insert into the format string
+ *
+ * Similar to the standard C vsprintf() function but safer, since it
+ * calculates the maximum space required and allocates memory to hold
+ * the result. The returned string should be freed with g_free() when
+ * no longer needed.
+ *
+ * See also g_vasprintf(), which offers the same functionality, but
+ * additionally returns the length of the allocated string.
+ *
+ * Returns: a newly-allocated string holding the result
+ */
+gchar*
+g_strdup_vprintf (const gchar *format,
+                  va_list      args)
+{
+  gchar *string = NULL;
+
+  g_vasprintf (&string, format, args);
+
+  return string;
+}
+
+/**
+ * g_strdup_printf:
+ * @format: a standard printf() format string, but notice
+ *     <link linkend="string-precision">string precision pitfalls</link>
+ * @Varargs: the parameters to insert into the format string
+ *
+ * Similar to the standard C sprintf() function but safer, since it
+ * calculates the maximum space required and allocates memory to hold
+ * the result. The returned string should be freed with g_free() when no
+ * longer needed.
+ *
+ * Returns: a newly-allocated string holding the result
+ */
+gchar*
+g_strdup_printf (const gchar *format,
+                 ...)
+{
+  gchar *buffer;
+  va_list args;
+
+  va_start (args, format);
+  buffer = g_strdup_vprintf (format, args);
+  va_end (args);
+
+  return buffer;
+}
+
+/**
+ * g_strconcat:
+ * @string1: the first string to add, which must not be %NULL
+ * @Varargs: a %NULL-terminated list of strings to append to the string
+ *
+ * Concatenates all of the given strings into one long string.
+ * The returned string should be freed with g_free() when no longer needed.
+ *
+ * Note that this function is usually not the right function to use to
+ * assemble a translated message from pieces, since proper translation
+ * often requires the pieces to be reordered.
+ *
+ * <warning><para>The variable argument list <emphasis>must</emphasis> end
+ * with %NULL. If you forget the %NULL, g_strconcat() will start appending
+ * random memory junk to your string.</para></warning>
+ *
+ * Returns: a newly-allocated string containing all the string arguments
+ */
+gchar*
+g_strconcat (const gchar *string1, ...)
+{
+  gsize   l;
+  va_list args;
+  gchar   *s;
+  gchar   *concat;
+  gchar   *ptr;
+
+  if (!string1)
+    return NULL;
+
+  l = 1 + strlen (string1);
+  va_start (args, string1);
+  s = va_arg (args, gchar*);
+  while (s)
+    {
+      l += strlen (s);
+      s = va_arg (args, gchar*);
+    }
+  va_end (args);
+
+  concat = g_new (gchar, l);
+  ptr = concat;
+
+  ptr = g_stpcpy (ptr, string1);
+  va_start (args, string1);
+  s = va_arg (args, gchar*);
+  while (s)
+    {
+      ptr = g_stpcpy (ptr, s);
+      s = va_arg (args, gchar*);
+    }
+  va_end (args);
+
+  return concat;
+}
+
+/**
+ * g_strtod:
+ * @nptr:    the string to convert to a numeric value.
+ * @endptr:  if non-%NULL, it returns the character after
+ *           the last character used in the conversion.
+ *
+ * Converts a string to a #gdouble value.
+ * It calls the standard strtod() function to handle the conversion, but
+ * if the string is not completely converted it attempts the conversion
+ * again with g_ascii_strtod(), and returns the best match.
+ *
+ * This function should seldomly be used. The normal situation when reading
+ * numbers not for human consumption is to use g_ascii_strtod(). Only when
+ * you know that you must expect both locale formatted and C formatted numbers
+ * should you use this. Make sure that you don't pass strings such as comma
+ * separated lists of values, since the commas may be interpreted as a decimal
+ * point in some locales, causing unexpected results.
+ *
+ * Return value: the #gdouble value.
+ **/
+gdouble
+g_strtod (const gchar *nptr,
+          gchar      **endptr)
+{
+  gchar *fail_pos_1;
+  gchar *fail_pos_2;
+  gdouble val_1;
+  gdouble val_2 = 0;
+
+  g_return_val_if_fail (nptr != NULL, 0);
+
+  fail_pos_1 = NULL;
+  fail_pos_2 = NULL;
+
+  val_1 = strtod (nptr, &fail_pos_1);
+
+  if (fail_pos_1 && fail_pos_1[0] != 0)
+    val_2 = g_ascii_strtod (nptr, &fail_pos_2);
+
+  if (!fail_pos_1 || fail_pos_1[0] == 0 || fail_pos_1 >= fail_pos_2)
+    {
+      if (endptr)
+        *endptr = fail_pos_1;
+      return val_1;
+    }
+  else
+    {
+      if (endptr)
+        *endptr = fail_pos_2;
+      return val_2;
+    }
+}
+
+/**
+ * g_ascii_strtod:
+ * @nptr:    the string to convert to a numeric value.
+ * @endptr:  if non-%NULL, it returns the character after
+ *           the last character used in the conversion.
+ *
+ * Converts a string to a #gdouble value.
+ *
+ * This function behaves like the standard strtod() function
+ * does in the C locale. It does this without actually changing
+ * the current locale, since that would not be thread-safe.
+ * A limitation of the implementation is that this function
+ * will still accept localized versions of infinities and NANs.
+ *
+ * This function is typically used when reading configuration
+ * files or other non-user input that should be locale independent.
+ * To handle input from the user you should normally use the
+ * locale-sensitive system strtod() function.
+ *
+ * To convert from a #gdouble to a string in a locale-insensitive
+ * way, use g_ascii_dtostr().
+ *
+ * If the correct value would cause overflow, plus or minus %HUGE_VAL
+ * is returned (according to the sign of the value), and %ERANGE is
+ * stored in %errno. If the correct value would cause underflow,
+ * zero is returned and %ERANGE is stored in %errno.
+ *
+ * This function resets %errno before calling strtod() so that
+ * you can reliably detect overflow and underflow.
+ *
+ * Return value: the #gdouble value.
+ **/
+gdouble
+g_ascii_strtod (const gchar *nptr,
+                gchar      **endptr)
+{
+  gchar *fail_pos;
+  gdouble val;
+#ifndef BUILD_WITH_ANDROID
+  struct lconv *locale_data;
+#endif
+  const char *decimal_point;
+  int decimal_point_len;
+  const char *p, *decimal_point_pos;
+  const char *end = NULL; /* Silence gcc */
+  int strtod_errno;
+
+  g_return_val_if_fail (nptr != NULL, 0);
+
+  fail_pos = NULL;
+
+#ifndef BUILD_WITH_ANDROID
+  locale_data = localeconv ();
+  decimal_point = locale_data->decimal_point;
+#else
+  decimal_point = ".";
+#endif
+  decimal_point_len = strlen (decimal_point);
+
+  g_assert (decimal_point_len != 0);
+
+  decimal_point_pos = NULL;
+  end = NULL;
+
+  if (decimal_point[0] != '.' ||
+      decimal_point[1] != 0)
+    {
+      p = nptr;
+      /* Skip leading space */
+      while (g_ascii_isspace (*p))
+        p++;
+
+      /* Skip leading optional sign */
+      if (*p == '+' || *p == '-')
+        p++;
+
+      if (p[0] == '0' &&
+          (p[1] == 'x' || p[1] == 'X'))
+        {
+          p += 2;
+          /* HEX - find the (optional) decimal point */
+
+          while (g_ascii_isxdigit (*p))
+            p++;
+
+          if (*p == '.')
+            decimal_point_pos = p++;
+
+          while (g_ascii_isxdigit (*p))
+            p++;
+
+          if (*p == 'p' || *p == 'P')
+            p++;
+          if (*p == '+' || *p == '-')
+            p++;
+          while (g_ascii_isdigit (*p))
+            p++;
+
+          end = p;
+        }
+      else if (g_ascii_isdigit (*p) || *p == '.')
+        {
+          while (g_ascii_isdigit (*p))
+            p++;
+
+          if (*p == '.')
+            decimal_point_pos = p++;
+
+          while (g_ascii_isdigit (*p))
+            p++;
+
+          if (*p == 'e' || *p == 'E')
+            p++;
+          if (*p == '+' || *p == '-')
+            p++;
+          while (g_ascii_isdigit (*p))
+            p++;
+
+          end = p;
+        }
+      /* For the other cases, we need not convert the decimal point */
+    }
+
+  if (decimal_point_pos)
+    {
+      char *copy, *c;
+
+      /* We need to convert the '.' to the locale specific decimal point */
+      copy = g_malloc (end - nptr + 1 + decimal_point_len);
+
+      c = copy;
+      memcpy (c, nptr, decimal_point_pos - nptr);
+      c += decimal_point_pos - nptr;
+      memcpy (c, decimal_point, decimal_point_len);
+      c += decimal_point_len;
+      memcpy (c, decimal_point_pos + 1, end - (decimal_point_pos + 1));
+      c += end - (decimal_point_pos + 1);
+      *c = 0;
+
+      errno = 0;
+      val = strtod (copy, &fail_pos);
+      strtod_errno = errno;
+
+      if (fail_pos)
+        {
+          if (fail_pos - copy > decimal_point_pos - nptr)
+            fail_pos = (char *)nptr + (fail_pos - copy) - (decimal_point_len - 1);
+          else
+            fail_pos = (char *)nptr + (fail_pos - copy);
+        }
+
+      g_free (copy);
+
+    }
+  else if (end)
+    {
+      char *copy;
+
+      copy = g_malloc (end - (char *)nptr + 1);
+      memcpy (copy, nptr, end - nptr);
+      *(copy + (end - (char *)nptr)) = 0;
+
+      errno = 0;
+      val = strtod (copy, &fail_pos);
+      strtod_errno = errno;
+
+      if (fail_pos)
+        {
+          fail_pos = (char *)nptr + (fail_pos - copy);
+        }
+
+      g_free (copy);
+    }
+  else
+    {
+      errno = 0;
+      val = strtod (nptr, &fail_pos);
+      strtod_errno = errno;
+    }
+
+  if (endptr)
+    *endptr = fail_pos;
+
+  errno = strtod_errno;
+
+  return val;
+}
+
+
+/**
+ * g_ascii_dtostr:
+ * @buffer: A buffer to place the resulting string in
+ * @buf_len: The length of the buffer.
+ * @d: The #gdouble to convert
+ *
+ * Converts a #gdouble to a string, using the '.' as
+ * decimal point.
+ *
+ * This functions generates enough precision that converting
+ * the string back using g_ascii_strtod() gives the same machine-number
+ * (on machines with IEEE compatible 64bit doubles). It is
+ * guaranteed that the size of the resulting string will never
+ * be larger than @G_ASCII_DTOSTR_BUF_SIZE bytes.
+ *
+ * Return value: The pointer to the buffer with the converted string.
+ **/
+gchar *
+g_ascii_dtostr (gchar       *buffer,
+                gint         buf_len,
+                gdouble      d)
+{
+  return g_ascii_formatd (buffer, buf_len, "%.17g", d);
+}
+
+/**
+ * g_ascii_formatd:
+ * @buffer: A buffer to place the resulting string in
+ * @buf_len: The length of the buffer.
+ * @format: The printf()-style format to use for the
+ *          code to use for converting.
+ * @d: The #gdouble to convert
+ *
+ * Converts a #gdouble to a string, using the '.' as
+ * decimal point. To format the number you pass in
+ * a printf()-style format string. Allowed conversion
+ * specifiers are 'e', 'E', 'f', 'F', 'g' and 'G'.
+ *
+ * If you just want to want to serialize the value into a
+ * string, use g_ascii_dtostr().
+ *
+ * Return value: The pointer to the buffer with the converted string.
+ */
+gchar *
+g_ascii_formatd (gchar       *buffer,
+                 gint         buf_len,
+                 const gchar *format,
+                 gdouble      d)
+{
+#ifndef BUILD_WITH_ANDROID
+  struct lconv *locale_data;
+#endif
+  const char *decimal_point;
+  int decimal_point_len;
+  gchar *p;
+  int rest_len;
+  gchar format_char;
+
+  g_return_val_if_fail (buffer != NULL, NULL);
+  g_return_val_if_fail (format[0] == '%', NULL);
+  g_return_val_if_fail (strpbrk (format + 1, "'l%") == NULL, NULL);
+
+  format_char = format[strlen (format) - 1];
+
+  g_return_val_if_fail (format_char == 'e' || format_char == 'E' ||
+                        format_char == 'f' || format_char == 'F' ||
+                        format_char == 'g' || format_char == 'G',
+                        NULL);
+
+  if (format[0] != '%')
+    return NULL;
+
+  if (strpbrk (format + 1, "'l%"))
+    return NULL;
+
+  if (!(format_char == 'e' || format_char == 'E' ||
+        format_char == 'f' || format_char == 'F' ||
+        format_char == 'g' || format_char == 'G'))
+    return NULL;
+
+  _g_snprintf (buffer, buf_len, format, d);
+
+#ifndef BUILD_WITH_ANDROID
+  locale_data = localeconv ();
+  decimal_point = locale_data->decimal_point;
+#else
+  decimal_point = ".";
+#endif
+  decimal_point_len = strlen (decimal_point);
+
+  g_assert (decimal_point_len != 0);
+
+  if (decimal_point[0] != '.' ||
+      decimal_point[1] != 0)
+    {
+      p = buffer;
+
+      while (g_ascii_isspace (*p))
+        p++;
+
+      if (*p == '+' || *p == '-')
+        p++;
+
+      while (isdigit ((guchar)*p))
+        p++;
+
+      if (strncmp (p, decimal_point, decimal_point_len) == 0)
+        {
+          *p = '.';
+          p++;
+          if (decimal_point_len > 1)
+            {
+              rest_len = strlen (p + (decimal_point_len-1));
+              memmove (p, p + (decimal_point_len-1), rest_len);
+              p[rest_len] = 0;
+            }
+        }
+    }
+
+  return buffer;
+}
+
+static guint64
+g_parse_long_long (const gchar  *nptr,
+                   const gchar **endptr,
+                   guint         base,
+                   gboolean     *negative)
+{
+  /* this code is based on on the strtol(3) code from GNU libc released under
+   * the GNU Lesser General Public License.
+   *
+   * Copyright (C) 1991,92,94,95,96,97,98,99,2000,01,02
+   *        Free Software Foundation, Inc.
+   */
+#define ISSPACE(c)              ((c) == ' ' || (c) == '\f' || (c) == '\n' || \
+                                 (c) == '\r' || (c) == '\t' || (c) == '\v')
+#define ISUPPER(c)              ((c) >= 'A' && (c) <= 'Z')
+#define ISLOWER(c)              ((c) >= 'a' && (c) <= 'z')
+#define ISALPHA(c)              (ISUPPER (c) || ISLOWER (c))
+#define TOUPPER(c)              (ISLOWER (c) ? (c) - 'a' + 'A' : (c))
+#define TOLOWER(c)              (ISUPPER (c) ? (c) - 'A' + 'a' : (c))
+  gboolean overflow;
+  guint64 cutoff;
+  guint64 cutlim;
+  guint64 ui64;
+  const gchar *s, *save;
+  guchar c;
+
+  g_return_val_if_fail (nptr != NULL, 0);
+
+  *negative = FALSE;
+  if (base == 1 || base > 36)
+    {
+      errno = EINVAL;
+      if (endptr)
+        *endptr = nptr;
+      return 0;
+    }
+
+  save = s = nptr;
+
+  /* Skip white space.  */
+  while (ISSPACE (*s))
+    ++s;
+
+  if (G_UNLIKELY (!*s))
+    goto noconv;
+
+  /* Check for a sign.  */
+  if (*s == '-')
+    {
+      *negative = TRUE;
+      ++s;
+    }
+  else if (*s == '+')
+    ++s;
+
+  /* Recognize number prefix and if BASE is zero, figure it out ourselves.  */
+  if (*s == '0')
+    {
+      if ((base == 0 || base == 16) && TOUPPER (s[1]) == 'X')
+        {
+          s += 2;
+          base = 16;
+        }
+      else if (base == 0)
+        base = 8;
+    }
+  else if (base == 0)
+    base = 10;
+
+  /* Save the pointer so we can check later if anything happened.  */
+  save = s;
+  cutoff = G_MAXUINT64 / base;
+  cutlim = G_MAXUINT64 % base;
+
+  overflow = FALSE;
+  ui64 = 0;
+  c = *s;
+  for (; c; c = *++s)
+    {
+      if (c >= '0' && c <= '9')
+        c -= '0';
+      else if (ISALPHA (c))
+        c = TOUPPER (c) - 'A' + 10;
+      else
+        break;
+      if (c >= base)
+        break;
+      /* Check for overflow.  */
+      if (ui64 > cutoff || (ui64 == cutoff && c > cutlim))
+        overflow = TRUE;
+      else
+        {
+          ui64 *= base;
+          ui64 += c;
+        }
+    }
+
+  /* Check if anything actually happened.  */
+  if (s == save)
+    goto noconv;
+
+  /* Store in ENDPTR the address of one character
+     past the last character we converted.  */
+  if (endptr)
+    *endptr = s;
+
+  if (G_UNLIKELY (overflow))
+    {
+      errno = ERANGE;
+      return G_MAXUINT64;
+    }
+
+  return ui64;
+
+ noconv:
+  /* We must handle a special case here: the base is 0 or 16 and the
+     first two characters are '0' and 'x', but the rest are no
+     hexadecimal digits.  This is no error case.  We return 0 and
+     ENDPTR points to the `x`.  */
+  if (endptr)
+    {
+      if (save - nptr >= 2 && TOUPPER (save[-1]) == 'X'
+          && save[-2] == '0')
+        *endptr = &save[-1];
+      else
+        /*  There was no number to convert.  */
+        *endptr = nptr;
+    }
+  return 0;
+}
+
+/**
+ * g_ascii_strtoull:
+ * @nptr:    the string to convert to a numeric value.
+ * @endptr:  if non-%NULL, it returns the character after
+ *           the last character used in the conversion.
+ * @base:    to be used for the conversion, 2..36 or 0
+ *
+ * Converts a string to a #guint64 value.
+ * This function behaves like the standard strtoull() function
+ * does in the C locale. It does this without actually
+ * changing the current locale, since that would not be
+ * thread-safe.
+ *
+ * This function is typically used when reading configuration
+ * files or other non-user input that should be locale independent.
+ * To handle input from the user you should normally use the
+ * locale-sensitive system strtoull() function.
+ *
+ * If the correct value would cause overflow, %G_MAXUINT64
+ * is returned, and %ERANGE is stored in %errno.  If the base is
+ * outside the valid range, zero is returned, and %EINVAL is stored
+ * in %errno.  If the string conversion fails, zero is returned, and
+ * @endptr returns @nptr (if @endptr is non-%NULL).
+ *
+ * Return value: the #guint64 value or zero on error.
+ *
+ * Since: 2.2
+ */
+guint64
+g_ascii_strtoull (const gchar *nptr,
+                  gchar      **endptr,
+                  guint        base)
+{
+  gboolean negative;
+  guint64 result;
+
+  result = g_parse_long_long (nptr, (const gchar **) endptr, base, &negative);
+
+  /* Return the result of the appropriate sign.  */
+  return negative ? -result : result;
+}
+
+/**
+ * g_ascii_strtoll:
+ * @nptr:    the string to convert to a numeric value.
+ * @endptr:  if non-%NULL, it returns the character after
+ *           the last character used in the conversion.
+ * @base:    to be used for the conversion, 2..36 or 0
+ *
+ * Converts a string to a #gint64 value.
+ * This function behaves like the standard strtoll() function
+ * does in the C locale. It does this without actually
+ * changing the current locale, since that would not be
+ * thread-safe.
+ *
+ * This function is typically used when reading configuration
+ * files or other non-user input that should be locale independent.
+ * To handle input from the user you should normally use the
+ * locale-sensitive system strtoll() function.
+ *
+ * If the correct value would cause overflow, %G_MAXINT64 or %G_MININT64
+ * is returned, and %ERANGE is stored in %errno.  If the base is
+ * outside the valid range, zero is returned, and %EINVAL is stored
+ * in %errno.  If the string conversion fails, zero is returned, and
+ * @endptr returns @nptr (if @endptr is non-%NULL).
+ *
+ * Return value: the #gint64 value or zero on error.
+ *
+ * Since: 2.12
+ */
+gint64
+g_ascii_strtoll (const gchar *nptr,
+                 gchar      **endptr,
+                 guint        base)
+{
+  gboolean negative;
+  guint64 result;
+
+  result = g_parse_long_long (nptr, (const gchar **) endptr, base, &negative);
+
+  if (negative && result > (guint64) G_MININT64)
+    {
+      errno = ERANGE;
+      return G_MININT64;
+    }
+  else if (!negative && result > (guint64) G_MAXINT64)
+    {
+      errno = ERANGE;
+      return G_MAXINT64;
+    }
+  else if (negative)
+    return - (gint64) result;
+  else
+    return (gint64) result;
+}
+
+/**
+ * g_strerror:
+ * @errnum: the system error number. See the standard C %errno
+ *     documentation
+ *
+ * Returns a string corresponding to the given error code, e.g.
+ * "no such process". You should use this function in preference to
+ * strerror(), because it returns a string in UTF-8 encoding, and since
+ * not all platforms support the strerror() function.
+ *
+ * Returns: a UTF-8 string describing the error code. If the error code
+ *     is unknown, it returns "unknown error (&lt;code&gt;)". The string
+ *     can only be used until the next call to g_strerror()
+ */
+G_CONST_RETURN gchar*
+g_strerror (gint errnum)
+{
+  static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
+  char *msg;
+  int saved_errno = errno;
+
+#ifdef HAVE_STRERROR
+  const char *msg_locale;
+
+  msg_locale = strerror (errnum);
+  if (g_get_charset (NULL))
+    {
+      errno = saved_errno;
+      return msg_locale;
+    }
+  else
+    {
+      gchar *msg_utf8 = g_locale_to_utf8 (msg_locale, -1, NULL, NULL, NULL);
+      if (msg_utf8)
+        {
+          /* Stick in the quark table so that we can return a static result
+           */
+          GQuark msg_quark = g_quark_from_string (msg_utf8);
+          g_free (msg_utf8);
+
+          msg_utf8 = (gchar *) g_quark_to_string (msg_quark);
+          errno = saved_errno;
+          return msg_utf8;
+        }
+    }
+#elif NO_SYS_ERRLIST
+  switch (errnum)
+    {
+#ifdef E2BIG
+    case E2BIG: return "argument list too long";
+#endif
+#ifdef EACCES
+    case EACCES: return "permission denied";
+#endif
+#ifdef EADDRINUSE
+    case EADDRINUSE: return "address already in use";
+#endif
+#ifdef EADDRNOTAVAIL
+    case EADDRNOTAVAIL: return "can't assign requested address";
+#endif
+#ifdef EADV
+    case EADV: return "advertise error";
+#endif
+#ifdef EAFNOSUPPORT
+    case EAFNOSUPPORT: return "address family not supported by protocol family";
+#endif
+#ifdef EAGAIN
+    case EAGAIN: return "try again";
+#endif
+#ifdef EALIGN
+    case EALIGN: return "EALIGN";
+#endif
+#ifdef EALREADY
+    case EALREADY: return "operation already in progress";
+#endif
+#ifdef EBADE
+    case EBADE: return "bad exchange descriptor";
+#endif
+#ifdef EBADF
+    case EBADF: return "bad file number";
+#endif
+#ifdef EBADFD
+    case EBADFD: return "file descriptor in bad state";
+#endif
+#ifdef EBADMSG
+    case EBADMSG: return "not a data message";
+#endif
+#ifdef EBADR
+    case EBADR: return "bad request descriptor";
+#endif
+#ifdef EBADRPC
+    case EBADRPC: return "RPC structure is bad";
+#endif
+#ifdef EBADRQC
+    case EBADRQC: return "bad request code";
+#endif
+#ifdef EBADSLT
+    case EBADSLT: return "invalid slot";
+#endif
+#ifdef EBFONT
+    case EBFONT: return "bad font file format";
+#endif
+#ifdef EBUSY
+    case EBUSY: return "mount device busy";
+#endif
+#ifdef ECHILD
+    case ECHILD: return "no children";
+#endif
+#ifdef ECHRNG
+    case ECHRNG: return "channel number out of range";
+#endif
+#ifdef ECOMM
+    case ECOMM: return "communication error on send";
+#endif
+#ifdef ECONNABORTED
+    case ECONNABORTED: return "software caused connection abort";
+#endif
+#ifdef ECONNREFUSED
+    case ECONNREFUSED: return "connection refused";
+#endif
+#ifdef ECONNRESET
+    case ECONNRESET: return "connection reset by peer";
+#endif
+#if defined(EDEADLK) && (!defined(EWOULDBLOCK) || (EDEADLK != EWOULDBLOCK))
+    case EDEADLK: return "resource deadlock avoided";
+#endif
+#if defined(EDEADLOCK) && (!defined(EDEADLK) || (EDEADLOCK != EDEADLK))
+    case EDEADLOCK: return "resource deadlock avoided";
+#endif
+#ifdef EDESTADDRREQ
+    case EDESTADDRREQ: return "destination address required";
+#endif
+#ifdef EDIRTY
+    case EDIRTY: return "mounting a dirty fs w/o force";
+#endif
+#ifdef EDOM
+    case EDOM: return "math argument out of range";
+#endif
+#ifdef EDOTDOT
+    case EDOTDOT: return "cross mount point";
+#endif
+#ifdef EDQUOT
+    case EDQUOT: return "disk quota exceeded";
+#endif
+#ifdef EDUPPKG
+    case EDUPPKG: return "duplicate package name";
+#endif
+#ifdef EEXIST
+    case EEXIST: return "file already exists";
+#endif
+#ifdef EFAULT
+    case EFAULT: return "bad address in system call argument";
+#endif
+#ifdef EFBIG
+    case EFBIG: return "file too large";
+#endif
+#ifdef EHOSTDOWN
+    case EHOSTDOWN: return "host is down";
+#endif
+#ifdef EHOSTUNREACH
+    case EHOSTUNREACH: return "host is unreachable";
+#endif
+#ifdef EIDRM
+    case EIDRM: return "identifier removed";
+#endif
+#ifdef EINIT
+    case EINIT: return "initialization error";
+#endif
+#ifdef EINPROGRESS
+    case EINPROGRESS: return "operation now in progress";
+#endif
+#ifdef EINTR
+    case EINTR: return "interrupted system call";
+#endif
+#ifdef EINVAL
+    case EINVAL: return "invalid argument";
+#endif
+#ifdef EIO
+    case EIO: return "I/O error";
+#endif
+#ifdef EISCONN
+    case EISCONN: return "socket is already connected";
+#endif
+#ifdef EISDIR
+    case EISDIR: return "is a directory";
+#endif
+#ifdef EISNAME
+    case EISNAM: return "is a name file";
+#endif
+#ifdef ELBIN
+    case ELBIN: return "ELBIN";
+#endif
+#ifdef EL2HLT
+    case EL2HLT: return "level 2 halted";
+#endif
+#ifdef EL2NSYNC
+    case EL2NSYNC: return "level 2 not synchronized";
+#endif
+#ifdef EL3HLT
+    case EL3HLT: return "level 3 halted";
+#endif
+#ifdef EL3RST
+    case EL3RST: return "level 3 reset";
+#endif
+#ifdef ELIBACC
+    case ELIBACC: return "can not access a needed shared library";
+#endif
+#ifdef ELIBBAD
+    case ELIBBAD: return "accessing a corrupted shared library";
+#endif
+#ifdef ELIBEXEC
+    case ELIBEXEC: return "can not exec a shared library directly";
+#endif
+#ifdef ELIBMAX
+    case ELIBMAX: return "attempting to link in more shared libraries than system limit";
+#endif
+#ifdef ELIBSCN
+    case ELIBSCN: return ".lib section in a.out corrupted";
+#endif
+#ifdef ELNRNG
+    case ELNRNG: return "link number out of range";
+#endif
+#ifdef ELOOP
+    case ELOOP: return "too many levels of symbolic links";
+#endif
+#ifdef EMFILE
+    case EMFILE: return "too many open files";
+#endif
+#ifdef EMLINK
+    case EMLINK: return "too many links";
+#endif
+#ifdef EMSGSIZE
+    case EMSGSIZE: return "message too long";
+#endif
+#ifdef EMULTIHOP
+    case EMULTIHOP: return "multihop attempted";
+#endif
+#ifdef ENAMETOOLONG
+    case ENAMETOOLONG: return "file name too long";
+#endif
+#ifdef ENAVAIL
+    case ENAVAIL: return "not available";
+#endif
+#ifdef ENET
+    case ENET: return "ENET";
+#endif
+#ifdef ENETDOWN
+    case ENETDOWN: return "network is down";
+#endif
+#ifdef ENETRESET
+    case ENETRESET: return "network dropped connection on reset";
+#endif
+#ifdef ENETUNREACH
+    case ENETUNREACH: return "network is unreachable";
+#endif
+#ifdef ENFILE
+    case ENFILE: return "file table overflow";
+#endif
+#ifdef ENOANO
+    case ENOANO: return "anode table overflow";
+#endif
+#if defined(ENOBUFS) && (!defined(ENOSR) || (ENOBUFS != ENOSR))
+    case ENOBUFS: return "no buffer space available";
+#endif
+#ifdef ENOCSI
+    case ENOCSI: return "no CSI structure available";
+#endif
+#ifdef ENODATA
+    case ENODATA: return "no data available";
+#endif
+#ifdef ENODEV
+    case ENODEV: return "no such device";
+#endif
+#ifdef ENOENT
+    case ENOENT: return "no such file or directory";
+#endif
+#ifdef ENOEXEC
+    case ENOEXEC: return "exec format error";
+#endif
+#ifdef ENOLCK
+    case ENOLCK: return "no locks available";
+#endif
+#ifdef ENOLINK
+    case ENOLINK: return "link has be severed";
+#endif
+#ifdef ENOMEM
+    case ENOMEM: return "not enough memory";
+#endif
+#ifdef ENOMSG
+    case ENOMSG: return "no message of desired type";
+#endif
+#ifdef ENONET
+    case ENONET: return "machine is not on the network";
+#endif
+#ifdef ENOPKG
+    case ENOPKG: return "package not installed";
+#endif
+#ifdef ENOPROTOOPT
+    case ENOPROTOOPT: return "bad proocol option";
+#endif
+#ifdef ENOSPC
+    case ENOSPC: return "no space left on device";
+#endif
+#ifdef ENOSR
+    case ENOSR: return "out of stream resources";
+#endif
+#ifdef ENOSTR
+    case ENOSTR: return "not a stream device";
+#endif
+#ifdef ENOSYM
+    case ENOSYM: return "unresolved symbol name";
+#endif
+#ifdef ENOSYS
+    case ENOSYS: return "function not implemented";
+#endif
+#ifdef ENOTBLK
+    case ENOTBLK: return "block device required";
+#endif
+#ifdef ENOTCONN
+    case ENOTCONN: return "socket is not connected";
+#endif
+#ifdef ENOTDIR
+    case ENOTDIR: return "not a directory";
+#endif
+#ifdef ENOTEMPTY
+    case ENOTEMPTY: return "directory not empty";
+#endif
+#ifdef ENOTNAM
+    case ENOTNAM: return "not a name file";
+#endif
+#ifdef ENOTSOCK
+    case ENOTSOCK: return "socket operation on non-socket";
+#endif
+#ifdef ENOTTY
+    case ENOTTY: return "inappropriate device for ioctl";
+#endif
+#ifdef ENOTUNIQ
+    case ENOTUNIQ: return "name not unique on network";
+#endif
+#ifdef ENXIO
+    case ENXIO: return "no such device or address";
+#endif
+#ifdef EOPNOTSUPP
+    case EOPNOTSUPP: return "operation not supported on socket";
+#endif
+#ifdef EPERM
+    case EPERM: return "not owner";
+#endif
+#ifdef EPFNOSUPPORT
+    case EPFNOSUPPORT: return "protocol family not supported";
+#endif
+#ifdef EPIPE
+    case EPIPE: return "broken pipe";
+#endif
+#ifdef EPROCLIM
+    case EPROCLIM: return "too many processes";
+#endif
+#ifdef EPROCUNAVAIL
+    case EPROCUNAVAIL: return "bad procedure for program";
+#endif
+#ifdef EPROGMISMATCH
+    case EPROGMISMATCH: return "program version wrong";
+#endif
+#ifdef EPROGUNAVAIL
+    case EPROGUNAVAIL: return "RPC program not available";
+#endif
+#ifdef EPROTO
+    case EPROTO: return "protocol error";
+#endif
+#ifdef EPROTONOSUPPORT
+    case EPROTONOSUPPORT: return "protocol not suppored";
+#endif
+#ifdef EPROTOTYPE
+    case EPROTOTYPE: return "protocol wrong type for socket";
+#endif
+#ifdef ERANGE
+    case ERANGE: return "math result unrepresentable";
+#endif
+#if defined(EREFUSED) && (!defined(ECONNREFUSED) || (EREFUSED != ECONNREFUSED))
+    case EREFUSED: return "EREFUSED";
+#endif
+#ifdef EREMCHG
+    case EREMCHG: return "remote address changed";
+#endif
+#ifdef EREMDEV
+    case EREMDEV: return "remote device";
+#endif
+#ifdef EREMOTE
+    case EREMOTE: return "pathname hit remote file system";
+#endif
+#ifdef EREMOTEIO
+    case EREMOTEIO: return "remote i/o error";
+#endif
+#ifdef EREMOTERELEASE
+    case EREMOTERELEASE: return "EREMOTERELEASE";
+#endif
+#ifdef EROFS
+    case EROFS: return "read-only file system";
+#endif
+#ifdef ERPCMISMATCH
+    case ERPCMISMATCH: return "RPC version is wrong";
+#endif
+#ifdef ERREMOTE
+    case ERREMOTE: return "object is remote";
+#endif
+#ifdef ESHUTDOWN
+    case ESHUTDOWN: return "can't send afer socket shutdown";
+#endif
+#ifdef ESOCKTNOSUPPORT
+    case ESOCKTNOSUPPORT: return "socket type not supported";
+#endif
+#ifdef ESPIPE
+    case ESPIPE: return "invalid seek";
+#endif
+#ifdef ESRCH
+    case ESRCH: return "no such process";
+#endif
+#ifdef ESRMNT
+    case ESRMNT: return "srmount error";
+#endif
+#ifdef ESTALE
+    case ESTALE: return "stale remote file handle";
+#endif
+#ifdef ESUCCESS
+    case ESUCCESS: return "Error 0";
+#endif
+#ifdef ETIME
+    case ETIME: return "timer expired";
+#endif
+#ifdef ETIMEDOUT
+    case ETIMEDOUT: return "connection timed out";
+#endif
+#ifdef ETOOMANYREFS
+    case ETOOMANYREFS: return "too many references: can't splice";
+#endif
+#ifdef ETXTBSY
+    case ETXTBSY: return "text file or pseudo-device busy";
+#endif
+#ifdef EUCLEAN
+    case EUCLEAN: return "structure needs cleaning";
+#endif
+#ifdef EUNATCH
+    case EUNATCH: return "protocol driver not attached";
+#endif
+#ifdef EUSERS
+    case EUSERS: return "too many users";
+#endif
+#ifdef EVERSION
+    case EVERSION: return "version mismatch";
+#endif
+#if defined(EWOULDBLOCK) && (!defined(EAGAIN) || (EWOULDBLOCK != EAGAIN))
+    case EWOULDBLOCK: return "operation would block";
+#endif
+#ifdef EXDEV
+    case EXDEV: return "cross-domain link";
+#endif
+#ifdef EXFULL
+    case EXFULL: return "message tables full";
+#endif
+    }
+#else /* NO_SYS_ERRLIST */
+  extern int sys_nerr;
+  extern char *sys_errlist[];
+
+  if ((errnum > 0) && (errnum <= sys_nerr))
+    return sys_errlist [errnum];
+#endif /* NO_SYS_ERRLIST */
+
+  msg = g_static_private_get (&msg_private);
+  if (!msg)
+    {
+      msg = g_new (gchar, 64);
+      g_static_private_set (&msg_private, msg, g_free);
+    }
+
+  _g_sprintf (msg, "unknown error (%d)", errnum);
+
+  errno = saved_errno;
+  return msg;
+}
+
+/**
+ * g_strsignal:
+ * @signum: the signal number. See the <literal>signal</literal>
+ *     documentation
+ *
+ * Returns a string describing the given signal, e.g. "Segmentation fault".
+ * You should use this function in preference to strsignal(), because it
+ * returns a string in UTF-8 encoding, and since not all platforms support
+ * the strsignal() function.
+ *
+ * Returns: a UTF-8 string describing the signal. If the signal is unknown,
+ *     it returns "unknown signal (&lt;signum&gt;)". The string can only be
+ *     used until the next call to g_strsignal()
+ */
+G_CONST_RETURN gchar*
+g_strsignal (gint signum)
+{
+  static GStaticPrivate msg_private = G_STATIC_PRIVATE_INIT;
+  char *msg;
+
+#ifdef HAVE_STRSIGNAL
+  const char *msg_locale;
+
+#if defined(G_OS_BEOS) || defined(G_WITH_CYGWIN)
+extern const char *strsignal(int);
+#else
+  /* this is declared differently (const) in string.h on BeOS */
+  extern char *strsignal (int sig);
+#endif /* !G_OS_BEOS && !G_WITH_CYGWIN */
+  msg_locale = strsignal (signum);
+  if (g_get_charset (NULL))
+    return msg_locale;
+  else
+    {
+      gchar *msg_utf8 = g_locale_to_utf8 (msg_locale, -1, NULL, NULL, NULL);
+      if (msg_utf8)
+        {
+          /* Stick in the quark table so that we can return a static result
+           */
+          GQuark msg_quark = g_quark_from_string (msg_utf8);
+          g_free (msg_utf8);
+
+          return g_quark_to_string (msg_quark);
+        }
+    }
+#elif NO_SYS_SIGLIST
+  switch (signum)
+    {
+#ifdef SIGHUP
+    case SIGHUP: return "Hangup";
+#endif
+#ifdef SIGINT
+    case SIGINT: return "Interrupt";
+#endif
+#ifdef SIGQUIT
+    case SIGQUIT: return "Quit";
+#endif
+#ifdef SIGILL
+    case SIGILL: return "Illegal instruction";
+#endif
+#ifdef SIGTRAP
+    case SIGTRAP: return "Trace/breakpoint trap";
+#endif
+#ifdef SIGABRT
+    case SIGABRT: return "IOT trap/Abort";
+#endif
+#ifdef SIGBUS
+    case SIGBUS: return "Bus error";
+#endif
+#ifdef SIGFPE
+    case SIGFPE: return "Floating point exception";
+#endif
+#ifdef SIGKILL
+    case SIGKILL: return "Killed";
+#endif
+#ifdef SIGUSR1
+    case SIGUSR1: return "User defined signal 1";
+#endif
+#ifdef SIGSEGV
+    case SIGSEGV: return "Segmentation fault";
+#endif
+#ifdef SIGUSR2
+    case SIGUSR2: return "User defined signal 2";
+#endif
+#ifdef SIGPIPE
+    case SIGPIPE: return "Broken pipe";
+#endif
+#ifdef SIGALRM
+    case SIGALRM: return "Alarm clock";
+#endif
+#ifdef SIGTERM
+    case SIGTERM: return "Terminated";
+#endif
+#ifdef SIGSTKFLT
+    case SIGSTKFLT: return "Stack fault";
+#endif
+#ifdef SIGCHLD
+    case SIGCHLD: return "Child exited";
+#endif
+#ifdef SIGCONT
+    case SIGCONT: return "Continued";
+#endif
+#ifdef SIGSTOP
+    case SIGSTOP: return "Stopped (signal)";
+#endif
+#ifdef SIGTSTP
+    case SIGTSTP: return "Stopped";
+#endif
+#ifdef SIGTTIN
+    case SIGTTIN: return "Stopped (tty input)";
+#endif
+#ifdef SIGTTOU
+    case SIGTTOU: return "Stopped (tty output)";
+#endif
+#ifdef SIGURG
+    case SIGURG: return "Urgent condition";
+#endif
+#ifdef SIGXCPU
+    case SIGXCPU: return "CPU time limit exceeded";
+#endif
+#ifdef SIGXFSZ
+    case SIGXFSZ: return "File size limit exceeded";
+#endif
+#ifdef SIGVTALRM
+    case SIGVTALRM: return "Virtual time alarm";
+#endif
+#ifdef SIGPROF
+    case SIGPROF: return "Profile signal";
+#endif
+#ifdef SIGWINCH
+    case SIGWINCH: return "Window size changed";
+#endif
+#ifdef SIGIO
+    case SIGIO: return "Possible I/O";
+#endif
+#ifdef SIGPWR
+    case SIGPWR: return "Power failure";
+#endif
+#ifdef SIGUNUSED
+    case SIGUNUSED: return "Unused signal";
+#endif
+    }
+#else /* NO_SYS_SIGLIST */
+
+#ifdef NO_SYS_SIGLIST_DECL
+  extern char *sys_siglist[];   /*(see Tue Jan 19 00:44:24 1999 in changelog)*/
+#endif
+
+  return (char*) /* this function should return const --josh */ sys_siglist [signum];
+#endif /* NO_SYS_SIGLIST */
+
+  msg = g_static_private_get (&msg_private);
+  if (!msg)
+    {
+      msg = g_new (gchar, 64);
+      g_static_private_set (&msg_private, msg, g_free);
+    }
+
+  _g_sprintf (msg, "unknown signal (%d)", signum);
+
+  return msg;
+}
+
+/* Functions g_strlcpy and g_strlcat were originally developed by
+ * Todd C. Miller <Todd.Miller@courtesan.com> to simplify writing secure code.
+ * See ftp://ftp.openbsd.org/pub/OpenBSD/src/lib/libc/string/strlcpy.3
+ * for more information.
+ */
+
+#ifdef HAVE_STRLCPY
+/* Use the native ones, if available; they might be implemented in assembly */
+gsize
+g_strlcpy (gchar       *dest,
+           const gchar *src,
+           gsize        dest_size)
+{
+  g_return_val_if_fail (dest != NULL, 0);
+  g_return_val_if_fail (src  != NULL, 0);
+
+  return strlcpy (dest, src, dest_size);
+}
+
+gsize
+g_strlcat (gchar       *dest,
+           const gchar *src,
+           gsize        dest_size)
+{
+  g_return_val_if_fail (dest != NULL, 0);
+  g_return_val_if_fail (src  != NULL, 0);
+
+  return strlcat (dest, src, dest_size);
+}
+
+#else /* ! HAVE_STRLCPY */
+/**
+ * g_strlcpy:
+ * @dest: destination buffer
+ * @src: source buffer
+ * @dest_size: length of @dest in bytes
+ *
+ * Portability wrapper that calls strlcpy() on systems which have it,
+ * and emulates strlcpy() otherwise. Copies @src to @dest; @dest is
+ * guaranteed to be nul-terminated; @src must be nul-terminated;
+ * @dest_size is the buffer size, not the number of chars to copy.
+ *
+ * At most dest_size - 1 characters will be copied. Always nul-terminates
+ * (unless dest_size == 0). This function does <emphasis>not</emphasis>
+ * allocate memory. Unlike strncpy(), this function doesn't pad dest (so
+ * it's often faster). It returns the size of the attempted result,
+ * strlen (src), so if @retval >= @dest_size, truncation occurred.
+ *
+ * <note><para>Caveat: strlcpy() is supposedly more secure than
+ * strcpy() or strncpy(), but if you really want to avoid screwups,
+ * g_strdup() is an even better idea.</para></note>
+ *
+ * Returns: length of @src
+ */
+gsize
+g_strlcpy (gchar       *dest,
+           const gchar *src,
+           gsize        dest_size)
+{
+  register gchar *d = dest;
+  register const gchar *s = src;
+  register gsize n = dest_size;
+
+  g_return_val_if_fail (dest != NULL, 0);
+  g_return_val_if_fail (src  != NULL, 0);
+
+  /* Copy as many bytes as will fit */
+  if (n != 0 && --n != 0)
+    do
+      {
+        register gchar c = *s++;
+
+        *d++ = c;
+        if (c == 0)
+          break;
+      }
+    while (--n != 0);
+
+  /* If not enough room in dest, add NUL and traverse rest of src */
+  if (n == 0)
+    {
+      if (dest_size != 0)
+        *d = 0;
+      while (*s++)
+        ;
+    }
+
+  return s - src - 1;  /* count does not include NUL */
+}
+
+/**
+ * g_strlcat:
+ * @dest: destination buffer, already containing one nul-terminated string
+ * @src: source buffer
+ * @dest_size: length of @dest buffer in bytes (not length of existing string
+ *     inside @dest)
+ *
+ * Portability wrapper that calls strlcat() on systems which have it,
+ * and emulates it otherwise. Appends nul-terminated @src string to @dest,
+ * guaranteeing nul-termination for @dest. The total size of @dest won't
+ * exceed @dest_size.
+ *
+ * At most dest_size - 1 characters will be copied.
+ * Unlike strncat, dest_size is the full size of dest, not the space left over.
+ * This function does NOT allocate memory.
+ * This always NUL terminates (unless siz == 0 or there were no NUL characters
+ * in the dest_size characters of dest to start with).
+ *
+ * <note><para>Caveat: this is supposedly a more secure alternative to
+ * strcat() or strncat(), but for real security g_strconcat() is harder
+ * to mess up.</para></note>
+ *
+ * Returns: size of attempted result, which is MIN (dest_size, strlen
+ *          (original dest)) + strlen (src), so if retval >= dest_size,
+ *          truncation occurred.
+ **/
+gsize
+g_strlcat (gchar       *dest,
+           const gchar *src,
+           gsize        dest_size)
+{
+  register gchar *d = dest;
+  register const gchar *s = src;
+  register gsize bytes_left = dest_size;
+  gsize dlength;  /* Logically, MIN (strlen (d), dest_size) */
+
+  g_return_val_if_fail (dest != NULL, 0);
+  g_return_val_if_fail (src  != NULL, 0);
+
+  /* Find the end of dst and adjust bytes left but don't go past end */
+  while (*d != 0 && bytes_left-- != 0)
+    d++;
+  dlength = d - dest;
+  bytes_left = dest_size - dlength;
+
+  if (bytes_left == 0)
+    return dlength + strlen (s);
+
+  while (*s != 0)
+    {
+      if (bytes_left != 1)
+        {
+          *d++ = *s;
+          bytes_left--;
+        }
+      s++;
+    }
+  *d = 0;
+
+  return dlength + (s - src);  /* count does not include NUL */
+}
+#endif /* ! HAVE_STRLCPY */
+
+/**
+ * g_ascii_strdown:
+ * @str: a string.
+ * @len: length of @str in bytes, or -1 if @str is nul-terminated.
+ *
+ * Converts all upper case ASCII letters to lower case ASCII letters.
+ *
+ * Return value: a newly-allocated string, with all the upper case
+ *               characters in @str converted to lower case, with
+ *               semantics that exactly match g_ascii_tolower(). (Note
+ *               that this is unlike the old g_strdown(), which modified
+ *               the string in place.)
+ **/
+gchar*
+g_ascii_strdown (const gchar *str,
+                 gssize       len)
+{
+  gchar *result, *s;
+
+  g_return_val_if_fail (str != NULL, NULL);
+
+  if (len < 0)
+    len = strlen (str);
+
+  result = g_strndup (str, len);
+  for (s = result; *s; s++)
+    *s = g_ascii_tolower (*s);
+
+  return result;
+}
+
+/**
+ * g_ascii_strup:
+ * @str: a string.
+ * @len: length of @str in bytes, or -1 if @str is nul-terminated.
+ *
+ * Converts all lower case ASCII letters to upper case ASCII letters.
+ *
+ * Return value: a newly allocated string, with all the lower case
+ *               characters in @str converted to upper case, with
+ *               semantics that exactly match g_ascii_toupper(). (Note
+ *               that this is unlike the old g_strup(), which modified
+ *               the string in place.)
+ **/
+gchar*
+g_ascii_strup (const gchar *str,
+               gssize       len)
+{
+  gchar *result, *s;
+
+  g_return_val_if_fail (str != NULL, NULL);
+
+  if (len < 0)
+    len = strlen (str);
+
+  result = g_strndup (str, len);
+  for (s = result; *s; s++)
+    *s = g_ascii_toupper (*s);
+
+  return result;
+}
+
+/**
+ * g_strdown:
+ * @string: the string to convert.
+ *
+ * Converts a string to lower case.
+ *
+ * Return value: the string
+ *
+ * Deprecated:2.2: This function is totally broken for the reasons discussed
+ * in the g_strncasecmp() docs - use g_ascii_strdown() or g_utf8_strdown()
+ * instead.
+ **/
+gchar*
+g_strdown (gchar *string)
+{
+  register guchar *s;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  s = (guchar *) string;
+
+  while (*s)
+    {
+      if (isupper (*s))
+        *s = tolower (*s);
+      s++;
+    }
+
+  return (gchar *) string;
+}
+
+/**
+ * g_strup:
+ * @string: the string to convert.
+ *
+ * Converts a string to upper case.
+ *
+ * Return value: the string
+ *
+ * Deprecated:2.2: This function is totally broken for the reasons discussed
+ * in the g_strncasecmp() docs - use g_ascii_strup() or g_utf8_strup() instead.
+ **/
+gchar*
+g_strup (gchar *string)
+{
+  register guchar *s;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  s = (guchar *) string;
+
+  while (*s)
+    {
+      if (islower (*s))
+        *s = toupper (*s);
+      s++;
+    }
+
+  return (gchar *) string;
+}
+
+/**
+ * g_strreverse:
+ * @string: the string to reverse
+ *
+ * Reverses all of the bytes in a string. For example,
+ * <literal>g_strreverse ("abcdef")</literal> will result
+ * in "fedcba".
+ *
+ * Note that g_strreverse() doesn't work on UTF-8 strings
+ * containing multibyte characters. For that purpose, use
+ * g_utf8_strreverse().
+ *
+ * Returns: the same pointer passed in as @string
+ */
+gchar*
+g_strreverse (gchar *string)
+{
+  g_return_val_if_fail (string != NULL, NULL);
+
+  if (*string)
+    {
+      register gchar *h, *t;
+
+      h = string;
+      t = string + strlen (string) - 1;
+
+      while (h < t)
+        {
+          register gchar c;
+
+          c = *h;
+          *h = *t;
+          h++;
+          *t = c;
+          t--;
+        }
+    }
+
+  return string;
+}
+
+/**
+ * g_ascii_tolower:
+ * @c: any character.
+ *
+ * Convert a character to ASCII lower case.
+ *
+ * Unlike the standard C library tolower() function, this only
+ * recognizes standard ASCII letters and ignores the locale, returning
+ * all non-ASCII characters unchanged, even if they are lower case
+ * letters in a particular character set. Also unlike the standard
+ * library function, this takes and returns a char, not an int, so
+ * don't call it on %EOF but no need to worry about casting to #guchar
+ * before passing a possibly non-ASCII character in.
+ *
+ * Return value: the result of converting @c to lower case.
+ *               If @c is not an ASCII upper case letter,
+ *               @c is returned unchanged.
+ **/
+gchar
+g_ascii_tolower (gchar c)
+{
+  return g_ascii_isupper (c) ? c - 'A' + 'a' : c;
+}
+
+/**
+ * g_ascii_toupper:
+ * @c: any character.
+ *
+ * Convert a character to ASCII upper case.
+ *
+ * Unlike the standard C library toupper() function, this only
+ * recognizes standard ASCII letters and ignores the locale, returning
+ * all non-ASCII characters unchanged, even if they are upper case
+ * letters in a particular character set. Also unlike the standard
+ * library function, this takes and returns a char, not an int, so
+ * don't call it on %EOF but no need to worry about casting to #guchar
+ * before passing a possibly non-ASCII character in.
+ *
+ * Return value: the result of converting @c to upper case.
+ *               If @c is not an ASCII lower case letter,
+ *               @c is returned unchanged.
+ **/
+gchar
+g_ascii_toupper (gchar c)
+{
+  return g_ascii_islower (c) ? c - 'a' + 'A' : c;
+}
+
+/**
+ * g_ascii_digit_value:
+ * @c: an ASCII character.
+ *
+ * Determines the numeric value of a character as a decimal
+ * digit. Differs from g_unichar_digit_value() because it takes
+ * a char, so there's no worry about sign extension if characters
+ * are signed.
+ *
+ * Return value: If @c is a decimal digit (according to
+ * g_ascii_isdigit()), its numeric value. Otherwise, -1.
+ **/
+int
+g_ascii_digit_value (gchar c)
+{
+  if (g_ascii_isdigit (c))
+    return c - '0';
+  return -1;
+}
+
+/**
+ * g_ascii_xdigit_value:
+ * @c: an ASCII character.
+ *
+ * Determines the numeric value of a character as a hexidecimal
+ * digit. Differs from g_unichar_xdigit_value() because it takes
+ * a char, so there's no worry about sign extension if characters
+ * are signed.
+ *
+ * Return value: If @c is a hex digit (according to
+ * g_ascii_isxdigit()), its numeric value. Otherwise, -1.
+ **/
+int
+g_ascii_xdigit_value (gchar c)
+{
+  if (c >= 'A' && c <= 'F')
+    return c - 'A' + 10;
+  if (c >= 'a' && c <= 'f')
+    return c - 'a' + 10;
+  return g_ascii_digit_value (c);
+}
+
+/**
+ * g_ascii_strcasecmp:
+ * @s1: string to compare with @s2.
+ * @s2: string to compare with @s1.
+ *
+ * Compare two strings, ignoring the case of ASCII characters.
+ *
+ * Unlike the BSD strcasecmp() function, this only recognizes standard
+ * ASCII letters and ignores the locale, treating all non-ASCII
+ * bytes as if they are not letters.
+ *
+ * This function should be used only on strings that are known to be
+ * in encodings where the bytes corresponding to ASCII letters always
+ * represent themselves. This includes UTF-8 and the ISO-8859-*
+ * charsets, but not for instance double-byte encodings like the
+ * Windows Codepage 932, where the trailing bytes of double-byte
+ * characters include all ASCII letters. If you compare two CP932
+ * strings using this function, you will get false matches.
+ *
+ * Return value: 0 if the strings match, a negative value if @s1 &lt; @s2,
+ *   or a positive value if @s1 &gt; @s2.
+ **/
+gint
+g_ascii_strcasecmp (const gchar *s1,
+                    const gchar *s2)
+{
+  gint c1, c2;
+
+  g_return_val_if_fail (s1 != NULL, 0);
+  g_return_val_if_fail (s2 != NULL, 0);
+
+  while (*s1 && *s2)
+    {
+      c1 = (gint)(guchar) TOLOWER (*s1);
+      c2 = (gint)(guchar) TOLOWER (*s2);
+      if (c1 != c2)
+        return (c1 - c2);
+      s1++; s2++;
+    }
+
+  return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
+}
+
+/**
+ * g_ascii_strncasecmp:
+ * @s1: string to compare with @s2.
+ * @s2: string to compare with @s1.
+ * @n:  number of characters to compare.
+ *
+ * Compare @s1 and @s2, ignoring the case of ASCII characters and any
+ * characters after the first @n in each string.
+ *
+ * Unlike the BSD strcasecmp() function, this only recognizes standard
+ * ASCII letters and ignores the locale, treating all non-ASCII
+ * characters as if they are not letters.
+ *
+ * The same warning as in g_ascii_strcasecmp() applies: Use this
+ * function only on strings known to be in encodings where bytes
+ * corresponding to ASCII letters always represent themselves.
+ *
+ * Return value: 0 if the strings match, a negative value if @s1 &lt; @s2,
+ *   or a positive value if @s1 &gt; @s2.
+ **/
+gint
+g_ascii_strncasecmp (const gchar *s1,
+                     const gchar *s2,
+                     gsize n)
+{
+  gint c1, c2;
+
+  g_return_val_if_fail (s1 != NULL, 0);
+  g_return_val_if_fail (s2 != NULL, 0);
+
+  while (n && *s1 && *s2)
+    {
+      n -= 1;
+      c1 = (gint)(guchar) TOLOWER (*s1);
+      c2 = (gint)(guchar) TOLOWER (*s2);
+      if (c1 != c2)
+        return (c1 - c2);
+      s1++; s2++;
+    }
+
+  if (n)
+    return (((gint) (guchar) *s1) - ((gint) (guchar) *s2));
+  else
+    return 0;
+}
+
+/**
+ * g_strcasecmp:
+ * @s1: a string.
+ * @s2: a string to compare with @s1.
+ *
+ * A case-insensitive string comparison, corresponding to the standard
+ * strcasecmp() function on platforms which support it.
+ *
+ * Return value: 0 if the strings match, a negative value if @s1 &lt; @s2,
+ *   or a positive value if @s1 &gt; @s2.
+ *
+ * Deprecated:2.2: See g_strncasecmp() for a discussion of why this function
+ *   is deprecated and how to replace it.
+ **/
+gint
+g_strcasecmp (const gchar *s1,
+              const gchar *s2)
+{
+#ifdef HAVE_STRCASECMP
+  g_return_val_if_fail (s1 != NULL, 0);
+  g_return_val_if_fail (s2 != NULL, 0);
+
+  return strcasecmp (s1, s2);
+#else
+  gint c1, c2;
+
+  g_return_val_if_fail (s1 != NULL, 0);
+  g_return_val_if_fail (s2 != NULL, 0);
+
+  while (*s1 && *s2)
+    {
+      /* According to A. Cox, some platforms have islower's that
+       * don't work right on non-uppercase
+       */
+      c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
+      c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
+      if (c1 != c2)
+        return (c1 - c2);
+      s1++; s2++;
+    }
+
+  return (((gint)(guchar) *s1) - ((gint)(guchar) *s2));
+#endif
+}
+
+/**
+ * g_strncasecmp:
+ * @s1: a string.
+ * @s2: a string to compare with @s1.
+ * @n: the maximum number of characters to compare.
+ *
+ * A case-insensitive string comparison, corresponding to the standard
+ * strncasecmp() function on platforms which support it.
+ * It is similar to g_strcasecmp() except it only compares the first @n
+ * characters of the strings.
+ *
+ * Return value: 0 if the strings match, a negative value if @s1 &lt; @s2,
+ *   or a positive value if @s1 &gt; @s2.
+ *
+ * Deprecated:2.2: The problem with g_strncasecmp() is that it does the
+ * comparison by calling toupper()/tolower(). These functions are
+ * locale-specific and operate on single bytes. However, it is impossible
+ * to handle things correctly from an I18N standpoint by operating on
+ * bytes, since characters may be multibyte. Thus g_strncasecmp() is
+ * broken if your string is guaranteed to be ASCII, since it's
+ * locale-sensitive, and it's broken if your string is localized, since
+ * it doesn't work on many encodings at all, including UTF-8, EUC-JP,
+ * etc.
+ *
+ * There are therefore two replacement functions: g_ascii_strncasecmp(),
+ * which only works on ASCII and is not locale-sensitive, and
+ * g_utf8_casefold(), which is good for case-insensitive sorting of UTF-8.
+ **/
+gint
+g_strncasecmp (const gchar *s1,
+               const gchar *s2,
+               guint n)
+{
+#ifdef HAVE_STRNCASECMP
+  return strncasecmp (s1, s2, n);
+#else
+  gint c1, c2;
+
+  g_return_val_if_fail (s1 != NULL, 0);
+  g_return_val_if_fail (s2 != NULL, 0);
+
+  while (n && *s1 && *s2)
+    {
+      n -= 1;
+      /* According to A. Cox, some platforms have islower's that
+       * don't work right on non-uppercase
+       */
+      c1 = isupper ((guchar)*s1) ? tolower ((guchar)*s1) : *s1;
+      c2 = isupper ((guchar)*s2) ? tolower ((guchar)*s2) : *s2;
+      if (c1 != c2)
+        return (c1 - c2);
+      s1++; s2++;
+    }
+
+  if (n)
+    return (((gint) (guchar) *s1) - ((gint) (guchar) *s2));
+  else
+    return 0;
+#endif
+}
+
+gchar*
+g_strdelimit (gchar       *string,
+              const gchar *delimiters,
+              gchar        new_delim)
+{
+  register gchar *c;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  if (!delimiters)
+    delimiters = G_STR_DELIMITERS;
+
+  for (c = string; *c; c++)
+    {
+      if (strchr (delimiters, *c))
+        *c = new_delim;
+    }
+
+  return string;
+}
+
+gchar*
+g_strcanon (gchar       *string,
+            const gchar *valid_chars,
+            gchar        substitutor)
+{
+  register gchar *c;
+
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (valid_chars != NULL, NULL);
+
+  for (c = string; *c; c++)
+    {
+      if (!strchr (valid_chars, *c))
+        *c = substitutor;
+    }
+
+  return string;
+}
+
+gchar*
+g_strcompress (const gchar *source)
+{
+  const gchar *p = source, *octal;
+  gchar *dest = g_malloc (strlen (source) + 1);
+  gchar *q = dest;
+
+  while (*p)
+    {
+      if (*p == '\\')
+        {
+          p++;
+          switch (*p)
+            {
+            case '\0':
+              g_warning ("g_strcompress: trailing \\");
+              goto out;
+            case '0':  case '1':  case '2':  case '3':  case '4':
+            case '5':  case '6':  case '7':
+              *q = 0;
+              octal = p;
+              while ((p < octal + 3) && (*p >= '0') && (*p <= '7'))
+                {
+                  *q = (*q * 8) + (*p - '0');
+                  p++;
+                }
+              q++;
+              p--;
+              break;
+            case 'b':
+              *q++ = '\b';
+              break;
+            case 'f':
+              *q++ = '\f';
+              break;
+            case 'n':
+              *q++ = '\n';
+              break;
+            case 'r':
+              *q++ = '\r';
+              break;
+            case 't':
+              *q++ = '\t';
+              break;
+            default:            /* Also handles \" and \\ */
+              *q++ = *p;
+              break;
+            }
+        }
+      else
+        *q++ = *p;
+      p++;
+    }
+out:
+  *q = 0;
+
+  return dest;
+}
+
+gchar *
+g_strescape (const gchar *source,
+             const gchar *exceptions)
+{
+  const guchar *p;
+  gchar *dest;
+  gchar *q;
+  guchar excmap[256];
+
+  g_return_val_if_fail (source != NULL, NULL);
+
+  p = (guchar *) source;
+  /* Each source byte needs maximally four destination chars (\777) */
+  q = dest = g_malloc (strlen (source) * 4 + 1);
+
+  memset (excmap, 0, 256);
+  if (exceptions)
+    {
+      guchar *e = (guchar *) exceptions;
+
+      while (*e)
+        {
+          excmap[*e] = 1;
+          e++;
+        }
+    }
+
+  while (*p)
+    {
+      if (excmap[*p])
+        *q++ = *p;
+      else
+        {
+          switch (*p)
+            {
+            case '\b':
+              *q++ = '\\';
+              *q++ = 'b';
+              break;
+            case '\f':
+              *q++ = '\\';
+              *q++ = 'f';
+              break;
+            case '\n':
+              *q++ = '\\';
+              *q++ = 'n';
+              break;
+            case '\r':
+              *q++ = '\\';
+              *q++ = 'r';
+              break;
+            case '\t':
+              *q++ = '\\';
+              *q++ = 't';
+              break;
+            case '\\':
+              *q++ = '\\';
+              *q++ = '\\';
+              break;
+            case '"':
+              *q++ = '\\';
+              *q++ = '"';
+              break;
+            default:
+              if ((*p < ' ') || (*p >= 0177))
+                {
+                  *q++ = '\\';
+                  *q++ = '0' + (((*p) >> 6) & 07);
+                  *q++ = '0' + (((*p) >> 3) & 07);
+                  *q++ = '0' + ((*p) & 07);
+                }
+              else
+                *q++ = *p;
+              break;
+            }
+        }
+      p++;
+    }
+  *q = 0;
+  return dest;
+}
+
+gchar*
+g_strchug (gchar *string)
+{
+  guchar *start;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  for (start = (guchar*) string; *start && g_ascii_isspace (*start); start++)
+    ;
+
+  g_memmove (string, start, strlen ((gchar *) start) + 1);
+
+  return string;
+}
+
+gchar*
+g_strchomp (gchar *string)
+{
+  gsize len;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  len = strlen (string);
+  while (len--)
+    {
+      if (g_ascii_isspace ((guchar) string[len]))
+        string[len] = '\0';
+      else
+        break;
+    }
+
+  return string;
+}
+
+/**
+ * g_strsplit:
+ * @string: a string to split.
+ * @delimiter: a string which specifies the places at which to split the string.
+ *     The delimiter is not included in any of the resulting strings, unless
+ *     @max_tokens is reached.
+ * @max_tokens: the maximum number of pieces to split @string into. If this is
+ *              less than 1, the string is split completely.
+ *
+ * Splits a string into a maximum of @max_tokens pieces, using the given
+ * @delimiter. If @max_tokens is reached, the remainder of @string is appended
+ * to the last token.
+ *
+ * As a special case, the result of splitting the empty string "" is an empty
+ * vector, not a vector containing a single string. The reason for this
+ * special case is that being able to represent a empty vector is typically
+ * more useful than consistent handling of empty elements. If you do need
+ * to represent empty elements, you'll need to check for the empty string
+ * before calling g_strsplit().
+ *
+ * Return value: a newly-allocated %NULL-terminated array of strings. Use
+ *    g_strfreev() to free it.
+ **/
+gchar**
+g_strsplit (const gchar *string,
+            const gchar *delimiter,
+            gint         max_tokens)
+{
+  GSList *string_list = NULL, *slist;
+  gchar **str_array, *s;
+  guint n = 0;
+  const gchar *remainder;
+
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (delimiter != NULL, NULL);
+  g_return_val_if_fail (delimiter[0] != '\0', NULL);
+
+  if (max_tokens < 1)
+    max_tokens = G_MAXINT;
+
+  remainder = string;
+  s = strstr (remainder, delimiter);
+  if (s)
+    {
+      gsize delimiter_len = strlen (delimiter);
+
+      while (--max_tokens && s)
+        {
+          gsize len;
+
+          len = s - remainder;
+          string_list = g_slist_prepend (string_list,
+                                         g_strndup (remainder, len));
+          n++;
+          remainder = s + delimiter_len;
+          s = strstr (remainder, delimiter);
+        }
+    }
+  if (*string)
+    {
+      n++;
+      string_list = g_slist_prepend (string_list, g_strdup (remainder));
+    }
+
+  str_array = g_new (gchar*, n + 1);
+
+  str_array[n--] = NULL;
+  for (slist = string_list; slist; slist = slist->next)
+    str_array[n--] = slist->data;
+
+  g_slist_free (string_list);
+
+  return str_array;
+}
+
+/**
+ * g_strsplit_set:
+ * @string: The string to be tokenized
+ * @delimiters: A nul-terminated string containing bytes that are used
+ *              to split the string.
+ * @max_tokens: The maximum number of tokens to split @string into.
+ *              If this is less than 1, the string is split completely
+ *
+ * Splits @string into a number of tokens not containing any of the characters
+ * in @delimiter. A token is the (possibly empty) longest string that does not
+ * contain any of the characters in @delimiters. If @max_tokens is reached, the
+ * remainder is appended to the last token.
+ *
+ * For example the result of g_strsplit_set ("abc:def/ghi", ":/", -1) is a
+ * %NULL-terminated vector containing the three strings "abc", "def",
+ * and "ghi".
+ *
+ * The result if g_strsplit_set (":def/ghi:", ":/", -1) is a %NULL-terminated
+ * vector containing the four strings "", "def", "ghi", and "".
+ *
+ * As a special case, the result of splitting the empty string "" is an empty
+ * vector, not a vector containing a single string. The reason for this
+ * special case is that being able to represent a empty vector is typically
+ * more useful than consistent handling of empty elements. If you do need
+ * to represent empty elements, you'll need to check for the empty string
+ * before calling g_strsplit_set().
+ *
+ * Note that this function works on bytes not characters, so it can't be used
+ * to delimit UTF-8 strings for anything but ASCII characters.
+ *
+ * Return value: a newly-allocated %NULL-terminated array of strings. Use
+ *    g_strfreev() to free it.
+ *
+ * Since: 2.4
+ **/
+gchar **
+g_strsplit_set (const gchar *string,
+                const gchar *delimiters,
+                gint         max_tokens)
+{
+  gboolean delim_table[256];
+  GSList *tokens, *list;
+  gint n_tokens;
+  const gchar *s;
+  const gchar *current;
+  gchar *token;
+  gchar **result;
+
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (delimiters != NULL, NULL);
+
+  if (max_tokens < 1)
+    max_tokens = G_MAXINT;
+
+  if (*string == '\0')
+    {
+      result = g_new (char *, 1);
+      result[0] = NULL;
+      return result;
+    }
+
+  memset (delim_table, FALSE, sizeof (delim_table));
+  for (s = delimiters; *s != '\0'; ++s)
+    delim_table[*(guchar *)s] = TRUE;
+
+  tokens = NULL;
+  n_tokens = 0;
+
+  s = current = string;
+  while (*s != '\0')
+    {
+      if (delim_table[*(guchar *)s] && n_tokens + 1 < max_tokens)
+        {
+          token = g_strndup (current, s - current);
+          tokens = g_slist_prepend (tokens, token);
+          ++n_tokens;
+
+          current = s + 1;
+        }
+
+      ++s;
+    }
+
+  token = g_strndup (current, s - current);
+  tokens = g_slist_prepend (tokens, token);
+  ++n_tokens;
+
+  result = g_new (gchar *, n_tokens + 1);
+
+  result[n_tokens] = NULL;
+  for (list = tokens; list != NULL; list = list->next)
+    result[--n_tokens] = list->data;
+
+  g_slist_free (tokens);
+
+  return result;
+}
+
+/**
+ * g_strfreev:
+ * @str_array: a %NULL-terminated array of strings to free.
+
+ * Frees a %NULL-terminated array of strings, and the array itself.
+ * If called on a %NULL value, g_strfreev() simply returns.
+ **/
+void
+g_strfreev (gchar **str_array)
+{
+  if (str_array)
+    {
+      int i;
+
+      for (i = 0; str_array[i] != NULL; i++)
+        g_free (str_array[i]);
+
+      g_free (str_array);
+    }
+}
+
+/**
+ * g_strdupv:
+ * @str_array: %NULL-terminated array of strings.
+ *
+ * Copies %NULL-terminated array of strings. The copy is a deep copy;
+ * the new array should be freed by first freeing each string, then
+ * the array itself. g_strfreev() does this for you. If called
+ * on a %NULL value, g_strdupv() simply returns %NULL.
+ *
+ * Return value: a new %NULL-terminated array of strings.
+ **/
+gchar**
+g_strdupv (gchar **str_array)
+{
+  if (str_array)
+    {
+      gint i;
+      gchar **retval;
+
+      i = 0;
+      while (str_array[i])
+        ++i;
+
+      retval = g_new (gchar*, i + 1);
+
+      i = 0;
+      while (str_array[i])
+        {
+          retval[i] = g_strdup (str_array[i]);
+          ++i;
+        }
+      retval[i] = NULL;
+
+      return retval;
+    }
+  else
+    return NULL;
+}
+
+/**
+ * g_strjoinv:
+ * @separator: a string to insert between each of the strings, or %NULL
+ * @str_array: a %NULL-terminated array of strings to join
+ *
+ * Joins a number of strings together to form one long string, with the
+ * optional @separator inserted between each of them. The returned string
+ * should be freed with g_free().
+ *
+ * Returns: a newly-allocated string containing all of the strings joined
+ *     together, with @separator between them
+ */
+gchar*
+g_strjoinv (const gchar  *separator,
+            gchar       **str_array)
+{
+  gchar *string;
+  gchar *ptr;
+
+  g_return_val_if_fail (str_array != NULL, NULL);
+
+  if (separator == NULL)
+    separator = "";
+
+  if (*str_array)
+    {
+      gint i;
+      gsize len;
+      gsize separator_len;
+
+      separator_len = strlen (separator);
+      /* First part, getting length */
+      len = 1 + strlen (str_array[0]);
+      for (i = 1; str_array[i] != NULL; i++)
+        len += strlen (str_array[i]);
+      len += separator_len * (i - 1);
+
+      /* Second part, building string */
+      string = g_new (gchar, len);
+      ptr = g_stpcpy (string, *str_array);
+      for (i = 1; str_array[i] != NULL; i++)
+        {
+          ptr = g_stpcpy (ptr, separator);
+          ptr = g_stpcpy (ptr, str_array[i]);
+        }
+      }
+  else
+    string = g_strdup ("");
+
+  return string;
+}
+
+/**
+ * g_strjoin:
+ * @separator: a string to insert between each of the strings, or %NULL
+ * @Varargs: a %NULL-terminated list of strings to join
+ *
+ * Joins a number of strings together to form one long string, with the
+ * optional @separator inserted between each of them. The returned string
+ * should be freed with g_free().
+ *
+ * Returns: a newly-allocated string containing all of the strings joined
+ *     together, with @separator between them
+ */
+gchar*
+g_strjoin (const gchar  *separator,
+           ...)
+{
+  gchar *string, *s;
+  va_list args;
+  gsize len;
+  gsize separator_len;
+  gchar *ptr;
+
+  if (separator == NULL)
+    separator = "";
+
+  separator_len = strlen (separator);
+
+  va_start (args, separator);
+
+  s = va_arg (args, gchar*);
+
+  if (s)
+    {
+      /* First part, getting length */
+      len = 1 + strlen (s);
+
+      s = va_arg (args, gchar*);
+      while (s)
+        {
+          len += separator_len + strlen (s);
+          s = va_arg (args, gchar*);
+        }
+      va_end (args);
+
+      /* Second part, building string */
+      string = g_new (gchar, len);
+
+      va_start (args, separator);
+
+      s = va_arg (args, gchar*);
+      ptr = g_stpcpy (string, s);
+
+      s = va_arg (args, gchar*);
+      while (s)
+        {
+          ptr = g_stpcpy (ptr, separator);
+          ptr = g_stpcpy (ptr, s);
+          s = va_arg (args, gchar*);
+        }
+    }
+  else
+    string = g_strdup ("");
+
+  va_end (args);
+
+  return string;
+}
+
+
+/**
+ * g_strstr_len:
+ * @haystack: a string.
+ * @haystack_len: the maximum length of @haystack. Note that -1 is
+ * a valid length, if @haystack is nul-terminated, meaning it will
+ * search through the whole string.
+ * @needle: the string to search for.
+ *
+ * Searches the string @haystack for the first occurrence
+ * of the string @needle, limiting the length of the search
+ * to @haystack_len.
+ *
+ * Return value: a pointer to the found occurrence, or
+ *    %NULL if not found.
+ **/
+gchar *
+g_strstr_len (const gchar *haystack,
+              gssize       haystack_len,
+              const gchar *needle)
+{
+  g_return_val_if_fail (haystack != NULL, NULL);
+  g_return_val_if_fail (needle != NULL, NULL);
+
+  if (haystack_len < 0)
+    return strstr (haystack, needle);
+  else
+    {
+      const gchar *p = haystack;
+      gsize needle_len = strlen (needle);
+      const gchar *end;
+      gsize i;
+
+      if (needle_len == 0)
+        return (gchar *)haystack;
+
+      if (haystack_len < needle_len)
+        return NULL;
+
+      end = haystack + haystack_len - needle_len;
+
+      while (p <= end && *p)
+        {
+          for (i = 0; i < needle_len; i++)
+            if (p[i] != needle[i])
+              goto next;
+
+          return (gchar *)p;
+
+        next:
+          p++;
+        }
+
+      return NULL;
+    }
+}
+
+/**
+ * g_strrstr:
+ * @haystack: a nul-terminated string.
+ * @needle: the nul-terminated string to search for.
+ *
+ * Searches the string @haystack for the last occurrence
+ * of the string @needle.
+ *
+ * Return value: a pointer to the found occurrence, or
+ *    %NULL if not found.
+ **/
+gchar *
+g_strrstr (const gchar *haystack,
+           const gchar *needle)
+{
+  gsize i;
+  gsize needle_len;
+  gsize haystack_len;
+  const gchar *p;
+
+  g_return_val_if_fail (haystack != NULL, NULL);
+  g_return_val_if_fail (needle != NULL, NULL);
+
+  needle_len = strlen (needle);
+  haystack_len = strlen (haystack);
+
+  if (needle_len == 0)
+    return (gchar *)haystack;
+
+  if (haystack_len < needle_len)
+    return NULL;
+
+  p = haystack + haystack_len - needle_len;
+
+  while (p >= haystack)
+    {
+      for (i = 0; i < needle_len; i++)
+        if (p[i] != needle[i])
+          goto next;
+
+      return (gchar *)p;
+
+    next:
+      p--;
+    }
+
+  return NULL;
+}
+
+/**
+ * g_strrstr_len:
+ * @haystack: a nul-terminated string.
+ * @haystack_len: the maximum length of @haystack.
+ * @needle: the nul-terminated string to search for.
+ *
+ * Searches the string @haystack for the last occurrence
+ * of the string @needle, limiting the length of the search
+ * to @haystack_len.
+ *
+ * Return value: a pointer to the found occurrence, or
+ *    %NULL if not found.
+ **/
+gchar *
+g_strrstr_len (const gchar *haystack,
+               gssize        haystack_len,
+               const gchar *needle)
+{
+  g_return_val_if_fail (haystack != NULL, NULL);
+  g_return_val_if_fail (needle != NULL, NULL);
+
+  if (haystack_len < 0)
+    return g_strrstr (haystack, needle);
+  else
+    {
+      gsize needle_len = strlen (needle);
+      const gchar *haystack_max = haystack + haystack_len;
+      const gchar *p = haystack;
+      gsize i;
+
+      while (p < haystack_max && *p)
+        p++;
+
+      if (p < haystack + needle_len)
+        return NULL;
+
+      p -= needle_len;
+
+      while (p >= haystack)
+        {
+          for (i = 0; i < needle_len; i++)
+            if (p[i] != needle[i])
+              goto next;
+
+          return (gchar *)p;
+
+        next:
+          p--;
+        }
+
+      return NULL;
+    }
+}
+
+
+/**
+ * g_str_has_suffix:
+ * @str: a nul-terminated string.
+ * @suffix: the nul-terminated suffix to look for.
+ *
+ * Looks whether the string @str ends with @suffix.
+ *
+ * Return value: %TRUE if @str end with @suffix, %FALSE otherwise.
+ *
+ * Since: 2.2
+ **/
+gboolean
+g_str_has_suffix (const gchar  *str,
+                  const gchar  *suffix)
+{
+  int str_len;
+  int suffix_len;
+
+  g_return_val_if_fail (str != NULL, FALSE);
+  g_return_val_if_fail (suffix != NULL, FALSE);
+
+  str_len = strlen (str);
+  suffix_len = strlen (suffix);
+
+  if (str_len < suffix_len)
+    return FALSE;
+
+  return strcmp (str + str_len - suffix_len, suffix) == 0;
+}
+
+/**
+ * g_str_has_prefix:
+ * @str: a nul-terminated string.
+ * @prefix: the nul-terminated prefix to look for.
+ *
+ * Looks whether the string @str begins with @prefix.
+ *
+ * Return value: %TRUE if @str begins with @prefix, %FALSE otherwise.
+ *
+ * Since: 2.2
+ **/
+gboolean
+g_str_has_prefix (const gchar  *str,
+                  const gchar  *prefix)
+{
+  int str_len;
+  int prefix_len;
+
+  g_return_val_if_fail (str != NULL, FALSE);
+  g_return_val_if_fail (prefix != NULL, FALSE);
+
+  str_len = strlen (str);
+  prefix_len = strlen (prefix);
+
+  if (str_len < prefix_len)
+    return FALSE;
+
+  return strncmp (str, prefix, prefix_len) == 0;
+}
+
+
+/**
+ * g_strip_context:
+ * @msgid: a string
+ * @msgval: another string
+ *
+ * An auxiliary function for gettext() support (see Q_()).
+ *
+ * Return value: @msgval, unless @msgval is identical to @msgid and contains
+ *   a '|' character, in which case a pointer to the substring of msgid after
+ *   the first '|' character is returned.
+ *
+ * Since: 2.4
+ **/
+G_CONST_RETURN gchar *
+g_strip_context  (const gchar *msgid,
+                  const gchar *msgval)
+{
+  if (msgval == msgid)
+    {
+      const char *c = strchr (msgid, '|');
+      if (c != NULL)
+        return c + 1;
+    }
+
+  return msgval;
+}
+
+
+/**
+ * g_strv_length:
+ * @str_array: a %NULL-terminated array of strings.
+ *
+ * Returns the length of the given %NULL-terminated
+ * string array @str_array.
+ *
+ * Return value: length of @str_array.
+ *
+ * Since: 2.6
+ **/
+guint
+g_strv_length (gchar **str_array)
+{
+  guint i = 0;
+
+  g_return_val_if_fail (str_array != NULL, 0);
+
+  while (str_array[i])
+    ++i;
+
+  return i;
+}
+
+
+/**
+ * g_dpgettext:
+ * @domain: the translation domain to use, or %NULL to use
+ *   the domain set with textdomain()
+ * @msgctxtid: a combined message context and message id, separated
+ *   by a \004 character
+ * @msgidoffset: the offset of the message id in @msgctxid
+ *
+ * This function is a variant of g_dgettext() which supports
+ * a disambiguating message context. GNU gettext uses the
+ * '\004' character to separate the message context and
+ * message id in @msgctxtid.
+ * If 0 is passed as @msgidoffset, this function will fall back to
+ * trying to use the deprecated convention of using "|" as a separation
+ * character.
+ *
+ * This uses g_dgettext() internally.  See that functions for differences
+ * with dgettext() proper.
+ *
+ * Applications should normally not use this function directly,
+ * but use the C_() macro for translations with context.
+ *
+ * Returns: The translated string
+ *
+ * Since: 2.16
+ */
+G_CONST_RETURN gchar *
+g_dpgettext (const gchar *domain,
+             const gchar *msgctxtid,
+             gsize        msgidoffset)
+{
+  const gchar *translation;
+  gchar *sep;
+
+  translation = g_dgettext (domain, msgctxtid);
+
+  if (translation == msgctxtid)
+    {
+      if (msgidoffset > 0)
+        return msgctxtid + msgidoffset;
+
+      sep = strchr (msgctxtid, '|');
+
+      if (sep)
+        {
+          /* try with '\004' instead of '|', in case
+           * xgettext -kQ_:1g was used
+           */
+          gchar *tmp = g_alloca (strlen (msgctxtid) + 1);
+          strcpy (tmp, msgctxtid);
+          tmp[sep - msgctxtid] = '\004';
+
+          translation = g_dgettext (domain, tmp);
+
+          if (translation == tmp)
+            return sep + 1;
+        }
+    }
+
+  return translation;
+}
+
+/* This function is taken from gettext.h
+ * GNU gettext uses '\004' to separate context and msgid in .mo files.
+ */
+/**
+ * g_dpgettext2:
+ * @domain: the translation domain to use, or %NULL to use
+ *   the domain set with textdomain()
+ * @context: the message context
+ * @msgid: the message
+ *
+ * This function is a variant of g_dgettext() which supports
+ * a disambiguating message context. GNU gettext uses the
+ * '\004' character to separate the message context and
+ * message id in @msgctxtid.
+ *
+ * This uses g_dgettext() internally.  See that functions for differences
+ * with dgettext() proper.
+ *
+ * This function differs from C_() in that it is not a macro and
+ * thus you may use non-string-literals as context and msgid arguments.
+ *
+ * Returns: The translated string
+ *
+ * Since: 2.18
+ */
+G_CONST_RETURN char *
+g_dpgettext2 (const char *domain,
+              const char *msgctxt,
+              const char *msgid)
+{
+  size_t msgctxt_len = strlen (msgctxt) + 1;
+  size_t msgid_len = strlen (msgid) + 1;
+  const char *translation;
+  char* msg_ctxt_id;
+
+  msg_ctxt_id = g_alloca (msgctxt_len + msgid_len);
+
+  memcpy (msg_ctxt_id, msgctxt, msgctxt_len - 1);
+  msg_ctxt_id[msgctxt_len - 1] = '\004';
+  memcpy (msg_ctxt_id + msgctxt_len, msgid, msgid_len);
+
+  translation = g_dgettext (domain, msg_ctxt_id);
+
+  if (translation == msg_ctxt_id)
+    {
+      /* try the old way of doing message contexts, too */
+      msg_ctxt_id[msgctxt_len - 1] = '|';
+      translation = g_dgettext (domain, msg_ctxt_id);
+
+      if (translation == msg_ctxt_id)
+        return msgid;
+    }
+
+  return translation;
+}
+
+static gboolean
+_g_dgettext_should_translate (void)
+{
+  static gsize translate = 0;
+  enum {
+    SHOULD_TRANSLATE = 1,
+    SHOULD_NOT_TRANSLATE = 2
+  };
+
+  if (G_UNLIKELY (g_once_init_enter (&translate)))
+    {
+      gboolean should_translate = TRUE;
+
+      const char *default_domain     = textdomain (NULL);
+      const char *translator_comment = gettext ("");
+#ifndef G_OS_WIN32
+      const char *translate_locale   = setlocale (LC_MESSAGES, NULL);
+#else
+      const char *translate_locale   = g_win32_getlocale ();
+#endif
+      /* We should NOT translate only if all the following hold:
+       *   - user has called textdomain() and set textdomain to non-default
+       *   - default domain has no translations
+       *   - locale does not start with "en_" and is not "C"
+       *
+       * Rationale:
+       *   - If text domain is still the default domain, maybe user calls
+       *     it later. Continue with old behavior of translating.
+       *   - If locale starts with "en_", we can continue using the
+       *     translations even if the app doesn't have translations for
+       *     this locale.  That is, en_UK and en_CA for example.
+       *   - If locale is "C", maybe user calls setlocale(LC_ALL,"") later.
+       *     Continue with old behavior of translating.
+       */
+      if (0 != strcmp (default_domain, "messages") &&
+          '\0' == *translator_comment &&
+          0 != strncmp (translate_locale, "en_", 3) &&
+          0 != strcmp (translate_locale, "C"))
+        should_translate = FALSE;
+
+      g_once_init_leave (&translate,
+                         should_translate ?
+                         SHOULD_TRANSLATE :
+                         SHOULD_NOT_TRANSLATE);
+    }
+
+  return translate == SHOULD_TRANSLATE;
+}
+
+/**
+ * g_dgettext:
+ * @domain: the translation domain to use, or %NULL to use
+ *   the domain set with textdomain()
+ * @msgid: message to translate
+ *
+ * This function is a wrapper of dgettext() which does not translate
+ * the message if the default domain as set with textdomain() has no
+ * translations for the current locale.
+ *
+ * The advantage of using this function over dgettext() proper is that
+ * libraries using this function (like GTK+) will not use translations
+ * if the application using the library does not have translations for
+ * the current locale.  This results in a consistent English-only
+ * interface instead of one having partial translations.  For this
+ * feature to work, the call to textdomain() and setlocale() should
+ * precede any g_dgettext() invocations.  For GTK+, it means calling
+ * textdomain() before gtk_init or its variants.
+ *
+ * This function disables translations if and only if upon its first
+ * call all the following conditions hold:
+ * <itemizedlist>
+ * <listitem>@domain is not %NULL</listitem>
+ * <listitem>textdomain() has been called to set a default text domain</listitem>
+ * <listitem>there is no translations available for the default text domain
+ *           and the current locale</listitem>
+ * <listitem>current locale is not "C" or any English locales (those
+ *           starting with "en_")</listitem>
+ * </itemizedlist>
+ *
+ * Note that this behavior may not be desired for example if an application
+ * has its untranslated messages in a language other than English.  In those
+ * cases the application should call textdomain() after initializing GTK+.
+ *
+ * Applications should normally not use this function directly,
+ * but use the _() macro for translations.
+ *
+ * Returns: The translated string
+ *
+ * Since: 2.18
+ */
+G_CONST_RETURN gchar *
+g_dgettext (const gchar *domain,
+            const gchar *msgid)
+{
+  if (domain && G_UNLIKELY (!_g_dgettext_should_translate ()))
+    return msgid;
+
+  return dgettext (domain, msgid);
+}
+
+/**
+ * g_dcgettext:
+ * @domain: (allow-none): the translation domain to use, or %NULL to use
+ *   the domain set with textdomain()
+ * @msgid: message to translate
+ * @category: a locale category
+ *
+ * This is a variant of g_dgettext() that allows specifying a locale
+ * category instead of always using %LC_MESSAGES. See g_dgettext() for
+ * more information about how this functions differs from calling
+ * dcgettext() directly.
+ *
+ * Returns: the translated string for the given locale category
+ *
+ * Since: 2.26
+ */
+G_CONST_RETURN gchar *
+g_dcgettext (const gchar *domain,
+             const gchar *msgid,
+             int          category)
+{
+  if (domain && G_UNLIKELY (!_g_dgettext_should_translate ()))
+    return msgid;
+
+  return dcgettext (domain, msgid, category);
+}
+
+/**
+ * g_dngettext:
+ * @domain: the translation domain to use, or %NULL to use
+ *   the domain set with textdomain()
+ * @msgid: message to translate
+ * @msgid_plural: plural form of the message
+ * @n: the quantity for which translation is needed
+ *
+ * This function is a wrapper of dngettext() which does not translate
+ * the message if the default domain as set with textdomain() has no
+ * translations for the current locale.
+ *
+ * See g_dgettext() for details of how this differs from dngettext()
+ * proper.
+ *
+ * Returns: The translated string
+ *
+ * Since: 2.18
+ */
+G_CONST_RETURN gchar *
+g_dngettext (const gchar *domain,
+             const gchar *msgid,
+             const gchar *msgid_plural,
+             gulong       n)
+{
+  if (domain && G_UNLIKELY (!_g_dgettext_should_translate ()))
+    return n == 1 ? msgid : msgid_plural;
+
+  return dngettext (domain, msgid, msgid_plural, n);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gstrfuncs.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gstrfuncs.h
new file mode 100644 (file)
index 0000000..5c7332a
--- /dev/null
@@ -0,0 +1,269 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_STRFUNCS_H__
+#define __G_STRFUNCS_H__
+
+#include <stdarg.h>
+#include <glib/gmacros.h>
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+/* Functions like the ones in <ctype.h> that are not affected by locale. */
+typedef enum {
+  G_ASCII_ALNUM  = 1 << 0,
+  G_ASCII_ALPHA  = 1 << 1,
+  G_ASCII_CNTRL  = 1 << 2,
+  G_ASCII_DIGIT  = 1 << 3,
+  G_ASCII_GRAPH  = 1 << 4,
+  G_ASCII_LOWER  = 1 << 5,
+  G_ASCII_PRINT  = 1 << 6,
+  G_ASCII_PUNCT  = 1 << 7,
+  G_ASCII_SPACE  = 1 << 8,
+  G_ASCII_UPPER  = 1 << 9,
+  G_ASCII_XDIGIT = 1 << 10
+} GAsciiType;
+
+GLIB_VAR const guint16 * const g_ascii_table;
+
+#define g_ascii_isalnum(c) \
+  ((g_ascii_table[(guchar) (c)] & G_ASCII_ALNUM) != 0)
+
+#define g_ascii_isalpha(c) \
+  ((g_ascii_table[(guchar) (c)] & G_ASCII_ALPHA) != 0)
+
+#define g_ascii_iscntrl(c) \
+  ((g_ascii_table[(guchar) (c)] & G_ASCII_CNTRL) != 0)
+
+#define g_ascii_isdigit(c) \
+  ((g_ascii_table[(guchar) (c)] & G_ASCII_DIGIT) != 0)
+
+#define g_ascii_isgraph(c) \
+  ((g_ascii_table[(guchar) (c)] & G_ASCII_GRAPH) != 0)
+
+#define g_ascii_islower(c) \
+  ((g_ascii_table[(guchar) (c)] & G_ASCII_LOWER) != 0)
+
+#define g_ascii_isprint(c) \
+  ((g_ascii_table[(guchar) (c)] & G_ASCII_PRINT) != 0)
+
+#define g_ascii_ispunct(c) \
+  ((g_ascii_table[(guchar) (c)] & G_ASCII_PUNCT) != 0)
+
+#define g_ascii_isspace(c) \
+  ((g_ascii_table[(guchar) (c)] & G_ASCII_SPACE) != 0)
+
+#define g_ascii_isupper(c) \
+  ((g_ascii_table[(guchar) (c)] & G_ASCII_UPPER) != 0)
+
+#define g_ascii_isxdigit(c) \
+  ((g_ascii_table[(guchar) (c)] & G_ASCII_XDIGIT) != 0)
+
+gchar                 g_ascii_tolower  (gchar        c) G_GNUC_CONST;
+gchar                 g_ascii_toupper  (gchar        c) G_GNUC_CONST;
+
+gint                  g_ascii_digit_value  (gchar    c) G_GNUC_CONST;
+gint                  g_ascii_xdigit_value (gchar    c) G_GNUC_CONST;
+
+/* String utility functions that modify a string argument or
+ * return a constant string that must not be freed.
+ */
+#define         G_STR_DELIMITERS       "_-|> <."
+gchar*               g_strdelimit     (gchar        *string,
+                                       const gchar  *delimiters,
+                                       gchar         new_delimiter);
+gchar*               g_strcanon       (gchar        *string,
+                                       const gchar  *valid_chars,
+                                       gchar         substitutor);
+G_CONST_RETURN gchar* g_strerror       (gint         errnum) G_GNUC_CONST;
+G_CONST_RETURN gchar* g_strsignal      (gint         signum) G_GNUC_CONST;
+gchar*               g_strreverse     (gchar        *string);
+gsize                g_strlcpy        (gchar        *dest,
+                                       const gchar  *src,
+                                       gsize         dest_size);
+gsize                g_strlcat        (gchar        *dest,
+                                       const gchar  *src,
+                                       gsize         dest_size);
+gchar *               g_strstr_len     (const gchar  *haystack,
+                                       gssize        haystack_len,
+                                       const gchar  *needle);
+gchar *               g_strrstr        (const gchar  *haystack,
+                                       const gchar  *needle);
+gchar *               g_strrstr_len    (const gchar  *haystack,
+                                       gssize        haystack_len,
+                                       const gchar  *needle);
+
+gboolean              g_str_has_suffix (const gchar  *str,
+                                       const gchar  *suffix);
+gboolean              g_str_has_prefix (const gchar  *str,
+                                       const gchar  *prefix);
+
+/* String to/from double conversion functions */
+
+gdouble                      g_strtod         (const gchar  *nptr,
+                                       gchar       **endptr);
+gdouble                      g_ascii_strtod   (const gchar  *nptr,
+                                       gchar       **endptr);
+guint64                      g_ascii_strtoull (const gchar *nptr,
+                                       gchar      **endptr,
+                                       guint        base);
+gint64               g_ascii_strtoll  (const gchar *nptr,
+                                       gchar      **endptr,
+                                       guint        base);
+/* 29 bytes should enough for all possible values that
+ * g_ascii_dtostr can produce.
+ * Then add 10 for good measure */
+#define G_ASCII_DTOSTR_BUF_SIZE (29 + 10)
+gchar *               g_ascii_dtostr   (gchar        *buffer,
+                                       gint          buf_len,
+                                       gdouble       d);
+gchar *               g_ascii_formatd  (gchar        *buffer,
+                                       gint          buf_len,
+                                       const gchar  *format,
+                                       gdouble       d);
+
+/* removes leading spaces */
+gchar*                g_strchug        (gchar        *string);
+/* removes trailing spaces */
+gchar*                g_strchomp       (gchar        *string);
+/* removes leading & trailing spaces */
+#define g_strstrip( string )   g_strchomp (g_strchug (string))
+
+gint                  g_ascii_strcasecmp  (const gchar *s1,
+                                          const gchar *s2);
+gint                  g_ascii_strncasecmp (const gchar *s1,
+                                          const gchar *s2,
+                                          gsize        n);
+gchar*                g_ascii_strdown     (const gchar *str,
+                                          gssize       len) G_GNUC_MALLOC;
+gchar*                g_ascii_strup       (const gchar *str,
+                                          gssize       len) G_GNUC_MALLOC;
+
+#ifndef G_DISABLE_DEPRECATED
+
+/* The following four functions are deprecated and will be removed in
+ * the next major release. They use the locale-specific tolower and
+ * toupper, which is almost never the right thing.
+ */
+
+gint                 g_strcasecmp     (const gchar *s1,
+                                       const gchar *s2);
+gint                 g_strncasecmp    (const gchar *s1,
+                                       const gchar *s2,
+                                       guint        n);
+gchar*               g_strdown        (gchar        *string);
+gchar*               g_strup          (gchar        *string);
+
+#endif /* G_DISABLE_DEPRECATED */
+
+/* String utility functions that return a newly allocated string which
+ * ought to be freed with g_free from the caller at some point.
+ */
+gchar*               g_strdup         (const gchar *str) G_GNUC_MALLOC;
+gchar*               g_strdup_printf  (const gchar *format,
+                                       ...) G_GNUC_PRINTF (1, 2) G_GNUC_MALLOC;
+gchar*               g_strdup_vprintf (const gchar *format,
+                                       va_list      args) G_GNUC_MALLOC;
+gchar*               g_strndup        (const gchar *str,
+                                       gsize        n) G_GNUC_MALLOC;  
+gchar*               g_strnfill       (gsize        length,  
+                                       gchar        fill_char) G_GNUC_MALLOC;
+gchar*               g_strconcat      (const gchar *string1,
+                                       ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
+gchar*                g_strjoin               (const gchar  *separator,
+                                       ...) G_GNUC_MALLOC G_GNUC_NULL_TERMINATED;
+
+/* Make a copy of a string interpreting C string -style escape
+ * sequences. Inverse of g_strescape. The recognized sequences are \b
+ * \f \n \r \t \\ \" and the octal format.
+ */
+gchar*                g_strcompress    (const gchar *source) G_GNUC_MALLOC;
+
+/* Copy a string escaping nonprintable characters like in C strings.
+ * Inverse of g_strcompress. The exceptions parameter, if non-NULL, points
+ * to a string containing characters that are not to be escaped.
+ *
+ * Deprecated API: gchar* g_strescape (const gchar *source);
+ * Luckily this function wasn't used much, using NULL as second parameter
+ * provides mostly identical semantics.
+ */
+gchar*                g_strescape      (const gchar *source,
+                                       const gchar *exceptions) G_GNUC_MALLOC;
+
+gpointer              g_memdup        (gconstpointer mem,
+                                       guint          byte_size) G_GNUC_MALLOC G_GNUC_ALLOC_SIZE(2);
+
+/* NULL terminated string arrays.
+ * g_strsplit(), g_strsplit_set() split up string into max_tokens tokens
+ * at delim and return a newly allocated string array.
+ * g_strjoinv() concatenates all of str_array's strings, sliding in an
+ * optional separator, the returned string is newly allocated.
+ * g_strfreev() frees the array itself and all of its strings.
+ * g_strdupv() copies a NULL-terminated array of strings
+ * g_strv_length() returns the length of a NULL-terminated array of strings
+ */
+gchar**                      g_strsplit       (const gchar  *string,
+                                       const gchar  *delimiter,
+                                       gint          max_tokens) G_GNUC_MALLOC;
+gchar **             g_strsplit_set   (const gchar *string,
+                                       const gchar *delimiters,
+                                       gint         max_tokens) G_GNUC_MALLOC;
+gchar*                g_strjoinv       (const gchar  *separator,
+                                       gchar       **str_array) G_GNUC_MALLOC;
+void                  g_strfreev       (gchar       **str_array);
+gchar**               g_strdupv        (gchar       **str_array) G_GNUC_MALLOC;
+guint                 g_strv_length    (gchar       **str_array);
+
+gchar*                g_stpcpy         (gchar        *dest,
+                                        const char   *src);
+
+G_CONST_RETURN gchar *g_strip_context  (const gchar *msgid, 
+                                       const gchar *msgval) G_GNUC_FORMAT(1);
+
+G_CONST_RETURN gchar *g_dgettext       (const gchar *domain,
+                                       const gchar *msgid) G_GNUC_FORMAT(2);
+G_CONST_RETURN gchar *g_dcgettext      (const gchar *domain,
+                                       const gchar *msgid,
+                                        int          category) G_GNUC_FORMAT(2);
+G_CONST_RETURN gchar *g_dngettext      (const gchar *domain,
+                                       const gchar *msgid,
+                                       const gchar *msgid_plural,
+                                       gulong       n) G_GNUC_FORMAT(3);
+G_CONST_RETURN gchar *g_dpgettext      (const gchar *domain,
+                                        const gchar *msgctxtid,
+                                        gsize        msgidoffset) G_GNUC_FORMAT(2);
+G_CONST_RETURN gchar *g_dpgettext2     (const gchar *domain,
+                                        const gchar *context,
+                                        const gchar *msgid) G_GNUC_FORMAT(3);
+
+G_END_DECLS
+
+#endif /* __G_STRFUNCS_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gstring.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gstring.c
new file mode 100644 (file)
index 0000000..9b25fb6
--- /dev/null
@@ -0,0 +1,1521 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+
+#include "gstring.h"
+
+#include "gprintf.h"
+
+
+/**
+ * SECTION: string_chunks
+ * @title: String Chunks
+ * @short_description: efficient storage of groups of strings
+ *
+ * String chunks are used to store groups of strings. Memory is
+ * allocated in blocks, and as strings are added to the #GStringChunk
+ * they are copied into the next free position in a block. When a block
+ * is full a new block is allocated.
+ *
+ * When storing a large number of strings, string chunks are more
+ * efficient than using g_strdup() since fewer calls to malloc() are
+ * needed, and less memory is wasted in memory allocation overheads.
+ *
+ * By adding strings with g_string_chunk_insert_const() it is also
+ * possible to remove duplicates.
+ *
+ * To create a new #GStringChunk use g_string_chunk_new().
+ *
+ * To add strings to a #GStringChunk use g_string_chunk_insert().
+ *
+ * To add strings to a #GStringChunk, but without duplicating strings
+ * which are already in the #GStringChunk, use
+ * g_string_chunk_insert_const().
+ *
+ * To free the entire #GStringChunk use g_string_chunk_free(). It is
+ * not possible to free individual strings.
+ **/
+
+/**
+ * GStringChunk:
+ *
+ * An opaque data structure representing String Chunks. It should only
+ * be accessed by using the following functions.
+ **/
+struct _GStringChunk
+{
+  GHashTable *const_table;
+  GSList     *storage_list;
+  gsize       storage_next;    
+  gsize       this_size;       
+  gsize       default_size;    
+};
+
+/* Hash Functions.
+ */
+
+/**
+ * g_str_equal:
+ * @v1: a key
+ * @v2: a key to compare with @v1
+ *
+ * Compares two strings for byte-by-byte equality and returns %TRUE
+ * if they are equal. It can be passed to g_hash_table_new() as the
+ * @key_equal_func parameter, when using strings as keys in a #GHashTable.
+ *
+ * Note that this function is primarily meant as a hash table comparison
+ * function. For a general-purpose, %NULL-safe string comparison function,
+ * see g_strcmp0().
+ *
+ * Returns: %TRUE if the two keys match
+ */
+gboolean
+g_str_equal (gconstpointer v1,
+            gconstpointer v2)
+{
+  const gchar *string1 = v1;
+  const gchar *string2 = v2;
+  
+  return strcmp (string1, string2) == 0;
+}
+
+/**
+ * g_str_hash:
+ * @v: a string key
+ *
+ * Converts a string to a hash value.
+ * It can be passed to g_hash_table_new() as the @hash_func 
+ * parameter, when using strings as keys in a #GHashTable.
+ *
+ * Returns: a hash value corresponding to the key
+ */
+guint
+g_str_hash (gconstpointer v)
+{
+  /* 31 bit hash function */
+  const signed char *p = v;
+  guint32 h = *p;
+
+  if (h)
+    for (p += 1; *p != '\0'; p++)
+      h = (h << 5) - h + *p;
+
+  return h;
+}
+
+#define MY_MAXSIZE ((gsize)-1)
+
+static inline gsize
+nearest_power (gsize base, gsize num)    
+{
+  if (num > MY_MAXSIZE / 2)
+    {
+      return MY_MAXSIZE;
+    }
+  else
+    {
+      gsize n = base;
+
+      while (n < num)
+       n <<= 1;
+      
+      return n;
+    }
+}
+
+/* String Chunks.
+ */
+
+/**
+ * g_string_chunk_new:
+ * @size: the default size of the blocks of memory which are 
+ *        allocated to store the strings. If a particular string 
+ *        is larger than this default size, a larger block of 
+ *        memory will be allocated for it.
+ * 
+ * Creates a new #GStringChunk. 
+ * 
+ * Returns: a new #GStringChunk
+ */
+GStringChunk*
+g_string_chunk_new (gsize size)    
+{
+  GStringChunk *new_chunk = g_new (GStringChunk, 1);
+  gsize actual_size = 1;    
+
+  actual_size = nearest_power (1, size);
+
+  new_chunk->const_table       = NULL;
+  new_chunk->storage_list      = NULL;
+  new_chunk->storage_next      = actual_size;
+  new_chunk->default_size      = actual_size;
+  new_chunk->this_size         = actual_size;
+
+  return new_chunk;
+}
+
+/**
+ * g_string_chunk_free:
+ * @chunk: a #GStringChunk 
+ * 
+ * Frees all memory allocated by the #GStringChunk.
+ * After calling g_string_chunk_free() it is not safe to
+ * access any of the strings which were contained within it.
+ */
+void
+g_string_chunk_free (GStringChunk *chunk)
+{
+  GSList *tmp_list;
+
+  g_return_if_fail (chunk != NULL);
+
+  if (chunk->storage_list)
+    {
+      for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
+       g_free (tmp_list->data);
+
+      g_slist_free (chunk->storage_list);
+    }
+
+  if (chunk->const_table)
+    g_hash_table_destroy (chunk->const_table);
+
+  g_free (chunk);
+}
+
+/**
+ * g_string_chunk_clear:
+ * @chunk: a #GStringChunk
+ *
+ * Frees all strings contained within the #GStringChunk.
+ * After calling g_string_chunk_clear() it is not safe to
+ * access any of the strings which were contained within it.
+ *
+ * Since: 2.14
+ */
+void
+g_string_chunk_clear (GStringChunk *chunk)
+{
+  GSList *tmp_list;
+
+  g_return_if_fail (chunk != NULL);
+
+  if (chunk->storage_list)
+    {
+      for (tmp_list = chunk->storage_list; tmp_list; tmp_list = tmp_list->next)
+        g_free (tmp_list->data);
+
+      g_slist_free (chunk->storage_list);
+
+      chunk->storage_list       = NULL;
+      chunk->storage_next       = chunk->default_size;
+      chunk->this_size          = chunk->default_size;
+    }
+
+  if (chunk->const_table)
+      g_hash_table_remove_all (chunk->const_table);
+}
+
+/**
+ * g_string_chunk_insert:
+ * @chunk: a #GStringChunk
+ * @string: the string to add
+ * 
+ * Adds a copy of @string to the #GStringChunk.
+ * It returns a pointer to the new copy of the string 
+ * in the #GStringChunk. The characters in the string 
+ * can be changed, if necessary, though you should not 
+ * change anything after the end of the string.
+ *
+ * Unlike g_string_chunk_insert_const(), this function 
+ * does not check for duplicates. Also strings added 
+ * with g_string_chunk_insert() will not be searched 
+ * by g_string_chunk_insert_const() when looking for 
+ * duplicates.
+ * 
+ * Returns: a pointer to the copy of @string within 
+ *          the #GStringChunk
+ */
+gchar*
+g_string_chunk_insert (GStringChunk *chunk,
+                      const gchar  *string)
+{
+  g_return_val_if_fail (chunk != NULL, NULL);
+
+  return g_string_chunk_insert_len (chunk, string, -1);
+}
+
+/**
+ * g_string_chunk_insert_const:
+ * @chunk: a #GStringChunk
+ * @string: the string to add
+ *
+ * Adds a copy of @string to the #GStringChunk, unless the same
+ * string has already been added to the #GStringChunk with
+ * g_string_chunk_insert_const().
+ *
+ * This function is useful if you need to copy a large number
+ * of strings but do not want to waste space storing duplicates.
+ * But you must remember that there may be several pointers to
+ * the same string, and so any changes made to the strings
+ * should be done very carefully.
+ *
+ * Note that g_string_chunk_insert_const() will not return a
+ * pointer to a string added with g_string_chunk_insert(), even
+ * if they do match.
+ *
+ * Returns: a pointer to the new or existing copy of @string
+ *          within the #GStringChunk
+ */
+gchar*
+g_string_chunk_insert_const (GStringChunk *chunk,
+                            const gchar  *string)
+{
+  char* lookup;
+
+  g_return_val_if_fail (chunk != NULL, NULL);
+
+  if (!chunk->const_table)
+    chunk->const_table = g_hash_table_new (g_str_hash, g_str_equal);
+
+  lookup = (char*) g_hash_table_lookup (chunk->const_table, (gchar *)string);
+
+  if (!lookup)
+    {
+      lookup = g_string_chunk_insert (chunk, string);
+      g_hash_table_insert (chunk->const_table, lookup, lookup);
+    }
+
+  return lookup;
+}
+
+/**
+ * g_string_chunk_insert_len:
+ * @chunk: a #GStringChunk
+ * @string: bytes to insert
+ * @len: number of bytes of @string to insert, or -1 to insert a
+ *     nul-terminated string
+ *
+ * Adds a copy of the first @len bytes of @string to the #GStringChunk.
+ * The copy is nul-terminated.
+ *
+ * Since this function does not stop at nul bytes, it is the caller's
+ * responsibility to ensure that @string has at least @len addressable
+ * bytes.
+ *
+ * The characters in the returned string can be changed, if necessary,
+ * though you should not change anything after the end of the string.
+ *
+ * Return value: a pointer to the copy of @string within the #GStringChunk
+ *
+ * Since: 2.4
+ */
+gchar*
+g_string_chunk_insert_len (GStringChunk *chunk,
+                          const gchar  *string,
+                          gssize        len)
+{
+  gssize size;
+  gchar* pos;
+
+  g_return_val_if_fail (chunk != NULL, NULL);
+
+  if (len < 0)
+    size = strlen (string);
+  else
+    size = len;
+
+  if ((chunk->storage_next + size + 1) > chunk->this_size)
+    {
+      gsize new_size = nearest_power (chunk->default_size, size + 1);
+
+      chunk->storage_list = g_slist_prepend (chunk->storage_list,
+                                            g_new (gchar, new_size));
+
+      chunk->this_size = new_size;
+      chunk->storage_next = 0;
+    }
+
+  pos = ((gchar *) chunk->storage_list->data) + chunk->storage_next;
+
+  *(pos + size) = '\0';
+
+  memcpy (pos, string, size);
+
+  chunk->storage_next += size + 1;
+
+  return pos;
+}
+
+/* Strings.
+ */
+static void
+g_string_maybe_expand (GString* string,
+                      gsize    len) 
+{
+  if (string->len + len >= string->allocated_len)
+    {
+      string->allocated_len = nearest_power (1, string->len + len + 1);
+      string->str = g_realloc (string->str, string->allocated_len);
+    }
+}
+
+/**
+ * g_string_sized_new:
+ * @dfl_size: the default size of the space allocated to 
+ *            hold the string
+ *
+ * Creates a new #GString, with enough space for @dfl_size 
+ * bytes. This is useful if you are going to add a lot of 
+ * text to the string and don't want it to be reallocated 
+ * too often.
+ *
+ * Returns: the new #GString
+ */
+GString*
+g_string_sized_new (gsize dfl_size)    
+{
+  GString *string = g_slice_new (GString);
+
+  string->allocated_len = 0;
+  string->len   = 0;
+  string->str   = NULL;
+
+  g_string_maybe_expand (string, MAX (dfl_size, 2));
+  string->str[0] = 0;
+
+  return string;
+}
+
+/**
+ * g_string_new:
+ * @init: the initial text to copy into the string
+ * 
+ * Creates a new #GString, initialized with the given string.
+ *
+ * Returns: the new #GString
+ */
+GString*
+g_string_new (const gchar *init)
+{
+  GString *string;
+
+  if (init == NULL || *init == '\0')
+    string = g_string_sized_new (2);
+  else 
+    {
+      gint len;
+
+      len = strlen (init);
+      string = g_string_sized_new (len + 2);
+
+      g_string_append_len (string, init, len);
+    }
+
+  return string;
+}
+
+/**
+ * g_string_new_len:
+ * @init: initial contents of the string
+ * @len: length of @init to use
+ *
+ * Creates a new #GString with @len bytes of the @init buffer.  
+ * Because a length is provided, @init need not be nul-terminated,
+ * and can contain embedded nul bytes.
+ *
+ * Since this function does not stop at nul bytes, it is the caller's
+ * responsibility to ensure that @init has at least @len addressable 
+ * bytes.
+ *
+ * Returns: a new #GString
+ */
+GString*
+g_string_new_len (const gchar *init,
+                  gssize       len)    
+{
+  GString *string;
+
+  if (len < 0)
+    return g_string_new (init);
+  else
+    {
+      string = g_string_sized_new (len);
+      
+      if (init)
+        g_string_append_len (string, init, len);
+      
+      return string;
+    }
+}
+
+/**
+ * g_string_free:
+ * @string: a #GString
+ * @free_segment: if %TRUE the actual character data is freed as well
+ *
+ * Frees the memory allocated for the #GString.
+ * If @free_segment is %TRUE it also frees the character data.
+ *
+ * Returns: the character data of @string 
+ *          (i.e. %NULL if @free_segment is %TRUE)
+ */
+gchar*
+g_string_free (GString *string,
+              gboolean free_segment)
+{
+  gchar *segment;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  if (free_segment)
+    {
+      g_free (string->str);
+      segment = NULL;
+    }
+  else
+    segment = string->str;
+
+  g_slice_free (GString, string);
+
+  return segment;
+}
+
+/**
+ * g_string_equal:
+ * @v: a #GString
+ * @v2: another #GString
+ *
+ * Compares two strings for equality, returning %TRUE if they are equal. 
+ * For use with #GHashTable.
+ *
+ * Returns: %TRUE if they strings are the same length and contain the 
+ *   same bytes
+ */
+gboolean
+g_string_equal (const GString *v,
+                const GString *v2)
+{
+  gchar *p, *q;
+  GString *string1 = (GString *) v;
+  GString *string2 = (GString *) v2;
+  gsize i = string1->len;    
+
+  if (i != string2->len)
+    return FALSE;
+
+  p = string1->str;
+  q = string2->str;
+  while (i)
+    {
+      if (*p != *q)
+       return FALSE;
+      p++;
+      q++;
+      i--;
+    }
+  return TRUE;
+}
+
+/**
+ * g_string_hash:
+ * @str: a string to hash
+ *
+ * Creates a hash code for @str; for use with #GHashTable.
+ *
+ * Returns: hash code for @str
+ */
+/* 31 bit hash function */
+guint
+g_string_hash (const GString *str)
+{
+  const gchar *p = str->str;
+  gsize n = str->len;    
+  guint h = 0;
+
+  while (n--)
+    {
+      h = (h << 5) - h + *p;
+      p++;
+    }
+
+  return h;
+}
+
+/**
+ * g_string_assign:
+ * @string: the destination #GString. Its current contents 
+ *          are destroyed.
+ * @rval: the string to copy into @string
+ *
+ * Copies the bytes from a string into a #GString, 
+ * destroying any previous contents. It is rather like 
+ * the standard strcpy() function, except that you do not 
+ * have to worry about having enough space to copy the string.
+ *
+ * Returns: @string
+ */
+GString*
+g_string_assign (GString     *string,
+                const gchar *rval)
+{
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (rval != NULL, string);
+
+  /* Make sure assigning to itself doesn't corrupt the string.  */
+  if (string->str != rval)
+    {
+      /* Assigning from substring should be ok since g_string_truncate
+        does not realloc.  */
+      g_string_truncate (string, 0);
+      g_string_append (string, rval);
+    }
+
+  return string;
+}
+
+/**
+ * g_string_truncate:
+ * @string: a #GString
+ * @len: the new size of @string
+ *
+ * Cuts off the end of the GString, leaving the first @len bytes. 
+ *
+ * Returns: @string
+ */
+GString*
+g_string_truncate (GString *string,
+                  gsize    len)    
+{
+  g_return_val_if_fail (string != NULL, NULL);
+
+  string->len = MIN (len, string->len);
+  string->str[string->len] = 0;
+
+  return string;
+}
+
+/**
+ * g_string_set_size:
+ * @string: a #GString
+ * @len: the new length
+ * 
+ * Sets the length of a #GString. If the length is less than
+ * the current length, the string will be truncated. If the
+ * length is greater than the current length, the contents
+ * of the newly added area are undefined. (However, as
+ * always, string->str[string->len] will be a nul byte.) 
+ * 
+ * Return value: @string
+ **/
+GString*
+g_string_set_size (GString *string,
+                  gsize    len)    
+{
+  g_return_val_if_fail (string != NULL, NULL);
+
+  if (len >= string->allocated_len)
+    g_string_maybe_expand (string, len - string->len);
+  
+  string->len = len;
+  string->str[len] = 0;
+
+  return string;
+}
+
+/**
+ * g_string_insert_len:
+ * @string: a #GString
+ * @pos: position in @string where insertion should
+ *       happen, or -1 for at the end
+ * @val: bytes to insert
+ * @len: number of bytes of @val to insert
+ *
+ * Inserts @len bytes of @val into @string at @pos.
+ * Because @len is provided, @val may contain embedded
+ * nuls and need not be nul-terminated. If @pos is -1,
+ * bytes are inserted at the end of the string.
+ *
+ * Since this function does not stop at nul bytes, it is
+ * the caller's responsibility to ensure that @val has at
+ * least @len addressable bytes.
+ *
+ * Returns: @string
+ */
+GString*
+g_string_insert_len (GString     *string,
+                    gssize       pos,
+                    const gchar *val,
+                    gssize       len)
+{
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (len == 0 || val != NULL, string);
+
+  if (len == 0)
+    return string;
+
+  if (len < 0)
+    len = strlen (val);
+
+  if (pos < 0)
+    pos = string->len;
+  else
+    g_return_val_if_fail (pos <= string->len, string);
+
+  /* Check whether val represents a substring of string.  This test
+     probably violates chapter and verse of the C standards, since
+     ">=" and "<=" are only valid when val really is a substring.
+     In practice, it will work on modern archs.  */
+  if (val >= string->str && val <= string->str + string->len)
+    {
+      gsize offset = val - string->str;
+      gsize precount = 0;
+
+      g_string_maybe_expand (string, len);
+      val = string->str + offset;
+      /* At this point, val is valid again.  */
+
+      /* Open up space where we are going to insert.  */
+      if (pos < string->len)
+        g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
+
+      /* Move the source part before the gap, if any.  */
+      if (offset < pos)
+        {
+          precount = MIN (len, pos - offset);
+          memcpy (string->str + pos, val, precount);
+        }
+
+      /* Move the source part after the gap, if any.  */
+      if (len > precount)
+        memcpy (string->str + pos + precount,
+                val + /* Already moved: */ precount + /* Space opened up: */ len,
+                len - precount);
+    }
+  else
+    {
+      g_string_maybe_expand (string, len);
+
+      /* If we aren't appending at the end, move a hunk
+       * of the old string to the end, opening up space
+       */
+      if (pos < string->len)
+        g_memmove (string->str + pos + len, string->str + pos, string->len - pos);
+
+      /* insert the new string */
+      if (len == 1)
+        string->str[pos] = *val;
+      else
+        memcpy (string->str + pos, val, len);
+    }
+
+  string->len += len;
+
+  string->str[string->len] = 0;
+
+  return string;
+}
+
+#define SUB_DELIM_CHARS  "!$&'()*+,;="
+
+static gboolean
+is_valid (char c, const char *reserved_chars_allowed)
+{
+  if (g_ascii_isalnum (c) ||
+      c == '-' ||
+      c == '.' ||
+      c == '_' ||
+      c == '~')
+    return TRUE;
+
+  if (reserved_chars_allowed &&
+      strchr (reserved_chars_allowed, c) != NULL)
+    return TRUE;
+  
+  return FALSE;
+}
+
+static gboolean 
+gunichar_ok (gunichar c)
+{
+  return
+    (c != (gunichar) -2) &&
+    (c != (gunichar) -1);
+}
+
+/**
+ * g_string_append_uri_escaped:
+ * @string: a #GString
+ * @unescaped: a string
+ * @reserved_chars_allowed: a string of reserved characters allowed to be used, or %NULL
+ * @allow_utf8: set %TRUE if the escaped string may include UTF8 characters
+ * 
+ * Appends @unescaped to @string, escaped any characters that
+ * are reserved in URIs using URI-style escape sequences.
+ * 
+ * Returns: @string
+ *
+ * Since: 2.16
+ **/
+GString *
+g_string_append_uri_escaped (GString *string,
+                            const char *unescaped,
+                            const char *reserved_chars_allowed,
+                            gboolean allow_utf8)
+{
+  unsigned char c;
+  const char *end;
+  static const gchar hex[16] = "0123456789ABCDEF";
+
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (unescaped != NULL, NULL);
+
+  end = unescaped + strlen (unescaped);
+  
+  while ((c = *unescaped) != 0)
+    {
+      if (c >= 0x80 && allow_utf8 &&
+         gunichar_ok (g_utf8_get_char_validated (unescaped, end - unescaped)))
+       {
+         int len = g_utf8_skip [c];
+         g_string_append_len (string, unescaped, len);
+         unescaped += len;
+       }
+      else if (is_valid (c, reserved_chars_allowed))
+       {
+         g_string_append_c (string, c);
+         unescaped++;
+       }
+      else
+       {
+         g_string_append_c (string, '%');
+         g_string_append_c (string, hex[((guchar)c) >> 4]);
+         g_string_append_c (string, hex[((guchar)c) & 0xf]);
+         unescaped++;
+       }
+    }
+
+  return string;
+}
+
+/**
+ * g_string_append:
+ * @string: a #GString
+ * @val: the string to append onto the end of @string
+ * 
+ * Adds a string onto the end of a #GString, expanding 
+ * it if necessary.
+ *
+ * Returns: @string
+ */
+GString*
+g_string_append (GString     *string,
+                const gchar *val)
+{  
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (val != NULL, string);
+
+  return g_string_insert_len (string, -1, val, -1);
+}
+
+/**
+ * g_string_append_len:
+ * @string: a #GString
+ * @val: bytes to append
+ * @len: number of bytes of @val to use
+ * 
+ * Appends @len bytes of @val to @string. Because @len is 
+ * provided, @val may contain embedded nuls and need not 
+ * be nul-terminated.
+ * 
+ * Since this function does not stop at nul bytes, it is 
+ * the caller's responsibility to ensure that @val has at 
+ * least @len addressable bytes.
+ *
+ * Returns: @string
+ */
+GString*
+g_string_append_len (GString    *string,
+                     const gchar *val,
+                     gssize       len)    
+{
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (len == 0 || val != NULL, string);
+
+  return g_string_insert_len (string, -1, val, len);
+}
+
+/**
+ * g_string_append_c:
+ * @string: a #GString
+ * @c: the byte to append onto the end of @string
+ *
+ * Adds a byte onto the end of a #GString, expanding 
+ * it if necessary.
+ * 
+ * Returns: @string
+ */
+#undef g_string_append_c
+GString*
+g_string_append_c (GString *string,
+                  gchar    c)
+{
+  g_return_val_if_fail (string != NULL, NULL);
+
+  return g_string_insert_c (string, -1, c);
+}
+
+/**
+ * g_string_append_unichar:
+ * @string: a #GString
+ * @wc: a Unicode character
+ * 
+ * Converts a Unicode character into UTF-8, and appends it
+ * to the string.
+ * 
+ * Return value: @string
+ **/
+GString*
+g_string_append_unichar (GString  *string,
+                        gunichar  wc)
+{  
+  g_return_val_if_fail (string != NULL, NULL);
+  
+  return g_string_insert_unichar (string, -1, wc);
+}
+
+/**
+ * g_string_prepend:
+ * @string: a #GString
+ * @val: the string to prepend on the start of @string
+ *
+ * Adds a string on to the start of a #GString, 
+ * expanding it if necessary.
+ *
+ * Returns: @string
+ */
+GString*
+g_string_prepend (GString     *string,
+                 const gchar *val)
+{
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (val != NULL, string);
+  
+  return g_string_insert_len (string, 0, val, -1);
+}
+
+/**
+ * g_string_prepend_len:
+ * @string: a #GString
+ * @val: bytes to prepend
+ * @len: number of bytes in @val to prepend
+ *
+ * Prepends @len bytes of @val to @string. 
+ * Because @len is provided, @val may contain 
+ * embedded nuls and need not be nul-terminated.
+ *
+ * Since this function does not stop at nul bytes, 
+ * it is the caller's responsibility to ensure that 
+ * @val has at least @len addressable bytes.
+ *
+ * Returns: @string
+ */
+GString*
+g_string_prepend_len (GString    *string,
+                      const gchar *val,
+                      gssize       len)    
+{
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (val != NULL, string);
+
+  return g_string_insert_len (string, 0, val, len);
+}
+
+/**
+ * g_string_prepend_c:
+ * @string: a #GString
+ * @c: the byte to prepend on the start of the #GString
+ *
+ * Adds a byte onto the start of a #GString, 
+ * expanding it if necessary.
+ *
+ * Returns: @string
+ */
+GString*
+g_string_prepend_c (GString *string,
+                   gchar    c)
+{  
+  g_return_val_if_fail (string != NULL, NULL);
+  
+  return g_string_insert_c (string, 0, c);
+}
+
+/**
+ * g_string_prepend_unichar:
+ * @string: a #GString
+ * @wc: a Unicode character
+ * 
+ * Converts a Unicode character into UTF-8, and prepends it
+ * to the string.
+ * 
+ * Return value: @string
+ **/
+GString*
+g_string_prepend_unichar (GString  *string,
+                         gunichar  wc)
+{  
+  g_return_val_if_fail (string != NULL, NULL);
+  
+  return g_string_insert_unichar (string, 0, wc);
+}
+
+/**
+ * g_string_insert:
+ * @string: a #GString
+ * @pos: the position to insert the copy of the string
+ * @val: the string to insert
+ *
+ * Inserts a copy of a string into a #GString, 
+ * expanding it if necessary.
+ *
+ * Returns: @string
+ */
+GString*
+g_string_insert (GString     *string,
+                gssize       pos,    
+                const gchar *val)
+{
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (val != NULL, string);
+  if (pos >= 0)
+    g_return_val_if_fail (pos <= string->len, string);
+  
+  return g_string_insert_len (string, pos, val, -1);
+}
+
+/**
+ * g_string_insert_c:
+ * @string: a #GString
+ * @pos: the position to insert the byte
+ * @c: the byte to insert
+ *
+ * Inserts a byte into a #GString, expanding it if necessary.
+ * 
+ * Returns: @string
+ */
+GString*
+g_string_insert_c (GString *string,
+                  gssize   pos,    
+                  gchar    c)
+{
+  g_return_val_if_fail (string != NULL, NULL);
+
+  g_string_maybe_expand (string, 1);
+
+  if (pos < 0)
+    pos = string->len;
+  else
+    g_return_val_if_fail (pos <= string->len, string);
+  
+  /* If not just an append, move the old stuff */
+  if (pos < string->len)
+    g_memmove (string->str + pos + 1, string->str + pos, string->len - pos);
+
+  string->str[pos] = c;
+
+  string->len += 1;
+
+  string->str[string->len] = 0;
+
+  return string;
+}
+
+/**
+ * g_string_insert_unichar:
+ * @string: a #GString
+ * @pos: the position at which to insert character, or -1 to
+ *       append at the end of the string
+ * @wc: a Unicode character
+ * 
+ * Converts a Unicode character into UTF-8, and insert it
+ * into the string at the given position.
+ * 
+ * Return value: @string
+ **/
+GString*
+g_string_insert_unichar (GString *string,
+                        gssize   pos,    
+                        gunichar wc)
+{
+  gint charlen, first, i;
+  gchar *dest;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  /* Code copied from g_unichar_to_utf() */
+  if (wc < 0x80)
+    {
+      first = 0;
+      charlen = 1;
+    }
+  else if (wc < 0x800)
+    {
+      first = 0xc0;
+      charlen = 2;
+    }
+  else if (wc < 0x10000)
+    {
+      first = 0xe0;
+      charlen = 3;
+    }
+   else if (wc < 0x200000)
+    {
+      first = 0xf0;
+      charlen = 4;
+    }
+  else if (wc < 0x4000000)
+    {
+      first = 0xf8;
+      charlen = 5;
+    }
+  else
+    {
+      first = 0xfc;
+      charlen = 6;
+    }
+  /* End of copied code */
+
+  g_string_maybe_expand (string, charlen);
+
+  if (pos < 0)
+    pos = string->len;
+  else
+    g_return_val_if_fail (pos <= string->len, string);
+
+  /* If not just an append, move the old stuff */
+  if (pos < string->len)
+    g_memmove (string->str + pos + charlen, string->str + pos, string->len - pos);
+
+  dest = string->str + pos;
+  /* Code copied from g_unichar_to_utf() */
+  for (i = charlen - 1; i > 0; --i)
+    {
+      dest[i] = (wc & 0x3f) | 0x80;
+      wc >>= 6;
+    }
+  dest[0] = wc | first;
+  /* End of copied code */
+  
+  string->len += charlen;
+
+  string->str[string->len] = 0;
+
+  return string;
+}
+
+/**
+ * g_string_overwrite:
+ * @string: a #GString
+ * @pos: the position at which to start overwriting
+ * @val: the string that will overwrite the @string starting at @pos
+ * 
+ * Overwrites part of a string, lengthening it if necessary.
+ * 
+ * Return value: @string
+ *
+ * Since: 2.14
+ **/
+GString *
+g_string_overwrite (GString     *string,
+                   gsize        pos,
+                   const gchar *val)
+{
+  g_return_val_if_fail (val != NULL, string);
+  return g_string_overwrite_len (string, pos, val, strlen (val));
+}
+
+/**
+ * g_string_overwrite_len:
+ * @string: a #GString
+ * @pos: the position at which to start overwriting
+ * @val: the string that will overwrite the @string starting at @pos
+ * @len: the number of bytes to write from @val
+ * 
+ * Overwrites part of a string, lengthening it if necessary. 
+ * This function will work with embedded nuls.
+ * 
+ * Return value: @string
+ *
+ * Since: 2.14
+ **/
+GString *
+g_string_overwrite_len (GString     *string,
+                       gsize        pos,
+                       const gchar *val,
+                       gssize       len)
+{
+  gsize end;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  if (!len)
+    return string;
+
+  g_return_val_if_fail (val != NULL, string);
+  g_return_val_if_fail (pos <= string->len, string);
+
+  if (len < 0)
+    len = strlen (val);
+
+  end = pos + len;
+
+  if (end > string->len)
+    g_string_maybe_expand (string, end - string->len);
+
+  memcpy (string->str + pos, val, len);
+
+  if (end > string->len)
+    {
+      string->str[end] = '\0';
+      string->len = end;
+    }
+
+  return string;
+}
+
+/**
+ * g_string_erase:
+ * @string: a #GString
+ * @pos: the position of the content to remove
+ * @len: the number of bytes to remove, or -1 to remove all
+ *       following bytes
+ *
+ * Removes @len bytes from a #GString, starting at position @pos.
+ * The rest of the #GString is shifted down to fill the gap.
+ *
+ * Returns: @string
+ */
+GString*
+g_string_erase (GString *string,
+               gssize   pos,
+               gssize   len)
+{
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (pos >= 0, string);
+  g_return_val_if_fail (pos <= string->len, string);
+
+  if (len < 0)
+    len = string->len - pos;
+  else
+    {
+      g_return_val_if_fail (pos + len <= string->len, string);
+
+      if (pos + len < string->len)
+       g_memmove (string->str + pos, string->str + pos + len, string->len - (pos + len));
+    }
+
+  string->len -= len;
+  
+  string->str[string->len] = 0;
+
+  return string;
+}
+
+/**
+ * g_string_ascii_down:
+ * @string: a GString
+ * 
+ * Converts all upper case ASCII letters to lower case ASCII letters.
+ * 
+ * Return value: passed-in @string pointer, with all the upper case
+ *               characters converted to lower case in place, with
+ *               semantics that exactly match g_ascii_tolower().
+ **/
+GString*
+g_string_ascii_down (GString *string)
+{
+  gchar *s;
+  gint n;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  n = string->len;
+  s = string->str;
+
+  while (n)
+    {
+      *s = g_ascii_tolower (*s);
+      s++;
+      n--;
+    }
+
+  return string;
+}
+
+/**
+ * g_string_ascii_up:
+ * @string: a GString
+ * 
+ * Converts all lower case ASCII letters to upper case ASCII letters.
+ * 
+ * Return value: passed-in @string pointer, with all the lower case
+ *               characters converted to upper case in place, with
+ *               semantics that exactly match g_ascii_toupper().
+ **/
+GString*
+g_string_ascii_up (GString *string)
+{
+  gchar *s;
+  gint n;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  n = string->len;
+  s = string->str;
+
+  while (n)
+    {
+      *s = g_ascii_toupper (*s);
+      s++;
+      n--;
+    }
+
+  return string;
+}
+
+/**
+ * g_string_down:
+ * @string: a #GString
+ *  
+ * Converts a #GString to lowercase.
+ *
+ * Returns: the #GString.
+ *
+ * Deprecated:2.2: This function uses the locale-specific 
+ *   tolower() function, which is almost never the right thing. 
+ *   Use g_string_ascii_down() or g_utf8_strdown() instead.
+ */
+GString*
+g_string_down (GString *string)
+{
+  guchar *s;
+  glong n;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  n = string->len;    
+  s = (guchar *) string->str;
+
+  while (n)
+    {
+      if (isupper (*s))
+       *s = tolower (*s);
+      s++;
+      n--;
+    }
+
+  return string;
+}
+
+/**
+ * g_string_up:
+ * @string: a #GString 
+ * 
+ * Converts a #GString to uppercase.
+ * 
+ * Return value: @string
+ *
+ * Deprecated:2.2: This function uses the locale-specific 
+ *   toupper() function, which is almost never the right thing. 
+ *   Use g_string_ascii_up() or g_utf8_strup() instead.
+ **/
+GString*
+g_string_up (GString *string)
+{
+  guchar *s;
+  glong n;
+
+  g_return_val_if_fail (string != NULL, NULL);
+
+  n = string->len;
+  s = (guchar *) string->str;
+
+  while (n)
+    {
+      if (islower (*s))
+       *s = toupper (*s);
+      s++;
+      n--;
+    }
+
+  return string;
+}
+
+/**
+ * g_string_append_vprintf:
+ * @string: a #GString
+ * @format: the string format. See the printf() documentation
+ * @args: the list of arguments to insert in the output
+ *
+ * Appends a formatted string onto the end of a #GString.
+ * This function is similar to g_string_append_printf()
+ * except that the arguments to the format string are passed
+ * as a va_list.
+ *
+ * Since: 2.14
+ */
+void
+g_string_append_vprintf (GString     *string,
+                        const gchar *format,
+                        va_list      args)
+{
+  gchar *buf;
+  gint len;
+  
+  g_return_if_fail (string != NULL);
+  g_return_if_fail (format != NULL);
+
+  len = g_vasprintf (&buf, format, args);
+
+  if (len >= 0)
+    {
+      g_string_maybe_expand (string, len);
+      memcpy (string->str + string->len, buf, len + 1);
+      string->len += len;
+      g_free (buf);
+    }
+}
+
+/**
+ * g_string_vprintf:
+ * @string: a #GString
+ * @format: the string format. See the printf() documentation
+ * @args: the parameters to insert into the format string
+ *
+ * Writes a formatted string into a #GString. 
+ * This function is similar to g_string_printf() except that 
+ * the arguments to the format string are passed as a va_list.
+ *
+ * Since: 2.14
+ */
+void
+g_string_vprintf (GString     *string,
+                 const gchar *format,
+                 va_list      args)
+{
+  g_string_truncate (string, 0);
+  g_string_append_vprintf (string, format, args);
+}
+
+/**
+ * g_string_sprintf:
+ * @string: a #GString
+ * @format: the string format. See the sprintf() documentation
+ * @Varargs: the parameters to insert into the format string
+ *
+ * Writes a formatted string into a #GString.
+ * This is similar to the standard sprintf() function,
+ * except that the #GString buffer automatically expands 
+ * to contain the results. The previous contents of the 
+ * #GString are destroyed. 
+ *
+ * Deprecated: This function has been renamed to g_string_printf().
+ */
+
+/**
+ * g_string_printf:
+ * @string: a #GString
+ * @format: the string format. See the printf() documentation
+ * @Varargs: the parameters to insert into the format string
+ *
+ * Writes a formatted string into a #GString.
+ * This is similar to the standard sprintf() function,
+ * except that the #GString buffer automatically expands 
+ * to contain the results. The previous contents of the 
+ * #GString are destroyed.
+ */
+void
+g_string_printf (GString     *string,
+                const gchar *format,
+                ...)
+{
+  va_list args;
+
+  g_string_truncate (string, 0);
+
+  va_start (args, format);
+  g_string_append_vprintf (string, format, args);
+  va_end (args);
+}
+
+/**
+ * g_string_sprintfa:
+ * @string: a #GString
+ * @format: the string format. See the sprintf() documentation
+ * @Varargs: the parameters to insert into the format string
+ *
+ * Appends a formatted string onto the end of a #GString.
+ * This function is similar to g_string_sprintf() except that
+ * the text is appended to the #GString. 
+ *
+ * Deprecated: This function has been renamed to g_string_append_printf()
+ */
+
+/**
+ * g_string_append_printf:
+ * @string: a #GString
+ * @format: the string format. See the printf() documentation
+ * @Varargs: the parameters to insert into the format string
+ *
+ * Appends a formatted string onto the end of a #GString.
+ * This function is similar to g_string_printf() except 
+ * that the text is appended to the #GString.
+ */
+void
+g_string_append_printf (GString     *string,
+                       const gchar *format,
+                       ...)
+{
+  va_list args;
+
+  va_start (args, format);
+  g_string_append_vprintf (string, format, args);
+  va_end (args);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gstring.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gstring.h
new file mode 100644 (file)
index 0000000..2b1dd6e
--- /dev/null
@@ -0,0 +1,178 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_STRING_H__
+#define __G_STRING_H__
+
+#include <glib/gtypes.h>
+#include <glib/gunicode.h>
+#include <glib/gutils.h>  /* for G_CAN_INLINE */
+
+G_BEGIN_DECLS
+
+typedef struct _GString                GString;
+typedef struct _GStringChunk   GStringChunk;
+
+struct _GString
+{
+  gchar  *str;
+  gsize len;    
+  gsize allocated_len;
+};
+
+/* String Chunks
+ */
+GStringChunk* g_string_chunk_new          (gsize size);  
+void         g_string_chunk_free          (GStringChunk *chunk);
+void         g_string_chunk_clear         (GStringChunk *chunk);
+gchar*       g_string_chunk_insert        (GStringChunk *chunk,
+                                           const gchar  *string);
+gchar*       g_string_chunk_insert_len    (GStringChunk *chunk,
+                                           const gchar  *string,
+                                           gssize        len);
+gchar*       g_string_chunk_insert_const  (GStringChunk *chunk,
+                                           const gchar  *string);
+
+
+/* Strings
+ */
+GString*     g_string_new              (const gchar     *init);
+GString*     g_string_new_len           (const gchar     *init,
+                                         gssize           len);   
+GString*     g_string_sized_new         (gsize            dfl_size);  
+gchar*      g_string_free              (GString         *string,
+                                        gboolean         free_segment);
+gboolean     g_string_equal             (const GString  *v,
+                                        const GString   *v2);
+guint        g_string_hash              (const GString   *str);
+GString*     g_string_assign            (GString        *string,
+                                        const gchar     *rval);
+GString*     g_string_truncate          (GString        *string,
+                                        gsize            len);    
+GString*     g_string_set_size          (GString         *string,
+                                        gsize            len);
+GString*     g_string_insert_len        (GString         *string,
+                                         gssize           pos,   
+                                         const gchar     *val,
+                                         gssize           len);  
+GString*     g_string_append            (GString        *string,
+                                        const gchar     *val);
+GString*     g_string_append_len        (GString        *string,
+                                        const gchar     *val,
+                                         gssize           len);  
+GString*     g_string_append_c          (GString        *string,
+                                        gchar            c);
+GString*     g_string_append_unichar    (GString        *string,
+                                        gunichar         wc);
+GString*     g_string_prepend           (GString        *string,
+                                        const gchar     *val);
+GString*     g_string_prepend_c         (GString        *string,
+                                        gchar            c);
+GString*     g_string_prepend_unichar   (GString        *string,
+                                        gunichar         wc);
+GString*     g_string_prepend_len       (GString        *string,
+                                        const gchar     *val,
+                                         gssize           len);  
+GString*     g_string_insert            (GString        *string,
+                                        gssize           pos,    
+                                        const gchar     *val);
+GString*     g_string_insert_c          (GString        *string,
+                                        gssize           pos,    
+                                        gchar            c);
+GString*     g_string_insert_unichar    (GString        *string,
+                                        gssize           pos,    
+                                        gunichar         wc);
+GString*     g_string_overwrite         (GString        *string,
+                                        gsize            pos,    
+                                        const gchar     *val);
+GString*     g_string_overwrite_len     (GString        *string,
+                                        gsize            pos,    
+                                        const gchar     *val,
+                                        gssize           len);
+GString*     g_string_erase            (GString         *string,
+                                        gssize           pos,
+                                        gssize           len);
+GString*     g_string_ascii_down        (GString        *string);
+GString*     g_string_ascii_up          (GString        *string);
+void         g_string_vprintf           (GString        *string,
+                                        const gchar     *format,
+                                        va_list          args);
+void         g_string_printf            (GString        *string,
+                                        const gchar     *format,
+                                        ...) G_GNUC_PRINTF (2, 3);
+void         g_string_append_vprintf    (GString        *string,
+                                        const gchar     *format,
+                                        va_list          args);
+void         g_string_append_printf     (GString        *string,
+                                        const gchar     *format,
+                                        ...) G_GNUC_PRINTF (2, 3);
+GString *    g_string_append_uri_escaped(GString         *string,
+                                        const char      *unescaped,
+                                        const char      *reserved_chars_allowed,
+                                        gboolean         allow_utf8);
+
+/* -- optimize g_strig_append_c --- */
+#ifdef G_CAN_INLINE
+static inline GString*
+g_string_append_c_inline (GString *gstring,
+                          gchar    c)
+{
+  if (gstring->len + 1 < gstring->allocated_len)
+    {
+      gstring->str[gstring->len++] = c;
+      gstring->str[gstring->len] = 0;
+    }
+  else
+    g_string_insert_c (gstring, -1, c);
+  return gstring;
+}
+#define g_string_append_c(gstr,c)       g_string_append_c_inline (gstr, c)
+#endif /* G_CAN_INLINE */
+
+
+#ifndef G_DISABLE_DEPRECATED
+
+/* The following two functions are deprecated and will be removed in
+ * the next major release. They use the locale-specific tolower and
+ * toupper, which is almost never the right thing.
+ */
+
+GString*     g_string_down              (GString        *string);
+GString*     g_string_up                (GString        *string);
+
+/* These aliases are included for compatibility. */
+#define        g_string_sprintf        g_string_printf
+#define        g_string_sprintfa       g_string_append_printf
+
+#endif /* G_DISABLE_DEPRECATED */
+
+G_END_DECLS
+
+#endif /* __G_STRING_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gtester-report b/resource/csdk/connectivity/lib/android/glib-master/glib/gtester-report
new file mode 100644 (file)
index 0000000..3bce548
--- /dev/null
@@ -0,0 +1,487 @@
+#! /usr/bin/env python
+# GLib Testing Framework Utility                       -*- Mode: python; -*-
+# Copyright (C) 2007 Imendio AB
+# Authors: Tim Janik
+#
+# 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 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., 59 Temple Place - Suite 330,
+# Boston, MA 02111-1307, USA.
+import datetime
+import optparse
+import sys, re, xml.dom.minidom
+
+try:
+    import subunit
+    from subunit import iso8601
+    from testtools.content import Content, ContentType
+    mime_utf8 = ContentType('text', 'plain', {'charset': 'utf8'})
+except ImportError:
+    subunit = None
+
+
+pkginstall_configvars = {
+  #@PKGINSTALL_CONFIGVARS_IN24LINES@ # configvars are substituted upon script installation
+}
+
+# xml utilities
+def find_child (node, child_name):
+  for child in node.childNodes:
+    if child.nodeName == child_name:
+      return child
+  return None
+def list_children (node, child_name):
+  rlist = []
+  for child in node.childNodes:
+    if child.nodeName == child_name:
+      rlist += [ child ]
+  return rlist
+def find_node (node, name = None):
+  if not node or node.nodeName == name or not name:
+    return node
+  for child in node.childNodes:
+    c = find_node (child, name)
+    if c:
+      return c
+  return None
+def node_as_text (node, name = None):
+  if name:
+    node = find_node (node, name)
+  txt = ''
+  if node:
+    if node.nodeValue:
+      txt += node.nodeValue
+    for child in node.childNodes:
+      txt += node_as_text (child)
+  return txt
+def attribute_as_text (node, aname, node_name = None):
+  node = find_node (node, node_name)
+  if not node:
+    return ''
+  attr = node.attributes.get (aname, '')
+  if hasattr (attr, 'value'):
+    return attr.value
+  return ''
+
+# HTML utilities
+def html_indent_string (n):
+  uncollapsible_space = ' &nbsp;' # HTML won't compress alternating sequences of ' ' and '&nbsp;'
+  string = ''
+  for i in range (0, (n + 1) / 2):
+    string += uncollapsible_space
+  return string
+
+# TestBinary object, instantiated per test binary in the log file
+class TestBinary:
+  def __init__ (self, name):
+    self.name = name
+    self.testcases = []
+    self.duration = 0
+    self.success_cases = 0
+    self.skipped_cases = 0
+    self.file = '???'
+    self.random_seed = ''
+
+# base class to handle processing/traversion of XML nodes
+class TreeProcess:
+  def __init__ (self):
+    self.nest_level = 0
+  def trampoline (self, node):
+    name = node.nodeName
+    if name == '#text':
+      self.handle_text (node)
+    else:
+      try:     method = getattr (self, 'handle_' + re.sub ('[^a-zA-Z0-9]', '_', name))
+      except:  method = None
+      if method:
+        return method (node)
+      else:
+        return self.process_recursive (name, node)
+  def process_recursive (self, node_name, node):
+    self.process_children (node)
+  def process_children (self, node):
+    self.nest_level += 1
+    for child in node.childNodes:
+      self.trampoline (child)
+    self.nest_level += 1
+
+# test report reader, this class collects some statistics and merges duplicate test binary runs
+class ReportReader (TreeProcess):
+  def __init__ (self):
+    TreeProcess.__init__ (self)
+    self.binary_names = []
+    self.binaries = {}
+    self.last_binary = None
+    self.info = {}
+  def binary_list (self):
+    lst = []
+    for name in self.binary_names:
+      lst += [ self.binaries[name] ]
+    return lst
+  def get_info (self):
+    return self.info
+  def handle_info (self, node):
+    dn = find_child (node, 'package')
+    self.info['package'] = node_as_text (dn)
+    dn = find_child (node, 'version')
+    self.info['version'] = node_as_text (dn)
+  def handle_testcase (self, node):
+    self.last_binary.testcases += [ node ]
+    result = attribute_as_text (node, 'result', 'status')
+    if result == 'success':
+      self.last_binary.success_cases += 1
+    if bool (int (attribute_as_text (node, 'skipped') + '0')):
+      self.last_binary.skipped_cases += 1
+  def handle_text (self, node):
+    pass
+  def handle_testbinary (self, node):
+    path = node.attributes.get ('path', None).value
+    if self.binaries.get (path, -1) == -1:
+      self.binaries[path] = TestBinary (path)
+      self.binary_names += [ path ]
+    self.last_binary = self.binaries[path]
+    dn = find_child (node, 'duration')
+    dur = node_as_text (dn)
+    try:        dur = float (dur)
+    except:     dur = 0
+    if dur:
+      self.last_binary.duration += dur
+    bin = find_child (node, 'binary')
+    if bin:
+      self.last_binary.file = attribute_as_text (bin, 'file')
+    rseed = find_child (node, 'random-seed')
+    if rseed:
+      self.last_binary.random_seed = node_as_text (rseed)
+    self.process_children (node)
+
+
+class ReportWriter(object):
+    """Base class for reporting."""
+
+    def __init__(self, binary_list):
+        self.binaries = binary_list
+
+    def _error_text(self, node):
+        """Get a string representing the error children of node."""
+        rlist = list_children(node, 'error')
+        txt = ''
+        for enode in rlist:
+            txt += node_as_text (enode)
+            if txt and txt[-1] != '\n':
+                txt += '\n'
+        return txt
+
+
+class HTMLReportWriter(ReportWriter):
+  # Javascript/CSS snippet to toggle element visibility
+  cssjs = r'''
+  <style type="text/css" media="screen">
+    .VisibleSection { }
+    .HiddenSection  { display: none; }
+  </style>
+  <script language="javascript" type="text/javascript"><!--
+  function toggle_display (parentid, tagtype, idmatch, keymatch) {
+    ptag = document.getElementById (parentid);
+    tags = ptag.getElementsByTagName (tagtype);
+    for (var i = 0; i < tags.length; i++) {
+      tag = tags[i];
+      var key = tag.getAttribute ("keywords");
+      if (tag.id.indexOf (idmatch) == 0 && key && key.match (keymatch)) {
+        if (tag.className.indexOf ("HiddenSection") >= 0)
+          tag.className = "VisibleSection";
+        else
+          tag.className = "HiddenSection";
+      }
+    }
+  }
+  message_array = Array();
+  function view_testlog (wname, file, random_seed, tcase, msgtitle, msgid) {
+      txt = message_array[msgid];
+      var w = window.open ("", // URI
+                           wname,
+                           "resizable,scrollbars,status,width=790,height=400");
+      var doc = w.document;
+      doc.write ("<h2>File: " + file + "</h2>\n");
+      doc.write ("<h3>Case: " + tcase + "</h3>\n");
+      doc.write ("<strong>Random Seed:</strong> <code>" + random_seed + "</code> <br /><br />\n");
+      doc.write ("<strong>" + msgtitle + "</strong><br />\n");
+      doc.write ("<pre>");
+      doc.write (txt);
+      doc.write ("</pre>\n");
+      doc.write ("<a href=\'javascript:window.close()\'>Close Window</a>\n");
+      doc.close();
+  }
+  --></script>
+  '''
+  def __init__ (self, info, binary_list):
+    ReportWriter.__init__(self, binary_list)
+    self.info = info
+    self.bcounter = 0
+    self.tcounter = 0
+    self.total_tcounter = 0
+    self.total_fcounter = 0
+    self.total_duration = 0
+    self.indent_depth = 0
+    self.lastchar = ''
+  def oprint (self, message):
+    sys.stdout.write (message)
+    if message:
+      self.lastchar = message[-1]
+  def handle_info (self):
+    self.oprint ('<h3>Package: %(package)s, version: %(version)s</h3>\n' % self.info)
+  def handle_text (self, node):
+    self.oprint (node.nodeValue)
+  def handle_testcase (self, node, binary):
+    skipped = bool (int (attribute_as_text (node, 'skipped') + '0'))
+    if skipped:
+      return            # skipped tests are uninteresting for HTML reports
+    path = attribute_as_text (node, 'path')
+    duration = node_as_text (node, 'duration')
+    result = attribute_as_text (node, 'result', 'status')
+    rcolor = {
+      'success': 'bgcolor="lightgreen"',
+      'failed':  'bgcolor="red"',
+    }.get (result, '')
+    if result != 'success':
+      duration = '-'    # ignore bogus durations
+    self.oprint ('<tr id="b%u_t%u_" keywords="%s all" class="HiddenSection">\n' % (self.bcounter, self.tcounter, result))
+    self.oprint ('<td>%s %s</td> <td align="right">%s</td> \n' % (html_indent_string (4), path, duration))
+    perflist = list_children (node, 'performance')
+    if result != 'success':
+      txt = self._error_text(node)
+      txt = re.sub (r'"', r'\\"', txt)
+      txt = re.sub (r'\n', r'\\n', txt)
+      txt = re.sub (r'&', r'&amp;', txt)
+      txt = re.sub (r'<', r'&lt;', txt)
+      self.oprint ('<script language="javascript" type="text/javascript">message_array["b%u_t%u_"] = "%s";</script>\n' % (self.bcounter, self.tcounter, txt))
+      self.oprint ('<td align="center"><a href="javascript:view_testlog (\'%s\', \'%s\', \'%s\', \'%s\', \'Output:\', \'b%u_t%u_\')">Details</a></td>\n' %
+                   ('TestResultWindow', binary.file, binary.random_seed, path, self.bcounter, self.tcounter))
+    elif perflist:
+      presults = []
+      for perf in perflist:
+        pmin = bool (int (attribute_as_text (perf, 'minimize')))
+        pmax = bool (int (attribute_as_text (perf, 'maximize')))
+        pval = float (attribute_as_text (perf, 'value'))
+        txt = node_as_text (perf)
+        txt = re.sub (r'&', r'&amp;', txt)
+        txt = re.sub (r'<', r'&gt;', txt)
+        txt = '<strong>Performance(' + (pmin and '<em>minimized</em>' or '<em>maximized</em>') + '):</strong> ' + txt.strip() + '<br />\n'
+        txt = re.sub (r'"', r'\\"', txt)
+        txt = re.sub (r'\n', r'\\n', txt)
+        presults += [ (pval, txt) ]
+      presults.sort()
+      ptxt = ''.join ([e[1] for e in presults])
+      self.oprint ('<script language="javascript" type="text/javascript">message_array["b%u_t%u_"] = "%s";</script>\n' % (self.bcounter, self.tcounter, ptxt))
+      self.oprint ('<td align="center"><a href="javascript:view_testlog (\'%s\', \'%s\', \'%s\', \'%s\', \'Test Results:\', \'b%u_t%u_\')">Details</a></td>\n' %
+                   ('TestResultWindow', binary.file, binary.random_seed, path, self.bcounter, self.tcounter))
+    else:
+      self.oprint ('<td align="center">-</td>\n')
+    self.oprint ('<td align="right" %s>%s</td>\n' % (rcolor, result))
+    self.oprint ('</tr>\n')
+    self.tcounter += 1
+    self.total_tcounter += 1
+    self.total_fcounter += result != 'success'
+  def handle_binary (self, binary):
+    self.tcounter = 1
+    self.bcounter += 1
+    self.total_duration += binary.duration
+    self.oprint ('<tr><td><strong>%s</strong></td><td align="right">%f</td> <td align="center">\n' % (binary.name, binary.duration))
+    erlink, oklink = ('', '')
+    real_cases = len (binary.testcases) - binary.skipped_cases
+    if binary.success_cases < real_cases:
+      erlink = 'href="javascript:toggle_display (\'ResultTable\', \'tr\', \'b%u_\', \'failed\')"' % self.bcounter
+    if binary.success_cases:
+      oklink = 'href="javascript:toggle_display (\'ResultTable\', \'tr\', \'b%u_\', \'success\')"' % self.bcounter
+    if real_cases != 0:
+       self.oprint ('<a %s>ER</a>\n' % erlink)
+       self.oprint ('<a %s>OK</a>\n' % oklink)
+       self.oprint ('</td>\n')
+       perc = binary.success_cases * 100.0 / real_cases
+       pcolor = {
+         100 : 'bgcolor="lightgreen"',
+         0   : 'bgcolor="red"',
+       }.get (int (perc), 'bgcolor="yellow"')
+       self.oprint ('<td align="right" %s>%.2f%%</td>\n' % (pcolor, perc))
+       self.oprint ('</tr>\n')
+    else:
+       self.oprint ('Empty\n')
+       self.oprint ('</td>\n')
+       self.oprint ('</tr>\n')
+    for tc in binary.testcases:
+      self.handle_testcase (tc, binary)
+  def handle_totals (self):
+    self.oprint ('<tr>')
+    self.oprint ('<td><strong>Totals:</strong> %u Binaries, %u Tests, %u Failed, %u Succeeded</td>' %
+                 (self.bcounter, self.total_tcounter, self.total_fcounter, self.total_tcounter - self.total_fcounter))
+    self.oprint ('<td align="right">%f</td>\n' % self.total_duration)
+    self.oprint ('<td align="center">-</td>\n')
+    if self.total_tcounter != 0:
+        perc = (self.total_tcounter - self.total_fcounter) * 100.0 / self.total_tcounter
+    else:
+        perc = 0.0
+    pcolor = {
+      100 : 'bgcolor="lightgreen"',
+      0   : 'bgcolor="red"',
+    }.get (int (perc), 'bgcolor="yellow"')
+    self.oprint ('<td align="right" %s>%.2f%%</td>\n' % (pcolor, perc))
+    self.oprint ('</tr>\n')
+  def printout (self):
+    self.oprint ('<html><head>\n')
+    self.oprint ('<title>GTester Unit Test Report</title>\n')
+    self.oprint (self.cssjs)
+    self.oprint ('</head>\n')
+    self.oprint ('<body>\n')
+    self.oprint ('<h2>GTester Unit Test Report</h2>\n')
+    self.handle_info ()
+    self.oprint ('<table id="ResultTable" width="100%" border="1">\n<tr>\n')
+    self.oprint ('<th>Program / Testcase </th>\n')
+    self.oprint ('<th style="width:8em">Duration (sec)</th>\n')
+    self.oprint ('<th style="width:5em">View</th>\n')
+    self.oprint ('<th style="width:5em">Result</th>\n')
+    self.oprint ('</tr>\n')
+    for tb in self.binaries:
+      self.handle_binary (tb)
+    self.handle_totals()
+    self.oprint ('</table>\n')
+    self.oprint ('</body>\n')
+    self.oprint ('</html>\n')
+
+
+class SubunitWriter(ReportWriter):
+    """Reporter to output a subunit stream."""
+
+    def printout(self):
+        reporter = subunit.TestProtocolClient(sys.stdout)
+        for binary in self.binaries:
+            for tc in binary.testcases:
+                test = GTestCase(tc, binary)
+                test.run(reporter)
+
+
+class GTestCase(object):
+    """A representation of a gtester test result as a pyunit TestCase."""
+
+    def __init__(self, case, binary):
+        """Create a GTestCase for case `case` from binary program `binary`."""
+        self._case = case
+        self._binary = binary
+        # the name of the case - e.g. /dbusmenu/glib/objects/menuitem/props_boolstr
+        self._path = attribute_as_text(self._case, 'path')
+
+    def id(self):
+        """What test is this? Returns the gtester path for the testcase."""
+        return self._path
+
+    def _get_details(self):
+        """Calculate a details dict for the test - attachments etc."""
+        details = {}
+        result = attribute_as_text(self._case, 'result', 'status')
+        details['filename'] = Content(mime_utf8, lambda:[self._binary.file])
+        details['random_seed'] = Content(mime_utf8,
+            lambda:[self._binary.random_seed])
+        if self._get_outcome() == 'addFailure':
+            # Extract the error details. Skips have no details because its not
+            # skip like unittest does, instead the runner just bypasses N test.
+            txt = self._error_text(self._case)
+            details['error'] = Content(mime_utf8, lambda:[txt])
+        if self._get_outcome() == 'addSuccess':
+            # Sucessful tests may have performance metrics.
+            perflist = list_children(self._case, 'performance')
+            if perflist:
+                presults = []
+                for perf in perflist:
+                    pmin = bool (int (attribute_as_text (perf, 'minimize')))
+                    pmax = bool (int (attribute_as_text (perf, 'maximize')))
+                    pval = float (attribute_as_text (perf, 'value'))
+                    txt = node_as_text (perf)
+                    txt = 'Performance(' + (pmin and 'minimized' or 'maximized'
+                        ) + '): ' + txt.strip() + '\n'
+                    presults += [(pval, txt)]
+                presults.sort()
+                perf_details = [e[1] for e in presults]
+                details['performance'] = Content(mime_utf8, lambda:perf_details)
+        return details
+
+    def _get_outcome(self):
+        if int(attribute_as_text(self._case, 'skipped') + '0'):
+            return 'addSkip'
+        outcome = attribute_as_text(self._case, 'result', 'status')
+        if outcome == 'success':
+            return 'addSuccess'
+        else:
+            return 'addFailure'
+
+    def run(self, result):
+        time = datetime.datetime.utcnow().replace(tzinfo=iso8601.Utc())
+        result.time(time)
+        result.startTest(self)
+        try:
+            outcome = self._get_outcome()
+            details = self._get_details()
+            # Only provide a duration IFF outcome == 'addSuccess' - the main
+            # parser claims bogus results otherwise: in that case emit time as
+            # zero perhaps.
+            if outcome == 'addSuccess':
+                duration = float(node_as_text(self._case, 'duration'))
+                duration = duration * 1000000
+                timedelta = datetime.timedelta(0, 0, duration)
+                time = time + timedelta
+                result.time(time)
+            getattr(result, outcome)(self, details=details)
+        finally:
+            result.stopTest(self)
+
+
+
+# main program handling
+def parse_opts():
+    """Parse program options.
+
+    :return: An options object and the program arguments.
+    """
+    parser = optparse.OptionParser()
+    parser.version =  pkginstall_configvars.get ('glib-version', '0.0-uninstalled')
+    parser.usage = "%prog [OPTIONS] <gtester-log.xml>"
+    parser.description = "Generate HTML reports from the XML log files generated by gtester."
+    parser.epilog = "gtester-report (GLib utils) version %s."% (parser.version,)
+    parser.add_option("-v", "--version", action="store_true", dest="version", default=False,
+        help="Show program version.")
+    parser.add_option("-s", "--subunit", action="store_true", dest="subunit", default=False,
+        help="Output subunit [See https://launchpad.net/subunit/"
+            " Needs python-subunit]")
+    options, files = parser.parse_args()
+    if options.version:
+        print parser.epilog
+        return None, None
+    if len(files) != 1:
+        parser.error("Must supply a log file to parse.")
+    if options.subunit and subunit is None:
+        parser.error("python-subunit is not installed.")
+    return options, files
+
+
+def main():
+  options, files = parse_opts()
+  if options is None:
+    return 0
+  xd = xml.dom.minidom.parse (files[0])
+  rr = ReportReader()
+  rr.trampoline (xd)
+  if not options.subunit:
+      HTMLReportWriter(rr.get_info(), rr.binary_list()).printout()
+  else:
+      SubunitWriter(rr.get_info(), rr.binary_list()).printout()
+
+
+if __name__ == '__main__':
+  main()
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gtester.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gtester.c
new file mode 100644 (file)
index 0000000..12e576c
--- /dev/null
@@ -0,0 +1,720 @@
+/* GLib testing framework runner
+ * Copyright (C) 2007 Sven Herzberg
+ * Copyright (C) 2007 Tim Janik
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+#include <glib.h>
+#include <gstdio.h>
+#include <string.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/wait.h>
+#include <errno.h>
+#include <signal.h>
+
+/* the read buffer size in bytes */
+#define READ_BUFFER_SIZE 4096
+
+/* --- prototypes --- */
+static int      main_selftest   (int    argc,
+                                 char **argv);
+static void     parse_args      (gint           *argc_p,
+                                 gchar        ***argv_p);
+
+/* --- variables --- */
+static GIOChannel  *ioc_report = NULL;
+static gboolean     gtester_quiet = FALSE;
+static gboolean     gtester_verbose = FALSE;
+static gboolean     gtester_list_tests = FALSE;
+static gboolean     gtester_selftest = FALSE;
+static gboolean     subtest_running = FALSE;
+static gint         subtest_exitstatus = 0;
+static gboolean     subtest_io_pending = FALSE;
+static gboolean     subtest_quiet = TRUE;
+static gboolean     subtest_verbose = FALSE;
+static gboolean     subtest_mode_fatal = TRUE;
+static gboolean     subtest_mode_perf = FALSE;
+static gboolean     subtest_mode_quick = TRUE;
+static const gchar *subtest_seedstr = NULL;
+static gchar       *subtest_last_seed = NULL;
+static GSList      *subtest_paths = NULL;
+static GSList      *subtest_args = NULL;
+static gboolean     testcase_open = FALSE;
+static guint        testcase_count = 0;
+static guint        testcase_fail_count = 0;
+static const gchar *output_filename = NULL;
+static guint        log_indent = 0;
+static gint         log_fd = -1;
+
+/* --- functions --- */
+static const char*
+sindent (guint n)
+{
+  static const char spaces[] = "                                                                                                    ";
+  int l = sizeof (spaces) - 1;
+  n = MIN (n, l);
+  return spaces + l - n;
+}
+
+static void G_GNUC_PRINTF (1, 2)
+test_log_printfe (const char *format,
+                  ...)
+{
+  char *result;
+  int r;
+  va_list args;
+  va_start (args, format);
+  result = g_markup_vprintf_escaped (format, args);
+  va_end (args);
+  do
+    r = write (log_fd, result, strlen (result));
+  while (r < 0 && errno == EINTR);
+  g_free (result);
+}
+
+static void
+terminate (void)
+{
+  kill (getpid(), SIGTERM);
+  abort();
+}
+
+static void
+testcase_close (long double duration,
+                gint        exit_status,
+                guint       n_forks)
+{
+  g_return_if_fail (testcase_open > 0);
+  test_log_printfe ("%s<duration>%.6Lf</duration>\n", sindent (log_indent), duration);
+  test_log_printfe ("%s<status exit-status=\"%d\" n-forks=\"%d\" result=\"%s\"/>\n",
+                    sindent (log_indent), exit_status, n_forks,
+                    exit_status ? "failed" : "success");
+  log_indent -= 2;
+  test_log_printfe ("%s</testcase>\n", sindent (log_indent));
+  testcase_open--;
+  if (gtester_verbose)
+    g_print ("%s\n", exit_status ? "FAIL" : "OK");
+  if (exit_status && subtest_last_seed)
+    g_print ("GTester: last random seed: %s\n", subtest_last_seed);
+  if (exit_status)
+    testcase_fail_count += 1;
+  if (subtest_mode_fatal && testcase_fail_count)
+    terminate();
+}
+
+static void
+test_log_msg (GTestLogMsg *msg)
+{
+  switch (msg->log_type)
+    {
+      guint i;
+      gchar **strv;
+    case G_TEST_LOG_NONE:
+      break;
+    case G_TEST_LOG_ERROR:
+      strv = g_strsplit (msg->strings[0], "\n", -1);
+      for (i = 0; strv[i]; i++)
+        test_log_printfe ("%s<error>%s</error>\n", sindent (log_indent), strv[i]);
+      g_strfreev (strv);
+      break;
+    case G_TEST_LOG_START_BINARY:
+      test_log_printfe ("%s<binary file=\"%s\"/>\n", sindent (log_indent), msg->strings[0]);
+      subtest_last_seed = g_strdup (msg->strings[1]);
+      test_log_printfe ("%s<random-seed>%s</random-seed>\n", sindent (log_indent), subtest_last_seed);
+      break;
+    case G_TEST_LOG_LIST_CASE:
+      g_print ("%s\n", msg->strings[0]);
+      break;
+    case G_TEST_LOG_START_CASE:
+      testcase_count++;
+      if (gtester_verbose)
+        {
+          gchar *sc = g_strconcat (msg->strings[0], ":", NULL);
+          gchar *sleft = g_strdup_printf ("%-68s", sc);
+          g_free (sc);
+          g_print ("%70s ", sleft);
+          g_free (sleft);
+        }
+      g_return_if_fail (testcase_open == 0);
+      testcase_open++;
+      test_log_printfe ("%s<testcase path=\"%s\">\n", sindent (log_indent), msg->strings[0]);
+      log_indent += 2;
+      break;
+    case G_TEST_LOG_SKIP_CASE:
+      if (FALSE && gtester_verbose) /* enable to debug test case skipping logic */
+        {
+          gchar *sc = g_strconcat (msg->strings[0], ":", NULL);
+          gchar *sleft = g_strdup_printf ("%-68s", sc);
+          g_free (sc);
+          g_print ("%70s SKIPPED\n", sleft);
+          g_free (sleft);
+        }
+      test_log_printfe ("%s<testcase path=\"%s\" skipped=\"1\"/>\n", sindent (log_indent), msg->strings[0]);
+      break;
+    case G_TEST_LOG_STOP_CASE:
+      testcase_close (msg->nums[2], (int) msg->nums[0], (int) msg->nums[1]);
+      break;
+    case G_TEST_LOG_MIN_RESULT:
+    case G_TEST_LOG_MAX_RESULT:
+      test_log_printfe ("%s<performance minimize=\"%d\" maximize=\"%d\" value=\"%.16Lg\">\n",
+                        sindent (log_indent), msg->log_type == G_TEST_LOG_MIN_RESULT, msg->log_type == G_TEST_LOG_MAX_RESULT, msg->nums[0]);
+      test_log_printfe ("%s%s\n", sindent (log_indent + 2), msg->strings[0]);
+      test_log_printfe ("%s</performance>\n", sindent (log_indent));
+      break;
+    case G_TEST_LOG_MESSAGE:
+      test_log_printfe ("%s<message>\n%s\n%s</message>\n", sindent (log_indent), msg->strings[0], sindent (log_indent));
+      break;
+    }
+}
+
+static gboolean
+child_report_cb (GIOChannel  *source,
+                 GIOCondition condition,
+                 gpointer     data)
+{
+  GTestLogBuffer *tlb = data;
+  GIOStatus status = G_IO_STATUS_NORMAL;
+  gboolean first_read_eof = FALSE, first_read = TRUE;
+  gsize length = 0;
+  do
+    {
+      guint8 buffer[READ_BUFFER_SIZE];
+      GError *error = NULL;
+      status = g_io_channel_read_chars (source, (gchar*) buffer, sizeof (buffer), &length, &error);
+      if (first_read && (condition & G_IO_IN))
+        {
+          /* on some unixes (MacOS) we need to detect non-blocking fd EOF
+           * by an IO_IN select/poll followed by read()==0.
+           */
+          first_read_eof = length == 0;
+        }
+      first_read = FALSE;
+      if (length)
+        {
+          GTestLogMsg *msg;
+          g_test_log_buffer_push (tlb, length, buffer);
+          do
+            {
+              msg = g_test_log_buffer_pop (tlb);
+              if (msg)
+                {
+                  test_log_msg (msg);
+                  g_test_log_msg_free (msg);
+                }
+            }
+          while (msg);
+        }
+      g_clear_error (&error);
+      /* ignore the io channel status, which will report intermediate EOFs for non blocking fds */
+      (void) status;
+    }
+  while (length > 0);
+  /* g_print ("LASTIOSTATE: first_read_eof=%d condition=%d\n", first_read_eof, condition); */
+  if (first_read_eof || (condition & (G_IO_ERR | G_IO_HUP)))
+    {
+      /* if there's no data to read and select() reports an error or hangup,
+       * the fd must have been closed remotely
+       */
+      subtest_io_pending = FALSE;
+      return FALSE;
+    }
+  return TRUE; /* keep polling */
+}
+
+static void
+child_watch_cb (GPid     pid,
+               gint     status,
+               gpointer data)
+{
+  g_spawn_close_pid (pid);
+  if (WIFEXITED (status)) /* normal exit */
+    subtest_exitstatus = WEXITSTATUS (status);
+  else /* signal or core dump, etc */
+    subtest_exitstatus = 0xffffffff;
+  subtest_running = FALSE;
+}
+
+static gchar*
+queue_gfree (GSList **slistp,
+             gchar   *string)
+{
+  *slistp = g_slist_prepend (*slistp, string);
+  return string;
+}
+
+static void
+unset_cloexec_fdp (gpointer fdp_data)
+{
+  int r, *fdp = fdp_data;
+  do
+    r = fcntl (*fdp, F_SETFD, 0 /* FD_CLOEXEC */);
+  while (r < 0 && errno == EINTR);
+}
+
+static gboolean
+launch_test_binary (const char *binary,
+                    guint       skip_tests)
+{
+  GTestLogBuffer *tlb;
+  GSList *slist, *free_list = NULL;
+  GError *error = NULL;
+  int argc = 0;
+  const gchar **argv;
+  GPid pid = 0;
+  gint report_pipe[2] = { -1, -1 };
+  guint child_report_cb_id = 0;
+  gboolean loop_pending;
+  gint i = 0;
+
+  if (pipe (report_pipe) < 0)
+    {
+      if (subtest_mode_fatal)
+        g_error ("Failed to open pipe for test binary: %s: %s", binary, g_strerror (errno));
+      else
+        g_warning ("Failed to open pipe for test binary: %s: %s", binary, g_strerror (errno));
+      return FALSE;
+    }
+
+  /* setup argc */
+  for (slist = subtest_args; slist; slist = slist->next)
+    argc++;
+  /* argc++; */
+  if (subtest_quiet)
+    argc++;
+  if (subtest_verbose)
+    argc++;
+  if (!subtest_mode_fatal)
+    argc++;
+  if (subtest_mode_quick)
+    argc++;
+  else
+    argc++;
+  if (subtest_mode_perf)
+    argc++;
+  if (gtester_list_tests)
+    argc++;
+  if (subtest_seedstr)
+    argc++;
+  argc++;
+  if (skip_tests)
+    argc++;
+  for (slist = subtest_paths; slist; slist = slist->next)
+    argc++;
+
+  /* setup argv */
+  argv = g_malloc ((argc + 2) * sizeof(gchar *));
+  argv[i++] = binary;
+  for (slist = subtest_args; slist; slist = slist->next)
+    argv[i++] = (gchar*) slist->data;
+  /* argv[i++] = "--debug-log"; */
+  if (subtest_quiet)
+    argv[i++] = "--quiet";
+  if (subtest_verbose)
+    argv[i++] = "--verbose";
+  if (!subtest_mode_fatal)
+    argv[i++] = "--keep-going";
+  if (subtest_mode_quick)
+    argv[i++] = "-m=quick";
+  else
+    argv[i++] = "-m=slow";
+  if (subtest_mode_perf)
+    argv[i++] = "-m=perf";
+  if (gtester_list_tests)
+    argv[i++] = "-l";
+  if (subtest_seedstr)
+    argv[i++] = queue_gfree (&free_list, g_strdup_printf ("--seed=%s", subtest_seedstr));
+  argv[i++] = queue_gfree (&free_list, g_strdup_printf ("--GTestLogFD=%u", report_pipe[1]));
+  if (skip_tests)
+    argv[i++] = queue_gfree (&free_list, g_strdup_printf ("--GTestSkipCount=%u", skip_tests));
+  for (slist = subtest_paths; slist; slist = slist->next)
+    argv[i++] = queue_gfree (&free_list, g_strdup_printf ("-p=%s", (gchar*) slist->data));
+  argv[i++] = NULL;
+
+  g_spawn_async_with_pipes (NULL, /* g_get_current_dir() */
+                            (gchar**) argv,
+                            NULL, /* envp */
+                            G_SPAWN_DO_NOT_REAP_CHILD, /* G_SPAWN_SEARCH_PATH */
+                            unset_cloexec_fdp, &report_pipe[1], /* pre-exec callback */
+                            &pid,
+                            NULL,       /* standard_input */
+                            NULL,       /* standard_output */
+                            NULL,       /* standard_error */
+                            &error);
+  g_slist_foreach (free_list, (void(*)(void*,void*)) g_free, NULL);
+  g_slist_free (free_list);
+  free_list = NULL;
+  close (report_pipe[1]);
+
+  if (!gtester_quiet)
+    g_print ("(pid=%lu)\n", (unsigned long) pid);
+
+  if (error)
+    {
+      close (report_pipe[0]);
+      if (subtest_mode_fatal)
+        g_error ("Failed to execute test binary: %s: %s", argv[0], error->message);
+      else
+        g_warning ("Failed to execute test binary: %s: %s", argv[0], error->message);
+      g_clear_error (&error);
+      g_free (argv);
+      return FALSE;
+    }
+  g_free (argv);
+
+  subtest_running = TRUE;
+  subtest_io_pending = TRUE;
+  tlb = g_test_log_buffer_new();
+  if (report_pipe[0] >= 0)
+    {
+      ioc_report = g_io_channel_unix_new (report_pipe[0]);
+      g_io_channel_set_flags (ioc_report, G_IO_FLAG_NONBLOCK, NULL);
+      g_io_channel_set_encoding (ioc_report, NULL, NULL);
+      g_io_channel_set_buffered (ioc_report, FALSE);
+      child_report_cb_id = g_io_add_watch_full (ioc_report, G_PRIORITY_DEFAULT - 1, G_IO_IN | G_IO_ERR | G_IO_HUP, child_report_cb, tlb, NULL);
+      g_io_channel_unref (ioc_report);
+    }
+  g_child_watch_add_full (G_PRIORITY_DEFAULT + 1, pid, child_watch_cb, NULL, NULL);
+
+  loop_pending = g_main_context_pending (NULL);
+  while (subtest_running ||     /* FALSE once child exits */
+         subtest_io_pending ||  /* FALSE once ioc_report closes */
+         loop_pending)          /* TRUE while idler, etc are running */
+    {
+      /* g_print ("LOOPSTATE: subtest_running=%d subtest_io_pending=%d\n", subtest_running, subtest_io_pending); */
+      /* check for unexpected hangs that are not signalled on report_pipe */
+      if (!subtest_running &&   /* child exited */
+          subtest_io_pending && /* no EOF detected on report_pipe */
+          !loop_pending)        /* no IO events pending however */
+        break;
+      g_main_context_iteration (NULL, TRUE);
+      loop_pending = g_main_context_pending (NULL);
+    }
+
+  g_source_remove (child_report_cb_id);
+  close (report_pipe[0]);
+  g_test_log_buffer_free (tlb);
+
+  return TRUE;
+}
+
+static void
+launch_test (const char *binary)
+{
+  gboolean success = TRUE;
+  GTimer *btimer = g_timer_new();
+  gboolean need_restart;
+  testcase_count = 0;
+  testcase_fail_count = 0;
+  if (!gtester_quiet)
+    g_print ("TEST: %s... ", binary);
+
+ retry:
+  test_log_printfe ("%s<testbinary path=\"%s\">\n", sindent (log_indent), binary);
+  log_indent += 2;
+  g_timer_start (btimer);
+  subtest_exitstatus = 0;
+  success &= launch_test_binary (binary, testcase_count);
+  success &= subtest_exitstatus == 0;
+  need_restart = testcase_open != 0;
+  if (testcase_open)
+    testcase_close (0, -256, 0);
+  g_timer_stop (btimer);
+  test_log_printfe ("%s<duration>%.6f</duration>\n", sindent (log_indent), g_timer_elapsed (btimer, NULL));
+  log_indent -= 2;
+  test_log_printfe ("%s</testbinary>\n", sindent (log_indent));
+  g_free (subtest_last_seed);
+  subtest_last_seed = NULL;
+  if (need_restart)
+    {
+      /* restart test binary, skipping processed test cases */
+      goto retry;
+    }
+
+  if (!gtester_quiet)
+    g_print ("%s: %s\n", testcase_fail_count || !success ? "FAIL" : "PASS", binary);
+  g_timer_destroy (btimer);
+  if (subtest_mode_fatal && !success)
+    terminate();
+}
+
+static void
+usage (gboolean just_version)
+{
+  if (just_version)
+    {
+      g_print ("gtester version %d.%d.%d\n", GLIB_MAJOR_VERSION, GLIB_MINOR_VERSION, GLIB_MICRO_VERSION);
+      return;
+    }
+  g_print ("Usage: gtester [OPTIONS] testprogram...\n");
+  /*        12345678901234567890123456789012345678901234567890123456789012345678901234567890 */
+  g_print ("Options:\n");
+  g_print ("  -h, --help                  show this help message\n");
+  g_print ("  -v, --version               print version informations\n");
+  g_print ("  --g-fatal-warnings          make warnings fatal (abort)\n");
+  g_print ("  -k, --keep-going            continue running after tests failed\n");
+  g_print ("  -l                          list paths of available test cases\n");
+  g_print ("  -m=perf, -m=slow, -m=quick -m=thorough\n");
+  g_print ("                              run test cases in mode perf, slow/thorough or quick (default)\n");
+  g_print ("  -p=TESTPATH                 only start test cases matching TESTPATH\n");
+  g_print ("  --seed=SEEDSTRING           start all tests with random number seed SEEDSTRING\n");
+  g_print ("  -o=LOGFILE                  write the test log to LOGFILE\n");
+  g_print ("  -q, --quiet                 suppress per test binary output\n");
+  g_print ("  --verbose                   report success per testcase\n");
+}
+
+static void
+parse_args (gint    *argc_p,
+            gchar ***argv_p)
+{
+  guint argc = *argc_p;
+  gchar **argv = *argv_p;
+  guint i, e;
+  /* parse known args */
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], "--g-fatal-warnings") == 0)
+        {
+          GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK);
+          fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
+          g_log_set_always_fatal (fatal_mask);
+          argv[i] = NULL;
+        }
+      else if (strcmp (argv[i], "--gtester-selftest") == 0)
+        {
+          gtester_selftest = TRUE;
+          argv[i] = NULL;
+          break;        /* stop parsing regular gtester arguments */
+        }
+      else if (strcmp (argv[i], "-h") == 0 || strcmp (argv[i], "--help") == 0)
+        {
+          usage (FALSE);
+          exit (0);
+          argv[i] = NULL;
+        }
+      else if (strcmp (argv[i], "-v") == 0 || strcmp (argv[i], "--version") == 0)
+        {
+          usage (TRUE);
+          exit (0);
+          argv[i] = NULL;
+        }
+      else if (strcmp (argv[i], "--keep-going") == 0 ||
+               strcmp (argv[i], "-k") == 0)
+        {
+          subtest_mode_fatal = FALSE;
+          argv[i] = NULL;
+        }
+      else if (strcmp ("-p", argv[i]) == 0 || strncmp ("-p=", argv[i], 3) == 0)
+        {
+          gchar *equal = argv[i] + 2;
+          if (*equal == '=')
+            subtest_paths = g_slist_prepend (subtest_paths, equal + 1);
+          else if (i + 1 < argc)
+            {
+              argv[i++] = NULL;
+              subtest_paths = g_slist_prepend (subtest_paths, argv[i]);
+            }
+          argv[i] = NULL;
+        }
+      else if (strcmp ("--test-arg", argv[i]) == 0 || strncmp ("--test-arg=", argv[i], 11) == 0)
+        {
+          gchar *equal = argv[i] + 10;
+          if (*equal == '=')
+            subtest_args = g_slist_prepend (subtest_args, equal + 1);
+          else if (i + 1 < argc)
+            {
+              argv[i++] = NULL;
+              subtest_args = g_slist_prepend (subtest_args, argv[i]);
+            }
+          argv[i] = NULL;
+        }
+      else if (strcmp ("-o", argv[i]) == 0 || strncmp ("-o=", argv[i], 3) == 0)
+        {
+          gchar *equal = argv[i] + 2;
+          if (*equal == '=')
+            output_filename = equal + 1;
+          else if (i + 1 < argc)
+            {
+              argv[i++] = NULL;
+              output_filename = argv[i];
+            }
+          argv[i] = NULL;
+        }
+      else if (strcmp ("-m", argv[i]) == 0 || strncmp ("-m=", argv[i], 3) == 0)
+        {
+          gchar *equal = argv[i] + 2;
+          const gchar *mode = "";
+          if (*equal == '=')
+            mode = equal + 1;
+          else if (i + 1 < argc)
+            {
+              argv[i++] = NULL;
+              mode = argv[i];
+            }
+          if (strcmp (mode, "perf") == 0)
+            subtest_mode_perf = TRUE;
+          else if (strcmp (mode, "slow") == 0 || strcmp (mode, "thorough") == 0)
+            subtest_mode_quick = FALSE;
+          else if (strcmp (mode, "quick") == 0)
+            {
+              subtest_mode_quick = TRUE;
+              subtest_mode_perf = FALSE;
+            }
+          else
+            g_error ("unknown test mode: -m %s", mode);
+          argv[i] = NULL;
+        }
+      else if (strcmp ("-q", argv[i]) == 0 || strcmp ("--quiet", argv[i]) == 0)
+        {
+          gtester_quiet = TRUE;
+          gtester_verbose = FALSE;
+          argv[i] = NULL;
+        }
+      else if (strcmp ("--verbose", argv[i]) == 0)
+        {
+          gtester_quiet = FALSE;
+          gtester_verbose = TRUE;
+          argv[i] = NULL;
+        }
+      else if (strcmp ("-l", argv[i]) == 0)
+        {
+          gtester_list_tests = TRUE;
+          argv[i] = NULL;
+        }
+      else if (strcmp ("--seed", argv[i]) == 0 || strncmp ("--seed=", argv[i], 7) == 0)
+        {
+          gchar *equal = argv[i] + 6;
+          if (*equal == '=')
+            subtest_seedstr = equal + 1;
+          else if (i + 1 < argc)
+            {
+              argv[i++] = NULL;
+              subtest_seedstr = argv[i];
+            }
+          argv[i] = NULL;
+        }
+    }
+  /* collapse argv */
+  e = 1;
+  for (i = 1; i < argc; i++)
+    if (argv[i])
+      {
+        argv[e++] = argv[i];
+        if (i >= e)
+          argv[i] = NULL;
+      }
+  *argc_p = e;
+}
+
+static gboolean
+do_nothing (gpointer data)
+{
+  return TRUE;
+}
+
+int
+main (int    argc,
+      char **argv)
+{
+  guint ui;
+
+  /* See #578295 */
+  g_timeout_add_seconds (5, do_nothing, NULL);
+
+  /* some unices need SA_RESTART for SIGCHLD to return -EAGAIN for io.
+   * we must fiddle with sigaction() *before* glib is used, otherwise
+   * we could revoke signal hanmdler setups from glib initialization code.
+   */
+  if (TRUE)
+    {
+      struct sigaction sa;
+      struct sigaction osa;
+      sa.sa_handler = SIG_DFL;
+      sigfillset (&sa.sa_mask);
+      sa.sa_flags = SA_RESTART;
+      sigaction (SIGCHLD, &sa, &osa);
+    }
+
+  g_set_prgname (argv[0]);
+  parse_args (&argc, &argv);
+  if (gtester_selftest)
+    return main_selftest (argc, argv);
+
+  if (argc <= 1)
+    {
+      usage (FALSE);
+      return 1;
+    }
+
+  if (output_filename)
+    {
+      log_fd = g_open (output_filename, O_WRONLY | O_CREAT | O_TRUNC, 0666);
+      if (log_fd < 0)
+        g_error ("Failed to open log file '%s': %s", output_filename, g_strerror (errno));
+    }
+
+  test_log_printfe ("<?xml version=\"1.0\"?>\n");
+  test_log_printfe ("%s<gtester>\n", sindent (log_indent));
+  log_indent += 2;
+  for (ui = 1; ui < argc; ui++)
+    {
+      const char *binary = argv[ui];
+      launch_test (binary);
+      /* we only get here on success or if !subtest_mode_fatal */
+    }
+  log_indent -= 2;
+  test_log_printfe ("%s</gtester>\n", sindent (log_indent));
+
+  close (log_fd);
+
+  return testcase_fail_count == 0 ? 0 : 1;
+}
+
+static void
+fixture_setup (guint        *fix,
+               gconstpointer test_data)
+{
+  g_assert_cmphex (*fix, ==, 0);
+  *fix = 0xdeadbeef;
+}
+static void
+fixture_test (guint        *fix,
+              gconstpointer test_data)
+{
+  g_assert_cmphex (*fix, ==, 0xdeadbeef);
+  g_test_message ("This is a test message API test message.");
+  g_test_bug_base ("http://www.example.com/bugtracker/");
+  g_test_bug ("123");
+  g_test_bug_base ("http://www.example.com/bugtracker?bugnum=%s;cmd=showbug");
+  g_test_bug ("456");
+}
+static void
+fixture_teardown (guint        *fix,
+                  gconstpointer test_data)
+{
+  g_assert_cmphex (*fix, ==, 0xdeadbeef);
+}
+
+static int
+main_selftest (int    argc,
+               char **argv)
+{
+  /* gtester main() for --gtester-selftest invokations */
+  g_test_init (&argc, &argv, NULL);
+  g_test_add ("/gtester/fixture-test", guint, NULL, fixture_setup, fixture_test, fixture_teardown);
+  return g_test_run();
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gtestutils.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gtestutils.c
new file mode 100644 (file)
index 0000000..c5754ec
--- /dev/null
@@ -0,0 +1,2067 @@
+/* GLib testing utilities
+ * Copyright (C) 2007 Imendio AB
+ * Authors: Tim Janik, Sven Herzberg
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include "gtestutils.h"
+
+#include <sys/types.h>
+#ifdef G_OS_UNIX
+#include <sys/wait.h>
+#include <sys/time.h>
+#include <fcntl.h>
+#endif
+#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#ifdef G_OS_WIN32
+#include <io.h>
+#endif
+#include <errno.h>
+#include <signal.h>
+#ifdef HAVE_SYS_SELECT_H
+#include <sys/select.h>
+#endif /* HAVE_SYS_SELECT_H */
+
+#include "gmain.h"
+#include "gpattern.h"
+#include "grand.h"
+#include "gstrfuncs.h"
+#include "gtimer.h"
+
+/* Global variable for storing assertion messages; this is the counterpart to
+ * glibc's (private) __abort_msg variable, and allows developers and crash
+ * analysis systems like Apport and ABRT to fish out assertion messages from
+ * core dumps, instead of having to catch them on screen output. */
+char *__glib_assert_msg = NULL;
+
+/* --- structures --- */
+struct GTestCase
+{
+  gchar  *name;
+  guint   fixture_size;
+  void   (*fixture_setup)    (void*, gconstpointer);
+  void   (*fixture_test)     (void*, gconstpointer);
+  void   (*fixture_teardown) (void*, gconstpointer);
+  gpointer test_data;
+};
+struct GTestSuite
+{
+  gchar  *name;
+  GSList *suites;
+  GSList *cases;
+};
+typedef struct DestroyEntry DestroyEntry;
+struct DestroyEntry
+{
+  DestroyEntry *next;
+  GDestroyNotify destroy_func;
+  gpointer       destroy_data;
+};
+
+/* --- prototypes --- */
+static void     test_run_seed                   (const gchar *rseed);
+static void     test_trap_clear                 (void);
+static guint8*  g_test_log_dump                 (GTestLogMsg *msg,
+                                                 guint       *len);
+static void     gtest_default_log_handler       (const gchar    *log_domain,
+                                                 GLogLevelFlags  log_level,
+                                                 const gchar    *message,
+                                                 gpointer        unused_data);
+
+
+/* --- variables --- */
+static int         test_log_fd = -1;
+static gboolean    test_mode_fatal = TRUE;
+static gboolean    g_test_run_once = TRUE;
+static gboolean    test_run_list = FALSE;
+static gchar      *test_run_seedstr = NULL;
+static GRand      *test_run_rand = NULL;
+static gchar      *test_run_name = "";
+static guint       test_run_forks = 0;
+static guint       test_run_count = 0;
+static guint       test_skip_count = 0;
+static GTimer     *test_user_timer = NULL;
+static double      test_user_stamp = 0;
+static GSList     *test_paths = NULL;
+static GTestSuite *test_suite_root = NULL;
+static int         test_trap_last_status = 0;
+static int         test_trap_last_pid = 0;
+static char       *test_trap_last_stdout = NULL;
+static char       *test_trap_last_stderr = NULL;
+static char       *test_uri_base = NULL;
+static gboolean    test_debug_log = FALSE;
+static DestroyEntry *test_destroy_queue = NULL;
+static GTestConfig mutable_test_config_vars = {
+  FALSE,        /* test_initialized */
+  TRUE,         /* test_quick */
+  FALSE,        /* test_perf */
+  FALSE,        /* test_verbose */
+  FALSE,        /* test_quiet */
+};
+const GTestConfig * const g_test_config_vars = &mutable_test_config_vars;
+
+/* --- functions --- */
+const char*
+g_test_log_type_name (GTestLogType log_type)
+{
+  switch (log_type)
+    {
+    case G_TEST_LOG_NONE:               return "none";
+    case G_TEST_LOG_ERROR:              return "error";
+    case G_TEST_LOG_START_BINARY:       return "binary";
+    case G_TEST_LOG_LIST_CASE:          return "list";
+    case G_TEST_LOG_SKIP_CASE:          return "skip";
+    case G_TEST_LOG_START_CASE:         return "start";
+    case G_TEST_LOG_STOP_CASE:          return "stop";
+    case G_TEST_LOG_MIN_RESULT:         return "minperf";
+    case G_TEST_LOG_MAX_RESULT:         return "maxperf";
+    case G_TEST_LOG_MESSAGE:            return "message";
+    }
+  return "???";
+}
+
+static void
+g_test_log_send (guint         n_bytes,
+                 const guint8 *buffer)
+{
+  if (test_log_fd >= 0)
+    {
+      int r;
+      do
+        r = write (test_log_fd, buffer, n_bytes);
+      while (r < 0 && errno == EINTR);
+    }
+  if (test_debug_log)
+    {
+      GTestLogBuffer *lbuffer = g_test_log_buffer_new ();
+      GTestLogMsg *msg;
+      guint ui;
+      g_test_log_buffer_push (lbuffer, n_bytes, buffer);
+      msg = g_test_log_buffer_pop (lbuffer);
+      g_warn_if_fail (msg != NULL);
+      g_warn_if_fail (lbuffer->data->len == 0);
+      g_test_log_buffer_free (lbuffer);
+      /* print message */
+      g_printerr ("{*LOG(%s)", g_test_log_type_name (msg->log_type));
+      for (ui = 0; ui < msg->n_strings; ui++)
+        g_printerr (":{%s}", msg->strings[ui]);
+      if (msg->n_nums)
+        {
+          g_printerr (":(");
+          for (ui = 0; ui < msg->n_nums; ui++)
+            g_printerr ("%s%.16Lg", ui ? ";" : "", msg->nums[ui]);
+          g_printerr (")");
+        }
+      g_printerr (":LOG*}\n");
+      g_test_log_msg_free (msg);
+    }
+}
+
+static void
+g_test_log (GTestLogType lbit,
+            const gchar *string1,
+            const gchar *string2,
+            guint        n_args,
+            long double *largs)
+{
+  gboolean fail = lbit == G_TEST_LOG_STOP_CASE && largs[0] != 0;
+  GTestLogMsg msg;
+  gchar *astrings[3] = { NULL, NULL, NULL };
+  guint8 *dbuffer;
+  guint32 dbufferlen;
+
+  switch (lbit)
+    {
+    case G_TEST_LOG_START_BINARY:
+      if (g_test_verbose())
+        g_print ("GTest: random seed: %s\n", string2);
+      break;
+    case G_TEST_LOG_STOP_CASE:
+      if (g_test_verbose())
+        g_print ("GTest: result: %s\n", fail ? "FAIL" : "OK");
+      else if (!g_test_quiet())
+        g_print ("%s\n", fail ? "FAIL" : "OK");
+      if (fail && test_mode_fatal)
+        abort();
+      break;
+    case G_TEST_LOG_MIN_RESULT:
+      if (g_test_verbose())
+        g_print ("(MINPERF:%s)\n", string1);
+      break;
+    case G_TEST_LOG_MAX_RESULT:
+      if (g_test_verbose())
+        g_print ("(MAXPERF:%s)\n", string1);
+      break;
+    case G_TEST_LOG_MESSAGE:
+      if (g_test_verbose())
+        g_print ("(MSG: %s)\n", string1);
+      break;
+    default: ;
+    }
+
+  msg.log_type = lbit;
+  msg.n_strings = (string1 != NULL) + (string1 && string2);
+  msg.strings = astrings;
+  astrings[0] = (gchar*) string1;
+  astrings[1] = astrings[0] ? (gchar*) string2 : NULL;
+  msg.n_nums = n_args;
+  msg.nums = largs;
+  dbuffer = g_test_log_dump (&msg, &dbufferlen);
+  g_test_log_send (dbufferlen, dbuffer);
+  g_free (dbuffer);
+
+  switch (lbit)
+    {
+    case G_TEST_LOG_START_CASE:
+      if (g_test_verbose())
+        g_print ("GTest: run: %s\n", string1);
+      else if (!g_test_quiet())
+        g_print ("%s: ", string1);
+      break;
+    default: ;
+    }
+}
+
+/* We intentionally parse the command line without GOptionContext
+ * because otherwise you would never be able to test it.
+ */
+static void
+parse_args (gint    *argc_p,
+            gchar ***argv_p)
+{
+  guint argc = *argc_p;
+  gchar **argv = *argv_p;
+  guint i, e;
+  /* parse known args */
+  for (i = 1; i < argc; i++)
+    {
+      if (strcmp (argv[i], "--g-fatal-warnings") == 0)
+        {
+          GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK);
+          fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
+          g_log_set_always_fatal (fatal_mask);
+          argv[i] = NULL;
+        }
+      else if (strcmp (argv[i], "--keep-going") == 0 ||
+               strcmp (argv[i], "-k") == 0)
+        {
+          test_mode_fatal = FALSE;
+          argv[i] = NULL;
+        }
+      else if (strcmp (argv[i], "--debug-log") == 0)
+        {
+          test_debug_log = TRUE;
+          argv[i] = NULL;
+        }
+      else if (strcmp ("--GTestLogFD", argv[i]) == 0 || strncmp ("--GTestLogFD=", argv[i], 13) == 0)
+        {
+          gchar *equal = argv[i] + 12;
+          if (*equal == '=')
+            test_log_fd = g_ascii_strtoull (equal + 1, NULL, 0);
+          else if (i + 1 < argc)
+            {
+              argv[i++] = NULL;
+              test_log_fd = g_ascii_strtoull (argv[i], NULL, 0);
+            }
+          argv[i] = NULL;
+        }
+      else if (strcmp ("--GTestSkipCount", argv[i]) == 0 || strncmp ("--GTestSkipCount=", argv[i], 17) == 0)
+        {
+          gchar *equal = argv[i] + 16;
+          if (*equal == '=')
+            test_skip_count = g_ascii_strtoull (equal + 1, NULL, 0);
+          else if (i + 1 < argc)
+            {
+              argv[i++] = NULL;
+              test_skip_count = g_ascii_strtoull (argv[i], NULL, 0);
+            }
+          argv[i] = NULL;
+        }
+      else if (strcmp ("-p", argv[i]) == 0 || strncmp ("-p=", argv[i], 3) == 0)
+        {
+          gchar *equal = argv[i] + 2;
+          if (*equal == '=')
+            test_paths = g_slist_prepend (test_paths, equal + 1);
+          else if (i + 1 < argc)
+            {
+              argv[i++] = NULL;
+              test_paths = g_slist_prepend (test_paths, argv[i]);
+            }
+          argv[i] = NULL;
+        }
+      else if (strcmp ("-m", argv[i]) == 0 || strncmp ("-m=", argv[i], 3) == 0)
+        {
+          gchar *equal = argv[i] + 2;
+          const gchar *mode = "";
+          if (*equal == '=')
+            mode = equal + 1;
+          else if (i + 1 < argc)
+            {
+              argv[i++] = NULL;
+              mode = argv[i];
+            }
+          if (strcmp (mode, "perf") == 0)
+            mutable_test_config_vars.test_perf = TRUE;
+          else if (strcmp (mode, "slow") == 0)
+            mutable_test_config_vars.test_quick = FALSE;
+          else if (strcmp (mode, "thorough") == 0)
+            mutable_test_config_vars.test_quick = FALSE;
+          else if (strcmp (mode, "quick") == 0)
+            {
+              mutable_test_config_vars.test_quick = TRUE;
+              mutable_test_config_vars.test_perf = FALSE;
+            }
+          else
+            g_error ("unknown test mode: -m %s", mode);
+          argv[i] = NULL;
+        }
+      else if (strcmp ("-q", argv[i]) == 0 || strcmp ("--quiet", argv[i]) == 0)
+        {
+          mutable_test_config_vars.test_quiet = TRUE;
+          mutable_test_config_vars.test_verbose = FALSE;
+          argv[i] = NULL;
+        }
+      else if (strcmp ("--verbose", argv[i]) == 0)
+        {
+          mutable_test_config_vars.test_quiet = FALSE;
+          mutable_test_config_vars.test_verbose = TRUE;
+          argv[i] = NULL;
+        }
+      else if (strcmp ("-l", argv[i]) == 0)
+        {
+          test_run_list = TRUE;
+          argv[i] = NULL;
+        }
+      else if (strcmp ("--seed", argv[i]) == 0 || strncmp ("--seed=", argv[i], 7) == 0)
+        {
+          gchar *equal = argv[i] + 6;
+          if (*equal == '=')
+            test_run_seedstr = equal + 1;
+          else if (i + 1 < argc)
+            {
+              argv[i++] = NULL;
+              test_run_seedstr = argv[i];
+            }
+          argv[i] = NULL;
+        }
+      else if (strcmp ("-?", argv[i]) == 0 || strcmp ("--help", argv[i]) == 0)
+        {
+          printf ("Usage:\n"
+                  "  %s [OPTION...]\n\n"
+                  "Help Options:\n"
+                  "  -?, --help                     Show help options\n"
+                  "Test Options:\n"
+                  "  -l                             List test cases available in a test executable\n"
+                  "  -seed=RANDOMSEED               Provide a random seed to reproduce test\n"
+                  "                                 runs using random numbers\n"
+                  "  --verbose                      Run tests verbosely\n"
+                  "  -q, --quiet                    Run tests quietly\n"
+                  "  -p TESTPATH                    execute all tests matching TESTPATH\n"
+                  "  -m {perf|slow|thorough|quick}  Execute tests according modes\n"
+                  "  --debug-log                    debug test logging output\n"
+                  "  -k, --keep-going               gtester-specific argument\n"
+                  "  --GTestLogFD=N                 gtester-specific argument\n"
+                  "  --GTestSkipCount=N             gtester-specific argument\n",
+                  argv[0]);
+          exit (0);
+        }
+    }
+  /* collapse argv */
+  e = 1;
+  for (i = 1; i < argc; i++)
+    if (argv[i])
+      {
+        argv[e++] = argv[i];
+        if (i >= e)
+          argv[i] = NULL;
+      }
+  *argc_p = e;
+}
+
+/**
+ * g_test_init:
+ * @argc: Address of the @argc parameter of the main() function.
+ *        Changed if any arguments were handled.
+ * @argv: Address of the @argv parameter of main().
+ *        Any parameters understood by g_test_init() stripped before return.
+ * @Varargs: Reserved for future extension. Currently, you must pass %NULL.
+ *
+ * Initialize the GLib testing framework, e.g. by seeding the
+ * test random number generator, the name for g_get_prgname()
+ * and parsing test related command line args.
+ * So far, the following arguments are understood:
+ * <variablelist>
+ *   <varlistentry>
+ *     <term><option>-l</option></term>
+ *     <listitem><para>
+ *       list test cases available in a test executable.
+ *     </para></listitem>
+ *   </varlistentry>
+ *   <varlistentry>
+ *     <term><option>--seed=<replaceable>RANDOMSEED</replaceable></option></term>
+ *     <listitem><para>
+ *       provide a random seed to reproduce test runs using random numbers.
+ *     </para></listitem>
+ *     </varlistentry>
+ *     <varlistentry>
+ *       <term><option>--verbose</option></term>
+ *       <listitem><para>run tests verbosely.</para></listitem>
+ *     </varlistentry>
+ *     <varlistentry>
+ *       <term><option>-q</option>, <option>--quiet</option></term>
+ *       <listitem><para>run tests quietly.</para></listitem>
+ *     </varlistentry>
+ *     <varlistentry>
+ *       <term><option>-p <replaceable>TESTPATH</replaceable></option></term>
+ *       <listitem><para>
+ *         execute all tests matching <replaceable>TESTPATH</replaceable>.
+ *       </para></listitem>
+ *     </varlistentry>
+ *     <varlistentry>
+ *       <term><option>-m {perf|slow|thorough|quick}</option></term>
+ *       <listitem><para>
+ *         execute tests according to these test modes:
+ *         <variablelist>
+ *           <varlistentry>
+ *             <term>perf</term>
+ *             <listitem><para>
+ *               performance tests, may take long and report results.
+ *             </para></listitem>
+ *           </varlistentry>
+ *           <varlistentry>
+ *             <term>slow, thorough</term>
+ *             <listitem><para>
+ *               slow and thorough tests, may take quite long and 
+ *               maximize coverage.
+ *             </para></listitem>
+ *           </varlistentry>
+ *           <varlistentry>
+ *             <term>quick</term>
+ *             <listitem><para>
+ *               quick tests, should run really quickly and give good coverage.
+ *             </para></listitem>
+ *           </varlistentry>
+ *         </variablelist>
+ *       </para></listitem>
+ *     </varlistentry>
+ *     <varlistentry>
+ *       <term><option>--debug-log</option></term>
+ *       <listitem><para>debug test logging output.</para></listitem>
+ *     </varlistentry>
+ *     <varlistentry>
+ *       <term><option>-k</option>, <option>--keep-going</option></term>
+ *       <listitem><para>gtester-specific argument.</para></listitem>
+ *     </varlistentry>
+ *     <varlistentry>
+ *       <term><option>--GTestLogFD <replaceable>N</replaceable></option></term>
+ *       <listitem><para>gtester-specific argument.</para></listitem>
+ *     </varlistentry>
+ *     <varlistentry>
+ *       <term><option>--GTestSkipCount <replaceable>N</replaceable></option></term>
+ *       <listitem><para>gtester-specific argument.</para></listitem>
+ *     </varlistentry>
+ *  </variablelist>
+ *
+ * Since: 2.16
+ */
+void
+g_test_init (int    *argc,
+             char ***argv,
+             ...)
+{
+  static char seedstr[4 + 4 * 8 + 1];
+  va_list args;
+  gpointer vararg1;
+  /* make warnings and criticals fatal for all test programs */
+  GLogLevelFlags fatal_mask = (GLogLevelFlags) g_log_set_always_fatal ((GLogLevelFlags) G_LOG_FATAL_MASK);
+  fatal_mask = (GLogLevelFlags) (fatal_mask | G_LOG_LEVEL_WARNING | G_LOG_LEVEL_CRITICAL);
+  g_log_set_always_fatal (fatal_mask);
+  /* check caller args */
+  g_return_if_fail (argc != NULL);
+  g_return_if_fail (argv != NULL);
+  g_return_if_fail (g_test_config_vars->test_initialized == FALSE);
+  mutable_test_config_vars.test_initialized = TRUE;
+
+  va_start (args, argv);
+  vararg1 = va_arg (args, gpointer); /* reserved for future extensions */
+  va_end (args);
+  g_return_if_fail (vararg1 == NULL);
+
+  /* setup random seed string */
+  g_snprintf (seedstr, sizeof (seedstr), "R02S%08x%08x%08x%08x", g_random_int(), g_random_int(), g_random_int(), g_random_int());
+  test_run_seedstr = seedstr;
+
+  /* parse args, sets up mode, changes seed, etc. */
+  parse_args (argc, argv);
+  if (!g_get_prgname())
+    g_set_prgname ((*argv)[0]);
+
+  /* verify GRand reliability, needed for reliable seeds */
+  if (1)
+    {
+      GRand *rg = g_rand_new_with_seed (0xc8c49fb6);
+      guint32 t1 = g_rand_int (rg), t2 = g_rand_int (rg), t3 = g_rand_int (rg), t4 = g_rand_int (rg);
+      /* g_print ("GRand-current: 0x%x 0x%x 0x%x 0x%x\n", t1, t2, t3, t4); */
+      if (t1 != 0xfab39f9b || t2 != 0xb948fb0e || t3 != 0x3d31be26 || t4 != 0x43a19d66)
+        g_warning ("random numbers are not GRand-2.2 compatible, seeds may be broken (check $G_RANDOM_VERSION)");
+      g_rand_free (rg);
+    }
+
+  /* check rand seed */
+  test_run_seed (test_run_seedstr);
+
+  /* report program start */
+  g_log_set_default_handler (gtest_default_log_handler, NULL);
+  g_test_log (G_TEST_LOG_START_BINARY, g_get_prgname(), test_run_seedstr, 0, NULL);
+}
+
+static void
+test_run_seed (const gchar *rseed)
+{
+  guint seed_failed = 0;
+  if (test_run_rand)
+    g_rand_free (test_run_rand);
+  test_run_rand = NULL;
+  while (strchr (" \t\v\r\n\f", *rseed))
+    rseed++;
+  if (strncmp (rseed, "R02S", 4) == 0)  /* seed for random generator 02 (GRand-2.2) */
+    {
+      const char *s = rseed + 4;
+      if (strlen (s) >= 32)             /* require 4 * 8 chars */
+        {
+          guint32 seedarray[4];
+          gchar *p, hexbuf[9] = { 0, };
+          memcpy (hexbuf, s + 0, 8);
+          seedarray[0] = g_ascii_strtoull (hexbuf, &p, 16);
+          seed_failed += p != NULL && *p != 0;
+          memcpy (hexbuf, s + 8, 8);
+          seedarray[1] = g_ascii_strtoull (hexbuf, &p, 16);
+          seed_failed += p != NULL && *p != 0;
+          memcpy (hexbuf, s + 16, 8);
+          seedarray[2] = g_ascii_strtoull (hexbuf, &p, 16);
+          seed_failed += p != NULL && *p != 0;
+          memcpy (hexbuf, s + 24, 8);
+          seedarray[3] = g_ascii_strtoull (hexbuf, &p, 16);
+          seed_failed += p != NULL && *p != 0;
+          if (!seed_failed)
+            {
+              test_run_rand = g_rand_new_with_seed_array (seedarray, 4);
+              return;
+            }
+        }
+    }
+  g_error ("Unknown or invalid random seed: %s", rseed);
+}
+
+/**
+ * g_test_rand_int:
+ *
+ * Get a reproducible random integer number.
+ *
+ * The random numbers generated by the g_test_rand_*() family of functions
+ * change with every new test program start, unless the --seed option is
+ * given when starting test programs.
+ *
+ * For individual test cases however, the random number generator is
+ * reseeded, to avoid dependencies between tests and to make --seed
+ * effective for all test cases.
+ *
+ * Returns: a random number from the seeded random number generator.
+ *
+ * Since: 2.16
+ */
+gint32
+g_test_rand_int (void)
+{
+  return g_rand_int (test_run_rand);
+}
+
+/**
+ * g_test_rand_int_range:
+ * @begin: the minimum value returned by this function
+ * @end:   the smallest value not to be returned by this function
+ *
+ * Get a reproducible random integer number out of a specified range,
+ * see g_test_rand_int() for details on test case random numbers.
+ *
+ * Returns: a number with @begin <= number < @end.
+ * 
+ * Since: 2.16
+ */
+gint32
+g_test_rand_int_range (gint32          begin,
+                       gint32          end)
+{
+  return g_rand_int_range (test_run_rand, begin, end);
+}
+
+/**
+ * g_test_rand_double:
+ *
+ * Get a reproducible random floating point number,
+ * see g_test_rand_int() for details on test case random numbers.
+ *
+ * Returns: a random number from the seeded random number generator.
+ *
+ * Since: 2.16
+ */
+double
+g_test_rand_double (void)
+{
+  return g_rand_double (test_run_rand);
+}
+
+/**
+ * g_test_rand_double_range:
+ * @range_start: the minimum value returned by this function
+ * @range_end: the minimum value not returned by this function
+ *
+ * Get a reproducible random floating pointer number out of a specified range,
+ * see g_test_rand_int() for details on test case random numbers.
+ *
+ * Returns: a number with @range_start <= number < @range_end.
+ *
+ * Since: 2.16
+ */
+double
+g_test_rand_double_range (double          range_start,
+                          double          range_end)
+{
+  return g_rand_double_range (test_run_rand, range_start, range_end);
+}
+
+/**
+ * g_test_timer_start:
+ *
+ * Start a timing test. Call g_test_timer_elapsed() when the task is supposed
+ * to be done. Call this function again to restart the timer.
+ *
+ * Since: 2.16
+ */
+void
+g_test_timer_start (void)
+{
+  if (!test_user_timer)
+    test_user_timer = g_timer_new();
+  test_user_stamp = 0;
+  g_timer_start (test_user_timer);
+}
+
+/**
+ * g_test_timer_elapsed:
+ *
+ * Get the time since the last start of the timer with g_test_timer_start().
+ *
+ * Returns: the time since the last start of the timer, as a double
+ *
+ * Since: 2.16
+ */
+double
+g_test_timer_elapsed (void)
+{
+  test_user_stamp = test_user_timer ? g_timer_elapsed (test_user_timer, NULL) : 0;
+  return test_user_stamp;
+}
+
+/**
+ * g_test_timer_last:
+ *
+ * Report the last result of g_test_timer_elapsed().
+ *
+ * Returns: the last result of g_test_timer_elapsed(), as a double
+ *
+ * Since: 2.16
+ */
+double
+g_test_timer_last (void)
+{
+  return test_user_stamp;
+}
+
+/**
+ * g_test_minimized_result:
+ * @minimized_quantity: the reported value
+ * @format: the format string of the report message
+ * @Varargs: arguments to pass to the printf() function
+ *
+ * Report the result of a performance or measurement test.
+ * The test should generally strive to minimize the reported
+ * quantities (smaller values are better than larger ones),
+ * this and @minimized_quantity can determine sorting
+ * order for test result reports.
+ *
+ * Since: 2.16
+ */
+void
+g_test_minimized_result (double          minimized_quantity,
+                         const char     *format,
+                         ...)
+{
+  long double largs = minimized_quantity;
+  gchar *buffer;
+  va_list args;
+  va_start (args, format);
+  buffer = g_strdup_vprintf (format, args);
+  va_end (args);
+  g_test_log (G_TEST_LOG_MIN_RESULT, buffer, NULL, 1, &largs);
+  g_free (buffer);
+}
+
+/**
+ * g_test_maximized_result:
+ * @maximized_quantity: the reported value
+ * @format: the format string of the report message
+ * @Varargs: arguments to pass to the printf() function
+ *
+ * Report the result of a performance or measurement test.
+ * The test should generally strive to maximize the reported
+ * quantities (larger values are better than smaller ones),
+ * this and @maximized_quantity can determine sorting
+ * order for test result reports.
+ *
+ * Since: 2.16
+ */
+void
+g_test_maximized_result (double          maximized_quantity,
+                         const char     *format,
+                         ...)
+{
+  long double largs = maximized_quantity;
+  gchar *buffer;
+  va_list args;
+  va_start (args, format);
+  buffer = g_strdup_vprintf (format, args);
+  va_end (args);
+  g_test_log (G_TEST_LOG_MAX_RESULT, buffer, NULL, 1, &largs);
+  g_free (buffer);
+}
+
+/**
+ * g_test_message:
+ * @format: the format string
+ * @...:    printf-like arguments to @format
+ *
+ * Add a message to the test report.
+ *
+ * Since: 2.16
+ */
+void
+g_test_message (const char *format,
+                ...)
+{
+  gchar *buffer;
+  va_list args;
+  va_start (args, format);
+  buffer = g_strdup_vprintf (format, args);
+  va_end (args);
+  g_test_log (G_TEST_LOG_MESSAGE, buffer, NULL, 0, NULL);
+  g_free (buffer);
+}
+
+/**
+ * g_test_bug_base:
+ * @uri_pattern: the base pattern for bug URIs
+ *
+ * Specify the base URI for bug reports.
+ *
+ * The base URI is used to construct bug report messages for
+ * g_test_message() when g_test_bug() is called.
+ * Calling this function outside of a test case sets the
+ * default base URI for all test cases. Calling it from within
+ * a test case changes the base URI for the scope of the test
+ * case only.
+ * Bug URIs are constructed by appending a bug specific URI
+ * portion to @uri_pattern, or by replacing the special string
+ * '%s' within @uri_pattern if that is present.
+ *
+ * Since: 2.16
+ */
+void
+g_test_bug_base (const char *uri_pattern)
+{
+  g_free (test_uri_base);
+  test_uri_base = g_strdup (uri_pattern);
+}
+
+/**
+ * g_test_bug:
+ * @bug_uri_snippet: Bug specific bug tracker URI portion.
+ *
+ * This function adds a message to test reports that
+ * associates a bug URI with a test case.
+ * Bug URIs are constructed from a base URI set with g_test_bug_base()
+ * and @bug_uri_snippet.
+ *
+ * Since: 2.16
+ */
+void
+g_test_bug (const char *bug_uri_snippet)
+{
+  char *c;
+  g_return_if_fail (test_uri_base != NULL);
+  g_return_if_fail (bug_uri_snippet != NULL);
+  c = strstr (test_uri_base, "%s");
+  if (c)
+    {
+      char *b = g_strndup (test_uri_base, c - test_uri_base);
+      char *s = g_strconcat (b, bug_uri_snippet, c + 2, NULL);
+      g_free (b);
+      g_test_message ("Bug Reference: %s", s);
+      g_free (s);
+    }
+  else
+    g_test_message ("Bug Reference: %s%s", test_uri_base, bug_uri_snippet);
+}
+
+/**
+ * g_test_get_root:
+ *
+ * Get the toplevel test suite for the test path API.
+ *
+ * Returns: the toplevel #GTestSuite
+ *
+ * Since: 2.16
+ */
+GTestSuite*
+g_test_get_root (void)
+{
+  if (!test_suite_root)
+    {
+      test_suite_root = g_test_create_suite ("root");
+      g_free (test_suite_root->name);
+      test_suite_root->name = g_strdup ("");
+    }
+  return test_suite_root;
+}
+
+/**
+ * g_test_run:
+ *
+ * Runs all tests under the toplevel suite which can be retrieved
+ * with g_test_get_root(). Similar to g_test_run_suite(), the test
+ * cases to be run are filtered according to
+ * test path arguments (-p <replaceable>testpath</replaceable>) as 
+ * parsed by g_test_init().
+ * g_test_run_suite() or g_test_run() may only be called once
+ * in a program.
+ *
+ * Returns: 0 on success
+ *
+ * Since: 2.16
+ */
+int
+g_test_run (void)
+{
+  return g_test_run_suite (g_test_get_root());
+}
+
+/**
+ * g_test_create_case:
+ * @test_name:     the name for the test case
+ * @data_size:     the size of the fixture data structure
+ * @test_data:     test data argument for the test functions
+ * @data_setup:    the function to set up the fixture data
+ * @data_test:     the actual test function
+ * @data_teardown: the function to teardown the fixture data
+ *
+ * Create a new #GTestCase, named @test_name, this API is fairly
+ * low level, calling g_test_add() or g_test_add_func() is preferable.
+ * When this test is executed, a fixture structure of size @data_size
+ * will be allocated and filled with 0s. Then data_setup() is called
+ * to initialize the fixture. After fixture setup, the actual test
+ * function data_test() is called. Once the test run completed, the
+ * fixture structure is torn down  by calling data_teardown() and
+ * after that the memory is released.
+ *
+ * Splitting up a test run into fixture setup, test function and
+ * fixture teardown is most usful if the same fixture is used for
+ * multiple tests. In this cases, g_test_create_case() will be
+ * called with the same fixture, but varying @test_name and
+ * @data_test arguments.
+ *
+ * Returns: a newly allocated #GTestCase.
+ *
+ * Since: 2.16
+ */
+GTestCase*
+g_test_create_case (const char       *test_name,
+                    gsize             data_size,
+                    gconstpointer     test_data,
+                    GTestFixtureFunc  data_setup,
+                    GTestFixtureFunc  data_test,
+                    GTestFixtureFunc  data_teardown)
+{
+  GTestCase *tc;
+  g_return_val_if_fail (test_name != NULL, NULL);
+  g_return_val_if_fail (strchr (test_name, '/') == NULL, NULL);
+  g_return_val_if_fail (test_name[0] != 0, NULL);
+  g_return_val_if_fail (data_test != NULL, NULL);
+  tc = g_slice_new0 (GTestCase);
+  tc->name = g_strdup (test_name);
+  tc->test_data = (gpointer) test_data;
+  tc->fixture_size = data_size;
+  tc->fixture_setup = (void*) data_setup;
+  tc->fixture_test = (void*) data_test;
+  tc->fixture_teardown = (void*) data_teardown;
+  return tc;
+}
+
+/**
+ * GTestFixtureFunc:
+ * @fixture: the test fixture
+ * @user_data: the data provided when registering the test
+ *
+ * The type used for functions that operate on test fixtures.  This is
+ * used for the fixture setup and teardown functions as well as for the
+ * testcases themselves.
+ *
+ * @user_data is a pointer to the data that was given when registering
+ * the test case.
+ *
+ * @fixture will be a pointer to the area of memory allocated by the
+ * test framework, of the size requested.  If the requested size was
+ * zero then @fixture will be equal to @user_data.
+ **/
+void
+g_test_add_vtable (const char       *testpath,
+                   gsize             data_size,
+                   gconstpointer     test_data,
+                   GTestFixtureFunc  data_setup,
+                   GTestFixtureFunc  fixture_test_func,
+                   GTestFixtureFunc  data_teardown)
+{
+  gchar **segments;
+  guint ui;
+  GTestSuite *suite;
+
+  g_return_if_fail (testpath != NULL);
+  g_return_if_fail (testpath[0] == '/');
+  g_return_if_fail (fixture_test_func != NULL);
+
+  suite = g_test_get_root();
+  segments = g_strsplit (testpath, "/", -1);
+  for (ui = 0; segments[ui] != NULL; ui++)
+    {
+      const char *seg = segments[ui];
+      gboolean islast = segments[ui + 1] == NULL;
+      if (islast && !seg[0])
+        g_error ("invalid test case path: %s", testpath);
+      else if (!seg[0])
+        continue;       /* initial or duplicate slash */
+      else if (!islast)
+        {
+          GTestSuite *csuite = g_test_create_suite (seg);
+          g_test_suite_add_suite (suite, csuite);
+          suite = csuite;
+        }
+      else /* islast */
+        {
+          GTestCase *tc = g_test_create_case (seg, data_size, test_data, data_setup, fixture_test_func, data_teardown);
+          g_test_suite_add (suite, tc);
+        }
+    }
+  g_strfreev (segments);
+}
+
+/**
+ * GTestFunc:
+ *
+ * The type used for test case functions.
+ **/
+/**
+ * g_test_add_func:
+ * @testpath:   Slash-separated test case path name for the test.
+ * @test_func:  The test function to invoke for this test.
+ *
+ * Create a new test case, similar to g_test_create_case(). However
+ * the test is assumed to use no fixture, and test suites are automatically
+ * created on the fly and added to the root fixture, based on the
+ * slash-separated portions of @testpath.
+ *
+ * Since: 2.16
+ */
+void
+g_test_add_func (const char *testpath,
+                 GTestFunc   test_func)
+{
+  g_return_if_fail (testpath != NULL);
+  g_return_if_fail (testpath[0] == '/');
+  g_return_if_fail (test_func != NULL);
+  g_test_add_vtable (testpath, 0, NULL, NULL, (GTestFixtureFunc) test_func, NULL);
+}
+
+/**
+ * GTestDataFunc:
+ * @user_data: the data provided when registering the test
+ *
+ * The type used for test case functions that take an extra pointer
+ * argument.
+ **/
+/**
+ * g_test_add_data_func:
+ * @testpath:   Slash-separated test case path name for the test.
+ * @test_data:  Test data argument for the test function.
+ * @test_func:  The test function to invoke for this test.
+ *
+ * Create a new test case, similar to g_test_create_case(). However
+ * the test is assumed to use no fixture, and test suites are automatically
+ * created on the fly and added to the root fixture, based on the
+ * slash-separated portions of @testpath. The @test_data argument
+ * will be passed as first argument to @test_func.
+ *
+ * Since: 2.16
+ */
+void
+g_test_add_data_func (const char     *testpath,
+                      gconstpointer   test_data,
+                      GTestDataFunc   test_func)
+{
+  g_return_if_fail (testpath != NULL);
+  g_return_if_fail (testpath[0] == '/');
+  g_return_if_fail (test_func != NULL);
+  g_test_add_vtable (testpath, 0, test_data, NULL, (GTestFixtureFunc) test_func, NULL);
+}
+
+/**
+ * g_test_create_suite:
+ * @suite_name: a name for the suite
+ *
+ * Create a new test suite with the name @suite_name.
+ *
+ * Returns: A newly allocated #GTestSuite instance.
+ *
+ * Since: 2.16
+ */
+GTestSuite*
+g_test_create_suite (const char *suite_name)
+{
+  GTestSuite *ts;
+  g_return_val_if_fail (suite_name != NULL, NULL);
+  g_return_val_if_fail (strchr (suite_name, '/') == NULL, NULL);
+  g_return_val_if_fail (suite_name[0] != 0, NULL);
+  ts = g_slice_new0 (GTestSuite);
+  ts->name = g_strdup (suite_name);
+  return ts;
+}
+
+/**
+ * g_test_suite_add:
+ * @suite: a #GTestSuite
+ * @test_case: a #GTestCase
+ *
+ * Adds @test_case to @suite.
+ *
+ * Since: 2.16
+ */
+void
+g_test_suite_add (GTestSuite     *suite,
+                  GTestCase      *test_case)
+{
+  g_return_if_fail (suite != NULL);
+  g_return_if_fail (test_case != NULL);
+  suite->cases = g_slist_prepend (suite->cases, test_case);
+}
+
+/**
+ * g_test_suite_add_suite:
+ * @suite:       a #GTestSuite
+ * @nestedsuite: another #GTestSuite
+ *
+ * Adds @nestedsuite to @suite.
+ *
+ * Since: 2.16
+ */
+void
+g_test_suite_add_suite (GTestSuite     *suite,
+                        GTestSuite     *nestedsuite)
+{
+  g_return_if_fail (suite != NULL);
+  g_return_if_fail (nestedsuite != NULL);
+  suite->suites = g_slist_prepend (suite->suites, nestedsuite);
+}
+
+/**
+ * g_test_queue_free:
+ * @gfree_pointer: the pointer to be stored.
+ *
+ * Enqueue a pointer to be released with g_free() during the next
+ * teardown phase. This is equivalent to calling g_test_queue_destroy()
+ * with a destroy callback of g_free().
+ *
+ * Since: 2.16
+ */
+void
+g_test_queue_free (gpointer gfree_pointer)
+{
+  if (gfree_pointer)
+    g_test_queue_destroy (g_free, gfree_pointer);
+}
+
+/**
+ * g_test_queue_destroy:
+ * @destroy_func:       Destroy callback for teardown phase.
+ * @destroy_data:       Destroy callback data.
+ *
+ * This function enqueus a callback @destroy_func() to be executed
+ * during the next test case teardown phase. This is most useful
+ * to auto destruct allocted test resources at the end of a test run.
+ * Resources are released in reverse queue order, that means enqueueing
+ * callback A before callback B will cause B() to be called before
+ * A() during teardown.
+ *
+ * Since: 2.16
+ */
+void
+g_test_queue_destroy (GDestroyNotify destroy_func,
+                      gpointer       destroy_data)
+{
+  DestroyEntry *dentry;
+  g_return_if_fail (destroy_func != NULL);
+  dentry = g_slice_new0 (DestroyEntry);
+  dentry->destroy_func = destroy_func;
+  dentry->destroy_data = destroy_data;
+  dentry->next = test_destroy_queue;
+  test_destroy_queue = dentry;
+}
+
+static int
+test_case_run (GTestCase *tc)
+{
+  gchar *old_name = test_run_name, *old_base = g_strdup (test_uri_base);
+  test_run_name = g_strconcat (old_name, "/", tc->name, NULL);
+  if (++test_run_count <= test_skip_count)
+    g_test_log (G_TEST_LOG_SKIP_CASE, test_run_name, NULL, 0, NULL);
+  else if (test_run_list)
+    {
+      g_print ("%s\n", test_run_name);
+      g_test_log (G_TEST_LOG_LIST_CASE, test_run_name, NULL, 0, NULL);
+    }
+  else
+    {
+      GTimer *test_run_timer = g_timer_new();
+      long double largs[3];
+      void *fixture;
+      g_test_log (G_TEST_LOG_START_CASE, test_run_name, NULL, 0, NULL);
+      test_run_forks = 0;
+      g_test_log_set_fatal_handler (NULL, NULL);
+      g_timer_start (test_run_timer);
+      fixture = tc->fixture_size ? g_malloc0 (tc->fixture_size) : tc->test_data;
+      test_run_seed (test_run_seedstr);
+      if (tc->fixture_setup)
+        tc->fixture_setup (fixture, tc->test_data);
+      tc->fixture_test (fixture, tc->test_data);
+      test_trap_clear();
+      while (test_destroy_queue)
+        {
+          DestroyEntry *dentry = test_destroy_queue;
+          test_destroy_queue = dentry->next;
+          dentry->destroy_func (dentry->destroy_data);
+          g_slice_free (DestroyEntry, dentry);
+        }
+      if (tc->fixture_teardown)
+        tc->fixture_teardown (fixture, tc->test_data);
+      if (tc->fixture_size)
+        g_free (fixture);
+      g_timer_stop (test_run_timer);
+      largs[0] = 0; /* OK */
+      largs[1] = test_run_forks;
+      largs[2] = g_timer_elapsed (test_run_timer, NULL);
+      g_test_log (G_TEST_LOG_STOP_CASE, NULL, NULL, G_N_ELEMENTS (largs), largs);
+      g_timer_destroy (test_run_timer);
+    }
+  g_free (test_run_name);
+  test_run_name = old_name;
+  g_free (test_uri_base);
+  test_uri_base = old_base;
+  return 0;
+}
+
+static int
+g_test_run_suite_internal (GTestSuite *suite,
+                           const char *path)
+{
+  guint n_bad = 0, n_good = 0, bad_suite = 0, l;
+  gchar *rest, *old_name = test_run_name;
+  GSList *slist, *reversed;
+  g_return_val_if_fail (suite != NULL, -1);
+  while (path[0] == '/')
+    path++;
+  l = strlen (path);
+  rest = strchr (path, '/');
+  l = rest ? MIN (l, rest - path) : l;
+  test_run_name = suite->name[0] == 0 ? g_strdup (test_run_name) : g_strconcat (old_name, "/", suite->name, NULL);
+  reversed = g_slist_reverse (g_slist_copy (suite->cases));
+  for (slist = reversed; slist; slist = slist->next)
+    {
+      GTestCase *tc = slist->data;
+      guint n = l ? strlen (tc->name) : 0;
+      if (l == n && strncmp (path, tc->name, n) == 0)
+        {
+          n_good++;
+          n_bad += test_case_run (tc) != 0;
+        }
+    }
+  g_slist_free (reversed);
+  reversed = g_slist_reverse (g_slist_copy (suite->suites));
+  for (slist = reversed; slist; slist = slist->next)
+    {
+      GTestSuite *ts = slist->data;
+      guint n = l ? strlen (ts->name) : 0;
+      if (l == n && strncmp (path, ts->name, n) == 0)
+        bad_suite += g_test_run_suite_internal (ts, rest ? rest : "") != 0;
+    }
+  g_slist_free (reversed);
+  g_free (test_run_name);
+  test_run_name = old_name;
+  return n_bad || bad_suite;
+}
+
+/**
+ * g_test_run_suite:
+ * @suite: a #GTestSuite
+ *
+ * Execute the tests within @suite and all nested #GTestSuites.
+ * The test suites to be executed are filtered according to
+ * test path arguments (-p <replaceable>testpath</replaceable>) 
+ * as parsed by g_test_init().
+ * g_test_run_suite() or g_test_run() may only be called once
+ * in a program.
+ *
+ * Returns: 0 on success
+ *
+ * Since: 2.16
+ */
+int
+g_test_run_suite (GTestSuite *suite)
+{
+  guint n_bad = 0;
+  g_return_val_if_fail (g_test_config_vars->test_initialized, -1);
+  g_return_val_if_fail (g_test_run_once == TRUE, -1);
+  g_test_run_once = FALSE;
+  if (!test_paths)
+    test_paths = g_slist_prepend (test_paths, "");
+  while (test_paths)
+    {
+      const char *rest, *path = test_paths->data;
+      guint l, n = strlen (suite->name);
+      test_paths = g_slist_delete_link (test_paths, test_paths);
+      while (path[0] == '/')
+        path++;
+      if (!n) /* root suite, run unconditionally */
+        {
+          n_bad += 0 != g_test_run_suite_internal (suite, path);
+          continue;
+        }
+      /* regular suite, match path */
+      rest = strchr (path, '/');
+      l = strlen (path);
+      l = rest ? MIN (l, rest - path) : l;
+      if ((!l || l == n) && strncmp (path, suite->name, n) == 0)
+        n_bad += 0 != g_test_run_suite_internal (suite, rest ? rest : "");
+    }
+  return n_bad;
+}
+
+static void
+gtest_default_log_handler (const gchar    *log_domain,
+                           GLogLevelFlags  log_level,
+                           const gchar    *message,
+                           gpointer        unused_data)
+{
+  const gchar *strv[16];
+  gboolean fatal = FALSE;
+  gchar *msg;
+  guint i = 0;
+  if (log_domain)
+    {
+      strv[i++] = log_domain;
+      strv[i++] = "-";
+    }
+  if (log_level & G_LOG_FLAG_FATAL)
+    {
+      strv[i++] = "FATAL-";
+      fatal = TRUE;
+    }
+  if (log_level & G_LOG_FLAG_RECURSION)
+    strv[i++] = "RECURSIVE-";
+  if (log_level & G_LOG_LEVEL_ERROR)
+    strv[i++] = "ERROR";
+  if (log_level & G_LOG_LEVEL_CRITICAL)
+    strv[i++] = "CRITICAL";
+  if (log_level & G_LOG_LEVEL_WARNING)
+    strv[i++] = "WARNING";
+  if (log_level & G_LOG_LEVEL_MESSAGE)
+    strv[i++] = "MESSAGE";
+  if (log_level & G_LOG_LEVEL_INFO)
+    strv[i++] = "INFO";
+  if (log_level & G_LOG_LEVEL_DEBUG)
+    strv[i++] = "DEBUG";
+  strv[i++] = ": ";
+  strv[i++] = message;
+  strv[i++] = NULL;
+  msg = g_strjoinv ("", (gchar**) strv);
+  g_test_log (fatal ? G_TEST_LOG_ERROR : G_TEST_LOG_MESSAGE, msg, NULL, 0, NULL);
+  g_log_default_handler (log_domain, log_level, message, unused_data);
+  g_free (msg);
+}
+
+void
+g_assertion_message (const char     *domain,
+                     const char     *file,
+                     int             line,
+                     const char     *func,
+                     const char     *message)
+{
+  char lstr[32];
+  char *s;
+  if (!message)
+    message = "code should not be reached";
+  g_snprintf (lstr, 32, "%d", line);
+  s = g_strconcat (domain ? domain : "", domain && domain[0] ? ":" : "",
+                   "ERROR:", file, ":", lstr, ":",
+                   func, func[0] ? ":" : "",
+                   " ", message, NULL);
+  g_printerr ("**\n%s\n", s);
+
+  /* store assertion message in global variable, so that it can be found in a
+   * core dump */
+  if (__glib_assert_msg != NULL)
+      /* free the old one */
+      free (__glib_assert_msg);
+  __glib_assert_msg = (char*) malloc (strlen (s) + 1);
+  strcpy (__glib_assert_msg, s);
+
+  g_test_log (G_TEST_LOG_ERROR, s, NULL, 0, NULL);
+  g_free (s);
+  abort();
+}
+
+void
+g_assertion_message_expr (const char     *domain,
+                          const char     *file,
+                          int             line,
+                          const char     *func,
+                          const char     *expr)
+{
+  char *s = g_strconcat ("assertion failed: (", expr, ")", NULL);
+  g_assertion_message (domain, file, line, func, s);
+  g_free (s);
+}
+
+void
+g_assertion_message_cmpnum (const char     *domain,
+                            const char     *file,
+                            int             line,
+                            const char     *func,
+                            const char     *expr,
+                            long double     arg1,
+                            const char     *cmp,
+                            long double     arg2,
+                            char            numtype)
+{
+  char *s = NULL;
+  switch (numtype)
+    {
+    case 'i':   s = g_strdup_printf ("assertion failed (%s): (%.0Lf %s %.0Lf)", expr, arg1, cmp, arg2); break;
+    case 'x':   s = g_strdup_printf ("assertion failed (%s): (0x%08" G_GINT64_MODIFIER "x %s 0x%08" G_GINT64_MODIFIER "x)", expr, (guint64) arg1, cmp, (guint64) arg2); break;
+    case 'f':   s = g_strdup_printf ("assertion failed (%s): (%.9Lg %s %.9Lg)", expr, arg1, cmp, arg2); break;
+      /* ideally use: floats=%.7g double=%.17g */
+    }
+  g_assertion_message (domain, file, line, func, s);
+  g_free (s);
+}
+
+void
+g_assertion_message_cmpstr (const char     *domain,
+                            const char     *file,
+                            int             line,
+                            const char     *func,
+                            const char     *expr,
+                            const char     *arg1,
+                            const char     *cmp,
+                            const char     *arg2)
+{
+  char *a1, *a2, *s, *t1 = NULL, *t2 = NULL;
+  a1 = arg1 ? g_strconcat ("\"", t1 = g_strescape (arg1, NULL), "\"", NULL) : g_strdup ("NULL");
+  a2 = arg2 ? g_strconcat ("\"", t2 = g_strescape (arg2, NULL), "\"", NULL) : g_strdup ("NULL");
+  g_free (t1);
+  g_free (t2);
+  s = g_strdup_printf ("assertion failed (%s): (%s %s %s)", expr, a1, cmp, a2);
+  g_free (a1);
+  g_free (a2);
+  g_assertion_message (domain, file, line, func, s);
+  g_free (s);
+}
+
+void
+g_assertion_message_error (const char     *domain,
+                          const char     *file,
+                          int             line,
+                          const char     *func,
+                          const char     *expr,
+                          const GError   *error,
+                          GQuark          error_domain,
+                          int             error_code)
+{
+  GString *gstring;
+
+  /* This is used by both g_assert_error() and g_assert_no_error(), so there
+   * are three cases: expected an error but got the wrong error, expected
+   * an error but got no error, and expected no error but got an error.
+   */
+
+  gstring = g_string_new ("assertion failed ");
+  if (error_domain)
+      g_string_append_printf (gstring, "(%s == (%s, %d)): ", expr,
+                             g_quark_to_string (error_domain), error_code);
+  else
+    g_string_append_printf (gstring, "(%s == NULL): ", expr);
+
+  if (error)
+      g_string_append_printf (gstring, "%s (%s, %d)", error->message,
+                             g_quark_to_string (error->domain), error->code);
+  else
+    g_string_append_printf (gstring, "%s is NULL", expr);
+
+  g_assertion_message (domain, file, line, func, gstring->str);
+  g_string_free (gstring, TRUE);
+}
+
+/**
+ * g_strcmp0:
+ * @str1: a C string or %NULL
+ * @str2: another C string or %NULL
+ *
+ * Compares @str1 and @str2 like strcmp(). Handles %NULL 
+ * gracefully by sorting it before non-%NULL strings.
+ * Comparing two %NULL pointers returns 0.
+ *
+ * Returns: -1, 0 or 1, if @str1 is <, == or > than @str2.
+ *
+ * Since: 2.16
+ */
+int
+g_strcmp0 (const char     *str1,
+           const char     *str2)
+{
+  if (!str1)
+    return -(str1 != str2);
+  if (!str2)
+    return str1 != str2;
+  return strcmp (str1, str2);
+}
+
+#ifdef G_OS_UNIX
+static int /* 0 on success */
+kill_child (int  pid,
+            int *status,
+            int  patience)
+{
+  int wr;
+  if (patience >= 3)    /* try graceful reap */
+    {
+      if (waitpid (pid, status, WNOHANG) > 0)
+        return 0;
+    }
+  if (patience >= 2)    /* try SIGHUP */
+    {
+      kill (pid, SIGHUP);
+      if (waitpid (pid, status, WNOHANG) > 0)
+        return 0;
+      g_usleep (20 * 1000); /* give it some scheduling/shutdown time */
+      if (waitpid (pid, status, WNOHANG) > 0)
+        return 0;
+      g_usleep (50 * 1000); /* give it some scheduling/shutdown time */
+      if (waitpid (pid, status, WNOHANG) > 0)
+        return 0;
+      g_usleep (100 * 1000); /* give it some scheduling/shutdown time */
+      if (waitpid (pid, status, WNOHANG) > 0)
+        return 0;
+    }
+  if (patience >= 1)    /* try SIGTERM */
+    {
+      kill (pid, SIGTERM);
+      if (waitpid (pid, status, WNOHANG) > 0)
+        return 0;
+      g_usleep (200 * 1000); /* give it some scheduling/shutdown time */
+      if (waitpid (pid, status, WNOHANG) > 0)
+        return 0;
+      g_usleep (400 * 1000); /* give it some scheduling/shutdown time */
+      if (waitpid (pid, status, WNOHANG) > 0)
+        return 0;
+    }
+  /* finish it off */
+  kill (pid, SIGKILL);
+  do
+    wr = waitpid (pid, status, 0);
+  while (wr < 0 && errno == EINTR);
+  return wr;
+}
+#endif
+
+static inline int
+g_string_must_read (GString *gstring,
+                    int      fd)
+{
+#define STRING_BUFFER_SIZE     4096
+  char buf[STRING_BUFFER_SIZE];
+  gssize bytes;
+ again:
+  bytes = read (fd, buf, sizeof (buf));
+  if (bytes == 0)
+    return 0; /* EOF, calling this function assumes data is available */
+  else if (bytes > 0)
+    {
+      g_string_append_len (gstring, buf, bytes);
+      return 1;
+    }
+  else if (bytes < 0 && errno == EINTR)
+    goto again;
+  else /* bytes < 0 */
+    {
+      g_warning ("failed to read() from child process (%d): %s", test_trap_last_pid, g_strerror (errno));
+      return 1; /* ignore error after warning */
+    }
+}
+
+static inline void
+g_string_write_out (GString *gstring,
+                    int      outfd,
+                    int     *stringpos)
+{
+  if (*stringpos < gstring->len)
+    {
+      int r;
+      do
+        r = write (outfd, gstring->str + *stringpos, gstring->len - *stringpos);
+      while (r < 0 && errno == EINTR);
+      *stringpos += MAX (r, 0);
+    }
+}
+
+static void
+test_trap_clear (void)
+{
+  test_trap_last_status = 0;
+  test_trap_last_pid = 0;
+  g_free (test_trap_last_stdout);
+  test_trap_last_stdout = NULL;
+  g_free (test_trap_last_stderr);
+  test_trap_last_stderr = NULL;
+}
+
+#ifdef G_OS_UNIX
+
+static int
+sane_dup2 (int fd1,
+           int fd2)
+{
+  int ret;
+  do
+    ret = dup2 (fd1, fd2);
+  while (ret < 0 && errno == EINTR);
+  return ret;
+}
+
+static guint64
+test_time_stamp (void)
+{
+  GTimeVal tv;
+  guint64 stamp;
+  g_get_current_time (&tv);
+  stamp = tv.tv_sec;
+  stamp = stamp * 1000000 + tv.tv_usec;
+  return stamp;
+}
+
+#endif
+
+/**
+ * g_test_trap_fork:
+ * @usec_timeout:    Timeout for the forked test in micro seconds.
+ * @test_trap_flags: Flags to modify forking behaviour.
+ *
+ * Fork the current test program to execute a test case that might
+ * not return or that might abort. The forked test case is aborted
+ * and considered failing if its run time exceeds @usec_timeout.
+ *
+ * The forking behavior can be configured with the #GTestTrapFlags flags.
+ *
+ * In the following example, the test code forks, the forked child
+ * process produces some sample output and exits successfully.
+ * The forking parent process then asserts successful child program
+ * termination and validates child program outputs.
+ *
+ * |[
+ *   static void
+ *   test_fork_patterns (void)
+ *   {
+ *     if (g_test_trap_fork (0, G_TEST_TRAP_SILENCE_STDOUT | G_TEST_TRAP_SILENCE_STDERR))
+ *       {
+ *         g_print ("some stdout text: somagic17\n");
+ *         g_printerr ("some stderr text: semagic43\n");
+ *         exit (0); /&ast; successful test run &ast;/
+ *       }
+ *     g_test_trap_assert_passed();
+ *     g_test_trap_assert_stdout ("*somagic17*");
+ *     g_test_trap_assert_stderr ("*semagic43*");
+ *   }
+ * ]|
+ *
+ * This function is implemented only on Unix platforms.
+ *
+ * Returns: %TRUE for the forked child and %FALSE for the executing parent process.
+ *
+ * Since: 2.16
+ */
+gboolean
+g_test_trap_fork (guint64        usec_timeout,
+                  GTestTrapFlags test_trap_flags)
+{
+#ifdef G_OS_UNIX
+  gboolean pass_on_forked_log = FALSE;
+  int stdout_pipe[2] = { -1, -1 };
+  int stderr_pipe[2] = { -1, -1 };
+  int stdtst_pipe[2] = { -1, -1 };
+  test_trap_clear();
+  if (pipe (stdout_pipe) < 0 || pipe (stderr_pipe) < 0 || pipe (stdtst_pipe) < 0)
+    g_error ("failed to create pipes to fork test program: %s", g_strerror (errno));
+  signal (SIGCHLD, SIG_DFL);
+  test_trap_last_pid = fork ();
+  if (test_trap_last_pid < 0)
+    g_error ("failed to fork test program: %s", g_strerror (errno));
+  if (test_trap_last_pid == 0)  /* child */
+    {
+      int fd0 = -1;
+      close (stdout_pipe[0]);
+      close (stderr_pipe[0]);
+      close (stdtst_pipe[0]);
+      if (!(test_trap_flags & G_TEST_TRAP_INHERIT_STDIN))
+        fd0 = open ("/dev/null", O_RDONLY);
+      if (sane_dup2 (stdout_pipe[1], 1) < 0 || sane_dup2 (stderr_pipe[1], 2) < 0 || (fd0 >= 0 && sane_dup2 (fd0, 0) < 0))
+        g_error ("failed to dup2() in forked test program: %s", g_strerror (errno));
+      if (fd0 >= 3)
+        close (fd0);
+      if (stdout_pipe[1] >= 3)
+        close (stdout_pipe[1]);
+      if (stderr_pipe[1] >= 3)
+        close (stderr_pipe[1]);
+      test_log_fd = stdtst_pipe[1];
+      return TRUE;
+    }
+  else                          /* parent */
+    {
+      GString *sout = g_string_new (NULL);
+      GString *serr = g_string_new (NULL);
+      guint64 sstamp;
+      int soutpos = 0, serrpos = 0, wr, need_wait = TRUE;
+      test_run_forks++;
+      close (stdout_pipe[1]);
+      close (stderr_pipe[1]);
+      close (stdtst_pipe[1]);
+      sstamp = test_time_stamp();
+      /* read data until we get EOF on all pipes */
+      while (stdout_pipe[0] >= 0 || stderr_pipe[0] >= 0 || stdtst_pipe[0] > 0)
+        {
+          fd_set fds;
+          struct timeval tv;
+          int ret;
+          FD_ZERO (&fds);
+          if (stdout_pipe[0] >= 0)
+            FD_SET (stdout_pipe[0], &fds);
+          if (stderr_pipe[0] >= 0)
+            FD_SET (stderr_pipe[0], &fds);
+          if (stdtst_pipe[0] >= 0)
+            FD_SET (stdtst_pipe[0], &fds);
+          tv.tv_sec = 0;
+          tv.tv_usec = MIN (usec_timeout ? usec_timeout : 1000000, 100 * 1000); /* sleep at most 0.5 seconds to catch clock skews, etc. */
+          ret = select (MAX (MAX (stdout_pipe[0], stderr_pipe[0]), stdtst_pipe[0]) + 1, &fds, NULL, NULL, &tv);
+          if (ret < 0 && errno != EINTR)
+            {
+              g_warning ("Unexpected error in select() while reading from child process (%d): %s", test_trap_last_pid, g_strerror (errno));
+              break;
+            }
+          if (stdout_pipe[0] >= 0 && FD_ISSET (stdout_pipe[0], &fds) &&
+              g_string_must_read (sout, stdout_pipe[0]) == 0)
+            {
+              close (stdout_pipe[0]);
+              stdout_pipe[0] = -1;
+            }
+          if (stderr_pipe[0] >= 0 && FD_ISSET (stderr_pipe[0], &fds) &&
+              g_string_must_read (serr, stderr_pipe[0]) == 0)
+            {
+              close (stderr_pipe[0]);
+              stderr_pipe[0] = -1;
+            }
+          if (stdtst_pipe[0] >= 0 && FD_ISSET (stdtst_pipe[0], &fds))
+            {
+              guint8 buffer[4096];
+              gint l, r = read (stdtst_pipe[0], buffer, sizeof (buffer));
+              if (r > 0 && test_log_fd > 0)
+                do
+                  l = write (pass_on_forked_log ? test_log_fd : -1, buffer, r);
+                while (l < 0 && errno == EINTR);
+              if (r == 0 || (r < 0 && errno != EINTR && errno != EAGAIN))
+                {
+                  close (stdtst_pipe[0]);
+                  stdtst_pipe[0] = -1;
+                }
+            }
+          if (!(test_trap_flags & G_TEST_TRAP_SILENCE_STDOUT))
+            g_string_write_out (sout, 1, &soutpos);
+          if (!(test_trap_flags & G_TEST_TRAP_SILENCE_STDERR))
+            g_string_write_out (serr, 2, &serrpos);
+          if (usec_timeout)
+            {
+              guint64 nstamp = test_time_stamp();
+              int status = 0;
+              sstamp = MIN (sstamp, nstamp); /* guard against backwards clock skews */
+              if (usec_timeout < nstamp - sstamp)
+                {
+                  /* timeout reached, need to abort the child now */
+                  kill_child (test_trap_last_pid, &status, 3);
+                  test_trap_last_status = 1024; /* timeout */
+                  if (0 && WIFSIGNALED (status))
+                    g_printerr ("%s: child timed out and received: %s\n", G_STRFUNC, g_strsignal (WTERMSIG (status)));
+                  need_wait = FALSE;
+                  break;
+                }
+            }
+        }
+      close (stdout_pipe[0]);
+      close (stderr_pipe[0]);
+      close (stdtst_pipe[0]);
+      if (need_wait)
+        {
+          int status = 0;
+          do
+            wr = waitpid (test_trap_last_pid, &status, 0);
+          while (wr < 0 && errno == EINTR);
+          if (WIFEXITED (status)) /* normal exit */
+            test_trap_last_status = WEXITSTATUS (status); /* 0..255 */
+          else if (WIFSIGNALED (status))
+            test_trap_last_status = (WTERMSIG (status) << 12); /* signalled */
+          else /* WCOREDUMP (status) */
+            test_trap_last_status = 512; /* coredump */
+        }
+      test_trap_last_stdout = g_string_free (sout, FALSE);
+      test_trap_last_stderr = g_string_free (serr, FALSE);
+      return FALSE;
+    }
+#else
+  g_message ("Not implemented: g_test_trap_fork");
+
+  return FALSE;
+#endif
+}
+
+/**
+ * g_test_trap_has_passed:
+ *
+ * Check the result of the last g_test_trap_fork() call.
+ *
+ * Returns: %TRUE if the last forked child terminated successfully.
+ *
+ * Since: 2.16
+ */
+gboolean
+g_test_trap_has_passed (void)
+{
+  return test_trap_last_status == 0; /* exit_status == 0 && !signal && !coredump */
+}
+
+/**
+ * g_test_trap_reached_timeout:
+ *
+ * Check the result of the last g_test_trap_fork() call.
+ *
+ * Returns: %TRUE if the last forked child got killed due to a fork timeout.
+ *
+ * Since: 2.16
+ */
+gboolean
+g_test_trap_reached_timeout (void)
+{
+  return 0 != (test_trap_last_status & 1024); /* timeout flag */
+}
+
+void
+g_test_trap_assertions (const char     *domain,
+                        const char     *file,
+                        int             line,
+                        const char     *func,
+                        guint64         assertion_flags, /* 0-pass, 1-fail, 2-outpattern, 4-errpattern */
+                        const char     *pattern)
+{
+#ifdef G_OS_UNIX
+  gboolean must_pass = assertion_flags == 0;
+  gboolean must_fail = assertion_flags == 1;
+  gboolean match_result = 0 == (assertion_flags & 1);
+  const char *stdout_pattern = (assertion_flags & 2) ? pattern : NULL;
+  const char *stderr_pattern = (assertion_flags & 4) ? pattern : NULL;
+  const char *match_error = match_result ? "failed to match" : "contains invalid match";
+  if (test_trap_last_pid == 0)
+    g_error ("child process failed to exit after g_test_trap_fork() and before g_test_trap_assert*()");
+  if (must_pass && !g_test_trap_has_passed())
+    {
+      char *msg = g_strdup_printf ("child process (%d) of test trap failed unexpectedly", test_trap_last_pid);
+      g_assertion_message (domain, file, line, func, msg);
+      g_free (msg);
+    }
+  if (must_fail && g_test_trap_has_passed())
+    {
+      char *msg = g_strdup_printf ("child process (%d) did not fail as expected", test_trap_last_pid);
+      g_assertion_message (domain, file, line, func, msg);
+      g_free (msg);
+    }
+  if (stdout_pattern && match_result == !g_pattern_match_simple (stdout_pattern, test_trap_last_stdout))
+    {
+      char *msg = g_strdup_printf ("stdout of child process (%d) %s: %s", test_trap_last_pid, match_error, stdout_pattern);
+      g_assertion_message (domain, file, line, func, msg);
+      g_free (msg);
+    }
+  if (stderr_pattern && match_result == !g_pattern_match_simple (stderr_pattern, test_trap_last_stderr))
+    {
+      char *msg = g_strdup_printf ("stderr of child process (%d) %s: %s", test_trap_last_pid, match_error, stderr_pattern);
+      g_assertion_message (domain, file, line, func, msg);
+      g_free (msg);
+    }
+#endif
+}
+
+static void
+gstring_overwrite_int (GString *gstring,
+                       guint    pos,
+                       guint32  vuint)
+{
+  vuint = g_htonl (vuint);
+  g_string_overwrite_len (gstring, pos, (const gchar*) &vuint, 4);
+}
+
+static void
+gstring_append_int (GString *gstring,
+                    guint32  vuint)
+{
+  vuint = g_htonl (vuint);
+  g_string_append_len (gstring, (const gchar*) &vuint, 4);
+}
+
+static void
+gstring_append_double (GString *gstring,
+                       double   vdouble)
+{
+  union { double vdouble; guint64 vuint64; } u;
+  u.vdouble = vdouble;
+  u.vuint64 = GUINT64_TO_BE (u.vuint64);
+  g_string_append_len (gstring, (const gchar*) &u.vuint64, 8);
+}
+
+static guint8*
+g_test_log_dump (GTestLogMsg *msg,
+                 guint       *len)
+{
+  GString *gstring = g_string_sized_new (1024);
+  guint ui;
+  gstring_append_int (gstring, 0);              /* message length */
+  gstring_append_int (gstring, msg->log_type);
+  gstring_append_int (gstring, msg->n_strings);
+  gstring_append_int (gstring, msg->n_nums);
+  gstring_append_int (gstring, 0);      /* reserved */
+  for (ui = 0; ui < msg->n_strings; ui++)
+    {
+      guint l = strlen (msg->strings[ui]);
+      gstring_append_int (gstring, l);
+      g_string_append_len (gstring, msg->strings[ui], l);
+    }
+  for (ui = 0; ui < msg->n_nums; ui++)
+    gstring_append_double (gstring, msg->nums[ui]);
+  *len = gstring->len;
+  gstring_overwrite_int (gstring, 0, *len);     /* message length */
+  return (guint8*) g_string_free (gstring, FALSE);
+}
+
+static inline long double
+net_double (const gchar **ipointer)
+{
+  union { guint64 vuint64; double vdouble; } u;
+  guint64 aligned_int64;
+  memcpy (&aligned_int64, *ipointer, 8);
+  *ipointer += 8;
+  u.vuint64 = GUINT64_FROM_BE (aligned_int64);
+  return u.vdouble;
+}
+
+static inline guint32
+net_int (const gchar **ipointer)
+{
+  guint32 aligned_int;
+  memcpy (&aligned_int, *ipointer, 4);
+  *ipointer += 4;
+  return g_ntohl (aligned_int);
+}
+
+static gboolean
+g_test_log_extract (GTestLogBuffer *tbuffer)
+{
+  const gchar *p = tbuffer->data->str;
+  GTestLogMsg msg;
+  guint mlength;
+  if (tbuffer->data->len < 4 * 5)
+    return FALSE;
+  mlength = net_int (&p);
+  if (tbuffer->data->len < mlength)
+    return FALSE;
+  msg.log_type = net_int (&p);
+  msg.n_strings = net_int (&p);
+  msg.n_nums = net_int (&p);
+  if (net_int (&p) == 0)
+    {
+      guint ui;
+      msg.strings = g_new0 (gchar*, msg.n_strings + 1);
+      msg.nums = g_new0 (long double, msg.n_nums);
+      for (ui = 0; ui < msg.n_strings; ui++)
+        {
+          guint sl = net_int (&p);
+          msg.strings[ui] = g_strndup (p, sl);
+          p += sl;
+        }
+      for (ui = 0; ui < msg.n_nums; ui++)
+        msg.nums[ui] = net_double (&p);
+      if (p <= tbuffer->data->str + mlength)
+        {
+          g_string_erase (tbuffer->data, 0, mlength);
+          tbuffer->msgs = g_slist_prepend (tbuffer->msgs, g_memdup (&msg, sizeof (msg)));
+          return TRUE;
+        }
+    }
+  g_free (msg.nums);
+  g_strfreev (msg.strings);
+  g_error ("corrupt log stream from test program");
+  return FALSE;
+}
+
+/**
+ * g_test_log_buffer_new:
+ *
+ * Internal function for gtester to decode test log messages, no ABI guarantees provided.
+ */
+GTestLogBuffer*
+g_test_log_buffer_new (void)
+{
+  GTestLogBuffer *tb = g_new0 (GTestLogBuffer, 1);
+  tb->data = g_string_sized_new (1024);
+  return tb;
+}
+
+/**
+ * g_test_log_buffer_free
+ *
+ * Internal function for gtester to free test log messages, no ABI guarantees provided.
+ */
+void
+g_test_log_buffer_free (GTestLogBuffer *tbuffer)
+{
+  g_return_if_fail (tbuffer != NULL);
+  while (tbuffer->msgs)
+    g_test_log_msg_free (g_test_log_buffer_pop (tbuffer));
+  g_string_free (tbuffer->data, TRUE);
+  g_free (tbuffer);
+}
+
+/**
+ * g_test_log_buffer_push
+ *
+ * Internal function for gtester to decode test log messages, no ABI guarantees provided.
+ */
+void
+g_test_log_buffer_push (GTestLogBuffer *tbuffer,
+                        guint           n_bytes,
+                        const guint8   *bytes)
+{
+  g_return_if_fail (tbuffer != NULL);
+  if (n_bytes)
+    {
+      gboolean more_messages;
+      g_return_if_fail (bytes != NULL);
+      g_string_append_len (tbuffer->data, (const gchar*) bytes, n_bytes);
+      do
+        more_messages = g_test_log_extract (tbuffer);
+      while (more_messages);
+    }
+}
+
+/**
+ * g_test_log_buffer_pop:
+ *
+ * Internal function for gtester to retrieve test log messages, no ABI guarantees provided.
+ */
+GTestLogMsg*
+g_test_log_buffer_pop (GTestLogBuffer *tbuffer)
+{
+  GTestLogMsg *msg = NULL;
+  g_return_val_if_fail (tbuffer != NULL, NULL);
+  if (tbuffer->msgs)
+    {
+      GSList *slist = g_slist_last (tbuffer->msgs);
+      msg = slist->data;
+      tbuffer->msgs = g_slist_delete_link (tbuffer->msgs, slist);
+    }
+  return msg;
+}
+
+/**
+ * g_test_log_msg_free:
+ *
+ * Internal function for gtester to free test log messages, no ABI guarantees provided.
+ */
+void
+g_test_log_msg_free (GTestLogMsg *tmsg)
+{
+  g_return_if_fail (tmsg != NULL);
+  g_strfreev (tmsg->strings);
+  g_free (tmsg->nums);
+  g_free (tmsg);
+}
+
+/* --- macros docs START --- */
+/**
+ * g_test_add:
+ * @testpath:  The test path for a new test case.
+ * @Fixture:   The type of a fixture data structure.
+ * @tdata:     Data argument for the test functions.
+ * @fsetup:    The function to set up the fixture data.
+ * @ftest:     The actual test function.
+ * @fteardown: The function to tear down the fixture data.
+ *
+ * Hook up a new test case at @testpath, similar to g_test_add_func().
+ * A fixture data structure with setup and teardown function may be provided
+ * though, similar to g_test_create_case().
+ * g_test_add() is implemented as a macro, so that the fsetup(), ftest() and
+ * fteardown() callbacks can expect a @Fixture pointer as first argument in
+ * a type safe manner.
+ *
+ * Since: 2.16
+ **/
+/* --- macros docs END --- */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gtestutils.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gtestutils.h
new file mode 100644 (file)
index 0000000..b441fe0
--- /dev/null
@@ -0,0 +1,297 @@
+/* GLib testing utilities
+ * Copyright (C) 2007 Imendio AB
+ * Authors: Tim Janik
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_TEST_UTILS_H__
+#define __G_TEST_UTILS_H__
+
+#include <glib/gmessages.h>
+#include <glib/gstring.h>
+#include <glib/gerror.h>
+#include <glib/gslist.h>
+
+G_BEGIN_DECLS
+
+typedef struct GTestCase  GTestCase;
+typedef struct GTestSuite GTestSuite;
+typedef void (*GTestFunc)        (void);
+typedef void (*GTestDataFunc)    (gconstpointer user_data);
+typedef void (*GTestFixtureFunc) (gpointer      fixture,
+                                  gconstpointer user_data);
+
+/* assertion API */
+#define g_assert_cmpstr(s1, cmp, s2)    do { const char *__s1 = (s1), *__s2 = (s2); \
+                                             if (g_strcmp0 (__s1, __s2) cmp 0) ; else \
+                                               g_assertion_message_cmpstr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+                                                 #s1 " " #cmp " " #s2, __s1, #cmp, __s2); } while (0)
+#define g_assert_cmpint(n1, cmp, n2)    do { gint64 __n1 = (n1), __n2 = (n2); \
+                                             if (__n1 cmp __n2) ; else \
+                                               g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+                                                 #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); } while (0)
+#define g_assert_cmpuint(n1, cmp, n2)   do { guint64 __n1 = (n1), __n2 = (n2); \
+                                             if (__n1 cmp __n2) ; else \
+                                               g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+                                                 #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'i'); } while (0)
+#define g_assert_cmphex(n1, cmp, n2)    do { guint64 __n1 = (n1), __n2 = (n2); \
+                                             if (__n1 cmp __n2) ; else \
+                                               g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+                                                 #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'x'); } while (0)
+#define g_assert_cmpfloat(n1,cmp,n2)    do { long double __n1 = (n1), __n2 = (n2); \
+                                             if (__n1 cmp __n2) ; else \
+                                               g_assertion_message_cmpnum (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+                                                 #n1 " " #cmp " " #n2, __n1, #cmp, __n2, 'f'); } while (0)
+#define g_assert_no_error(err)          do { if (err) \
+                                               g_assertion_message_error (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+                                                 #err, err, 0, 0); } while (0)
+#define g_assert_error(err, dom, c)    do { if (!err || (err)->domain != dom || (err)->code != c) \
+                                               g_assertion_message_error (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+                                                 #err, err, dom, c); } while (0)
+#ifdef G_DISABLE_ASSERT
+#define g_assert_not_reached()          do { (void) 0; } while (0)
+#define g_assert(expr)                  do { (void) 0; } while (0)
+#else /* !G_DISABLE_ASSERT */
+#define g_assert_not_reached()          do { g_assertion_message (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, NULL); } while (0)
+#define g_assert(expr)                  do { if G_LIKELY (expr) ; else \
+                                               g_assertion_message_expr (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, \
+                                                 #expr); } while (0)
+#endif /* !G_DISABLE_ASSERT */
+
+int     g_strcmp0                       (const char     *str1,
+                                         const char     *str2);
+
+/* report performance results */
+void    g_test_minimized_result         (double          minimized_quantity,
+                                         const char     *format,
+                                         ...) G_GNUC_PRINTF (2, 3);
+void    g_test_maximized_result         (double          maximized_quantity,
+                                         const char     *format,
+                                         ...) G_GNUC_PRINTF (2, 3);
+
+/* initialize testing framework */
+void    g_test_init                     (int            *argc,
+                                         char         ***argv,
+                                         ...);
+/* query testing framework config */
+#define g_test_quick()                  (g_test_config_vars->test_quick)
+#define g_test_slow()                   (!g_test_config_vars->test_quick)
+#define g_test_thorough()               (!g_test_config_vars->test_quick)
+#define g_test_perf()                   (g_test_config_vars->test_perf)
+#define g_test_verbose()                (g_test_config_vars->test_verbose)
+#define g_test_quiet()                  (g_test_config_vars->test_quiet)
+/* run all tests under toplevel suite (path: /) */
+int     g_test_run                      (void);
+/* hook up a test functions under test path */
+void    g_test_add_func                 (const char     *testpath,
+                                         GTestFunc       test_func);
+
+void    g_test_add_data_func            (const char     *testpath,
+                                         gconstpointer   test_data,
+                                         GTestDataFunc   test_func);
+
+/* hook up a test with fixture under test path */
+#define g_test_add(testpath, Fixture, tdata, fsetup, ftest, fteardown) \
+                                       G_STMT_START {                  \
+                                         void (*add_vtable) (const char*,       \
+                                                    gsize,             \
+                                                    gconstpointer,     \
+                                                    void (*) (Fixture*, gconstpointer),   \
+                                                    void (*) (Fixture*, gconstpointer),   \
+                                                    void (*) (Fixture*, gconstpointer)) =  (void (*) (const gchar *, gsize, gconstpointer, void (*) (Fixture*, gconstpointer), void (*) (Fixture*, gconstpointer), void (*) (Fixture*, gconstpointer))) g_test_add_vtable; \
+                                         add_vtable \
+                                          (testpath, sizeof (Fixture), tdata, fsetup, ftest, fteardown); \
+                                       } G_STMT_END
+
+/* add test messages to the test report */
+void    g_test_message                  (const char *format,
+                                         ...) G_GNUC_PRINTF (1, 2);
+void    g_test_bug_base                 (const char *uri_pattern);
+void    g_test_bug                      (const char *bug_uri_snippet);
+/* measure test timings */
+void    g_test_timer_start              (void);
+double  g_test_timer_elapsed            (void); /* elapsed seconds */
+double  g_test_timer_last               (void); /* repeat last elapsed() result */
+
+/* automatically g_free or g_object_unref upon teardown */
+void    g_test_queue_free               (gpointer gfree_pointer);
+void    g_test_queue_destroy            (GDestroyNotify destroy_func,
+                                         gpointer       destroy_data);
+#define g_test_queue_unref(gobject)     g_test_queue_destroy (g_object_unref, gobject)
+
+/* test traps are guards used around forked tests */
+typedef enum {
+  G_TEST_TRAP_SILENCE_STDOUT    = 1 << 7,
+  G_TEST_TRAP_SILENCE_STDERR    = 1 << 8,
+  G_TEST_TRAP_INHERIT_STDIN     = 1 << 9
+} GTestTrapFlags;
+gboolean g_test_trap_fork               (guint64              usec_timeout,
+                                         GTestTrapFlags       test_trap_flags);
+gboolean g_test_trap_has_passed         (void);
+gboolean g_test_trap_reached_timeout    (void);
+#define  g_test_trap_assert_passed()                      g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 0, 0)
+#define  g_test_trap_assert_failed()                      g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 1, 0)
+#define  g_test_trap_assert_stdout(soutpattern)           g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 2, soutpattern)
+#define  g_test_trap_assert_stdout_unmatched(soutpattern) g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 3, soutpattern)
+#define  g_test_trap_assert_stderr(serrpattern)           g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 4, serrpattern)
+#define  g_test_trap_assert_stderr_unmatched(serrpattern) g_test_trap_assertions (G_LOG_DOMAIN, __FILE__, __LINE__, G_STRFUNC, 5, serrpattern)
+
+/* provide seed-able random numbers for tests */
+#define  g_test_rand_bit()              (0 != (g_test_rand_int() & (1 << 15)))
+gint32   g_test_rand_int                (void);
+gint32   g_test_rand_int_range          (gint32          begin,
+                                         gint32          end);
+double   g_test_rand_double             (void);
+double   g_test_rand_double_range       (double          range_start,
+                                         double          range_end);
+
+/* semi-internal API */
+GTestCase*    g_test_create_case        (const char       *test_name,
+                                         gsize             data_size,
+                                         gconstpointer     test_data,
+                                         GTestFixtureFunc  data_setup,
+                                         GTestFixtureFunc  data_test,
+                                         GTestFixtureFunc  data_teardown);
+GTestSuite*   g_test_create_suite       (const char       *suite_name);
+GTestSuite*   g_test_get_root           (void);
+void          g_test_suite_add          (GTestSuite     *suite,
+                                         GTestCase      *test_case);
+void          g_test_suite_add_suite    (GTestSuite     *suite,
+                                         GTestSuite     *nestedsuite);
+int           g_test_run_suite          (GTestSuite     *suite);
+
+/* internal ABI */
+void    g_test_trap_assertions          (const char     *domain,
+                                         const char     *file,
+                                         int             line,
+                                         const char     *func,
+                                         guint64         assertion_flags, /* 0-pass, 1-fail, 2-outpattern, 4-errpattern */
+                                         const char     *pattern);
+void    g_assertion_message             (const char     *domain,
+                                         const char     *file,
+                                         int             line,
+                                         const char     *func,
+                                         const char     *message) G_GNUC_NORETURN;
+void    g_assertion_message_expr        (const char     *domain,
+                                         const char     *file,
+                                         int             line,
+                                         const char     *func,
+                                         const char     *expr) G_GNUC_NORETURN;
+void    g_assertion_message_cmpstr      (const char     *domain,
+                                         const char     *file,
+                                         int             line,
+                                         const char     *func,
+                                         const char     *expr,
+                                         const char     *arg1,
+                                         const char     *cmp,
+                                         const char     *arg2) G_GNUC_NORETURN;
+void    g_assertion_message_cmpnum      (const char     *domain,
+                                         const char     *file,
+                                         int             line,
+                                         const char     *func,
+                                         const char     *expr,
+                                         long double     arg1,
+                                         const char     *cmp,
+                                         long double     arg2,
+                                         char            numtype) G_GNUC_NORETURN;
+void    g_assertion_message_error       (const char     *domain,
+                                         const char     *file,
+                                         int             line,
+                                         const char     *func,
+                                         const char     *expr,
+                                         const GError   *error,
+                                         GQuark          error_domain,
+                                         int             error_code) G_GNUC_NORETURN;
+void    g_test_add_vtable               (const char     *testpath,
+                                         gsize           data_size,
+                                         gconstpointer   test_data,
+                                         GTestFixtureFunc  data_setup,
+                                         GTestFixtureFunc  data_test,
+                                         GTestFixtureFunc  data_teardown);
+typedef struct {
+  gboolean      test_initialized;
+  gboolean      test_quick;     /* disable thorough tests */
+  gboolean      test_perf;      /* run performance tests */
+  gboolean      test_verbose;   /* extra info */
+  gboolean      test_quiet;     /* reduce output */
+} GTestConfig;
+GLIB_VAR const GTestConfig * const g_test_config_vars;
+
+/* internal logging API */
+typedef enum {
+  G_TEST_LOG_NONE,
+  G_TEST_LOG_ERROR,             /* s:msg */
+  G_TEST_LOG_START_BINARY,      /* s:binaryname s:seed */
+  G_TEST_LOG_LIST_CASE,         /* s:testpath */
+  G_TEST_LOG_SKIP_CASE,         /* s:testpath */
+  G_TEST_LOG_START_CASE,        /* s:testpath */
+  G_TEST_LOG_STOP_CASE,         /* d:status d:nforks d:elapsed */
+  G_TEST_LOG_MIN_RESULT,        /* s:blurb d:result */
+  G_TEST_LOG_MAX_RESULT,        /* s:blurb d:result */
+  G_TEST_LOG_MESSAGE            /* s:blurb */
+} GTestLogType;
+
+typedef struct {
+  GTestLogType  log_type;
+  guint         n_strings;
+  gchar       **strings; /* NULL terminated */
+  guint         n_nums;
+  long double  *nums;
+} GTestLogMsg;
+typedef struct {
+  /*< private >*/
+  GString     *data;
+  GSList      *msgs;
+} GTestLogBuffer;
+
+const char*     g_test_log_type_name    (GTestLogType    log_type);
+GTestLogBuffer* g_test_log_buffer_new   (void);
+void            g_test_log_buffer_free  (GTestLogBuffer *tbuffer);
+void            g_test_log_buffer_push  (GTestLogBuffer *tbuffer,
+                                         guint           n_bytes,
+                                         const guint8   *bytes);
+GTestLogMsg*    g_test_log_buffer_pop   (GTestLogBuffer *tbuffer);
+void            g_test_log_msg_free     (GTestLogMsg    *tmsg);
+
+/**
+ * GTestLogFatalFunc:
+ * @log_domain: the log domain of the message
+ * @log_level: the log level of the message (including the fatal and recursion flags)
+ * @message: the message to process
+ * @user_data: user data, set in g_test_log_set_fatal_handler()
+ *
+ * Specifies the prototype of fatal log handler functions.
+ *
+ * Return value: %TRUE if the program should abort, %FALSE otherwise
+ *
+ * Since: 2.22
+ */
+typedef gboolean        (*GTestLogFatalFunc)    (const gchar    *log_domain,
+                                                 GLogLevelFlags  log_level,
+                                                 const gchar    *message,
+                                                 gpointer        user_data);
+void
+g_test_log_set_fatal_handler            (GTestLogFatalFunc log_func,
+                                         gpointer          user_data);
+
+G_END_DECLS
+
+#endif /* __G_TEST_UTILS_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gthread.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gthread.c
new file mode 100644 (file)
index 0000000..2a00c60
--- /dev/null
@@ -0,0 +1,2538 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gthread.c: MT safety related functions
+ * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
+ *                Owen Taylor
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/* Prelude {{{1 ----------------------------------------------------------- */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+/* implement gthread.h's inline functions */
+#define G_IMPLEMENT_INLINES 1
+#define __G_THREAD_C__
+
+#include "config.h"
+
+#include "gthread.h"
+#include "gthreadprivate.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+
+#ifndef G_OS_WIN32
+#include <sys/time.h>
+#include <time.h>
+#else
+#include <windows.h>
+#endif /* G_OS_WIN32 */
+
+#include <string.h>
+
+#include "garray.h"
+#include "gslist.h"
+#include "gtestutils.h"
+#include "gtimer.h"
+
+
+/**
+ * SECTION: threads
+ * @title: Threads
+ * @short_description: thread abstraction; including threads, different
+ *                     mutexes, conditions and thread private data
+ * @see_also: #GThreadPool, #GAsyncQueue
+ *
+ * Threads act almost like processes, but unlike processes all threads
+ * of one process share the same memory. This is good, as it provides
+ * easy communication between the involved threads via this shared
+ * memory, and it is bad, because strange things (so called
+ * "Heisenbugs") might happen if the program is not carefully designed.
+ * In particular, due to the concurrent nature of threads, no
+ * assumptions on the order of execution of code running in different
+ * threads can be made, unless order is explicitly forced by the
+ * programmer through synchronization primitives.
+ *
+ * The aim of the thread related functions in GLib is to provide a
+ * portable means for writing multi-threaded software. There are
+ * primitives for mutexes to protect the access to portions of memory
+ * (#GMutex, #GStaticMutex, #G_LOCK_DEFINE, #GStaticRecMutex and
+ * #GStaticRWLock). There are primitives for condition variables to
+ * allow synchronization of threads (#GCond).  There are primitives for
+ * thread-private data - data that every thread has a private instance
+ * of (#GPrivate, #GStaticPrivate). Last but definitely not least there
+ * are primitives to portably create and manage threads (#GThread).
+ *
+ * The threading system is initialized with g_thread_init(), which
+ * takes an optional custom thread implementation or %NULL for the
+ * default implementation. If you want to call g_thread_init() with a
+ * non-%NULL argument this must be done before executing any other GLib
+ * functions (except g_mem_set_vtable()). This is a requirement even if
+ * no threads are in fact ever created by the process.
+ *
+ * Calling g_thread_init() with a %NULL argument is somewhat more
+ * relaxed. You may call any other glib functions in the main thread
+ * before g_thread_init() as long as g_thread_init() is not called from
+ * a glib callback, or with any locks held. However, many libraries
+ * above glib does not support late initialization of threads, so doing
+ * this should be avoided if possible.
+ *
+ * Please note that since version 2.24 the GObject initialization
+ * function g_type_init() initializes threads (with a %NULL argument),
+ * so most applications, including those using Gtk+ will run with
+ * threads enabled. If you want a special thread implementation, make
+ * sure you call g_thread_init() before g_type_init() is called.
+ *
+ * After calling g_thread_init(), GLib is completely thread safe (all
+ * global data is automatically locked), but individual data structure
+ * instances are not automatically locked for performance reasons. So,
+ * for example you must coordinate accesses to the same #GHashTable
+ * from multiple threads.  The two notable exceptions from this rule
+ * are #GMainLoop and #GAsyncQueue, which <emphasis>are</emphasis>
+ * threadsafe and need no further application-level locking to be
+ * accessed from multiple threads.
+ *
+ * To help debugging problems in multithreaded applications, GLib
+ * supports error-checking mutexes that will give you helpful error
+ * messages on common problems. To use error-checking mutexes, define
+ * the symbol #G_ERRORCHECK_MUTEXES when compiling the application.
+ **/
+
+/**
+ * G_THREADS_IMPL_POSIX:
+ *
+ * This macro is defined if POSIX style threads are used.
+ **/
+
+/**
+ * G_THREADS_ENABLED:
+ *
+ * This macro is defined if GLib was compiled with thread support. This
+ * does not necessarily mean that there is a thread implementation
+ * available, but it does mean that the infrastructure is in place and
+ * that once you provide a thread implementation to g_thread_init(),
+ * GLib will be multi-thread safe. If #G_THREADS_ENABLED is not
+ * defined, then Glib is not, and cannot be, multi-thread safe.
+ **/
+
+/**
+ * G_THREADS_IMPL_NONE:
+ *
+ * This macro is defined if no thread implementation is used. You can,
+ * however, provide one to g_thread_init() to make GLib multi-thread
+ * safe.
+ **/
+
+/* G_LOCK Documentation {{{1 ---------------------------------------------- */
+
+/* IMPLEMENTATION NOTE:
+ *
+ * G_LOCK_DEFINE and friends are convenience macros defined in
+ * gthread.h.  Their documentation lives here.
+ */
+
+/**
+ * G_LOCK_DEFINE:
+ * @name: the name of the lock.
+ *
+ * The %G_LOCK_* macros provide a convenient interface to #GStaticMutex
+ * with the advantage that they will expand to nothing in programs
+ * compiled against a thread-disabled GLib, saving code and memory
+ * there. #G_LOCK_DEFINE defines a lock. It can appear anywhere
+ * variable definitions may appear in programs, i.e. in the first block
+ * of a function or outside of functions. The @name parameter will be
+ * mangled to get the name of the #GStaticMutex. This means that you
+ * can use names of existing variables as the parameter - e.g. the name
+ * of the variable you intent to protect with the lock. Look at our
+ * <function>give_me_next_number()</function> example using the
+ * %G_LOCK_* macros:
+ *
+ * <example>
+ *  <title>Using the %G_LOCK_* convenience macros</title>
+ *  <programlisting>
+ *   G_LOCK_DEFINE (current_number);
+ *
+ *   int
+ *   give_me_next_number (void)
+ *   {
+ *     static int current_number = 0;
+ *     int ret_val;
+ *
+ *     G_LOCK (current_number);
+ *     ret_val = current_number = calc_next_number (current_number);
+ *     G_UNLOCK (current_number);
+ *
+ *     return ret_val;
+ *   }
+ *  </programlisting>
+ * </example>
+ **/
+
+/**
+ * G_LOCK_DEFINE_STATIC:
+ * @name: the name of the lock.
+ *
+ * This works like #G_LOCK_DEFINE, but it creates a static object.
+ **/
+
+/**
+ * G_LOCK_EXTERN:
+ * @name: the name of the lock.
+ *
+ * This declares a lock, that is defined with #G_LOCK_DEFINE in another
+ * module.
+ **/
+
+/**
+ * G_LOCK:
+ * @name: the name of the lock.
+ *
+ * Works like g_mutex_lock(), but for a lock defined with
+ * #G_LOCK_DEFINE.
+ **/
+
+/**
+ * G_TRYLOCK:
+ * @name: the name of the lock.
+ * @Returns: %TRUE, if the lock could be locked.
+ *
+ * Works like g_mutex_trylock(), but for a lock defined with
+ * #G_LOCK_DEFINE.
+ **/
+
+/**
+ * G_UNLOCK:
+ * @name: the name of the lock.
+ *
+ * Works like g_mutex_unlock(), but for a lock defined with
+ * #G_LOCK_DEFINE.
+ **/
+
+/* GThreadError {{{1 ------------------------------------------------------- */
+/**
+ * GThreadError:
+ * @G_THREAD_ERROR_AGAIN: a thread couldn't be created due to resource
+ *                        shortage. Try again later.
+ *
+ * Possible errors of thread related functions.
+ **/
+
+/**
+ * G_THREAD_ERROR:
+ *
+ * The error domain of the GLib thread subsystem.
+ **/
+GQuark
+g_thread_error_quark (void)
+{
+  return g_quark_from_static_string ("g_thread_error");
+}
+
+/* Miscellaneous Structures {{{1 ------------------------------------------ */
+/* Keep this in sync with GRealThread in gmain.c! */
+typedef struct _GRealThread GRealThread;
+struct  _GRealThread
+{
+  GThread thread;
+  gpointer private_data;
+  GRealThread *next;
+  gpointer retval;
+  GSystemThread system_thread;
+};
+
+typedef struct _GStaticPrivateNode GStaticPrivateNode;
+struct _GStaticPrivateNode
+{
+  gpointer       data;
+  GDestroyNotify destroy;
+};
+
+static void    g_thread_cleanup (gpointer data);
+static void    g_thread_fail (void);
+static guint64 gettime (void);
+
+guint64        (*g_thread_gettime) (void) = gettime;
+
+/* Global Variables {{{1 -------------------------------------------------- */
+
+static GSystemThread zero_thread; /* This is initialized to all zero */
+gboolean g_thread_use_default_impl = TRUE;
+
+/**
+ * g_thread_supported:
+ * @Returns: %TRUE, if the thread system is initialized.
+ *
+ * This function returns %TRUE if the thread system is initialized, and
+ * %FALSE if it is not.
+ *
+ * <note><para>This function is actually a macro. Apart from taking the
+ * address of it you can however use it as if it was a
+ * function.</para></note>
+ **/
+
+/* IMPLEMENTATION NOTE:
+ *
+ * g_thread_supported() is just returns g_threads_got_initialized
+ */
+gboolean g_threads_got_initialized = FALSE;
+
+
+/* Thread Implementation Virtual Function Table {{{1 ---------------------- */
+/* Virtual Function Table Documentation {{{2 ------------------------------ */
+/**
+ * GThreadFunctions:
+ * @mutex_new: virtual function pointer for g_mutex_new()
+ * @mutex_lock: virtual function pointer for g_mutex_lock()
+ * @mutex_trylock: virtual function pointer for g_mutex_trylock()
+ * @mutex_unlock: virtual function pointer for g_mutex_unlock()
+ * @mutex_free: virtual function pointer for g_mutex_free()
+ * @cond_new: virtual function pointer for g_cond_new()
+ * @cond_signal: virtual function pointer for g_cond_signal()
+ * @cond_broadcast: virtual function pointer for g_cond_broadcast()
+ * @cond_wait: virtual function pointer for g_cond_wait()
+ * @cond_timed_wait: virtual function pointer for g_cond_timed_wait()
+ * @cond_free: virtual function pointer for g_cond_free()
+ * @private_new: virtual function pointer for g_private_new()
+ * @private_get: virtual function pointer for g_private_get()
+ * @private_set: virtual function pointer for g_private_set()
+ * @thread_create: virtual function pointer for g_thread_create()
+ * @thread_yield: virtual function pointer for g_thread_yield()
+ * @thread_join: virtual function pointer for g_thread_join()
+ * @thread_exit: virtual function pointer for g_thread_exit()
+ * @thread_set_priority: virtual function pointer for
+ *                       g_thread_set_priority()
+ * @thread_self: virtual function pointer for g_thread_self()
+ * @thread_equal: used internally by recursive mutex locks and by some
+ *                assertion checks
+ *
+ * This function table is used by g_thread_init() to initialize the
+ * thread system. The functions in the table are directly used by their
+ * g_* prepended counterparts (described in this document).  For
+ * example, if you call g_mutex_new() then mutex_new() from the table
+ * provided to g_thread_init() will be called.
+ *
+ * <note><para>Do not use this struct unless you know what you are
+ * doing.</para></note>
+ **/
+
+/* IMPLEMENTATION NOTE:
+ *
+ * g_thread_functions_for_glib_use is a global symbol that gets used by
+ * most of the "primative" threading calls.  g_mutex_lock(), for
+ * example, is just a macro that calls the appropriate virtual function
+ * out of this table.
+ *
+ * For that reason, all of those macros are documented here.
+ */
+GThreadFunctions g_thread_functions_for_glib_use = {
+/* GMutex Virtual Functions {{{2 ------------------------------------------ */
+
+/**
+ * GMutex:
+ *
+ * The #GMutex struct is an opaque data structure to represent a mutex
+ * (mutual exclusion). It can be used to protect data against shared
+ * access. Take for example the following function:
+ *
+ * <example>
+ *  <title>A function which will not work in a threaded environment</title>
+ *  <programlisting>
+ *   int
+ *   give_me_next_number (void)
+ *   {
+ *     static int current_number = 0;
+ *
+ *     /<!-- -->* now do a very complicated calculation to calculate the new
+ *      * number, this might for example be a random number generator
+ *      *<!-- -->/
+ *     current_number = calc_next_number (current_number);
+ *
+ *     return current_number;
+ *   }
+ *  </programlisting>
+ * </example>
+ *
+ * It is easy to see that this won't work in a multi-threaded
+ * application. There current_number must be protected against shared
+ * access. A first naive implementation would be:
+ *
+ * <example>
+ *  <title>The wrong way to write a thread-safe function</title>
+ *  <programlisting>
+ *   int
+ *   give_me_next_number (void)
+ *   {
+ *     static int current_number = 0;
+ *     int ret_val;
+ *     static GMutex * mutex = NULL;
+ *
+ *     if (!mutex) mutex = g_mutex_new (<!-- -->);
+ *
+ *     g_mutex_lock (mutex);
+ *     ret_val = current_number = calc_next_number (current_number);
+ *     g_mutex_unlock (mutex);
+ *
+ *     return ret_val;
+ *   }
+ *  </programlisting>
+ * </example>
+ *
+ * This looks like it would work, but there is a race condition while
+ * constructing the mutex and this code cannot work reliable. Please do
+ * not use such constructs in your own programs! One working solution
+ * is:
+ *
+ * <example>
+ *  <title>A correct thread-safe function</title>
+ *  <programlisting>
+ *   static GMutex *give_me_next_number_mutex = NULL;
+ *
+ *   /<!-- -->* this function must be called before any call to
+ *    * give_me_next_number(<!-- -->)
+ *    *
+ *    * it must be called exactly once.
+ *    *<!-- -->/
+ *   void
+ *   init_give_me_next_number (void)
+ *   {
+ *     g_assert (give_me_next_number_mutex == NULL);
+ *     give_me_next_number_mutex = g_mutex_new (<!-- -->);
+ *   }
+ *
+ *   int
+ *   give_me_next_number (void)
+ *   {
+ *     static int current_number = 0;
+ *     int ret_val;
+ *
+ *     g_mutex_lock (give_me_next_number_mutex);
+ *     ret_val = current_number = calc_next_number (current_number);
+ *     g_mutex_unlock (give_me_next_number_mutex);
+ *
+ *     return ret_val;
+ *   }
+ *  </programlisting>
+ * </example>
+ *
+ * #GStaticMutex provides a simpler and safer way of doing this.
+ *
+ * If you want to use a mutex, and your code should also work without
+ * calling g_thread_init() first, then you can not use a #GMutex, as
+ * g_mutex_new() requires that the thread system be initialized. Use a
+ * #GStaticMutex instead.
+ *
+ * A #GMutex should only be accessed via the following functions.
+ *
+ * <note><para>All of the <function>g_mutex_*</function> functions are
+ * actually macros. Apart from taking their addresses, you can however
+ * use them as if they were functions.</para></note>
+ **/
+
+/**
+ * g_mutex_new:
+ * @Returns: a new #GMutex.
+ *
+ * Creates a new #GMutex.
+ *
+ * <note><para>This function will abort if g_thread_init() has not been
+ * called yet.</para></note>
+ **/
+  (GMutex*(*)())g_thread_fail,
+
+/**
+ * g_mutex_lock:
+ * @mutex: a #GMutex.
+ *
+ * Locks @mutex. If @mutex is already locked by another thread, the
+ * current thread will block until @mutex is unlocked by the other
+ * thread.
+ *
+ * This function can be used even if g_thread_init() has not yet been
+ * called, and, in that case, will do nothing.
+ *
+ * <note><para>#GMutex is neither guaranteed to be recursive nor to be
+ * non-recursive, i.e. a thread could deadlock while calling
+ * g_mutex_lock(), if it already has locked @mutex. Use
+ * #GStaticRecMutex, if you need recursive mutexes.</para></note>
+ **/
+  NULL,
+
+/**
+ * g_mutex_trylock:
+ * @mutex: a #GMutex.
+ * @Returns: %TRUE, if @mutex could be locked.
+ *
+ * Tries to lock @mutex. If @mutex is already locked by another thread,
+ * it immediately returns %FALSE. Otherwise it locks @mutex and returns
+ * %TRUE.
+ *
+ * This function can be used even if g_thread_init() has not yet been
+ * called, and, in that case, will immediately return %TRUE.
+ *
+ * <note><para>#GMutex is neither guaranteed to be recursive nor to be
+ * non-recursive, i.e. the return value of g_mutex_trylock() could be
+ * both %FALSE or %TRUE, if the current thread already has locked
+ * @mutex. Use #GStaticRecMutex, if you need recursive
+ * mutexes.</para></note>
+ **/
+  NULL,
+
+/**
+ * g_mutex_unlock:
+ * @mutex: a #GMutex.
+ *
+ * Unlocks @mutex. If another thread is blocked in a g_mutex_lock()
+ * call for @mutex, it will be woken and can lock @mutex itself.
+ *
+ * This function can be used even if g_thread_init() has not yet been
+ * called, and, in that case, will do nothing.
+ **/
+  NULL,
+
+/**
+ * g_mutex_free:
+ * @mutex: a #GMutex.
+ *
+ * Destroys @mutex.
+ *
+ * <note><para>Calling g_mutex_free() on a locked mutex may result in
+ * undefined behaviour.</para></note>
+ **/
+  NULL,
+
+/* GCond Virtual Functions {{{2 ------------------------------------------ */
+
+/**
+ * GCond:
+ *
+ * The #GCond struct is an opaque data structure that represents a
+ * condition. Threads can block on a #GCond if they find a certain
+ * condition to be false. If other threads change the state of this
+ * condition they signal the #GCond, and that causes the waiting
+ * threads to be woken up.
+ *
+ * <example>
+ *  <title>
+ *   Using GCond to block a thread until a condition is satisfied
+ *  </title>
+ *  <programlisting>
+ *   GCond* data_cond = NULL; /<!-- -->* Must be initialized somewhere *<!-- -->/
+ *   GMutex* data_mutex = NULL; /<!-- -->* Must be initialized somewhere *<!-- -->/
+ *   gpointer current_data = NULL;
+ *
+ *   void
+ *   push_data (gpointer data)
+ *   {
+ *     g_mutex_lock (data_mutex);
+ *     current_data = data;
+ *     g_cond_signal (data_cond);
+ *     g_mutex_unlock (data_mutex);
+ *   }
+ *
+ *   gpointer
+ *   pop_data (void)
+ *   {
+ *     gpointer data;
+ *
+ *     g_mutex_lock (data_mutex);
+ *     while (!current_data)
+ *       g_cond_wait (data_cond, data_mutex);
+ *     data = current_data;
+ *     current_data = NULL;
+ *     g_mutex_unlock (data_mutex);
+ *
+ *     return data;
+ *   }
+ *  </programlisting>
+ * </example>
+ *
+ * Whenever a thread calls <function>pop_data()</function> now, it will
+ * wait until current_data is non-%NULL, i.e. until some other thread
+ * has called <function>push_data()</function>.
+ *
+ * <note><para>It is important to use the g_cond_wait() and
+ * g_cond_timed_wait() functions only inside a loop which checks for the
+ * condition to be true.  It is not guaranteed that the waiting thread
+ * will find the condition fulfilled after it wakes up, even if the
+ * signaling thread left the condition in that state: another thread may
+ * have altered the condition before the waiting thread got the chance
+ * to be woken up, even if the condition itself is protected by a
+ * #GMutex, like above.</para></note>
+ *
+ * A #GCond should only be accessed via the following functions.
+ *
+ * <note><para>All of the <function>g_cond_*</function> functions are
+ * actually macros. Apart from taking their addresses, you can however
+ * use them as if they were functions.</para></note>
+ **/
+
+/**
+ * g_cond_new:
+ * @Returns: a new #GCond.
+ *
+ * Creates a new #GCond. This function will abort, if g_thread_init()
+ * has not been called yet.
+ **/
+  (GCond*(*)())g_thread_fail,
+
+/**
+ * g_cond_signal:
+ * @cond: a #GCond.
+ *
+ * If threads are waiting for @cond, exactly one of them is woken up.
+ * It is good practice to hold the same lock as the waiting thread
+ * while calling this function, though not required.
+ *
+ * This function can be used even if g_thread_init() has not yet been
+ * called, and, in that case, will do nothing.
+ **/
+  NULL,
+
+/**
+ * g_cond_broadcast:
+ * @cond: a #GCond.
+ *
+ * If threads are waiting for @cond, all of them are woken up. It is
+ * good practice to lock the same mutex as the waiting threads, while
+ * calling this function, though not required.
+ *
+ * This function can be used even if g_thread_init() has not yet been
+ * called, and, in that case, will do nothing.
+ **/
+  NULL,
+
+/**
+ * g_cond_wait:
+ * @cond: a #GCond.
+ * @mutex: a #GMutex, that is currently locked.
+ *
+ * Waits until this thread is woken up on @cond. The @mutex is unlocked
+ * before falling asleep and locked again before resuming.
+ *
+ * This function can be used even if g_thread_init() has not yet been
+ * called, and, in that case, will immediately return.
+ **/
+  NULL,
+
+/**
+ * g_cond_timed_wait:
+ * @cond: a #GCond.
+ * @mutex: a #GMutex that is currently locked.
+ * @abs_time: a #GTimeVal, determining the final time.
+ * @Returns: %TRUE if @cond was signalled, or %FALSE on timeout.
+ *
+ * Waits until this thread is woken up on @cond, but not longer than
+ * until the time specified by @abs_time. The @mutex is unlocked before
+ * falling asleep and locked again before resuming.
+ *
+ * If @abs_time is %NULL, g_cond_timed_wait() acts like g_cond_wait().
+ *
+ * This function can be used even if g_thread_init() has not yet been
+ * called, and, in that case, will immediately return %TRUE.
+ *
+ * To easily calculate @abs_time a combination of g_get_current_time()
+ * and g_time_val_add() can be used.
+ **/
+  NULL,
+
+/**
+ * g_cond_free:
+ * @cond: a #GCond.
+ *
+ * Destroys the #GCond.
+ **/
+  NULL,
+
+/* GPrivate Virtual Functions {{{2 --------------------------------------- */
+
+/**
+ * GPrivate:
+ *
+ * The #GPrivate struct is an opaque data structure to represent a
+ * thread private data key. Threads can thereby obtain and set a
+ * pointer which is private to the current thread. Take our
+ * <function>give_me_next_number(<!-- -->)</function> example from
+ * above.  Suppose we don't want <literal>current_number</literal> to be
+ * shared between the threads, but instead to be private to each thread.
+ * This can be done as follows:
+ *
+ * <example>
+ *  <title>Using GPrivate for per-thread data</title>
+ *  <programlisting>
+ *   GPrivate* current_number_key = NULL; /<!-- -->* Must be initialized somewhere
+ *                                           with g_private_new (g_free); *<!-- -->/
+ *
+ *   int
+ *   give_me_next_number (void)
+ *   {
+ *     int *current_number = g_private_get (current_number_key);
+ *
+ *     if (!current_number)
+ *       {
+ *         current_number = g_new (int, 1);
+ *         *current_number = 0;
+ *         g_private_set (current_number_key, current_number);
+ *       }
+ *
+ *     *current_number = calc_next_number (*current_number);
+ *
+ *     return *current_number;
+ *   }
+ *  </programlisting>
+ * </example>
+ *
+ * Here the pointer belonging to the key
+ * <literal>current_number_key</literal> is read. If it is %NULL, it has
+ * not been set yet. Then get memory for an integer value, assign this
+ * memory to the pointer and write the pointer back. Now we have an
+ * integer value that is private to the current thread.
+ *
+ * The #GPrivate struct should only be accessed via the following
+ * functions.
+ *
+ * <note><para>All of the <function>g_private_*</function> functions are
+ * actually macros. Apart from taking their addresses, you can however
+ * use them as if they were functions.</para></note>
+ **/
+
+/**
+ * g_private_new:
+ * @destructor: a function to destroy the data keyed to #GPrivate when
+ *              a thread ends.
+ * @Returns: a new #GPrivate.
+ *
+ * Creates a new #GPrivate. If @destructor is non-%NULL, it is a
+ * pointer to a destructor function. Whenever a thread ends and the
+ * corresponding pointer keyed to this instance of #GPrivate is
+ * non-%NULL, the destructor is called with this pointer as the
+ * argument.
+ *
+ * <note><para>@destructor is used quite differently from @notify in
+ * g_static_private_set().</para></note>
+ *
+ * <note><para>A #GPrivate can not be freed. Reuse it instead, if you
+ * can, to avoid shortage, or use #GStaticPrivate.</para></note>
+ *
+ * <note><para>This function will abort if g_thread_init() has not been
+ * called yet.</para></note>
+ **/
+  (GPrivate*(*)(GDestroyNotify))g_thread_fail,
+
+/**
+ * g_private_get:
+ * @private_key: a #GPrivate.
+ * @Returns: the corresponding pointer.
+ *
+ * Returns the pointer keyed to @private_key for the current thread. If
+ * g_private_set() hasn't been called for the current @private_key and
+ * thread yet, this pointer will be %NULL.
+ *
+ * This function can be used even if g_thread_init() has not yet been
+ * called, and, in that case, will return the value of @private_key
+ * casted to #gpointer. Note however, that private data set
+ * <emphasis>before</emphasis> g_thread_init() will
+ * <emphasis>not</emphasis> be retained <emphasis>after</emphasis> the
+ * call. Instead, %NULL will be returned in all threads directly after
+ * g_thread_init(), regardless of any g_private_set() calls issued
+ * before threading system intialization.
+ **/
+  NULL,
+
+/**
+ * g_private_set:
+ * @private_key: a #GPrivate.
+ * @data: the new pointer.
+ *
+ * Sets the pointer keyed to @private_key for the current thread.
+ *
+ * This function can be used even if g_thread_init() has not yet been
+ * called, and, in that case, will set @private_key to @data casted to
+ * #GPrivate*. See g_private_get() for resulting caveats.
+ **/
+  NULL,
+
+/* GThread Virtual Functions {{{2 ---------------------------------------- */
+/**
+ * GThread:
+ *
+ * The #GThread struct represents a running thread. It has three public
+ * read-only members, but the underlying struct is bigger, so you must
+ * not copy this struct.
+ *
+ * <note><para>Resources for a joinable thread are not fully released
+ * until g_thread_join() is called for that thread.</para></note>
+ **/
+
+/**
+ * GThreadFunc:
+ * @data: data passed to the thread.
+ * @Returns: the return value of the thread, which will be returned by
+ *           g_thread_join().
+ *
+ * Specifies the type of the @func functions passed to
+ * g_thread_create() or g_thread_create_full().
+ **/
+
+/**
+ * GThreadPriority:
+ * @G_THREAD_PRIORITY_LOW: a priority lower than normal
+ * @G_THREAD_PRIORITY_NORMAL: the default priority
+ * @G_THREAD_PRIORITY_HIGH: a priority higher than normal
+ * @G_THREAD_PRIORITY_URGENT: the highest priority
+ *
+ * Specifies the priority of a thread.
+ *
+ * <note><para>It is not guaranteed that threads with different priorities
+ * really behave accordingly. On some systems (e.g. Linux) there are no
+ * thread priorities. On other systems (e.g. Solaris) there doesn't
+ * seem to be different scheduling for different priorities. All in all
+ * try to avoid being dependent on priorities.</para></note>
+ **/
+
+/**
+ * g_thread_create:
+ * @func: a function to execute in the new thread.
+ * @data: an argument to supply to the new thread.
+ * @joinable: should this thread be joinable?
+ * @error: return location for error.
+ * @Returns: the new #GThread on success.
+ *
+ * This function creates a new thread with the default priority.
+ *
+ * If @joinable is %TRUE, you can wait for this threads termination
+ * calling g_thread_join(). Otherwise the thread will just disappear
+ * when it terminates.
+ *
+ * The new thread executes the function @func with the argument @data.
+ * If the thread was created successfully, it is returned.
+ *
+ * @error can be %NULL to ignore errors, or non-%NULL to report errors.
+ * The error is set, if and only if the function returns %NULL.
+ **/
+  (void(*)(GThreadFunc, gpointer, gulong,
+          gboolean, gboolean, GThreadPriority,
+          gpointer, GError**))g_thread_fail,
+
+/**
+ * g_thread_yield:
+ *
+ * Gives way to other threads waiting to be scheduled.
+ *
+ * This function is often used as a method to make busy wait less evil.
+ * But in most cases you will encounter, there are better methods to do
+ * that. So in general you shouldn't use this function.
+ **/
+  NULL,
+
+  NULL,                                        /* thread_join */
+  NULL,                                        /* thread_exit */
+  NULL,                                        /* thread_set_priority */
+  NULL,                                        /* thread_self */
+  NULL                                         /* thread_equal */
+};
+
+/* Local Data {{{1 -------------------------------------------------------- */
+
+static GMutex   *g_once_mutex = NULL;
+static GCond    *g_once_cond = NULL;
+static GPrivate *g_thread_specific_private = NULL;
+static GRealThread *g_thread_all_threads = NULL;
+static GSList   *g_thread_free_indeces = NULL;
+static GSList*   g_once_init_list = NULL;
+
+G_LOCK_DEFINE_STATIC (g_thread);
+
+/* Initialisation {{{1 ---------------------------------------------------- */
+
+#ifdef G_THREADS_ENABLED
+/**
+ * g_thread_init:
+ * @vtable: a function table of type #GThreadFunctions, that provides
+ *          the entry points to the thread system to be used.
+ *
+ * If you use GLib from more than one thread, you must initialize the
+ * thread system by calling g_thread_init(). Most of the time you will
+ * only have to call <literal>g_thread_init (NULL)</literal>.
+ *
+ * <note><para>Do not call g_thread_init() with a non-%NULL parameter unless
+ * you really know what you are doing.</para></note>
+ *
+ * <note><para>g_thread_init() must not be called directly or indirectly as a
+ * callback from GLib. Also no mutexes may be currently locked while
+ * calling g_thread_init().</para></note>
+ *
+ * <note><para>g_thread_init() changes the way in which #GTimer measures
+ * elapsed time. As a consequence, timers that are running while
+ * g_thread_init() is called may report unreliable times.</para></note>
+ *
+ * Calling g_thread_init() multiple times is allowed (since version
+ * 2.24), but nothing happens except for the first call. If the
+ * argument is non-%NULL on such a call a warning will be printed, but
+ * otherwise the argument is ignored.
+ *
+ * If no thread system is available and @vtable is %NULL or if not all
+ * elements of @vtable are non-%NULL, then g_thread_init() will abort.
+ *
+ * <note><para>To use g_thread_init() in your program, you have to link with
+ * the libraries that the command <command>pkg-config --libs
+ * gthread-2.0</command> outputs. This is not the case for all the
+ * other thread related functions of GLib. Those can be used without
+ * having to link with the thread libraries.</para></note>
+ **/
+
+/* This must be called only once, before any threads are created.
+ * It will only be called from g_thread_init() in -lgthread.
+ */
+void
+g_thread_init_glib (void)
+{
+  /* We let the main thread (the one that calls g_thread_init) inherit
+   * the static_private data set before calling g_thread_init
+   */
+  GRealThread* main_thread = (GRealThread*) g_thread_self ();
+
+  /* mutex and cond creation works without g_threads_got_initialized */
+  g_once_mutex = g_mutex_new ();
+  g_once_cond = g_cond_new ();
+
+  /* we may only create mutex and cond in here */
+  _g_mem_thread_init_noprivate_nomessage ();
+
+  /* setup the basic threading system */
+  g_threads_got_initialized = TRUE;
+  g_thread_specific_private = g_private_new (g_thread_cleanup);
+  g_private_set (g_thread_specific_private, main_thread);
+  G_THREAD_UF (thread_self, (&main_thread->system_thread));
+
+  /* complete memory system initialization, g_private_*() works now */
+  _g_slice_thread_init_nomessage ();
+
+  /* accomplish log system initialization to enable messaging */
+  _g_messages_thread_init_nomessage ();
+
+  /* we may run full-fledged initializers from here */
+  _g_atomic_thread_init ();
+  _g_convert_thread_init ();
+  _g_rand_thread_init ();
+  _g_main_thread_init ();
+  _g_utils_thread_init ();
+  _g_futex_thread_init ();
+#ifdef G_OS_WIN32
+  _g_win32_thread_init ();
+#endif
+}
+#endif /* G_THREADS_ENABLED */
+
+/* The following sections implement: GOnce, GStaticMutex, GStaticRecMutex,
+ * GStaticPrivate, 
+ **/
+
+/* GOnce {{{1 ------------------------------------------------------------- */
+
+/**
+ * GOnce:
+ * @status: the status of the #GOnce
+ * @retval: the value returned by the call to the function, if @status
+ *          is %G_ONCE_STATUS_READY
+ *
+ * A #GOnce struct controls a one-time initialization function. Any
+ * one-time initialization function must have its own unique #GOnce
+ * struct.
+ *
+ * Since: 2.4
+ **/
+
+/**
+ * G_ONCE_INIT:
+ *
+ * A #GOnce must be initialized with this macro before it can be used.
+ *
+ * <informalexample>
+ *  <programlisting>
+ *   GOnce my_once = G_ONCE_INIT;
+ *  </programlisting>
+ * </informalexample>
+ *
+ * Since: 2.4
+ **/
+
+/**
+ * GOnceStatus:
+ * @G_ONCE_STATUS_NOTCALLED: the function has not been called yet.
+ * @G_ONCE_STATUS_PROGRESS: the function call is currently in progress.
+ * @G_ONCE_STATUS_READY: the function has been called.
+ *
+ * The possible statuses of a one-time initialization function
+ * controlled by a #GOnce struct.
+ *
+ * Since: 2.4
+ **/
+
+/**
+ * g_once:
+ * @once: a #GOnce structure
+ * @func: the #GThreadFunc function associated to @once. This function
+ *        is called only once, regardless of the number of times it and
+ *        its associated #GOnce struct are passed to g_once().
+ * @arg: data to be passed to @func
+ *
+ * The first call to this routine by a process with a given #GOnce
+ * struct calls @func with the given argument. Thereafter, subsequent
+ * calls to g_once()  with the same #GOnce struct do not call @func
+ * again, but return the stored result of the first call. On return
+ * from g_once(), the status of @once will be %G_ONCE_STATUS_READY.
+ *
+ * For example, a mutex or a thread-specific data key must be created
+ * exactly once. In a threaded environment, calling g_once() ensures
+ * that the initialization is serialized across multiple threads.
+ *
+ * <note><para>Calling g_once() recursively on the same #GOnce struct in
+ * @func will lead to a deadlock.</para></note>
+ *
+ * <informalexample>
+ *  <programlisting>
+ *   gpointer
+ *   get_debug_flags (void)
+ *   {
+ *     static GOnce my_once = G_ONCE_INIT;
+ *
+ *     g_once (&my_once, parse_debug_flags, NULL);
+ *
+ *     return my_once.retval;
+ *   }
+ *  </programlisting>
+ * </informalexample>
+ *
+ * Since: 2.4
+ **/
+gpointer
+g_once_impl (GOnce       *once,
+            GThreadFunc  func,
+            gpointer     arg)
+{
+  g_mutex_lock (g_once_mutex);
+
+  while (once->status == G_ONCE_STATUS_PROGRESS)
+    g_cond_wait (g_once_cond, g_once_mutex);
+
+  if (once->status != G_ONCE_STATUS_READY)
+    {
+      once->status = G_ONCE_STATUS_PROGRESS;
+      g_mutex_unlock (g_once_mutex);
+
+      once->retval = func (arg);
+
+      g_mutex_lock (g_once_mutex);
+      once->status = G_ONCE_STATUS_READY;
+      g_cond_broadcast (g_once_cond);
+    }
+
+  g_mutex_unlock (g_once_mutex);
+
+  return once->retval;
+}
+
+/**
+ * g_once_init_enter:
+ * @value_location: location of a static initializable variable
+ *                  containing 0.
+ * @Returns: %TRUE if the initialization section should be entered,
+ *           %FALSE and blocks otherwise
+ *
+ * Function to be called when starting a critical initialization
+ * section. The argument @value_location must point to a static
+ * 0-initialized variable that will be set to a value other than 0 at
+ * the end of the initialization section. In combination with
+ * g_once_init_leave() and the unique address @value_location, it can
+ * be ensured that an initialization section will be executed only once
+ * during a program's life time, and that concurrent threads are
+ * blocked until initialization completed. To be used in constructs
+ * like this:
+ *
+ * <informalexample>
+ *  <programlisting>
+ *   static gsize initialization_value = 0;
+ *
+ *   if (g_once_init_enter (&amp;initialization_value))
+ *     {
+ *       gsize setup_value = 42; /<!-- -->* initialization code here *<!-- -->/
+ *
+ *       g_once_init_leave (&amp;initialization_value, setup_value);
+ *     }
+ *
+ *   /<!-- -->* use initialization_value here *<!-- -->/
+ *  </programlisting>
+ * </informalexample>
+ *
+ * Since: 2.14
+ **/
+gboolean
+g_once_init_enter_impl (volatile gsize *value_location)
+{
+  gboolean need_init = FALSE;
+  g_mutex_lock (g_once_mutex);
+  if (g_atomic_pointer_get (value_location) == NULL)
+    {
+      if (!g_slist_find (g_once_init_list, (void*) value_location))
+        {
+          need_init = TRUE;
+          g_once_init_list = g_slist_prepend (g_once_init_list, (void*) value_location);
+        }
+      else
+        do
+          g_cond_wait (g_once_cond, g_once_mutex);
+        while (g_slist_find (g_once_init_list, (void*) value_location));
+    }
+  g_mutex_unlock (g_once_mutex);
+  return need_init;
+}
+
+/**
+ * g_once_init_leave:
+ * @value_location: location of a static initializable variable
+ *                  containing 0.
+ * @initialization_value: new non-0 value for *@value_location.
+ *
+ * Counterpart to g_once_init_enter(). Expects a location of a static
+ * 0-initialized initialization variable, and an initialization value
+ * other than 0. Sets the variable to the initialization value, and
+ * releases concurrent threads blocking in g_once_init_enter() on this
+ * initialization variable.
+ *
+ * Since: 2.14
+ **/
+void
+g_once_init_leave (volatile gsize *value_location,
+                   gsize           initialization_value)
+{
+  g_return_if_fail (g_atomic_pointer_get (value_location) == NULL);
+  g_return_if_fail (initialization_value != 0);
+  g_return_if_fail (g_once_init_list != NULL);
+
+  g_atomic_pointer_set ((void**)value_location, (void*) initialization_value);
+  g_mutex_lock (g_once_mutex);
+  g_once_init_list = g_slist_remove (g_once_init_list, (void*) value_location);
+  g_cond_broadcast (g_once_cond);
+  g_mutex_unlock (g_once_mutex);
+}
+
+/* GStaticMutex {{{1 ------------------------------------------------------ */
+
+/**
+ * GStaticMutex:
+ *
+ * A #GStaticMutex works like a #GMutex, but it has one significant
+ * advantage. It doesn't need to be created at run-time like a #GMutex,
+ * but can be defined at compile-time. Here is a shorter, easier and
+ * safer version of our <function>give_me_next_number()</function>
+ * example:
+ *
+ * <example>
+ *  <title>
+ *   Using <structname>GStaticMutex</structname>
+ *   to simplify thread-safe programming
+ *  </title>
+ *  <programlisting>
+ *   int
+ *   give_me_next_number (void)
+ *   {
+ *     static int current_number = 0;
+ *     int ret_val;
+ *     static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+ *
+ *     g_static_mutex_lock (&amp;mutex);
+ *     ret_val = current_number = calc_next_number (current_number);
+ *     g_static_mutex_unlock (&amp;mutex);
+ *
+ *     return ret_val;
+ *   }
+ *  </programlisting>
+ * </example>
+ *
+ * Sometimes you would like to dynamically create a mutex. If you don't
+ * want to require prior calling to g_thread_init(), because your code
+ * should also be usable in non-threaded programs, you are not able to
+ * use g_mutex_new() and thus #GMutex, as that requires a prior call to
+ * g_thread_init(). In theses cases you can also use a #GStaticMutex.
+ * It must be initialized with g_static_mutex_init() before using it
+ * and freed with with g_static_mutex_free() when not needed anymore to
+ * free up any allocated resources.
+ *
+ * Even though #GStaticMutex is not opaque, it should only be used with
+ * the following functions, as it is defined differently on different
+ * platforms.
+ *
+ * All of the <function>g_static_mutex_*</function> functions apart
+ * from <function>g_static_mutex_get_mutex</function> can also be used
+ * even if g_thread_init() has not yet been called. Then they do
+ * nothing, apart from <function>g_static_mutex_trylock</function>,
+ * which does nothing but returning %TRUE.
+ *
+ * <note><para>All of the <function>g_static_mutex_*</function>
+ * functions are actually macros. Apart from taking their addresses, you
+ * can however use them as if they were functions.</para></note>
+ **/
+
+/**
+ * G_STATIC_MUTEX_INIT:
+ *
+ * A #GStaticMutex must be initialized with this macro, before it can
+ * be used. This macro can used be to initialize a variable, but it
+ * cannot be assigned to a variable. In that case you have to use
+ * g_static_mutex_init().
+ *
+ * <informalexample>
+ *  <programlisting>
+ *   GStaticMutex my_mutex = G_STATIC_MUTEX_INIT;
+ *  </programlisting>
+ * </informalexample>
+ **/
+
+/**
+ * g_static_mutex_init:
+ * @mutex: a #GStaticMutex to be initialized.
+ *
+ * Initializes @mutex. Alternatively you can initialize it with
+ * #G_STATIC_MUTEX_INIT.
+ **/
+void
+g_static_mutex_init (GStaticMutex *mutex)
+{
+  static const GStaticMutex init_mutex = G_STATIC_MUTEX_INIT;
+
+  g_return_if_fail (mutex);
+
+  *mutex = init_mutex;
+}
+
+/* IMPLEMENTATION NOTE:
+ *
+ * On some platforms a GStaticMutex is actually a normal GMutex stored
+ * inside of a structure instead of being allocated dynamically.  We can
+ * only do this for platforms on which we know, in advance, how to
+ * allocate (size) and initialise (value) that memory.
+ *
+ * On other platforms, a GStaticMutex is nothing more than a pointer to
+ * a GMutex.  In that case, the first access we make to the static mutex
+ * must first allocate the normal GMutex and store it into the pointer.
+ *
+ * configure.ac writes macros into glibconfig.h to determine if
+ * g_static_mutex_get_mutex() accesses the sturcture in memory directly
+ * (on platforms where we are able to do that) or if it ends up here,
+ * where we may have to allocate the GMutex before returning it.
+ */
+
+/**
+ * g_static_mutex_get_mutex:
+ * @mutex: a #GStaticMutex.
+ * @Returns: the #GMutex corresponding to @mutex.
+ *
+ * For some operations (like g_cond_wait()) you must have a #GMutex
+ * instead of a #GStaticMutex. This function will return the
+ * corresponding #GMutex for @mutex.
+ **/
+GMutex *
+g_static_mutex_get_mutex_impl (GMutex** mutex)
+{
+  if (!g_thread_supported ())
+    return NULL;
+
+  g_assert (g_once_mutex);
+
+  g_mutex_lock (g_once_mutex);
+
+  if (!(*mutex))
+    g_atomic_pointer_set (mutex, g_mutex_new());
+
+  g_mutex_unlock (g_once_mutex);
+
+  return *mutex;
+}
+
+/* IMPLEMENTATION NOTE:
+ *
+ * g_static_mutex_lock(), g_static_mutex_trylock() and
+ * g_static_mutex_unlock() are all preprocessor macros that wrap the
+ * corresponding g_mutex_*() function around a call to
+ * g_static_mutex_get_mutex().
+ */
+
+/**
+ * g_static_mutex_lock:
+ * @mutex: a #GStaticMutex.
+ *
+ * Works like g_mutex_lock(), but for a #GStaticMutex.
+ **/
+
+/**
+ * g_static_mutex_trylock:
+ * @mutex: a #GStaticMutex.
+ * @Returns: %TRUE, if the #GStaticMutex could be locked.
+ *
+ * Works like g_mutex_trylock(), but for a #GStaticMutex.
+ **/
+
+/**
+ * g_static_mutex_unlock:
+ * @mutex: a #GStaticMutex.
+ *
+ * Works like g_mutex_unlock(), but for a #GStaticMutex.
+ **/
+
+/**
+ * g_static_mutex_free:
+ * @mutex: a #GStaticMutex to be freed.
+ *
+ * Releases all resources allocated to @mutex.
+ *
+ * You don't have to call this functions for a #GStaticMutex with an
+ * unbounded lifetime, i.e. objects declared 'static', but if you have
+ * a #GStaticMutex as a member of a structure and the structure is
+ * freed, you should also free the #GStaticMutex.
+ *
+ * <note><para>Calling g_static_mutex_free() on a locked mutex may
+ * result in undefined behaviour.</para></note>
+ **/
+void
+g_static_mutex_free (GStaticMutex* mutex)
+{
+  GMutex **runtime_mutex;
+
+  g_return_if_fail (mutex);
+
+  /* The runtime_mutex is the first (or only) member of GStaticMutex,
+   * see both versions (of glibconfig.h) in configure.ac. Note, that
+   * this variable is NULL, if g_thread_init() hasn't been called or
+   * if we're using the default thread implementation and it provides
+   * static mutexes. */
+  runtime_mutex = ((GMutex**)mutex);
+
+  if (*runtime_mutex)
+    g_mutex_free (*runtime_mutex);
+
+  *runtime_mutex = NULL;
+}
+
+/* ------------------------------------------------------------------------ */
+
+/**
+ * GStaticRecMutex:
+ *
+ * A #GStaticRecMutex works like a #GStaticMutex, but it can be locked
+ * multiple times by one thread. If you enter it n times, you have to
+ * unlock it n times again to let other threads lock it. An exception
+ * is the function g_static_rec_mutex_unlock_full(): that allows you to
+ * unlock a #GStaticRecMutex completely returning the depth, (i.e. the
+ * number of times this mutex was locked). The depth can later be used
+ * to restore the state of the #GStaticRecMutex by calling
+ * g_static_rec_mutex_lock_full().
+ *
+ * Even though #GStaticRecMutex is not opaque, it should only be used
+ * with the following functions.
+ *
+ * All of the <function>g_static_rec_mutex_*</function> functions can
+ * be used even if g_thread_init() has not been called. Then they do
+ * nothing, apart from <function>g_static_rec_mutex_trylock</function>,
+ * which does nothing but returning %TRUE.
+ **/
+
+/**
+ * G_STATIC_REC_MUTEX_INIT:
+ *
+ * A #GStaticRecMutex must be initialized with this macro before it can
+ * be used. This macro can used be to initialize a variable, but it
+ * cannot be assigned to a variable. In that case you have to use
+ * g_static_rec_mutex_init().
+ *
+ * <informalexample>
+ *  <programlisting>
+ *   GStaticRecMutex my_mutex = G_STATIC_REC_MUTEX_INIT;
+ * </programlisting>
+ </informalexample>
+ **/
+
+/**
+ * g_static_rec_mutex_init:
+ * @mutex: a #GStaticRecMutex to be initialized.
+ *
+ * A #GStaticRecMutex must be initialized with this function before it
+ * can be used. Alternatively you can initialize it with
+ * #G_STATIC_REC_MUTEX_INIT.
+ **/
+void
+g_static_rec_mutex_init (GStaticRecMutex *mutex)
+{
+  static const GStaticRecMutex init_mutex = G_STATIC_REC_MUTEX_INIT;
+
+  g_return_if_fail (mutex);
+
+  *mutex = init_mutex;
+}
+
+/**
+ * g_static_rec_mutex_lock:
+ * @mutex: a #GStaticRecMutex to lock.
+ *
+ * Locks @mutex. If @mutex is already locked by another thread, the
+ * current thread will block until @mutex is unlocked by the other
+ * thread. If @mutex is already locked by the calling thread, this
+ * functions increases the depth of @mutex and returns immediately.
+ **/
+void
+g_static_rec_mutex_lock (GStaticRecMutex* mutex)
+{
+  GSystemThread self;
+
+  g_return_if_fail (mutex);
+
+  if (!g_thread_supported ())
+    return;
+
+  G_THREAD_UF (thread_self, (&self));
+
+  if (g_system_thread_equal (self, mutex->owner))
+    {
+      mutex->depth++;
+      return;
+    }
+  g_static_mutex_lock (&mutex->mutex);
+  g_system_thread_assign (mutex->owner, self);
+  mutex->depth = 1;
+}
+
+/**
+ * g_static_rec_mutex_trylock:
+ * @mutex: a #GStaticRecMutex to lock.
+ * @Returns: %TRUE, if @mutex could be locked.
+ *
+ * Tries to lock @mutex. If @mutex is already locked by another thread,
+ * it immediately returns %FALSE. Otherwise it locks @mutex and returns
+ * %TRUE. If @mutex is already locked by the calling thread, this
+ * functions increases the depth of @mutex and immediately returns
+ * %TRUE.
+ **/
+gboolean
+g_static_rec_mutex_trylock (GStaticRecMutex* mutex)
+{
+  GSystemThread self;
+
+  g_return_val_if_fail (mutex, FALSE);
+
+  if (!g_thread_supported ())
+    return TRUE;
+
+  G_THREAD_UF (thread_self, (&self));
+
+  if (g_system_thread_equal (self, mutex->owner))
+    {
+      mutex->depth++;
+      return TRUE;
+    }
+
+  if (!g_static_mutex_trylock (&mutex->mutex))
+    return FALSE;
+
+  g_system_thread_assign (mutex->owner, self);
+  mutex->depth = 1;
+  return TRUE;
+}
+
+/**
+ * g_static_rec_mutex_unlock:
+ * @mutex: a #GStaticRecMutex to unlock.
+ *
+ * Unlocks @mutex. Another thread will be allowed to lock @mutex only
+ * when it has been unlocked as many times as it had been locked
+ * before. If @mutex is completely unlocked and another thread is
+ * blocked in a g_static_rec_mutex_lock() call for @mutex, it will be
+ * woken and can lock @mutex itself.
+ **/
+void
+g_static_rec_mutex_unlock (GStaticRecMutex* mutex)
+{
+  g_return_if_fail (mutex);
+
+  if (!g_thread_supported ())
+    return;
+
+  if (mutex->depth > 1)
+    {
+      mutex->depth--;
+      return;
+    }
+  g_system_thread_assign (mutex->owner, zero_thread);
+  g_static_mutex_unlock (&mutex->mutex);
+}
+
+/**
+ * g_static_rec_mutex_lock_full:
+ * @mutex: a #GStaticRecMutex to lock.
+ * @depth: number of times this mutex has to be unlocked to be
+ *         completely unlocked.
+ *
+ * Works like calling g_static_rec_mutex_lock() for @mutex @depth times.
+ **/
+void
+g_static_rec_mutex_lock_full   (GStaticRecMutex *mutex,
+                               guint            depth)
+{
+  GSystemThread self;
+  g_return_if_fail (mutex);
+
+  if (!g_thread_supported ())
+    return;
+
+  if (depth == 0)
+    return;
+
+  G_THREAD_UF (thread_self, (&self));
+
+  if (g_system_thread_equal (self, mutex->owner))
+    {
+      mutex->depth += depth;
+      return;
+    }
+  g_static_mutex_lock (&mutex->mutex);
+  g_system_thread_assign (mutex->owner, self);
+  mutex->depth = depth;
+}
+
+/**
+ * g_static_rec_mutex_unlock_full:
+ * @mutex: a #GStaticRecMutex to completely unlock.
+ * @Returns: number of times @mutex has been locked by the current
+ *           thread.
+ *
+ * Completely unlocks @mutex. If another thread is blocked in a
+ * g_static_rec_mutex_lock() call for @mutex, it will be woken and can
+ * lock @mutex itself. This function returns the number of times that
+ * @mutex has been locked by the current thread. To restore the state
+ * before the call to g_static_rec_mutex_unlock_full() you can call
+ * g_static_rec_mutex_lock_full() with the depth returned by this
+ * function.
+ **/
+guint
+g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex)
+{
+  guint depth;
+
+  g_return_val_if_fail (mutex, 0);
+
+  if (!g_thread_supported ())
+    return 1;
+
+  depth = mutex->depth;
+
+  g_system_thread_assign (mutex->owner, zero_thread);
+  mutex->depth = 0;
+  g_static_mutex_unlock (&mutex->mutex);
+
+  return depth;
+}
+
+/**
+ * g_static_rec_mutex_free:
+ * @mutex: a #GStaticRecMutex to be freed.
+ *
+ * Releases all resources allocated to a #GStaticRecMutex.
+ *
+ * You don't have to call this functions for a #GStaticRecMutex with an
+ * unbounded lifetime, i.e. objects declared 'static', but if you have
+ * a #GStaticRecMutex as a member of a structure and the structure is
+ * freed, you should also free the #GStaticRecMutex.
+ **/
+void
+g_static_rec_mutex_free (GStaticRecMutex *mutex)
+{
+  g_return_if_fail (mutex);
+
+  g_static_mutex_free (&mutex->mutex);
+}
+
+/* GStaticPrivate {{{1 ---------------------------------------------------- */
+
+/**
+ * GStaticPrivate:
+ *
+ * A #GStaticPrivate works almost like a #GPrivate, but it has one
+ * significant advantage. It doesn't need to be created at run-time
+ * like a #GPrivate, but can be defined at compile-time. This is
+ * similar to the difference between #GMutex and #GStaticMutex. Now
+ * look at our <function>give_me_next_number()</function> example with
+ * #GStaticPrivate:
+ *
+ * <example>
+ *  <title>Using GStaticPrivate for per-thread data</title>
+ *  <programlisting>
+ *   int
+ *   give_me_next_number (<!-- -->)
+ *   {
+ *     static GStaticPrivate current_number_key = G_STATIC_PRIVATE_INIT;
+ *     int *current_number = g_static_private_get (&amp;current_number_key);
+ *
+ *     if (!current_number)
+ *       {
+ *         current_number = g_new (int,1);
+ *         *current_number = 0;
+ *         g_static_private_set (&amp;current_number_key, current_number, g_free);
+ *       }
+ *
+ *     *current_number = calc_next_number (*current_number);
+ *
+ *     return *current_number;
+ *   }
+ *  </programlisting>
+ * </example>
+ **/
+
+/**
+ * G_STATIC_PRIVATE_INIT:
+ *
+ * Every #GStaticPrivate must be initialized with this macro, before it
+ * can be used.
+ *
+ * <informalexample>
+ *  <programlisting>
+ *   GStaticPrivate my_private = G_STATIC_PRIVATE_INIT;
+ *  </programlisting>
+ * </informalexample>
+ **/
+
+/**
+ * g_static_private_init:
+ * @private_key: a #GStaticPrivate to be initialized.
+ *
+ * Initializes @private_key. Alternatively you can initialize it with
+ * #G_STATIC_PRIVATE_INIT.
+ **/
+void
+g_static_private_init (GStaticPrivate *private_key)
+{
+  private_key->index = 0;
+}
+
+/**
+ * g_static_private_get:
+ * @private_key: a #GStaticPrivate.
+ * @Returns: the corresponding pointer.
+ *
+ * Works like g_private_get() only for a #GStaticPrivate.
+ *
+ * This function works even if g_thread_init() has not yet been called.
+ **/
+gpointer
+g_static_private_get (GStaticPrivate *private_key)
+{
+  GRealThread *self = (GRealThread*) g_thread_self ();
+  GArray *array;
+
+  array = self->private_data;
+  if (!array)
+    return NULL;
+
+  if (!private_key->index)
+    return NULL;
+  else if (private_key->index <= array->len)
+    return g_array_index (array, GStaticPrivateNode,
+                         private_key->index - 1).data;
+  else
+    return NULL;
+}
+
+/**
+ * g_static_private_set:
+ * @private_key: a #GStaticPrivate.
+ * @data: the new pointer.
+ * @notify: a function to be called with the pointer whenever the
+ *          current thread ends or sets this pointer again.
+ *
+ * Sets the pointer keyed to @private_key for the current thread and
+ * the function @notify to be called with that pointer (%NULL or
+ * non-%NULL), whenever the pointer is set again or whenever the
+ * current thread ends.
+ *
+ * This function works even if g_thread_init() has not yet been called.
+ * If g_thread_init() is called later, the @data keyed to @private_key
+ * will be inherited only by the main thread, i.e. the one that called
+ * g_thread_init().
+ *
+ * <note><para>@notify is used quite differently from @destructor in
+ * g_private_new().</para></note>
+ **/
+void
+g_static_private_set (GStaticPrivate *private_key,
+                     gpointer        data,
+                     GDestroyNotify  notify)
+{
+  GRealThread *self = (GRealThread*) g_thread_self ();
+  GArray *array;
+  static guint next_index = 0;
+  GStaticPrivateNode *node;
+
+  array = self->private_data;
+  if (!array)
+    {
+      array = g_array_new (FALSE, TRUE, sizeof (GStaticPrivateNode));
+      self->private_data = array;
+    }
+
+  if (!private_key->index)
+    {
+      G_LOCK (g_thread);
+
+      if (!private_key->index)
+       {
+         if (g_thread_free_indeces)
+           {
+             private_key->index =
+               GPOINTER_TO_UINT (g_thread_free_indeces->data);
+             g_thread_free_indeces =
+               g_slist_delete_link (g_thread_free_indeces,
+                                    g_thread_free_indeces);
+           }
+         else
+           private_key->index = ++next_index;
+       }
+
+      G_UNLOCK (g_thread);
+    }
+
+  if (private_key->index > array->len)
+    g_array_set_size (array, private_key->index);
+
+  node = &g_array_index (array, GStaticPrivateNode, private_key->index - 1);
+  if (node->destroy)
+    {
+      gpointer ddata = node->data;
+      GDestroyNotify ddestroy = node->destroy;
+
+      node->data = data;
+      node->destroy = notify;
+
+      ddestroy (ddata);
+    }
+  else
+    {
+      node->data = data;
+      node->destroy = notify;
+    }
+}
+
+/**
+ * g_static_private_free:
+ * @private_key: a #GStaticPrivate to be freed.
+ *
+ * Releases all resources allocated to @private_key.
+ *
+ * You don't have to call this functions for a #GStaticPrivate with an
+ * unbounded lifetime, i.e. objects declared 'static', but if you have
+ * a #GStaticPrivate as a member of a structure and the structure is
+ * freed, you should also free the #GStaticPrivate.
+ **/
+void
+g_static_private_free (GStaticPrivate *private_key)
+{
+  guint idx = private_key->index;
+  GRealThread *thread;
+
+  if (!idx)
+    return;
+
+  private_key->index = 0;
+
+  G_LOCK (g_thread);
+
+  thread = g_thread_all_threads;
+  while (thread)
+    {
+      GArray *array = thread->private_data;
+      thread = thread->next;
+
+      if (array && idx <= array->len)
+       {
+         GStaticPrivateNode *node = &g_array_index (array,
+                                                    GStaticPrivateNode,
+                                                    idx - 1);
+         gpointer ddata = node->data;
+         GDestroyNotify ddestroy = node->destroy;
+
+         node->data = NULL;
+         node->destroy = NULL;
+
+          if (ddestroy)
+            {
+              G_UNLOCK (g_thread);
+              ddestroy (ddata);
+              G_LOCK (g_thread);
+            }
+       }
+    }
+  g_thread_free_indeces = g_slist_prepend (g_thread_free_indeces,
+                                          GUINT_TO_POINTER (idx));
+  G_UNLOCK (g_thread);
+}
+
+/* GThread Extra Functions {{{1 ------------------------------------------- */
+static void
+g_thread_cleanup (gpointer data)
+{
+  if (data)
+    {
+      GRealThread* thread = data;
+      if (thread->private_data)
+       {
+         GArray* array = thread->private_data;
+         guint i;
+
+         for (i = 0; i < array->len; i++ )
+           {
+             GStaticPrivateNode *node =
+               &g_array_index (array, GStaticPrivateNode, i);
+             if (node->destroy)
+               node->destroy (node->data);
+           }
+         g_array_free (array, TRUE);
+       }
+
+      /* We only free the thread structure, if it isn't joinable. If
+         it is, the structure is freed in g_thread_join */
+      if (!thread->thread.joinable)
+       {
+         GRealThread *t, *p;
+
+         G_LOCK (g_thread);
+         for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next)
+           {
+             if (t == thread)
+               {
+                 if (p)
+                   p->next = t->next;
+                 else
+                   g_thread_all_threads = t->next;
+                 break;
+               }
+           }
+         G_UNLOCK (g_thread);
+
+         /* Just to make sure, this isn't used any more */
+         g_system_thread_assign (thread->system_thread, zero_thread);
+          g_free (thread);
+       }
+    }
+}
+
+static void
+g_thread_fail (void)
+{
+  g_error ("The thread system is not yet initialized.");
+}
+
+#define G_NSEC_PER_SEC 1000000000
+
+static guint64
+gettime (void)
+{
+#ifdef G_OS_WIN32
+  guint64 v;
+
+  /* Returns 100s of nanoseconds since start of 1601 */
+  GetSystemTimeAsFileTime ((FILETIME *)&v);
+
+  /* Offset to Unix epoch */
+  v -= G_GINT64_CONSTANT (116444736000000000);
+  /* Convert to nanoseconds */
+  v *= 100;
+
+  return v;
+#else
+  struct timeval tv;
+
+  gettimeofday (&tv, NULL);
+
+  return (guint64) tv.tv_sec * G_NSEC_PER_SEC + tv.tv_usec * (G_NSEC_PER_SEC / G_USEC_PER_SEC); 
+#endif
+}
+
+static gpointer
+g_thread_create_proxy (gpointer data)
+{
+  GRealThread* thread = data;
+
+  g_assert (data);
+
+  /* This has to happen before G_LOCK, as that might call g_thread_self */
+  g_private_set (g_thread_specific_private, data);
+
+  /* the lock makes sure, that thread->system_thread is written,
+     before thread->thread.func is called. See g_thread_create. */
+  G_LOCK (g_thread);
+  G_UNLOCK (g_thread);
+
+  thread->retval = thread->thread.func (thread->thread.data);
+
+  return NULL;
+}
+
+/**
+ * g_thread_create_full:
+ * @func: a function to execute in the new thread.
+ * @data: an argument to supply to the new thread.
+ * @stack_size: a stack size for the new thread.
+ * @joinable: should this thread be joinable?
+ * @bound: should this thread be bound to a system thread?
+ * @priority: a priority for the thread.
+ * @error: return location for error.
+ * @Returns: the new #GThread on success.
+ *
+ * This function creates a new thread with the priority @priority. If
+ * the underlying thread implementation supports it, the thread gets a
+ * stack size of @stack_size or the default value for the current
+ * platform, if @stack_size is 0.
+ *
+ * If @joinable is %TRUE, you can wait for this threads termination
+ * calling g_thread_join(). Otherwise the thread will just disappear
+ * when it terminates. If @bound is %TRUE, this thread will be
+ * scheduled in the system scope, otherwise the implementation is free
+ * to do scheduling in the process scope. The first variant is more
+ * expensive resource-wise, but generally faster. On some systems (e.g.
+ * Linux) all threads are bound.
+ *
+ * The new thread executes the function @func with the argument @data.
+ * If the thread was created successfully, it is returned.
+ *
+ * @error can be %NULL to ignore errors, or non-%NULL to report errors.
+ * The error is set, if and only if the function returns %NULL.
+ *
+ * <note><para>It is not guaranteed that threads with different priorities
+ * really behave accordingly. On some systems (e.g. Linux) there are no
+ * thread priorities. On other systems (e.g. Solaris) there doesn't
+ * seem to be different scheduling for different priorities. All in all
+ * try to avoid being dependent on priorities. Use
+ * %G_THREAD_PRIORITY_NORMAL here as a default.</para></note>
+ *
+ * <note><para>Only use g_thread_create_full() if you really can't use
+ * g_thread_create() instead. g_thread_create() does not take
+ * @stack_size, @bound, and @priority as arguments, as they should only
+ * be used in cases in which it is unavoidable.</para></note>
+ **/
+GThread*
+g_thread_create_full (GThreadFunc       func,
+                     gpointer          data,
+                     gulong            stack_size,
+                     gboolean          joinable,
+                     gboolean          bound,
+                     GThreadPriority   priority,
+                     GError          **error)
+{
+  GRealThread* result;
+  GError *local_error = NULL;
+  g_return_val_if_fail (func, NULL);
+  g_return_val_if_fail (priority >= G_THREAD_PRIORITY_LOW, NULL);
+  g_return_val_if_fail (priority <= G_THREAD_PRIORITY_URGENT, NULL);
+
+  result = g_new0 (GRealThread, 1);
+
+  result->thread.joinable = joinable;
+  result->thread.priority = priority;
+  result->thread.func = func;
+  result->thread.data = data;
+  result->private_data = NULL;
+  G_LOCK (g_thread);
+  G_THREAD_UF (thread_create, (g_thread_create_proxy, result,
+                              stack_size, joinable, bound, priority,
+                              &result->system_thread, &local_error));
+  if (!local_error)
+    {
+      result->next = g_thread_all_threads;
+      g_thread_all_threads = result;
+    }
+  G_UNLOCK (g_thread);
+
+  if (local_error)
+    {
+      g_propagate_error (error, local_error);
+      g_free (result);
+      return NULL;
+    }
+
+  return (GThread*) result;
+}
+
+/**
+ * g_thread_exit:
+ * @retval: the return value of this thread.
+ *
+ * Exits the current thread. If another thread is waiting for that
+ * thread using g_thread_join() and the current thread is joinable, the
+ * waiting thread will be woken up and get @retval as the return value
+ * of g_thread_join(). If the current thread is not joinable, @retval
+ * is ignored. Calling
+ *
+ * <informalexample>
+ *  <programlisting>
+ *   g_thread_exit (retval);
+ *  </programlisting>
+ * </informalexample>
+ *
+ * is equivalent to returning @retval from the function @func, as given
+ * to g_thread_create().
+ *
+ * <note><para>Never call g_thread_exit() from within a thread of a
+ * #GThreadPool, as that will mess up the bookkeeping and lead to funny
+ * and unwanted results.</para></note>
+ **/
+void
+g_thread_exit (gpointer retval)
+{
+  GRealThread* real = (GRealThread*) g_thread_self ();
+  real->retval = retval;
+  G_THREAD_CF (thread_exit, (void)0, ());
+}
+
+/**
+ * g_thread_join:
+ * @thread: a #GThread to be waited for.
+ * @Returns: the return value of the thread.
+ *
+ * Waits until @thread finishes, i.e. the function @func, as given to
+ * g_thread_create(), returns or g_thread_exit() is called by @thread.
+ * All resources of @thread including the #GThread struct are released.
+ * @thread must have been created with @joinable=%TRUE in
+ * g_thread_create(). The value returned by @func or given to
+ * g_thread_exit() by @thread is returned by this function.
+ **/
+gpointer
+g_thread_join (GThread* thread)
+{
+  GRealThread* real = (GRealThread*) thread;
+  GRealThread *p, *t;
+  gpointer retval;
+
+  g_return_val_if_fail (thread, NULL);
+  g_return_val_if_fail (thread->joinable, NULL);
+  g_return_val_if_fail (!g_system_thread_equal (real->system_thread,
+                                               zero_thread), NULL);
+
+  G_THREAD_UF (thread_join, (&real->system_thread));
+
+  retval = real->retval;
+
+  G_LOCK (g_thread);
+  for (t = g_thread_all_threads, p = NULL; t; p = t, t = t->next)
+    {
+      if (t == (GRealThread*) thread)
+       {
+         if (p)
+           p->next = t->next;
+         else
+           g_thread_all_threads = t->next;
+         break;
+       }
+    }
+  G_UNLOCK (g_thread);
+
+  /* Just to make sure, this isn't used any more */
+  thread->joinable = 0;
+  g_system_thread_assign (real->system_thread, zero_thread);
+
+  /* the thread structure for non-joinable threads is freed upon
+     thread end. We free the memory here. This will leave a loose end,
+     if a joinable thread is not joined. */
+
+  g_free (thread);
+
+  return retval;
+}
+
+/**
+ * g_thread_set_priority:
+ * @thread: a #GThread.
+ * @priority: a new priority for @thread.
+ *
+ * Changes the priority of @thread to @priority.
+ *
+ * <note><para>It is not guaranteed that threads with different
+ * priorities really behave accordingly. On some systems (e.g. Linux)
+ * there are no thread priorities. On other systems (e.g. Solaris) there
+ * doesn't seem to be different scheduling for different priorities. All
+ * in all try to avoid being dependent on priorities.</para></note>
+ **/
+void
+g_thread_set_priority (GThread* thread,
+                      GThreadPriority priority)
+{
+  GRealThread* real = (GRealThread*) thread;
+
+  g_return_if_fail (thread);
+  g_return_if_fail (!g_system_thread_equal (real->system_thread, zero_thread));
+  g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
+  g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
+
+  thread->priority = priority;
+
+  G_THREAD_CF (thread_set_priority, (void)0,
+              (&real->system_thread, priority));
+}
+
+/**
+ * g_thread_self:
+ * @Returns: the current thread.
+ *
+ * This functions returns the #GThread corresponding to the calling
+ * thread.
+ **/
+GThread*
+g_thread_self (void)
+{
+  GRealThread* thread = g_private_get (g_thread_specific_private);
+
+  if (!thread)
+    {
+      /* If no thread data is available, provide and set one.  This
+         can happen for the main thread and for threads, that are not
+         created by GLib. */
+      thread = g_new0 (GRealThread, 1);
+      thread->thread.joinable = FALSE; /* This is a save guess */
+      thread->thread.priority = G_THREAD_PRIORITY_NORMAL; /* This is
+                                                            just a guess */
+      thread->thread.func = NULL;
+      thread->thread.data = NULL;
+      thread->private_data = NULL;
+
+      if (g_thread_supported ())
+       G_THREAD_UF (thread_self, (&thread->system_thread));
+
+      g_private_set (g_thread_specific_private, thread);
+
+      G_LOCK (g_thread);
+      thread->next = g_thread_all_threads;
+      g_thread_all_threads = thread;
+      G_UNLOCK (g_thread);
+    }
+
+  return (GThread*)thread;
+}
+
+/* GStaticRWLock {{{1 ----------------------------------------------------- */
+
+/**
+ * GStaticRWLock:
+ *
+ * The #GStaticRWLock struct represents a read-write lock. A read-write
+ * lock can be used for protecting data that some portions of code only
+ * read from, while others also write. In such situations it is
+ * desirable that several readers can read at once, whereas of course
+ * only one writer may write at a time. Take a look at the following
+ * example:
+ *
+ * <example>
+ *  <title>An array with access functions</title>
+ *  <programlisting>
+ *   GStaticRWLock rwlock = G_STATIC_RW_LOCK_INIT;
+ *   GPtrArray *array;
+ *
+ *   gpointer
+ *   my_array_get (guint index)
+ *   {
+ *     gpointer retval = NULL;
+ *
+ *     if (!array)
+ *       return NULL;
+ *
+ *     g_static_rw_lock_reader_lock (&amp;rwlock);
+ *     if (index &lt; array->len)
+ *       retval = g_ptr_array_index (array, index);
+ *     g_static_rw_lock_reader_unlock (&amp;rwlock);
+ *
+ *     return retval;
+ *   }
+ *
+ *   void
+ *   my_array_set (guint index, gpointer data)
+ *   {
+ *     g_static_rw_lock_writer_lock (&amp;rwlock);
+ *
+ *     if (!array)
+ *       array = g_ptr_array_new (<!-- -->);
+ *
+ *     if (index >= array->len)
+ *       g_ptr_array_set_size (array, index+1);
+ *     g_ptr_array_index (array, index) = data;
+ *
+ *     g_static_rw_lock_writer_unlock (&amp;rwlock);
+ *   }
+ *  </programlisting>
+ * </example>
+ *
+ * This example shows an array which can be accessed by many readers
+ * (the <function>my_array_get()</function> function) simultaneously,
+ * whereas the writers (the <function>my_array_set()</function>
+ * function) will only be allowed once at a time and only if no readers
+ * currently access the array. This is because of the potentially
+ * dangerous resizing of the array. Using these functions is fully
+ * multi-thread safe now.
+ *
+ * Most of the time, writers should have precedence over readers. That
+ * means, for this implementation, that as soon as a writer wants to
+ * lock the data, no other reader is allowed to lock the data, whereas,
+ * of course, the readers that already have locked the data are allowed
+ * to finish their operation. As soon as the last reader unlocks the
+ * data, the writer will lock it.
+ *
+ * Even though #GStaticRWLock is not opaque, it should only be used
+ * with the following functions.
+ *
+ * All of the <function>g_static_rw_lock_*</function> functions can be
+ * used even if g_thread_init() has not been called. Then they do
+ * nothing, apart from <function>g_static_rw_lock_*_trylock</function>,
+ * which does nothing but returning %TRUE.
+ *
+ * <note><para>A read-write lock has a higher overhead than a mutex. For
+ * example, both g_static_rw_lock_reader_lock() and
+ * g_static_rw_lock_reader_unlock() have to lock and unlock a
+ * #GStaticMutex, so it takes at least twice the time to lock and unlock
+ * a #GStaticRWLock that it does to lock and unlock a #GStaticMutex. So
+ * only data structures that are accessed by multiple readers, and which
+ * keep the lock for a considerable time justify a #GStaticRWLock. The
+ * above example most probably would fare better with a
+ * #GStaticMutex.</para></note>
+ **/
+
+/**
+ * G_STATIC_RW_LOCK_INIT:
+ *
+ * A #GStaticRWLock must be initialized with this macro before it can
+ * be used. This macro can used be to initialize a variable, but it
+ * cannot be assigned to a variable. In that case you have to use
+ * g_static_rw_lock_init().
+ *
+ * <informalexample>
+ *  <programlisting>
+ *   GStaticRWLock my_lock = G_STATIC_RW_LOCK_INIT;
+ *  </programlisting>
+ * </informalexample>
+ **/
+
+/**
+ * g_static_rw_lock_init:
+ * @lock: a #GStaticRWLock to be initialized.
+ *
+ * A #GStaticRWLock must be initialized with this function before it
+ * can be used. Alternatively you can initialize it with
+ * #G_STATIC_RW_LOCK_INIT.
+ **/
+void
+g_static_rw_lock_init (GStaticRWLock* lock)
+{
+  static const GStaticRWLock init_lock = G_STATIC_RW_LOCK_INIT;
+
+  g_return_if_fail (lock);
+
+  *lock = init_lock;
+}
+
+inline static void
+g_static_rw_lock_wait (GCond** cond, GStaticMutex* mutex)
+{
+  if (!*cond)
+      *cond = g_cond_new ();
+  g_cond_wait (*cond, g_static_mutex_get_mutex (mutex));
+}
+
+inline static void
+g_static_rw_lock_signal (GStaticRWLock* lock)
+{
+  if (lock->want_to_write && lock->write_cond)
+    g_cond_signal (lock->write_cond);
+  else if (lock->want_to_read && lock->read_cond)
+    g_cond_broadcast (lock->read_cond);
+}
+
+/**
+ * g_static_rw_lock_reader_lock:
+ * @lock: a #GStaticRWLock to lock for reading.
+ *
+ * Locks @lock for reading. There may be unlimited concurrent locks for
+ * reading of a #GStaticRWLock at the same time.  If @lock is already
+ * locked for writing by another thread or if another thread is already
+ * waiting to lock @lock for writing, this function will block until
+ * @lock is unlocked by the other writing thread and no other writing
+ * threads want to lock @lock. This lock has to be unlocked by
+ * g_static_rw_lock_reader_unlock().
+ *
+ * #GStaticRWLock is not recursive. It might seem to be possible to
+ * recursively lock for reading, but that can result in a deadlock, due
+ * to writer preference.
+ **/
+void
+g_static_rw_lock_reader_lock (GStaticRWLock* lock)
+{
+  g_return_if_fail (lock);
+
+  if (!g_threads_got_initialized)
+    return;
+
+  g_static_mutex_lock (&lock->mutex);
+  lock->want_to_read++;
+  while (lock->have_writer || lock->want_to_write)
+    g_static_rw_lock_wait (&lock->read_cond, &lock->mutex);
+  lock->want_to_read--;
+  lock->read_counter++;
+  g_static_mutex_unlock (&lock->mutex);
+}
+
+/**
+ * g_static_rw_lock_reader_trylock:
+ * @lock: a #GStaticRWLock to lock for reading.
+ * @Returns: %TRUE, if @lock could be locked for reading.
+ *
+ * Tries to lock @lock for reading. If @lock is already locked for
+ * writing by another thread or if another thread is already waiting to
+ * lock @lock for writing, immediately returns %FALSE. Otherwise locks
+ * @lock for reading and returns %TRUE. This lock has to be unlocked by
+ * g_static_rw_lock_reader_unlock().
+ **/
+gboolean
+g_static_rw_lock_reader_trylock (GStaticRWLock* lock)
+{
+  gboolean ret_val = FALSE;
+
+  g_return_val_if_fail (lock, FALSE);
+
+  if (!g_threads_got_initialized)
+    return TRUE;
+
+  g_static_mutex_lock (&lock->mutex);
+  if (!lock->have_writer && !lock->want_to_write)
+    {
+      lock->read_counter++;
+      ret_val = TRUE;
+    }
+  g_static_mutex_unlock (&lock->mutex);
+  return ret_val;
+}
+
+/**
+ * g_static_rw_lock_reader_unlock:
+ * @lock: a #GStaticRWLock to unlock after reading.
+ *
+ * Unlocks @lock. If a thread waits to lock @lock for writing and all
+ * locks for reading have been unlocked, the waiting thread is woken up
+ * and can lock @lock for writing.
+ **/
+void
+g_static_rw_lock_reader_unlock  (GStaticRWLock* lock)
+{
+  g_return_if_fail (lock);
+
+  if (!g_threads_got_initialized)
+    return;
+
+  g_static_mutex_lock (&lock->mutex);
+  lock->read_counter--;
+  if (lock->read_counter == 0)
+    g_static_rw_lock_signal (lock);
+  g_static_mutex_unlock (&lock->mutex);
+}
+
+/**
+ * g_static_rw_lock_writer_lock:
+ * @lock: a #GStaticRWLock to lock for writing.
+ *
+ * Locks @lock for writing. If @lock is already locked for writing or
+ * reading by other threads, this function will block until @lock is
+ * completely unlocked and then lock @lock for writing. While this
+ * functions waits to lock @lock, no other thread can lock @lock for
+ * reading. When @lock is locked for writing, no other thread can lock
+ * @lock (neither for reading nor writing). This lock has to be
+ * unlocked by g_static_rw_lock_writer_unlock().
+ **/
+void
+g_static_rw_lock_writer_lock (GStaticRWLock* lock)
+{
+  g_return_if_fail (lock);
+
+  if (!g_threads_got_initialized)
+    return;
+
+  g_static_mutex_lock (&lock->mutex);
+  lock->want_to_write++;
+  while (lock->have_writer || lock->read_counter)
+    g_static_rw_lock_wait (&lock->write_cond, &lock->mutex);
+  lock->want_to_write--;
+  lock->have_writer = TRUE;
+  g_static_mutex_unlock (&lock->mutex);
+}
+
+/**
+ * g_static_rw_lock_writer_trylock:
+ * @lock: a #GStaticRWLock to lock for writing.
+ * @Returns: %TRUE, if @lock could be locked for writing.
+ *
+ * Tries to lock @lock for writing. If @lock is already locked (for
+ * either reading or writing) by another thread, it immediately returns
+ * %FALSE. Otherwise it locks @lock for writing and returns %TRUE. This
+ * lock has to be unlocked by g_static_rw_lock_writer_unlock().
+ **/
+gboolean
+g_static_rw_lock_writer_trylock (GStaticRWLock* lock)
+{
+  gboolean ret_val = FALSE;
+
+  g_return_val_if_fail (lock, FALSE);
+
+  if (!g_threads_got_initialized)
+    return TRUE;
+
+  g_static_mutex_lock (&lock->mutex);
+  if (!lock->have_writer && !lock->read_counter)
+    {
+      lock->have_writer = TRUE;
+      ret_val = TRUE;
+    }
+  g_static_mutex_unlock (&lock->mutex);
+  return ret_val;
+}
+
+/**
+ * g_static_rw_lock_writer_unlock:
+ * @lock: a #GStaticRWLock to unlock after writing.
+ *
+ * Unlocks @lock. If a thread is waiting to lock @lock for writing and
+ * all locks for reading have been unlocked, the waiting thread is
+ * woken up and can lock @lock for writing. If no thread is waiting to
+ * lock @lock for writing, and some thread or threads are waiting to
+ * lock @lock for reading, the waiting threads are woken up and can
+ * lock @lock for reading.
+ **/
+void
+g_static_rw_lock_writer_unlock (GStaticRWLock* lock)
+{
+  g_return_if_fail (lock);
+
+  if (!g_threads_got_initialized)
+    return;
+
+  g_static_mutex_lock (&lock->mutex);
+  lock->have_writer = FALSE;
+  g_static_rw_lock_signal (lock);
+  g_static_mutex_unlock (&lock->mutex);
+}
+
+/**
+ * g_static_rw_lock_free:
+ * @lock: a #GStaticRWLock to be freed.
+ *
+ * Releases all resources allocated to @lock.
+ *
+ * You don't have to call this functions for a #GStaticRWLock with an
+ * unbounded lifetime, i.e. objects declared 'static', but if you have
+ * a #GStaticRWLock as a member of a structure, and the structure is
+ * freed, you should also free the #GStaticRWLock.
+ **/
+void
+g_static_rw_lock_free (GStaticRWLock* lock)
+{
+  g_return_if_fail (lock);
+
+  if (lock->read_cond)
+    {
+      g_cond_free (lock->read_cond);
+      lock->read_cond = NULL;
+    }
+  if (lock->write_cond)
+    {
+      g_cond_free (lock->write_cond);
+      lock->write_cond = NULL;
+    }
+  g_static_mutex_free (&lock->mutex);
+}
+
+/* Unsorted {{{1 ---------------------------------------------------------- */
+
+/**
+ * g_thread_foreach
+ * @thread_func: function to call for all GThread structures
+ * @user_data:   second argument to @thread_func
+ *
+ * Call @thread_func on all existing #GThread structures. Note that
+ * threads may decide to exit while @thread_func is running, so
+ * without intimate knowledge about the lifetime of foreign threads,
+ * @thread_func shouldn't access the GThread* pointer passed in as
+ * first argument. However, @thread_func will not be called for threads
+ * which are known to have exited already.
+ *
+ * Due to thread lifetime checks, this function has an execution complexity
+ * which is quadratic in the number of existing threads.
+ *
+ * Since: 2.10
+ */
+void
+g_thread_foreach (GFunc    thread_func,
+                  gpointer user_data)
+{
+  GSList *slist = NULL;
+  GRealThread *thread;
+  g_return_if_fail (thread_func != NULL);
+  /* snapshot the list of threads for iteration */
+  G_LOCK (g_thread);
+  for (thread = g_thread_all_threads; thread; thread = thread->next)
+    slist = g_slist_prepend (slist, thread);
+  G_UNLOCK (g_thread);
+  /* walk the list, skipping non-existant threads */
+  while (slist)
+    {
+      GSList *node = slist;
+      slist = node->next;
+      /* check whether the current thread still exists */
+      G_LOCK (g_thread);
+      for (thread = g_thread_all_threads; thread; thread = thread->next)
+        if (thread == node->data)
+          break;
+      G_UNLOCK (g_thread);
+      if (thread)
+        thread_func (thread, user_data);
+      g_slist_free_1 (node);
+    }
+}
+
+/**
+ * g_thread_get_initialized
+ *
+ * Indicates if g_thread_init() has been called.
+ *
+ * Returns: %TRUE if threads have been initialized.
+ *
+ * Since: 2.20
+ */
+gboolean
+g_thread_get_initialized ()
+{
+  return g_thread_supported ();
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gthread.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gthread.h
new file mode 100644 (file)
index 0000000..82d40c0
--- /dev/null
@@ -0,0 +1,407 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_THREAD_H__
+#define __G_THREAD_H__
+
+#include <glib/gerror.h>
+#include <glib/gutils.h>        /* for G_INLINE_FUNC */
+#include <glib/gatomic.h>       /* for g_atomic_pointer_get */
+
+G_BEGIN_DECLS
+
+/* GLib Thread support
+ */
+
+extern GQuark g_thread_error_quark (void);
+#define G_THREAD_ERROR g_thread_error_quark ()
+
+typedef enum
+{
+  G_THREAD_ERROR_AGAIN /* Resource temporarily unavailable */
+} GThreadError;
+
+typedef gpointer (*GThreadFunc) (gpointer data);
+
+typedef enum
+{
+  G_THREAD_PRIORITY_LOW,
+  G_THREAD_PRIORITY_NORMAL,
+  G_THREAD_PRIORITY_HIGH,
+  G_THREAD_PRIORITY_URGENT
+} GThreadPriority;
+
+typedef struct _GThread         GThread;
+struct  _GThread
+{
+  /*< private >*/
+  GThreadFunc func;
+  gpointer data;
+  gboolean joinable;
+  GThreadPriority priority;
+};
+
+typedef struct _GMutex          GMutex;
+typedef struct _GCond           GCond;
+typedef struct _GPrivate        GPrivate;
+typedef struct _GStaticPrivate  GStaticPrivate;
+
+typedef struct _GThreadFunctions GThreadFunctions;
+struct _GThreadFunctions
+{
+  GMutex*  (*mutex_new)           (void);
+  void     (*mutex_lock)          (GMutex               *mutex);
+  gboolean (*mutex_trylock)       (GMutex               *mutex);
+  void     (*mutex_unlock)        (GMutex               *mutex);
+  void     (*mutex_free)          (GMutex               *mutex);
+  GCond*   (*cond_new)            (void);
+  void     (*cond_signal)         (GCond                *cond);
+  void     (*cond_broadcast)      (GCond                *cond);
+  void     (*cond_wait)           (GCond                *cond,
+                                   GMutex               *mutex);
+  gboolean (*cond_timed_wait)     (GCond                *cond,
+                                   GMutex               *mutex,
+                                   GTimeVal             *end_time);
+  void      (*cond_free)          (GCond                *cond);
+  GPrivate* (*private_new)        (GDestroyNotify        destructor);
+  gpointer  (*private_get)        (GPrivate             *private_key);
+  void      (*private_set)        (GPrivate             *private_key,
+                                   gpointer              data);
+  void      (*thread_create)      (GThreadFunc           func,
+                                   gpointer              data,
+                                   gulong                stack_size,
+                                   gboolean              joinable,
+                                   gboolean              bound,
+                                   GThreadPriority       priority,
+                                   gpointer              thread,
+                                   GError              **error);
+  void      (*thread_yield)       (void);
+  void      (*thread_join)        (gpointer              thread);
+  void      (*thread_exit)        (void);
+  void      (*thread_set_priority)(gpointer              thread,
+                                   GThreadPriority       priority);
+  void      (*thread_self)        (gpointer              thread);
+  gboolean  (*thread_equal)       (gpointer              thread1,
+                                  gpointer              thread2);
+};
+
+GLIB_VAR GThreadFunctions       g_thread_functions_for_glib_use;
+GLIB_VAR gboolean               g_thread_use_default_impl;
+GLIB_VAR gboolean               g_threads_got_initialized;
+
+GLIB_VAR guint64   (*g_thread_gettime) (void);
+
+/* initializes the mutex/cond/private implementation for glib, might
+ * only be called once, and must not be called directly or indirectly
+ * from another glib-function, e.g. as a callback.
+ */
+void    g_thread_init   (GThreadFunctions       *vtable);
+
+/* Errorcheck mutexes. If you define G_ERRORCHECK_MUTEXES, then all
+ * mutexes will check for re-locking and re-unlocking */
+
+/* Initialize thread system with errorcheck mutexes. vtable must be
+ * NULL. Do not call directly. Use #define G_ERRORCHECK_MUTEXES
+ * instead.
+ */
+void    g_thread_init_with_errorcheck_mutexes (GThreadFunctions* vtable);
+
+/* Checks if thread support is initialized.  Identical to the
+ * g_thread_supported macro but provided for language bindings.
+ */
+gboolean g_thread_get_initialized (void);
+
+/* A random number to recognize debug calls to g_mutex_... */
+#define G_MUTEX_DEBUG_MAGIC 0xf8e18ad7
+
+#ifdef G_ERRORCHECK_MUTEXES
+#define g_thread_init(vtable) g_thread_init_with_errorcheck_mutexes (vtable)
+#endif
+
+/* internal function for fallback static mutex implementation */
+GMutex* g_static_mutex_get_mutex_impl   (GMutex **mutex);
+
+#define g_static_mutex_get_mutex_impl_shortcut(mutex) \
+  (g_atomic_pointer_get (mutex) ? *(mutex) : \
+   g_static_mutex_get_mutex_impl (mutex))
+
+/* shorthands for conditional and unconditional function calls */
+
+#define G_THREAD_UF(op, arglist)                                       \
+    (*g_thread_functions_for_glib_use . op) arglist
+#define G_THREAD_CF(op, fail, arg)                                     \
+    (g_thread_supported () ? G_THREAD_UF (op, arg) : (fail))
+#define G_THREAD_ECF(op, fail, mutex, type)                            \
+    (g_thread_supported () ?                                           \
+      ((type(*)(GMutex*, const gulong, gchar const*))                  \
+      (*g_thread_functions_for_glib_use . op))                         \
+     (mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (fail))
+
+#ifndef G_ERRORCHECK_MUTEXES
+# define g_mutex_lock(mutex)                                           \
+    G_THREAD_CF (mutex_lock,     (void)0, (mutex))
+# define g_mutex_trylock(mutex)                                                \
+    G_THREAD_CF (mutex_trylock,  TRUE,    (mutex))
+# define g_mutex_unlock(mutex)                                         \
+    G_THREAD_CF (mutex_unlock,   (void)0, (mutex))
+# define g_mutex_free(mutex)                                           \
+    G_THREAD_CF (mutex_free,     (void)0, (mutex))
+# define g_cond_wait(cond, mutex)                                      \
+    G_THREAD_CF (cond_wait,      (void)0, (cond, mutex))
+# define g_cond_timed_wait(cond, mutex, abs_time)                      \
+    G_THREAD_CF (cond_timed_wait, TRUE,   (cond, mutex, abs_time))
+#else /* G_ERRORCHECK_MUTEXES */
+# define g_mutex_lock(mutex)                                           \
+    G_THREAD_ECF (mutex_lock,    (void)0, (mutex), void)
+# define g_mutex_trylock(mutex)                                                \
+    G_THREAD_ECF (mutex_trylock, TRUE,    (mutex), gboolean)
+# define g_mutex_unlock(mutex)                                         \
+    G_THREAD_ECF (mutex_unlock,  (void)0, (mutex), void)
+# define g_mutex_free(mutex)                                           \
+    G_THREAD_ECF (mutex_free,    (void)0, (mutex), void)
+# define g_cond_wait(cond, mutex)                                      \
+    (g_thread_supported () ? ((void(*)(GCond*, GMutex*, gulong, gchar*))\
+      g_thread_functions_for_glib_use.cond_wait)                       \
+        (cond, mutex, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : (void) 0)
+# define g_cond_timed_wait(cond, mutex, abs_time)                      \
+    (g_thread_supported () ?                                           \
+      ((gboolean(*)(GCond*, GMutex*, GTimeVal*, gulong, gchar*))       \
+        g_thread_functions_for_glib_use.cond_timed_wait)               \
+          (cond, mutex, abs_time, G_MUTEX_DEBUG_MAGIC, G_STRLOC) : TRUE)
+#endif /* G_ERRORCHECK_MUTEXES */
+
+#if defined(G_THREADS_ENABLED) && defined(G_THREADS_MANDATORY)
+#define g_thread_supported()     1
+#else
+#define g_thread_supported()    (g_threads_got_initialized)
+#endif
+#define g_mutex_new()            G_THREAD_UF (mutex_new,      ())
+#define g_cond_new()             G_THREAD_UF (cond_new,       ())
+#define g_cond_signal(cond)      G_THREAD_CF (cond_signal,    (void)0, (cond))
+#define g_cond_broadcast(cond)   G_THREAD_CF (cond_broadcast, (void)0, (cond))
+#define g_cond_free(cond)        G_THREAD_CF (cond_free,      (void)0, (cond))
+#define g_private_new(destructor) G_THREAD_UF (private_new, (destructor))
+#define g_private_get(private_key) G_THREAD_CF (private_get, \
+                                                ((gpointer)private_key), \
+                                                (private_key))
+#define g_private_set(private_key, value) G_THREAD_CF (private_set, \
+                                                       (void) (private_key = \
+                                                        (GPrivate*) (value)), \
+                                                       (private_key, value))
+#define g_thread_yield()              G_THREAD_CF (thread_yield, (void)0, ())
+
+#define g_thread_create(func, data, joinable, error)                   \
+  (g_thread_create_full (func, data, 0, joinable, FALSE,               \
+                         G_THREAD_PRIORITY_NORMAL, error))
+
+GThread* g_thread_create_full  (GThreadFunc            func,
+                                gpointer               data,
+                                gulong                 stack_size,
+                                gboolean               joinable,
+                                gboolean               bound,
+                                GThreadPriority        priority,
+                                GError               **error);
+GThread* g_thread_self         (void);
+void     g_thread_exit         (gpointer               retval);
+gpointer g_thread_join         (GThread               *thread);
+
+void     g_thread_set_priority (GThread               *thread,
+                                GThreadPriority        priority);
+
+/* GStaticMutexes can be statically initialized with the value
+ * G_STATIC_MUTEX_INIT, and then they can directly be used, that is
+ * much easier, than having to explicitly allocate the mutex before
+ * use
+ */
+#define g_static_mutex_lock(mutex) \
+    g_mutex_lock (g_static_mutex_get_mutex (mutex))
+#define g_static_mutex_trylock(mutex) \
+    g_mutex_trylock (g_static_mutex_get_mutex (mutex))
+#define g_static_mutex_unlock(mutex) \
+    g_mutex_unlock (g_static_mutex_get_mutex (mutex))
+void g_static_mutex_init (GStaticMutex *mutex);
+void g_static_mutex_free (GStaticMutex *mutex);
+
+struct _GStaticPrivate
+{
+  /*< private >*/
+  guint index;
+};
+#define G_STATIC_PRIVATE_INIT { 0 }
+void     g_static_private_init           (GStaticPrivate   *private_key);
+gpointer g_static_private_get            (GStaticPrivate   *private_key);
+void     g_static_private_set            (GStaticPrivate   *private_key,
+                                         gpointer          data,
+                                         GDestroyNotify    notify);
+void     g_static_private_free           (GStaticPrivate   *private_key);
+
+typedef struct _GStaticRecMutex GStaticRecMutex;
+struct _GStaticRecMutex
+{
+  /*< private >*/
+  GStaticMutex mutex;
+  guint depth;
+  GSystemThread owner;
+};
+
+#define G_STATIC_REC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
+void     g_static_rec_mutex_init        (GStaticRecMutex *mutex);
+void     g_static_rec_mutex_lock        (GStaticRecMutex *mutex);
+gboolean g_static_rec_mutex_trylock     (GStaticRecMutex *mutex);
+void     g_static_rec_mutex_unlock      (GStaticRecMutex *mutex);
+void     g_static_rec_mutex_lock_full   (GStaticRecMutex *mutex,
+                                         guint            depth);
+guint    g_static_rec_mutex_unlock_full (GStaticRecMutex *mutex);
+void     g_static_rec_mutex_free        (GStaticRecMutex *mutex);
+
+typedef struct _GStaticRWLock GStaticRWLock;
+struct _GStaticRWLock
+{
+  /*< private >*/
+  GStaticMutex mutex;
+  GCond *read_cond;
+  GCond *write_cond;
+  guint read_counter;
+  gboolean have_writer;
+  guint want_to_read;
+  guint want_to_write;
+};
+
+#define G_STATIC_RW_LOCK_INIT { G_STATIC_MUTEX_INIT, NULL, NULL, 0, FALSE, 0, 0 }
+
+void      g_static_rw_lock_init           (GStaticRWLock* lock);
+void      g_static_rw_lock_reader_lock    (GStaticRWLock* lock);
+gboolean  g_static_rw_lock_reader_trylock (GStaticRWLock* lock);
+void      g_static_rw_lock_reader_unlock  (GStaticRWLock* lock);
+void      g_static_rw_lock_writer_lock    (GStaticRWLock* lock);
+gboolean  g_static_rw_lock_writer_trylock (GStaticRWLock* lock);
+void      g_static_rw_lock_writer_unlock  (GStaticRWLock* lock);
+void      g_static_rw_lock_free           (GStaticRWLock* lock);
+
+void     g_thread_foreach                (GFunc          thread_func,
+                                          gpointer       user_data);
+
+typedef enum
+{
+  G_ONCE_STATUS_NOTCALLED,
+  G_ONCE_STATUS_PROGRESS,
+  G_ONCE_STATUS_READY  
+} GOnceStatus;
+
+typedef struct _GOnce GOnce;
+struct _GOnce
+{
+  volatile GOnceStatus status;
+  volatile gpointer retval;
+};
+
+#define G_ONCE_INIT { G_ONCE_STATUS_NOTCALLED, NULL }
+
+gpointer g_once_impl (GOnce *once, GThreadFunc func, gpointer arg);
+
+#ifdef G_ATOMIC_OP_MEMORY_BARRIER_NEEDED
+# define g_once(once, func, arg) g_once_impl ((once), (func), (arg))
+#else /* !G_ATOMIC_OP_MEMORY_BARRIER_NEEDED*/
+# define g_once(once, func, arg) \
+  (((once)->status == G_ONCE_STATUS_READY) ? \
+   (once)->retval : \
+   g_once_impl ((once), (func), (arg)))
+#endif /* G_ATOMIC_OP_MEMORY_BARRIER_NEEDED */
+
+/* initialize-once guards, keyed by value_location */
+G_INLINE_FUNC gboolean  g_once_init_enter       (volatile gsize *value_location);
+gboolean                g_once_init_enter_impl  (volatile gsize *value_location);
+void                    g_once_init_leave       (volatile gsize *value_location,
+                                                 gsize           initialization_value);
+#if defined (G_CAN_INLINE) || defined (__G_THREAD_C__)
+G_INLINE_FUNC gboolean
+g_once_init_enter (volatile gsize *value_location)
+{
+  if G_LIKELY ((gpointer) g_atomic_pointer_get (value_location) != NULL)
+    return FALSE;
+  else
+    return g_once_init_enter_impl (value_location);
+}
+#endif /* G_CAN_INLINE || __G_THREAD_C__ */
+
+/* these are some convenience macros that expand to nothing if GLib
+ * was configured with --disable-threads. for using StaticMutexes,
+ * you define them with G_LOCK_DEFINE_STATIC (name) or G_LOCK_DEFINE (name)
+ * if you need to export the mutex. With G_LOCK_EXTERN (name) you can
+ * declare such an globally defined lock. name is a unique identifier
+ * for the protected varibale or code portion. locking, testing and
+ * unlocking of such mutexes can be done with G_LOCK(), G_UNLOCK() and
+ * G_TRYLOCK() respectively.
+ */
+extern void glib_dummy_decl (void);
+#define G_LOCK_NAME(name)               g__ ## name ## _lock
+#ifdef  G_THREADS_ENABLED
+#  define G_LOCK_DEFINE_STATIC(name)    static G_LOCK_DEFINE (name)
+#  define G_LOCK_DEFINE(name)           \
+    GStaticMutex G_LOCK_NAME (name) = G_STATIC_MUTEX_INIT
+#  define G_LOCK_EXTERN(name)           extern GStaticMutex G_LOCK_NAME (name)
+
+#  ifdef G_DEBUG_LOCKS
+#    define G_LOCK(name)                G_STMT_START{             \
+        g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,                   \
+               "file %s: line %d (%s): locking: %s ",             \
+               __FILE__,        __LINE__, G_STRFUNC,              \
+               #name);                                            \
+        g_static_mutex_lock (&G_LOCK_NAME (name));                \
+     }G_STMT_END
+#    define G_UNLOCK(name)              G_STMT_START{             \
+        g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,                   \
+               "file %s: line %d (%s): unlocking: %s ",           \
+               __FILE__,        __LINE__, G_STRFUNC,              \
+               #name);                                            \
+       g_static_mutex_unlock (&G_LOCK_NAME (name));               \
+     }G_STMT_END
+#    define G_TRYLOCK(name)                                       \
+        (g_log (G_LOG_DOMAIN, G_LOG_LEVEL_DEBUG,                  \
+               "file %s: line %d (%s): try locking: %s ",         \
+               __FILE__,        __LINE__, G_STRFUNC,              \
+               #name), g_static_mutex_trylock (&G_LOCK_NAME (name)))
+#  else  /* !G_DEBUG_LOCKS */
+#    define G_LOCK(name) g_static_mutex_lock       (&G_LOCK_NAME (name))
+#    define G_UNLOCK(name) g_static_mutex_unlock   (&G_LOCK_NAME (name))
+#    define G_TRYLOCK(name) g_static_mutex_trylock (&G_LOCK_NAME (name))
+#  endif /* !G_DEBUG_LOCKS */
+#else   /* !G_THREADS_ENABLED */
+#  define G_LOCK_DEFINE_STATIC(name)    extern void glib_dummy_decl (void)
+#  define G_LOCK_DEFINE(name)           extern void glib_dummy_decl (void)
+#  define G_LOCK_EXTERN(name)           extern void glib_dummy_decl (void)
+#  define G_LOCK(name)
+#  define G_UNLOCK(name)
+#  define G_TRYLOCK(name)               (TRUE)
+#endif  /* !G_THREADS_ENABLED */
+
+G_END_DECLS
+
+#endif /* __G_THREAD_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gthreadpool.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gthreadpool.c
new file mode 100644 (file)
index 0000000..3bab274
--- /dev/null
@@ -0,0 +1,996 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * GAsyncQueue: thread pool implementation.
+ * Copyright (C) 2000 Sebastian Wilhelmi; University of Karlsruhe
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "gthreadpool.h"
+
+#include "gasyncqueue.h"
+#include "gmain.h"
+#include "gtestutils.h"
+#include "gtimer.h"
+
+/**
+ * SECTION: thread_pools
+ * @title: Thread Pools
+ * @short_description: pools of threads to execute work concurrently
+ * @see_also: <para> <variablelist> <varlistentry>
+ *            <term>#GThread</term> <listitem><para>GLib thread
+ *            system.</para></listitem> </varlistentry> </variablelist>
+ *            </para>
+ *
+ * Sometimes you wish to asynchronously fork out the execution of work
+ * and continue working in your own thread. If that will happen often,
+ * the overhead of starting and destroying a thread each time might be
+ * too high. In such cases reusing already started threads seems like a
+ * good idea. And it indeed is, but implementing this can be tedious
+ * and error-prone.
+ *
+ * Therefore GLib provides thread pools for your convenience. An added
+ * advantage is, that the threads can be shared between the different
+ * subsystems of your program, when they are using GLib.
+ *
+ * To create a new thread pool, you use g_thread_pool_new(). It is
+ * destroyed by g_thread_pool_free().
+ *
+ * If you want to execute a certain task within a thread pool, you call
+ * g_thread_pool_push().
+ *
+ * To get the current number of running threads you call
+ * g_thread_pool_get_num_threads(). To get the number of still
+ * unprocessed tasks you call g_thread_pool_unprocessed(). To control
+ * the maximal number of threads for a thread pool, you use
+ * g_thread_pool_get_max_threads() and g_thread_pool_set_max_threads().
+ *
+ * Finally you can control the number of unused threads, that are kept
+ * alive by GLib for future use. The current number can be fetched with
+ * g_thread_pool_get_num_unused_threads(). The maximal number can be
+ * controlled by g_thread_pool_get_max_unused_threads() and
+ * g_thread_pool_set_max_unused_threads(). All currently unused threads
+ * can be stopped by calling g_thread_pool_stop_unused_threads().
+ **/
+
+#define DEBUG_MSG(x)  
+/* #define DEBUG_MSG(args) g_printerr args ; g_printerr ("\n");    */
+
+typedef struct _GRealThreadPool GRealThreadPool;
+
+/**
+ * GThreadPool:
+ * @func: the function to execute in the threads of this pool
+ * @user_data: the user data for the threads of this pool
+ * @exclusive: are all threads exclusive to this pool
+ *
+ * The #GThreadPool struct represents a thread pool. It has three
+ * public read-only members, but the underlying struct is bigger, so
+ * you must not copy this struct.
+ **/
+struct _GRealThreadPool
+{
+  GThreadPool pool;
+  GAsyncQueue* queue;
+  GCond* cond;
+  gint max_threads;
+  gint num_threads;
+  gboolean running;
+  gboolean immediate;
+  gboolean waiting;
+  GCompareDataFunc sort_func;
+  gpointer sort_user_data;
+};
+
+/* The following is just an address to mark the wakeup order for a
+ * thread, it could be any address (as long, as it isn't a valid
+ * GThreadPool address) */
+static const gpointer wakeup_thread_marker = (gpointer) &g_thread_pool_new;
+static gint wakeup_thread_serial = 0;
+
+/* Here all unused threads are waiting  */
+static GAsyncQueue *unused_thread_queue = NULL;
+static gint unused_threads = 0;
+static gint max_unused_threads = 0;
+static gint kill_unused_threads = 0;
+static guint max_idle_time = 0;
+
+static void             g_thread_pool_queue_push_unlocked (GRealThreadPool  *pool,
+                                                          gpointer          data);
+static void             g_thread_pool_free_internal       (GRealThreadPool  *pool);
+static gpointer         g_thread_pool_thread_proxy        (gpointer          data);
+static void             g_thread_pool_start_thread        (GRealThreadPool  *pool,
+                                                          GError          **error);
+static void             g_thread_pool_wakeup_and_stop_all (GRealThreadPool  *pool);
+static GRealThreadPool* g_thread_pool_wait_for_new_pool   (void);
+static gpointer         g_thread_pool_wait_for_new_task   (GRealThreadPool  *pool);
+
+static void
+g_thread_pool_queue_push_unlocked (GRealThreadPool *pool,
+                                  gpointer         data)
+{
+  if (pool->sort_func) 
+    g_async_queue_push_sorted_unlocked (pool->queue, 
+                                       data,
+                                       pool->sort_func, 
+                                       pool->sort_user_data);
+  else
+    g_async_queue_push_unlocked (pool->queue, data);
+}
+
+static GRealThreadPool*
+g_thread_pool_wait_for_new_pool (void)
+{
+  GRealThreadPool *pool;
+  gint local_wakeup_thread_serial;
+  guint local_max_unused_threads;
+  gint local_max_idle_time;
+  gint last_wakeup_thread_serial;
+  gboolean have_relayed_thread_marker = FALSE;
+
+  local_max_unused_threads = g_atomic_int_get (&max_unused_threads);
+  local_max_idle_time = g_atomic_int_get (&max_idle_time);
+  last_wakeup_thread_serial = g_atomic_int_get (&wakeup_thread_serial);
+
+  g_atomic_int_inc (&unused_threads);
+
+  do
+    {
+      if (g_atomic_int_get (&unused_threads) >= local_max_unused_threads)
+       {
+         /* If this is a superfluous thread, stop it. */
+         pool = NULL;
+       }
+      else if (local_max_idle_time > 0)
+       {
+         /* If a maximal idle time is given, wait for the given time. */
+         GTimeVal end_time;
+
+         g_get_current_time (&end_time);
+         g_time_val_add (&end_time, local_max_idle_time * 1000);
+
+         DEBUG_MSG (("thread %p waiting in global pool for %f seconds.",
+                     g_thread_self (), local_max_idle_time / 1000.0));
+
+         pool = g_async_queue_timed_pop (unused_thread_queue, &end_time);
+       }
+      else
+       {
+         /* If no maximal idle time is given, wait indefinitely. */
+         DEBUG_MSG (("thread %p waiting in global pool.",
+                     g_thread_self ()));
+         pool = g_async_queue_pop (unused_thread_queue);
+       }
+
+      if (pool == wakeup_thread_marker)
+       {
+         local_wakeup_thread_serial = g_atomic_int_get (&wakeup_thread_serial);
+         if (last_wakeup_thread_serial == local_wakeup_thread_serial)
+           {
+             if (!have_relayed_thread_marker)
+             {
+               /* If this wakeup marker has been received for
+                * the second time, relay it. 
+                */
+               DEBUG_MSG (("thread %p relaying wakeup message to "
+                           "waiting thread with lower serial.",
+                           g_thread_self ()));
+
+               g_async_queue_push (unused_thread_queue, wakeup_thread_marker);
+               have_relayed_thread_marker = TRUE;
+
+               /* If a wakeup marker has been relayed, this thread
+                * will get out of the way for 100 microseconds to
+                * avoid receiving this marker again. */
+               g_usleep (100);
+             }
+           }
+         else
+           {
+             if (g_atomic_int_exchange_and_add (&kill_unused_threads, -1) > 0)
+               {
+                 pool = NULL;
+                 break;
+               }
+
+             DEBUG_MSG (("thread %p updating to new limits.",
+                         g_thread_self ()));
+
+             local_max_unused_threads = g_atomic_int_get (&max_unused_threads);
+             local_max_idle_time = g_atomic_int_get (&max_idle_time);
+             last_wakeup_thread_serial = local_wakeup_thread_serial;
+
+             have_relayed_thread_marker = FALSE;
+           }
+       }
+    }
+  while (pool == wakeup_thread_marker);
+
+  g_atomic_int_add (&unused_threads, -1);
+
+  return pool;
+}
+
+static gpointer
+g_thread_pool_wait_for_new_task (GRealThreadPool *pool)
+{
+  gpointer task = NULL;
+
+  if (pool->running || (!pool->immediate &&
+                       g_async_queue_length_unlocked (pool->queue) > 0))
+    {
+      /* This thread pool is still active. */
+      if (pool->num_threads > pool->max_threads && pool->max_threads != -1)
+       {
+         /* This is a superfluous thread, so it goes to the global pool. */
+         DEBUG_MSG (("superfluous thread %p in pool %p.",
+                     g_thread_self (), pool));
+       }
+      else if (pool->pool.exclusive)
+       {
+         /* Exclusive threads stay attached to the pool. */
+         task = g_async_queue_pop_unlocked (pool->queue);
+
+         DEBUG_MSG (("thread %p in exclusive pool %p waits for task "
+                     "(%d running, %d unprocessed).",
+                     g_thread_self (), pool, pool->num_threads,
+                     g_async_queue_length_unlocked (pool->queue)));
+       }
+      else
+       {
+         /* A thread will wait for new tasks for at most 1/2
+          * second before going to the global pool.
+          */
+         GTimeVal end_time;
+
+         g_get_current_time (&end_time);
+         g_time_val_add (&end_time, G_USEC_PER_SEC / 2);       /* 1/2 second */
+
+         DEBUG_MSG (("thread %p in pool %p waits for up to a 1/2 second for task "
+                     "(%d running, %d unprocessed).",
+                     g_thread_self (), pool, pool->num_threads,
+                     g_async_queue_length_unlocked (pool->queue)));
+
+         task = g_async_queue_timed_pop_unlocked (pool->queue, &end_time);
+       }
+    }
+  else
+    {
+      /* This thread pool is inactive, it will no longer process tasks. */
+      DEBUG_MSG (("pool %p not active, thread %p will go to global pool "
+                 "(running: %s, immediate: %s, len: %d).",
+                 pool, g_thread_self (),
+                 pool->running ? "true" : "false",
+                 pool->immediate ? "true" : "false",
+                 g_async_queue_length_unlocked (pool->queue)));
+    }
+
+  return task;
+}
+
+
+static gpointer 
+g_thread_pool_thread_proxy (gpointer data)
+{
+  GRealThreadPool *pool;
+
+  pool = data;
+
+  DEBUG_MSG (("thread %p started for pool %p.", 
+             g_thread_self (), pool));
+
+  g_async_queue_lock (pool->queue);
+
+  while (TRUE)
+    {
+      gpointer task;
+
+      task = g_thread_pool_wait_for_new_task (pool);
+      if (task)
+       {
+         if (pool->running || !pool->immediate)
+           {
+             /* A task was received and the thread pool is active, so
+              * execute the function. 
+              */
+             g_async_queue_unlock (pool->queue);
+             DEBUG_MSG (("thread %p in pool %p calling func.", 
+                         g_thread_self (), pool));
+             pool->pool.func (task, pool->pool.user_data);
+             g_async_queue_lock (pool->queue);
+           }
+       }
+      else
+       {
+         /* No task was received, so this thread goes to the global
+          * pool. 
+          */
+         gboolean free_pool = FALSE;
+         DEBUG_MSG (("thread %p leaving pool %p for global pool.", 
+                     g_thread_self (), pool));
+         pool->num_threads--;
+
+         if (!pool->running)
+           {
+             if (!pool->waiting)
+               {
+                 if (pool->num_threads == 0)
+                   {
+                     /* If the pool is not running and no other
+                      * thread is waiting for this thread pool to
+                      * finish and this is the last thread of this
+                      * pool, free the pool.
+                      */
+                     free_pool = TRUE;
+                   }           
+                 else 
+                   {
+                     /* If the pool is not running and no other
+                      * thread is waiting for this thread pool to
+                      * finish and this is not the last thread of
+                      * this pool and there are no tasks left in the
+                      * queue, wakeup the remaining threads. 
+                      */
+                     if (g_async_queue_length_unlocked (pool->queue) == 
+                         - pool->num_threads)
+                       g_thread_pool_wakeup_and_stop_all (pool);
+                   }
+               }
+             else if (pool->immediate || 
+                      g_async_queue_length_unlocked (pool->queue) <= 0)
+               {
+                 /* If the pool is not running and another thread is
+                  * waiting for this thread pool to finish and there
+                  * are either no tasks left or the pool shall stop
+                  * immediatly, inform the waiting thread of a change
+                  * of the thread pool state. 
+                  */
+                 g_cond_broadcast (pool->cond);
+               }
+           }
+
+         g_async_queue_unlock (pool->queue);
+
+         if (free_pool)
+           g_thread_pool_free_internal (pool);
+
+         if ((pool = g_thread_pool_wait_for_new_pool ()) == NULL) 
+           break;
+
+         g_async_queue_lock (pool->queue);
+         
+         DEBUG_MSG (("thread %p entering pool %p from global pool.", 
+                     g_thread_self (), pool));
+
+         /* pool->num_threads++ is not done here, but in
+           * g_thread_pool_start_thread to make the new started thread
+           * known to the pool, before itself can do it. 
+          */
+       }
+    }
+
+  return NULL;
+}
+
+static void
+g_thread_pool_start_thread (GRealThreadPool  *pool, 
+                           GError          **error)
+{
+  gboolean success = FALSE;
+  
+  if (pool->num_threads >= pool->max_threads && pool->max_threads != -1)
+    /* Enough threads are already running */
+    return;
+
+  g_async_queue_lock (unused_thread_queue);
+
+  if (g_async_queue_length_unlocked (unused_thread_queue) < 0)
+    {
+      g_async_queue_push_unlocked (unused_thread_queue, pool);
+      success = TRUE;
+    }
+
+  g_async_queue_unlock (unused_thread_queue);
+
+  if (!success)
+    {
+      GError *local_error = NULL;
+      /* No thread was found, we have to start a new one */
+      g_thread_create (g_thread_pool_thread_proxy, pool, FALSE, &local_error);
+      
+      if (local_error)
+       {
+         g_propagate_error (error, local_error);
+         return;
+       }
+    }
+
+  /* See comment in g_thread_pool_thread_proxy as to why this is done
+   * here and not there
+   */
+  pool->num_threads++;
+}
+
+/**
+ * g_thread_pool_new: 
+ * @func: a function to execute in the threads of the new thread pool
+ * @user_data: user data that is handed over to @func every time it 
+ *   is called
+ * @max_threads: the maximal number of threads to execute concurrently in 
+ *   the new thread pool, -1 means no limit
+ * @exclusive: should this thread pool be exclusive?
+ * @error: return location for error
+ *
+ * This function creates a new thread pool.
+ *
+ * Whenever you call g_thread_pool_push(), either a new thread is
+ * created or an unused one is reused. At most @max_threads threads
+ * are running concurrently for this thread pool. @max_threads = -1
+ * allows unlimited threads to be created for this thread pool. The
+ * newly created or reused thread now executes the function @func with
+ * the two arguments. The first one is the parameter to
+ * g_thread_pool_push() and the second one is @user_data.
+ *
+ * The parameter @exclusive determines, whether the thread pool owns
+ * all threads exclusive or whether the threads are shared
+ * globally. If @exclusive is %TRUE, @max_threads threads are started
+ * immediately and they will run exclusively for this thread pool until
+ * it is destroyed by g_thread_pool_free(). If @exclusive is %FALSE,
+ * threads are created, when needed and shared between all
+ * non-exclusive thread pools. This implies that @max_threads may not
+ * be -1 for exclusive thread pools.
+ *
+ * @error can be %NULL to ignore errors, or non-%NULL to report
+ * errors. An error can only occur when @exclusive is set to %TRUE and
+ * not all @max_threads threads could be created.
+ *
+ * Return value: the new #GThreadPool
+ **/
+GThreadPool* 
+g_thread_pool_new (GFunc            func,
+                  gpointer         user_data,
+                  gint             max_threads,
+                  gboolean         exclusive,
+                  GError         **error)
+{
+  GRealThreadPool *retval;
+  G_LOCK_DEFINE_STATIC (init);
+
+  g_return_val_if_fail (func, NULL);
+  g_return_val_if_fail (!exclusive || max_threads != -1, NULL);
+  g_return_val_if_fail (max_threads >= -1, NULL);
+  g_return_val_if_fail (g_thread_supported (), NULL);
+
+  retval = g_new (GRealThreadPool, 1);
+
+  retval->pool.func = func;
+  retval->pool.user_data = user_data;
+  retval->pool.exclusive = exclusive;
+  retval->queue = g_async_queue_new ();
+  retval->cond = NULL;
+  retval->max_threads = max_threads;
+  retval->num_threads = 0;
+  retval->running = TRUE;
+  retval->sort_func = NULL;
+  retval->sort_user_data = NULL;
+
+  G_LOCK (init);
+  if (!unused_thread_queue)
+      unused_thread_queue = g_async_queue_new ();
+  G_UNLOCK (init);
+
+  if (retval->pool.exclusive)
+    {
+      g_async_queue_lock (retval->queue);
+  
+      while (retval->num_threads < retval->max_threads)
+       {
+         GError *local_error = NULL;
+         g_thread_pool_start_thread (retval, &local_error);
+         if (local_error)
+           {
+             g_propagate_error (error, local_error);
+             break;
+           }
+       }
+
+      g_async_queue_unlock (retval->queue);
+    }
+
+  return (GThreadPool*) retval;
+}
+
+/**
+ * g_thread_pool_push:
+ * @pool: a #GThreadPool
+ * @data: a new task for @pool
+ * @error: return location for error
+ * 
+ * Inserts @data into the list of tasks to be executed by @pool. When
+ * the number of currently running threads is lower than the maximal
+ * allowed number of threads, a new thread is started (or reused) with
+ * the properties given to g_thread_pool_new (). Otherwise @data stays
+ * in the queue until a thread in this pool finishes its previous task
+ * and processes @data. 
+ *
+ * @error can be %NULL to ignore errors, or non-%NULL to report
+ * errors. An error can only occur when a new thread couldn't be
+ * created. In that case @data is simply appended to the queue of work
+ * to do.  
+ **/
+void 
+g_thread_pool_push (GThreadPool  *pool,
+                   gpointer      data,
+                   GError      **error)
+{
+  GRealThreadPool *real;
+
+  real = (GRealThreadPool*) pool;
+
+  g_return_if_fail (real);
+  g_return_if_fail (real->running);
+
+  g_async_queue_lock (real->queue);
+
+  if (g_async_queue_length_unlocked (real->queue) >= 0)
+    /* No thread is waiting in the queue */
+    g_thread_pool_start_thread (real, error);
+
+  g_thread_pool_queue_push_unlocked (real, data);
+  g_async_queue_unlock (real->queue);
+}
+
+/**
+ * g_thread_pool_set_max_threads:
+ * @pool: a #GThreadPool
+ * @max_threads: a new maximal number of threads for @pool
+ * @error: return location for error
+ * 
+ * Sets the maximal allowed number of threads for @pool. A value of -1
+ * means, that the maximal number of threads is unlimited.
+ *
+ * Setting @max_threads to 0 means stopping all work for @pool. It is
+ * effectively frozen until @max_threads is set to a non-zero value
+ * again.
+ * 
+ * A thread is never terminated while calling @func, as supplied by
+ * g_thread_pool_new (). Instead the maximal number of threads only
+ * has effect for the allocation of new threads in g_thread_pool_push(). 
+ * A new thread is allocated, whenever the number of currently
+ * running threads in @pool is smaller than the maximal number.
+ *
+ * @error can be %NULL to ignore errors, or non-%NULL to report
+ * errors. An error can only occur when a new thread couldn't be
+ * created. 
+ **/
+void
+g_thread_pool_set_max_threads (GThreadPool  *pool,
+                              gint          max_threads,
+                              GError      **error)
+{
+  GRealThreadPool *real;
+  gint to_start;
+
+  real = (GRealThreadPool*) pool;
+
+  g_return_if_fail (real);
+  g_return_if_fail (real->running);
+  g_return_if_fail (!real->pool.exclusive || max_threads != -1);
+  g_return_if_fail (max_threads >= -1);
+
+  g_async_queue_lock (real->queue);
+
+  real->max_threads = max_threads;
+  
+  if (pool->exclusive)
+    to_start = real->max_threads - real->num_threads;
+  else
+    to_start = g_async_queue_length_unlocked (real->queue);
+  
+  for ( ; to_start > 0; to_start--)
+    {
+      GError *local_error = NULL;
+
+      g_thread_pool_start_thread (real, &local_error);
+      if (local_error)
+       {
+         g_propagate_error (error, local_error);
+         break;
+       }
+    }
+   
+  g_async_queue_unlock (real->queue);
+}
+
+/**
+ * g_thread_pool_get_max_threads:
+ * @pool: a #GThreadPool
+ *
+ * Returns the maximal number of threads for @pool.
+ *
+ * Return value: the maximal number of threads
+ **/
+gint
+g_thread_pool_get_max_threads (GThreadPool *pool)
+{
+  GRealThreadPool *real;
+  gint retval;
+
+  real = (GRealThreadPool*) pool;
+
+  g_return_val_if_fail (real, 0);
+  g_return_val_if_fail (real->running, 0);
+
+  g_async_queue_lock (real->queue);
+  retval = real->max_threads;
+  g_async_queue_unlock (real->queue);
+
+  return retval;
+}
+
+/**
+ * g_thread_pool_get_num_threads:
+ * @pool: a #GThreadPool
+ *
+ * Returns the number of threads currently running in @pool.
+ *
+ * Return value: the number of threads currently running
+ **/
+guint
+g_thread_pool_get_num_threads (GThreadPool *pool)
+{
+  GRealThreadPool *real;
+  guint retval;
+
+  real = (GRealThreadPool*) pool;
+
+  g_return_val_if_fail (real, 0);
+  g_return_val_if_fail (real->running, 0);
+
+  g_async_queue_lock (real->queue);
+  retval = real->num_threads;
+  g_async_queue_unlock (real->queue);
+
+  return retval;
+}
+
+/**
+ * g_thread_pool_unprocessed:
+ * @pool: a #GThreadPool
+ *
+ * Returns the number of tasks still unprocessed in @pool.
+ *
+ * Return value: the number of unprocessed tasks
+ **/
+guint
+g_thread_pool_unprocessed (GThreadPool *pool)
+{
+  GRealThreadPool *real;
+  gint unprocessed;
+
+  real = (GRealThreadPool*) pool;
+
+  g_return_val_if_fail (real, 0);
+  g_return_val_if_fail (real->running, 0);
+
+  unprocessed = g_async_queue_length (real->queue);
+
+  return MAX (unprocessed, 0);
+}
+
+/**
+ * g_thread_pool_free:
+ * @pool: a #GThreadPool
+ * @immediate: should @pool shut down immediately?
+ * @wait_: should the function wait for all tasks to be finished?
+ *
+ * Frees all resources allocated for @pool.
+ *
+ * If @immediate is %TRUE, no new task is processed for
+ * @pool. Otherwise @pool is not freed before the last task is
+ * processed. Note however, that no thread of this pool is
+ * interrupted, while processing a task. Instead at least all still
+ * running threads can finish their tasks before the @pool is freed.
+ *
+ * If @wait_ is %TRUE, the functions does not return before all tasks
+ * to be processed (dependent on @immediate, whether all or only the
+ * currently running) are ready. Otherwise the function returns immediately.
+ *
+ * After calling this function @pool must not be used anymore. 
+ **/
+void
+g_thread_pool_free (GThreadPool *pool,
+                   gboolean     immediate,
+                   gboolean     wait_)
+{
+  GRealThreadPool *real;
+
+  real = (GRealThreadPool*) pool;
+
+  g_return_if_fail (real);
+  g_return_if_fail (real->running);
+
+  /* If there's no thread allowed here, there is not much sense in
+   * not stopping this pool immediately, when it's not empty 
+   */
+  g_return_if_fail (immediate || 
+                   real->max_threads != 0 || 
+                   g_async_queue_length (real->queue) == 0);
+
+  g_async_queue_lock (real->queue);
+
+  real->running = FALSE;
+  real->immediate = immediate;
+  real->waiting = wait_;
+
+  if (wait_)
+    {
+      real->cond = g_cond_new ();
+
+      while (g_async_queue_length_unlocked (real->queue) != -real->num_threads &&
+            !(immediate && real->num_threads == 0))
+       g_cond_wait (real->cond, _g_async_queue_get_mutex (real->queue));
+    }
+
+  if (immediate || g_async_queue_length_unlocked (real->queue) == -real->num_threads)
+    {
+      /* No thread is currently doing something (and nothing is left
+       * to process in the queue) 
+       */
+      if (real->num_threads == 0) 
+       {
+         /* No threads left, we clean up */
+         g_async_queue_unlock (real->queue);
+         g_thread_pool_free_internal (real);
+         return;
+       }
+
+      g_thread_pool_wakeup_and_stop_all (real);
+    }
+  
+  /* The last thread should cleanup the pool */
+  real->waiting = FALSE; 
+  g_async_queue_unlock (real->queue);
+}
+
+static void
+g_thread_pool_free_internal (GRealThreadPool* pool)
+{
+  g_return_if_fail (pool);
+  g_return_if_fail (pool->running == FALSE);
+  g_return_if_fail (pool->num_threads == 0);
+
+  g_async_queue_unref (pool->queue);
+
+  if (pool->cond)
+    g_cond_free (pool->cond);
+
+  g_free (pool);
+}
+
+static void
+g_thread_pool_wakeup_and_stop_all (GRealThreadPool* pool)
+{
+  guint i;
+  
+  g_return_if_fail (pool);
+  g_return_if_fail (pool->running == FALSE);
+  g_return_if_fail (pool->num_threads != 0);
+
+  pool->immediate = TRUE; 
+
+  for (i = 0; i < pool->num_threads; i++)
+    g_thread_pool_queue_push_unlocked (pool, GUINT_TO_POINTER (1));
+}
+
+/**
+ * g_thread_pool_set_max_unused_threads:
+ * @max_threads: maximal number of unused threads
+ *
+ * Sets the maximal number of unused threads to @max_threads. If
+ * @max_threads is -1, no limit is imposed on the number of unused
+ * threads.
+ **/
+void
+g_thread_pool_set_max_unused_threads (gint max_threads)
+{
+  g_return_if_fail (max_threads >= -1);  
+
+  g_atomic_int_set (&max_unused_threads, max_threads);
+
+  if (max_threads != -1)
+    {
+      max_threads -= g_atomic_int_get (&unused_threads);
+      if (max_threads < 0)
+       {
+         g_atomic_int_set (&kill_unused_threads, -max_threads);
+         g_atomic_int_inc (&wakeup_thread_serial);
+
+         g_async_queue_lock (unused_thread_queue);
+
+         do
+           {
+             g_async_queue_push_unlocked (unused_thread_queue,
+                                          wakeup_thread_marker);
+           }
+         while (++max_threads);
+
+         g_async_queue_unlock (unused_thread_queue);
+       }
+    }
+}
+
+/**
+ * g_thread_pool_get_max_unused_threads:
+ * 
+ * Returns the maximal allowed number of unused threads.
+ *
+ * Return value: the maximal number of unused threads
+ **/
+gint
+g_thread_pool_get_max_unused_threads (void)
+{
+  return g_atomic_int_get (&max_unused_threads);
+}
+
+/**
+ * g_thread_pool_get_num_unused_threads:
+ * 
+ * Returns the number of currently unused threads.
+ *
+ * Return value: the number of currently unused threads
+ **/
+guint 
+g_thread_pool_get_num_unused_threads (void)
+{
+  return g_atomic_int_get (&unused_threads);
+}
+
+/**
+ * g_thread_pool_stop_unused_threads:
+ * 
+ * Stops all currently unused threads. This does not change the
+ * maximal number of unused threads. This function can be used to
+ * regularly stop all unused threads e.g. from g_timeout_add().
+ **/
+void
+g_thread_pool_stop_unused_threads (void)
+{ 
+  guint oldval;
+
+  oldval = g_thread_pool_get_max_unused_threads ();
+
+  g_thread_pool_set_max_unused_threads (0);
+  g_thread_pool_set_max_unused_threads (oldval);
+}
+
+/**
+ * g_thread_pool_set_sort_function:
+ * @pool: a #GThreadPool
+ * @func: the #GCompareDataFunc used to sort the list of tasks. 
+ *     This function is passed two tasks. It should return
+ *     0 if the order in which they are handled does not matter, 
+ *     a negative value if the first task should be processed before
+ *     the second or a positive value if the second task should be 
+ *     processed first.
+ * @user_data: user data passed to @func.
+ *
+ * Sets the function used to sort the list of tasks. This allows the
+ * tasks to be processed by a priority determined by @func, and not
+ * just in the order in which they were added to the pool.
+ *
+ * Note, if the maximum number of threads is more than 1, the order
+ * that threads are executed can not be guranteed 100%. Threads are
+ * scheduled by the operating system and are executed at random. It
+ * cannot be assumed that threads are executed in the order they are
+ * created. 
+ *
+ * Since: 2.10
+ **/
+void 
+g_thread_pool_set_sort_function (GThreadPool      *pool,
+                                GCompareDataFunc  func,
+                                gpointer          user_data)
+{ 
+  GRealThreadPool *real;
+
+  real = (GRealThreadPool*) pool;
+
+  g_return_if_fail (real);
+  g_return_if_fail (real->running);
+
+  g_async_queue_lock (real->queue);
+
+  real->sort_func = func;
+  real->sort_user_data = user_data;
+  
+  if (func) 
+    g_async_queue_sort_unlocked (real->queue, 
+                                real->sort_func,
+                                real->sort_user_data);
+
+  g_async_queue_unlock (real->queue);
+}
+
+/**
+ * g_thread_pool_set_max_idle_time:
+ * @interval: the maximum @interval (1/1000ths of a second) a thread
+ *     can be idle. 
+ *
+ * This function will set the maximum @interval that a thread waiting
+ * in the pool for new tasks can be idle for before being
+ * stopped. This function is similar to calling
+ * g_thread_pool_stop_unused_threads() on a regular timeout, except,
+ * this is done on a per thread basis.    
+ *
+ * By setting @interval to 0, idle threads will not be stopped.
+ *  
+ * This function makes use of g_async_queue_timed_pop () using
+ * @interval.
+ *
+ * Since: 2.10
+ **/
+void
+g_thread_pool_set_max_idle_time (guint interval)
+{ 
+  guint i;
+
+  g_atomic_int_set (&max_idle_time, interval);
+
+  i = g_atomic_int_get (&unused_threads);
+  if (i > 0)
+    {
+      g_atomic_int_inc (&wakeup_thread_serial);
+      g_async_queue_lock (unused_thread_queue);
+
+      do
+       {
+         g_async_queue_push_unlocked (unused_thread_queue,
+                                      wakeup_thread_marker);
+       }
+      while (--i);
+
+      g_async_queue_unlock (unused_thread_queue);
+    }
+}
+
+/**
+ * g_thread_pool_get_max_idle_time:
+ * 
+ * This function will return the maximum @interval that a thread will
+ * wait in the thread pool for new tasks before being stopped.
+ *
+ * If this function returns 0, threads waiting in the thread pool for
+ * new work are not stopped.
+ *
+ * Return value: the maximum @interval to wait for new tasks in the
+ *     thread pool before stopping the thread (1/1000ths of a second).
+ *  
+ * Since: 2.10
+ **/
+guint
+g_thread_pool_get_max_idle_time (void)
+{ 
+  return g_atomic_int_get (&max_idle_time);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gthreadpool.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gthreadpool.h
new file mode 100644 (file)
index 0000000..d586424
--- /dev/null
@@ -0,0 +1,114 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_THREADPOOL_H__
+#define __G_THREADPOOL_H__
+
+#include <glib/gthread.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GThreadPool     GThreadPool;
+
+/* Thread Pools
+ */
+
+/* The real GThreadPool is bigger, so you may only create a thread
+ * pool with the constructor function */
+struct _GThreadPool
+{
+  GFunc func;
+  gpointer user_data;
+  gboolean exclusive;
+};
+
+/* Get a thread pool with the function func, at most max_threads may
+ * run at a time (max_threads == -1 means no limit), exclusive == TRUE
+ * means, that the threads shouldn't be shared and that they will be
+ * prestarted (otherwise they are started as needed) user_data is the
+ * 2nd argument to the func */
+GThreadPool*    g_thread_pool_new             (GFunc            func,
+                                               gpointer         user_data,
+                                               gint             max_threads,
+                                               gboolean         exclusive,
+                                               GError         **error);
+
+/* Push new data into the thread pool. This task is assigned to a thread later
+ * (when the maximal number of threads is reached for that pool) or now
+ * (otherwise). If necessary a new thread will be started. The function
+ * returns immediatly */
+void            g_thread_pool_push            (GThreadPool     *pool,
+                                               gpointer         data,
+                                               GError         **error);
+
+/* Set the number of threads, which can run concurrently for that pool, -1
+ * means no limit. 0 means has the effect, that the pool won't process
+ * requests until the limit is set higher again */
+void            g_thread_pool_set_max_threads (GThreadPool     *pool,
+                                               gint             max_threads,
+                                               GError         **error);
+gint            g_thread_pool_get_max_threads (GThreadPool     *pool);
+
+/* Get the number of threads assigned to that pool. This number doesn't
+ * necessarily represent the number of working threads in that pool */
+guint           g_thread_pool_get_num_threads (GThreadPool     *pool);
+
+/* Get the number of unprocessed items in the pool */
+guint           g_thread_pool_unprocessed     (GThreadPool     *pool);
+
+/* Free the pool, immediate means, that all unprocessed items in the queue
+ * wont be processed, wait means, that the function doesn't return immediatly,
+ * but after all threads in the pool are ready processing items. immediate
+ * does however not mean, that threads are killed. */
+void            g_thread_pool_free            (GThreadPool     *pool,
+                                               gboolean         immediate,
+                                               gboolean         wait_);
+
+/* Set the maximal number of unused threads before threads will be stopped by
+ * GLib, -1 means no limit */
+void            g_thread_pool_set_max_unused_threads (gint      max_threads);
+gint            g_thread_pool_get_max_unused_threads (void);
+guint           g_thread_pool_get_num_unused_threads (void);
+
+/* Stop all currently unused threads, but leave the limit untouched */
+void            g_thread_pool_stop_unused_threads    (void);
+
+/* Set sort function for priority threading */
+void            g_thread_pool_set_sort_function      (GThreadPool      *pool,
+                                                     GCompareDataFunc  func,
+                                                     gpointer          user_data);
+
+/* Set maximum time a thread can be idle in the pool before it is stopped */
+void            g_thread_pool_set_max_idle_time      (guint             interval);
+guint           g_thread_pool_get_max_idle_time      (void);
+
+G_END_DECLS
+
+#endif /* __G_THREADPOOL_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gthreadprivate.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gthreadprivate.h
new file mode 100644 (file)
index 0000000..c75924c
--- /dev/null
@@ -0,0 +1,69 @@
+/* GLIB - Library of useful routines for C programming
+ *
+ * gthreadprivate.h - GLib internal thread system related declarations.
+ *
+ *  Copyright (C) 2003 Sebastian Wilhelmi
+ *
+ * The Gnome 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 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *   Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_THREADPRIVATE_H__
+#define __G_THREADPRIVATE_H__
+
+G_BEGIN_DECLS
+
+/* System thread identifier comparision and assignment */
+#if GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P
+# define g_system_thread_equal_simple(thread1, thread2)                        \
+   ((thread1).dummy_pointer == (thread2).dummy_pointer)
+# define g_system_thread_assign(dest, src)                             \
+   ((dest).dummy_pointer = (src).dummy_pointer)
+#else /* GLIB_SIZEOF_SYSTEM_THREAD != SIZEOF_VOID_P */
+# define g_system_thread_equal_simple(thread1, thread2)                        \
+   (memcmp (&(thread1), &(thread2), GLIB_SIZEOF_SYSTEM_THREAD) == 0)
+# define g_system_thread_assign(dest, src)                             \
+   (memcpy (&(dest), &(src), GLIB_SIZEOF_SYSTEM_THREAD))
+#endif /* GLIB_SIZEOF_SYSTEM_THREAD == SIZEOF_VOID_P */
+
+#define g_system_thread_equal(thread1, thread2)                                \
+  (g_thread_functions_for_glib_use.thread_equal ?                      \
+   g_thread_functions_for_glib_use.thread_equal (&(thread1), &(thread2)) :\
+   g_system_thread_equal_simple((thread1), (thread2)))
+
+/* Is called from gthread/gthread-impl.c */
+void g_thread_init_glib (void);
+
+/* base initializers, may only use g_mutex_new(), g_cond_new() */
+G_GNUC_INTERNAL void _g_mem_thread_init_noprivate_nomessage (void);
+/* initializers that may also use g_private_new() */
+G_GNUC_INTERNAL void _g_slice_thread_init_nomessage        (void);
+G_GNUC_INTERNAL void _g_messages_thread_init_nomessage      (void);
+
+/* full fledged initializers */
+G_GNUC_INTERNAL void _g_convert_thread_init (void);
+G_GNUC_INTERNAL void _g_rand_thread_init (void);
+G_GNUC_INTERNAL void _g_main_thread_init (void);
+G_GNUC_INTERNAL void _g_atomic_thread_init (void);
+G_GNUC_INTERNAL void _g_utils_thread_init (void);
+G_GNUC_INTERNAL void _g_futex_thread_init (void);
+
+#ifdef G_OS_WIN32
+G_GNUC_INTERNAL void _g_win32_thread_init (void);
+#endif /* G_OS_WIN32 */
+
+G_END_DECLS
+
+#endif /* __G_THREADPRIVATE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gtimer.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gtimer.c
new file mode 100644 (file)
index 0000000..bc5b54c
--- /dev/null
@@ -0,0 +1,579 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+#include "glibconfig.h"
+
+#include <stdlib.h>
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif /* HAVE_UNISTD_H */
+
+#include <sys/time.h>
+#include <time.h>
+#ifndef G_OS_WIN32
+#include <errno.h>
+#endif /* G_OS_WIN32 */
+
+#ifdef G_OS_WIN32
+#include <windows.h>
+#endif /* G_OS_WIN32 */
+
+#include "gtimer.h"
+
+#include "gmem.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "gthread.h"
+
+/**
+ * SECTION: timers
+ * @title: Timers
+ * @short_description: keep track of elapsed time
+ *
+ * #GTimer records a start time, and counts microseconds elapsed since
+ * that time. This is done somewhat differently on different platforms,
+ * and can be tricky to get exactly right, so #GTimer provides a
+ * portable/convenient interface.
+ *
+ * <note><para>
+ *  #GTimer uses a higher-quality clock when thread support is available.
+ *  Therefore, calling g_thread_init() while timers are running may lead to
+ *  unreliable results. It is best to call g_thread_init() before starting any
+ *  timers, if you are using threads at all.
+ * </para></note>
+ **/
+
+#define G_NSEC_PER_SEC 1000000000
+
+#define GETTIME(v) (v = g_thread_gettime ())
+
+/**
+ * GTimer:
+ *
+ * Opaque datatype that records a start time.
+ **/
+struct _GTimer
+{
+  guint64 start;
+  guint64 end;
+
+  guint active : 1;
+};
+
+/**
+ * g_timer_new:
+ * @Returns: a new #GTimer.
+ *
+ * Creates a new timer, and starts timing (i.e. g_timer_start() is
+ * implicitly called for you).
+ **/
+GTimer*
+g_timer_new (void)
+{
+  GTimer *timer;
+
+  timer = g_new (GTimer, 1);
+  timer->active = TRUE;
+
+  GETTIME (timer->start);
+
+  return timer;
+}
+
+/**
+ * g_timer_destroy:
+ * @timer: a #GTimer to destroy.
+ *
+ * Destroys a timer, freeing associated resources.
+ **/
+void
+g_timer_destroy (GTimer *timer)
+{
+  g_return_if_fail (timer != NULL);
+
+  g_free (timer);
+}
+
+/**
+ * g_timer_start:
+ * @timer: a #GTimer.
+ *
+ * Marks a start time, so that future calls to g_timer_elapsed() will
+ * report the time since g_timer_start() was called. g_timer_new()
+ * automatically marks the start time, so no need to call
+ * g_timer_start() immediately after creating the timer.
+ **/
+void
+g_timer_start (GTimer *timer)
+{
+  g_return_if_fail (timer != NULL);
+
+  timer->active = TRUE;
+
+  GETTIME (timer->start);
+}
+
+/**
+ * g_timer_stop:
+ * @timer: a #GTimer.
+ *
+ * Marks an end time, so calls to g_timer_elapsed() will return the
+ * difference between this end time and the start time.
+ **/
+void
+g_timer_stop (GTimer *timer)
+{
+  g_return_if_fail (timer != NULL);
+
+  timer->active = FALSE;
+
+  GETTIME (timer->end);
+}
+
+/**
+ * g_timer_reset:
+ * @timer: a #GTimer.
+ *
+ * This function is useless; it's fine to call g_timer_start() on an
+ * already-started timer to reset the start time, so g_timer_reset()
+ * serves no purpose.
+ **/
+void
+g_timer_reset (GTimer *timer)
+{
+  g_return_if_fail (timer != NULL);
+
+  GETTIME (timer->start);
+}
+
+/**
+ * g_timer_continue:
+ * @timer: a #GTimer.
+ *
+ * Resumes a timer that has previously been stopped with
+ * g_timer_stop(). g_timer_stop() must be called before using this
+ * function.
+ *
+ * Since: 2.4
+ **/
+void
+g_timer_continue (GTimer *timer)
+{
+  guint64 elapsed;
+
+  g_return_if_fail (timer != NULL);
+  g_return_if_fail (timer->active == FALSE);
+
+  /* Get elapsed time and reset timer start time
+   *  to the current time minus the previously
+   *  elapsed interval.
+   */
+
+  elapsed = timer->end - timer->start;
+
+  GETTIME (timer->start);
+
+  timer->start -= elapsed;
+
+  timer->active = TRUE;
+}
+
+/**
+ * g_timer_elapsed:
+ * @timer: a #GTimer.
+ * @microseconds: return location for the fractional part of seconds
+ *                elapsed, in microseconds (that is, the total number
+ *                of microseconds elapsed, modulo 1000000), or %NULL
+ * @Returns: seconds elapsed as a floating point value, including any
+ *           fractional part.
+ *
+ * If @timer has been started but not stopped, obtains the time since
+ * the timer was started. If @timer has been stopped, obtains the
+ * elapsed time between the time it was started and the time it was
+ * stopped. The return value is the number of seconds elapsed,
+ * including any fractional part. The @microseconds out parameter is
+ * essentially useless.
+ *
+ * <warning><para>
+ *  Calling initialization functions, in particular g_thread_init(), while a
+ *  timer is running will cause invalid return values from this function.
+ * </para></warning>
+ **/
+gdouble
+g_timer_elapsed (GTimer *timer,
+                gulong *microseconds)
+{
+  gdouble total;
+  gint64 elapsed;
+
+  g_return_val_if_fail (timer != NULL, 0);
+
+  if (timer->active)
+    GETTIME (timer->end);
+
+  elapsed = timer->end - timer->start;
+
+  total = elapsed / 1e9;
+
+  if (microseconds)
+    *microseconds = (elapsed / 1000) % 1000000;
+
+  return total;
+}
+
+void
+g_usleep (gulong microseconds)
+{
+#ifdef G_OS_WIN32
+  Sleep (microseconds / 1000);
+#else /* !G_OS_WIN32 */
+# ifdef HAVE_NANOSLEEP
+  struct timespec request, remaining;
+  request.tv_sec = microseconds / G_USEC_PER_SEC;
+  request.tv_nsec = 1000 * (microseconds % G_USEC_PER_SEC);
+  while (nanosleep (&request, &remaining) == -1 && errno == EINTR)
+    request = remaining;
+# else /* !HAVE_NANOSLEEP */
+#  ifdef HAVE_NSLEEP
+  /* on AIX, nsleep is analogous to nanosleep */
+  struct timespec request, remaining;
+  request.tv_sec = microseconds / G_USEC_PER_SEC;
+  request.tv_nsec = 1000 * (microseconds % G_USEC_PER_SEC);
+  while (nsleep (&request, &remaining) == -1 && errno == EINTR)
+    request = remaining;
+#  else /* !HAVE_NSLEEP */
+  if (g_thread_supported ())
+    {
+      static GStaticMutex mutex = G_STATIC_MUTEX_INIT;
+      static GCond* cond = NULL;
+      GTimeVal end_time;
+      
+      g_get_current_time (&end_time);
+      if (microseconds > G_MAXLONG)
+       {
+         microseconds -= G_MAXLONG;
+         g_time_val_add (&end_time, G_MAXLONG);
+       }
+      g_time_val_add (&end_time, microseconds);
+
+      g_static_mutex_lock (&mutex);
+      
+      if (!cond)
+       cond = g_cond_new ();
+      
+      while (g_cond_timed_wait (cond, g_static_mutex_get_mutex (&mutex), 
+                               &end_time))
+       /* do nothing */;
+      
+      g_static_mutex_unlock (&mutex);
+    }
+  else
+    {
+      struct timeval tv;
+      tv.tv_sec = microseconds / G_USEC_PER_SEC;
+      tv.tv_usec = microseconds % G_USEC_PER_SEC;
+      select(0, NULL, NULL, NULL, &tv);
+    }
+#  endif /* !HAVE_NSLEEP */
+# endif /* !HAVE_NANOSLEEP */
+#endif /* !G_OS_WIN32 */
+}
+
+/**
+ * g_time_val_add:
+ * @time_: a #GTimeVal
+ * @microseconds: number of microseconds to add to @time
+ *
+ * Adds the given number of microseconds to @time_. @microseconds can
+ * also be negative to decrease the value of @time_.
+ **/
+void 
+g_time_val_add (GTimeVal *time_, glong microseconds)
+{
+  g_return_if_fail (time_->tv_usec >= 0 && time_->tv_usec < G_USEC_PER_SEC);
+
+  if (microseconds >= 0)
+    {
+      time_->tv_usec += microseconds % G_USEC_PER_SEC;
+      time_->tv_sec += microseconds / G_USEC_PER_SEC;
+      if (time_->tv_usec >= G_USEC_PER_SEC)
+       {
+         time_->tv_usec -= G_USEC_PER_SEC;
+         time_->tv_sec++;
+       }
+    }
+  else
+    {
+      microseconds *= -1;
+      time_->tv_usec -= microseconds % G_USEC_PER_SEC;
+      time_->tv_sec -= microseconds / G_USEC_PER_SEC;
+      if (time_->tv_usec < 0)
+       {
+         time_->tv_usec += G_USEC_PER_SEC;
+         time_->tv_sec--;
+       }      
+    }
+}
+
+/* converts a broken down date representation, relative to UTC, to
+ * a timestamp; it uses timegm() if it's available.
+ */
+static time_t
+mktime_utc (struct tm *tm)
+{
+  time_t retval;
+  
+#ifndef HAVE_TIMEGM
+  static const gint days_before[] =
+  {
+    0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334
+  };
+#endif
+
+#ifndef HAVE_TIMEGM
+  if (tm->tm_mon < 0 || tm->tm_mon > 11)
+    return (time_t) -1;
+
+  retval = (tm->tm_year - 70) * 365;
+  retval += (tm->tm_year - 68) / 4;
+  retval += days_before[tm->tm_mon] + tm->tm_mday - 1;
+  
+  if (tm->tm_year % 4 == 0 && tm->tm_mon < 2)
+    retval -= 1;
+  
+  retval = ((((retval * 24) + tm->tm_hour) * 60) + tm->tm_min) * 60 + tm->tm_sec;
+#else
+  retval = timegm (tm);
+#endif /* !HAVE_TIMEGM */
+  
+  return retval;
+}
+
+/**
+ * g_time_val_from_iso8601:
+ * @iso_date: an ISO 8601 encoded date string
+ * @time_: a #GTimeVal
+ *
+ * Converts a string containing an ISO 8601 encoded date and time
+ * to a #GTimeVal and puts it into @time_.
+ *
+ * Return value: %TRUE if the conversion was successful.
+ *
+ * Since: 2.12
+ */
+gboolean
+g_time_val_from_iso8601 (const gchar *iso_date,
+                        GTimeVal    *time_)
+{
+  struct tm tm = {0};
+  long val;
+
+  g_return_val_if_fail (iso_date != NULL, FALSE);
+  g_return_val_if_fail (time_ != NULL, FALSE);
+
+  /* Ensure that the first character is a digit,
+   * the first digit of the date, otherwise we don't
+   * have an ISO 8601 date */
+  while (g_ascii_isspace (*iso_date))
+    iso_date++;
+
+  if (*iso_date == '\0')
+    return FALSE;
+
+  if (!g_ascii_isdigit (*iso_date) && *iso_date != '-' && *iso_date != '+')
+    return FALSE;
+
+  val = strtoul (iso_date, (char **)&iso_date, 10);
+  if (*iso_date == '-')
+    {
+      /* YYYY-MM-DD */
+      tm.tm_year = val - 1900;
+      iso_date++;
+      tm.tm_mon = strtoul (iso_date, (char **)&iso_date, 10) - 1;
+      
+      if (*iso_date++ != '-')
+        return FALSE;
+      
+      tm.tm_mday = strtoul (iso_date, (char **)&iso_date, 10);
+    }
+  else
+    {
+      /* YYYYMMDD */
+      tm.tm_mday = val % 100;
+      tm.tm_mon = (val % 10000) / 100 - 1;
+      tm.tm_year = val / 10000 - 1900;
+    }
+
+  if (*iso_date != 'T')
+    {
+      /* Date only */
+      if (*iso_date == '\0')
+        return TRUE;
+      return FALSE;
+    }
+
+  iso_date++;
+
+  /* If there is a 'T' then there has to be a time */
+  if (!g_ascii_isdigit (*iso_date))
+    return FALSE;
+
+  val = strtoul (iso_date, (char **)&iso_date, 10);
+  if (*iso_date == ':')
+    {
+      /* hh:mm:ss */
+      tm.tm_hour = val;
+      iso_date++;
+      tm.tm_min = strtoul (iso_date, (char **)&iso_date, 10);
+      
+      if (*iso_date++ != ':')
+        return FALSE;
+      
+      tm.tm_sec = strtoul (iso_date, (char **)&iso_date, 10);
+    }
+  else
+    {
+      /* hhmmss */
+      tm.tm_sec = val % 100;
+      tm.tm_min = (val % 10000) / 100;
+      tm.tm_hour = val / 10000;
+    }
+
+  time_->tv_usec = 0;
+  
+  if (*iso_date == ',' || *iso_date == '.')
+    {
+      glong mul = 100000;
+
+      while (g_ascii_isdigit (*++iso_date))
+        {
+          time_->tv_usec += (*iso_date - '0') * mul;
+          mul /= 10;
+        }
+    }
+    
+  /* Now parse the offset and convert tm to a time_t */
+  if (*iso_date == 'Z')
+    {
+      iso_date++;
+      time_->tv_sec = mktime_utc (&tm);
+    }
+  else if (*iso_date == '+' || *iso_date == '-')
+    {
+      gint sign = (*iso_date == '+') ? -1 : 1;
+      
+      val = strtoul (iso_date + 1, (char **)&iso_date, 10);
+      
+      if (*iso_date == ':')
+        val = 60 * val + strtoul (iso_date + 1, (char **)&iso_date, 10);
+      else
+        val = 60 * (val / 100) + (val % 100);
+
+      time_->tv_sec = mktime_utc (&tm) + (time_t) (60 * val * sign);
+    }
+  else
+    {
+      /* No "Z" or offset, so local time */
+      tm.tm_isdst = -1; /* locale selects DST */
+      time_->tv_sec = mktime (&tm);
+    }
+
+  while (g_ascii_isspace (*iso_date))
+    iso_date++;
+
+  return *iso_date == '\0';
+}
+
+/**
+ * g_time_val_to_iso8601:
+ * @time_: a #GTimeVal
+ * 
+ * Converts @time_ into an ISO 8601 encoded string, relative to the
+ * Coordinated Universal Time (UTC).
+ *
+ * Return value: a newly allocated string containing an ISO 8601 date
+ *
+ * Since: 2.12
+ */
+gchar *
+g_time_val_to_iso8601 (GTimeVal *time_)
+{
+  gchar *retval;
+  struct tm *tm;
+#ifdef HAVE_GMTIME_R
+  struct tm tm_;
+#endif
+  time_t secs;
+  
+  g_return_val_if_fail (time_->tv_usec >= 0 && time_->tv_usec < G_USEC_PER_SEC, NULL);
+
+ secs = time_->tv_sec;
+#ifdef _WIN32
+ tm = gmtime (&secs);
+#else
+#ifdef HAVE_GMTIME_R
+  tm = gmtime_r (&secs, &tm_);
+#else
+  tm = gmtime (&secs);
+#endif
+#endif
+
+  if (time_->tv_usec != 0)
+    {
+      /* ISO 8601 date and time format, with fractionary seconds:
+       *   YYYY-MM-DDTHH:MM:SS.MMMMMMZ
+       */
+      retval = g_strdup_printf ("%4d-%02d-%02dT%02d:%02d:%02d.%06ldZ",
+                                tm->tm_year + 1900,
+                                tm->tm_mon + 1,
+                                tm->tm_mday,
+                                tm->tm_hour,
+                                tm->tm_min,
+                                tm->tm_sec,
+                                time_->tv_usec);
+    }
+  else
+    {
+      /* ISO 8601 date and time format:
+       *   YYYY-MM-DDTHH:MM:SSZ
+       */
+      retval = g_strdup_printf ("%4d-%02d-%02dT%02d:%02d:%02dZ",
+                                tm->tm_year + 1900,
+                                tm->tm_mon + 1,
+                                tm->tm_mday,
+                                tm->tm_hour,
+                                tm->tm_min,
+                                tm->tm_sec);
+    }
+  
+  return retval;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gtimer.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gtimer.h
new file mode 100644 (file)
index 0000000..743eed1
--- /dev/null
@@ -0,0 +1,65 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_TIMER_H__
+#define __G_TIMER_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+/* Timer
+ */
+
+/* microseconds per second */
+typedef struct _GTimer         GTimer;
+
+#define G_USEC_PER_SEC 1000000
+
+GTimer*  g_timer_new            (void);
+void    g_timer_destroy         (GTimer      *timer);
+void    g_timer_start           (GTimer      *timer);
+void    g_timer_stop            (GTimer      *timer);
+void    g_timer_reset           (GTimer      *timer);
+void    g_timer_continue        (GTimer      *timer);
+gdouble  g_timer_elapsed         (GTimer      *timer,
+                                 gulong      *microseconds);
+
+void     g_usleep                (gulong       microseconds);
+
+void     g_time_val_add          (GTimeVal    *time_, 
+                                  glong        microseconds);
+gboolean g_time_val_from_iso8601 (const gchar *iso_date,
+                                 GTimeVal    *time_);
+gchar*   g_time_val_to_iso8601   (GTimeVal    *time_) G_GNUC_MALLOC;
+
+G_END_DECLS
+
+#endif /* __G_TIMER_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gtimezone.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gtimezone.c
new file mode 100644 (file)
index 0000000..a909fc5
--- /dev/null
@@ -0,0 +1,774 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+/* Prologue {{{1 */
+
+#include "gtimezoneprivate.h"
+
+#include <string.h>
+#include <stdlib.h>
+#include <signal.h>
+
+#include "gmappedfile.h"
+#include "gtestutils.h"
+#include "gfileutils.h"
+#include "gstrfuncs.h"
+#include "ghash.h"
+#include "gthread.h"
+#include "gbuffer.h"
+
+/**
+ * SECTION:timezone
+ * @title: GTimeZone
+ * @short_description: A structure representing a time zone
+ * @see_also: #GDateTime
+ *
+ * #GTimeZone is a structure that represents a time zone, at no
+ * particular point in time.  It is refcounted and immutable.
+ *
+ * #GTimeZone is available since GLib 2.26.
+ */
+
+/**
+ * GTimeZone:
+ *
+ * #GDateTime is an opaque structure whose members cannot be accessed
+ * directly.
+ *
+ * Since: 2.26
+ **/
+
+/* zoneinfo file format {{{1 */
+
+/* unaligned */
+typedef struct { gchar bytes[8]; } gint64_be;
+typedef struct { gchar bytes[4]; } gint32_be;
+typedef struct { gchar bytes[4]; } guint32_be;
+
+static inline gint64 gint64_from_be (const gint64_be be) {
+  gint64 tmp; memcpy (&tmp, &be, sizeof tmp); return GINT64_FROM_BE (tmp);
+}
+
+static inline gint32 gint32_from_be (const gint32_be be) {
+  gint32 tmp; memcpy (&tmp, &be, sizeof tmp); return GINT32_FROM_BE (tmp);
+}
+
+static inline guint32 guint32_from_be (const guint32_be be) {
+  guint32 tmp; memcpy (&tmp, &be, sizeof tmp); return GUINT32_FROM_BE (tmp);
+}
+
+struct tzhead
+{
+  gchar      tzh_magic[4];
+  gchar      tzh_version;
+  guchar     tzh_reserved[15];
+
+  guint32_be tzh_ttisgmtcnt;
+  guint32_be tzh_ttisstdcnt;
+  guint32_be tzh_leapcnt;
+  guint32_be tzh_timecnt;
+  guint32_be tzh_typecnt;
+  guint32_be tzh_charcnt;
+};
+
+struct ttinfo
+{
+  gint32_be tt_gmtoff;
+  guint8    tt_isdst;
+  guint8    tt_abbrind;
+};
+
+/* GTimeZone structure and lifecycle {{{1 */
+struct _GTimeZone
+{
+  gchar   *name;
+
+  GBuffer *zoneinfo;
+
+  const struct tzhead *header;
+  const struct ttinfo *infos;
+  const gint64_be     *trans;
+  const guint8        *indices;
+  const gchar         *abbrs;
+  gint                 timecnt;
+
+  gint     ref_count;
+};
+
+G_LOCK_DEFINE_STATIC (time_zones);
+static GHashTable/*<string?, GTimeZone>*/ *time_zones;
+
+static guint
+g_str_hash0 (gconstpointer data)
+{
+  return data ? g_str_hash (data) : 0;
+}
+
+static gboolean
+g_str_equal0 (gconstpointer a,
+              gconstpointer b)
+{
+  if (a == b)
+    return TRUE;
+
+  if (!a || !b)
+    return FALSE;
+
+  return g_str_equal (a, b);
+}
+
+/**
+ * g_time_zone_unref:
+ * @tz: a #GTimeZone
+ *
+ * Decreases the reference count on @tz.
+ *
+ * Since: 2.26
+ **/
+void
+g_time_zone_unref (GTimeZone *tz)
+{
+  g_assert (tz->ref_count > 0);
+
+  if (g_atomic_int_dec_and_test (&tz->ref_count))
+    {
+      G_LOCK(time_zones);
+      g_hash_table_remove (time_zones, tz->name);
+      G_UNLOCK(time_zones);
+
+      if (tz->zoneinfo)
+        g_buffer_unref (tz->zoneinfo);
+
+      g_free (tz->name);
+
+      g_slice_free (GTimeZone, tz);
+    }
+}
+
+/**
+ * g_time_zone_ref:
+ * @tz: a #GTimeZone
+ *
+ * Increases the reference count on @tz.
+ *
+ * Returns: a new reference to @tz.
+ *
+ * Since: 2.26
+ **/
+GTimeZone *
+g_time_zone_ref (GTimeZone *tz)
+{
+  g_assert (tz->ref_count > 0);
+
+  g_atomic_int_inc (&tz->ref_count);
+
+  return tz;
+}
+
+/* fake zoneinfo creation (for RFC3339/ISO 8601 timezones) {{{1 */
+/*
+ * parses strings of the form 'hh' 'hhmm' or 'hh:mm' where:
+ *  - hh is 00 to 23
+ *  - mm is 00 to 59
+ */
+gboolean
+parse_time (const gchar *time,
+            gint32      *offset)
+{
+  if (*time < '0' || '2' < *time)
+    return FALSE;
+
+  *offset = 10 * 60 * 60 * (*time++ - '0');
+
+  if (*time < '0' || '9' < *time)
+    return FALSE;
+
+  *offset += 60 * 60 * (*time++ - '0');
+
+  if (*offset > 23 * 60 * 60)
+    return FALSE;
+
+  if (*time == '\0')
+    return TRUE;
+
+  if (*time == ':')
+    time++;
+
+  if (*time < '0' || '5' < *time)
+    return FALSE;
+
+  *offset += 10 * 60 * (*time++ - '0');
+
+  if (*time < '0' || '9' < *time)
+    return FALSE;
+
+  *offset += 60 * (*time++ - '0');
+
+  return *time == '\0';
+}
+
+gboolean
+parse_constant_offset (const gchar *name,
+                       gint32      *offset)
+{
+  switch (*name++)
+    {
+    case 'Z':
+      *offset = 0;
+      return !*name;
+
+    case '+':
+      return parse_time (name, offset);
+
+    case '-':
+      if (parse_time (name, offset))
+        {
+          *offset = -*offset;
+          return TRUE;
+        }
+
+    default:
+      return FALSE;
+    }
+}
+
+static GBuffer *
+zone_for_constant_offset (const gchar *name)
+{
+  const gchar fake_zoneinfo_headers[] =
+    "TZif" "2..." "...." "...." "...."
+    "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0"
+    "TZif" "2..." "...." "...." "...."
+    "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\0" "\0\0\0\1" "\0\0\0\7";
+  struct {
+    struct tzhead headers[2];
+    struct ttinfo info;
+    gchar abbr[8];
+  } *fake;
+  gint32 offset;
+
+  if (name == NULL || !parse_constant_offset (name, &offset))
+    return NULL;
+
+  offset = GINT32_TO_BE (offset);
+
+  fake = g_malloc (sizeof *fake);
+  memcpy (fake, fake_zoneinfo_headers, sizeof fake_zoneinfo_headers);
+  memcpy (&fake->info.tt_gmtoff, &offset, sizeof offset);
+  fake->info.tt_isdst = FALSE;
+  fake->info.tt_abbrind = 0;
+  strcpy (fake->abbr, name);
+
+  return g_buffer_new_take_data (fake, sizeof *fake);
+}
+
+/* Construction {{{1 */
+/**
+ * g_time_zone_new:
+ * @identifier: (allow-none): a timezone identifier
+ *
+ * Creates a #GTimeZone corresponding to @identifier.
+ *
+ * @identifier can either be an RFC3339/ISO 8601 time offset or
+ * something that would pass as a valid value for the
+ * <varname>TZ</varname> environment variable (including %NULL).
+ *
+ * Valid RFC3339 time offsets are <literal>"Z"</literal> (for UTC) or
+ * <literal>"±hh:mm"</literal>.  ISO 8601 additionally specifies
+ * <literal>"±hhmm"</literal> and <literal>"±hh"</literal>.
+ *
+ * The <varname>TZ</varname> environment variable typically corresponds
+ * to the name of a file in the zoneinfo database, but there are many
+ * other possibilities.  Note that those other possibilities are not
+ * currently implemented, but are planned.
+ *
+ * g_time_zone_new_local() calls this function with the value of the
+ * <varname>TZ</varname> environment variable.  This function itself is
+ * independent of the value of <varname>TZ</varname>, but if @identifier
+ * is %NULL then <filename>/etc/localtime</filename> will be consulted
+ * to discover the correct timezone.
+ *
+ * See <ulink
+ * url='http://tools.ietf.org/html/rfc3339#section-5.6'>RFC3339
+ * §5.6</ulink> for a precise definition of valid RFC3339 time offsets
+ * (the <varname>time-offset</varname> expansion) and ISO 8601 for the
+ * full list of valid time offsets.  See <ulink
+ * url='http://www.gnu.org/s/libc/manual/html_node/TZ-Variable.html'>The
+ * GNU C Library manual</ulink> for an explanation of the possible
+ * values of the <varname>TZ</varname> environment variable.
+ *
+ * You should release the return value by calling g_time_zone_unref()
+ * when you are done with it.
+ *
+ * Returns: the requested timezone
+ *
+ * Since: 2.26
+ **/
+GTimeZone *
+g_time_zone_new (const gchar *identifier)
+{
+  GTimeZone *tz;
+
+  G_LOCK (time_zones);
+  if (time_zones == NULL)
+    time_zones = g_hash_table_new (g_str_hash0,
+                                   g_str_equal0);
+
+  tz = g_hash_table_lookup (time_zones, identifier);
+  if (tz == NULL)
+    {
+      tz = g_slice_new0 (GTimeZone);
+      tz->name = g_strdup (identifier);
+      tz->ref_count = 0;
+
+      tz->zoneinfo = zone_for_constant_offset (identifier);
+
+      if (tz->zoneinfo == NULL)
+        {
+          gchar *filename;
+
+          if (identifier != NULL)
+            {
+              const gchar *tzdir;
+
+              tzdir = getenv ("TZDIR");
+              if (tzdir == NULL)
+                tzdir = "/usr/share/zoneinfo";
+
+              filename = g_build_filename (tzdir, identifier, NULL);
+            }
+          else
+            filename = g_strdup ("/etc/localtime");
+
+          tz->zoneinfo = (GBuffer *) g_mapped_file_new (filename, FALSE, NULL);
+          g_free (filename);
+        }
+
+      if (tz->zoneinfo != NULL)
+        {
+          const struct tzhead *header = tz->zoneinfo->data;
+          gsize size = tz->zoneinfo->size;
+
+          /* we only bother to support version 2 */
+          if (size < sizeof (struct tzhead) || memcmp (header, "TZif2", 5))
+            {
+              g_buffer_unref (tz->zoneinfo);
+              tz->zoneinfo = NULL;
+            }
+          else
+            {
+              gint typecnt;
+
+              /* we trust the file completely. */
+              tz->header = (const struct tzhead *)
+                (((const gchar *) (header + 1)) +
+                  guint32_from_be(header->tzh_ttisgmtcnt) +
+                  guint32_from_be(header->tzh_ttisstdcnt) +
+                  8 * guint32_from_be(header->tzh_leapcnt) +
+                  5 * guint32_from_be(header->tzh_timecnt) +
+                  6 * guint32_from_be(header->tzh_typecnt) +
+                  guint32_from_be(header->tzh_charcnt));
+
+              typecnt     = guint32_from_be (tz->header->tzh_typecnt);
+              tz->timecnt = guint32_from_be (tz->header->tzh_timecnt);
+              tz->trans   = (gconstpointer) (tz->header + 1);
+              tz->indices = (gconstpointer) (tz->trans + tz->timecnt);
+              tz->infos   = (gconstpointer) (tz->indices + tz->timecnt);
+              tz->abbrs   = (gconstpointer) (tz->infos + typecnt);
+            }
+        }
+
+      g_hash_table_insert (time_zones, tz->name, tz);
+    }
+  g_atomic_int_inc (&tz->ref_count);
+  G_UNLOCK (time_zones);
+
+  return tz;
+}
+
+/**
+ * g_time_zone_new_utc:
+ *
+ * Creates a #GTimeZone corresponding to UTC.
+ *
+ * This is equivalent to calling g_time_zone_new() with a value like
+ * "Z", "UTC", "+00", etc.
+ *
+ * You should release the return value by calling g_time_zone_unref()
+ * when you are done with it.
+ *
+ * Returns: the universal timezone
+ *
+ * Since: 2.26
+ **/
+GTimeZone *
+g_time_zone_new_utc (void)
+{
+  return g_time_zone_new ("UTC");
+}
+
+/**
+ * g_time_zone_new_local:
+ *
+ * Creates a #GTimeZone corresponding to local time.
+ *
+ * This is equivalent to calling g_time_zone_new() with the value of the
+ * <varname>TZ</varname> environment variable (including the possibility
+ * of %NULL).  Changes made to <varname>TZ</varname> after the first
+ * call to this function may or may not be noticed by future calls.
+ *
+ * You should release the return value by calling g_time_zone_unref()
+ * when you are done with it.
+ *
+ * Returns: the local timezone
+ *
+ * Since: 2.26
+ **/
+GTimeZone *
+g_time_zone_new_local (void)
+{
+  return g_time_zone_new (getenv ("TZ"));
+}
+
+/* Internal helpers {{{1 */
+inline static const struct ttinfo *
+interval_info (GTimeZone *tz,
+               gint       interval)
+{
+  if (interval)
+    return tz->infos + tz->indices[interval - 1];
+
+  return tz->infos;
+}
+
+inline static gint64
+interval_start (GTimeZone *tz,
+                gint       interval)
+{
+  if (interval)
+    return gint64_from_be (tz->trans[interval - 1]);
+
+  return G_MININT64;
+}
+
+inline static gint64
+interval_end (GTimeZone *tz,
+              gint       interval)
+{
+  if (interval < tz->timecnt)
+    return gint64_from_be (tz->trans[interval]) - 1;
+
+  return G_MAXINT64;
+}
+
+inline static gint32
+interval_offset (GTimeZone *tz,
+                 gint       interval)
+{
+  return gint32_from_be (interval_info (tz, interval)->tt_gmtoff);
+}
+
+inline static gboolean
+interval_isdst (GTimeZone *tz,
+                gint       interval)
+{
+  return interval_info (tz, interval)->tt_isdst;
+}
+
+inline static guint8
+interval_abbrind (GTimeZone *tz,
+                  gint       interval)
+{
+  return interval_info (tz, interval)->tt_abbrind;
+}
+
+inline static gint64
+interval_local_start (GTimeZone *tz,
+                      gint       interval)
+{
+  if (interval)
+    return interval_start (tz, interval) + interval_offset (tz, interval);
+
+  return G_MININT64;
+}
+
+inline static gint64
+interval_local_end (GTimeZone *tz,
+                    gint       interval)
+{
+  if (interval < tz->timecnt)
+    return interval_end (tz, interval) + interval_offset (tz, interval);
+
+  return G_MAXINT64;
+}
+
+static gboolean
+interval_valid (GTimeZone *tz,
+                gint       interval)
+{
+  return interval <= tz->timecnt;
+}
+
+/* g_time_zone_find_interval() {{{1 */
+
+/**
+ * g_time_zone_adjust_time:
+ * @tz: a #GTimeZone
+ * @type: the #GTimeType of @time
+ * @time: a pointer to a number of seconds since January 1, 1970
+ *
+ * Finds an interval within @tz that corresponds to the given @time,
+ * possibly adjusting @time if required to fit into an interval.
+ * The meaning of @time depends on @type.
+ *
+ * This function is similar to g_time_zone_find_interval(), with the
+ * difference that it always succeeds (by making the adjustments
+ * described below).
+ *
+ * In any of the cases where g_time_zone_find_interval() succeeds then
+ * this function returns the same value, without modifying @time.
+ *
+ * This function may, however, modify @time in order to deal with
+ * non-existent times.  If the non-existent local @time of 02:30 were
+ * requested on March 13th 2010 in Toronto then this function would
+ * adjust @time to be 03:00 and return the interval containing the
+ * adjusted time.
+ *
+ * Returns: the interval containing @time, never -1
+ *
+ * Since: 2.26
+ **/
+gint
+g_time_zone_adjust_time (GTimeZone *tz,
+                         GTimeType  type,
+                         gint64    *time)
+{
+  gint i;
+
+  if (tz->zoneinfo == NULL)
+    return 0;
+
+  /* find the interval containing *time UTC
+   * TODO: this could be binary searched (or better) */
+  for (i = 0; i < tz->timecnt; i++)
+    if (*time <= interval_end (tz, i))
+      break;
+
+  g_assert (interval_start (tz, i) <= *time && *time <= interval_end (tz, i));
+
+  if (type != G_TIME_TYPE_UNIVERSAL)
+    {
+      if (*time < interval_local_start (tz, i))
+        /* if time came before the start of this interval... */
+        {
+          i--;
+
+          /* if it's not in the previous interval... */
+          if (*time > interval_local_end (tz, i))
+            {
+              /* it doesn't exist.  fast-forward it. */
+              i++;
+              *time = interval_local_start (tz, i);
+            }
+        }
+
+      else if (*time > interval_local_end (tz, i))
+        /* if time came after the end of this interval... */
+        {
+          i++;
+
+          /* if it's not in the next interval... */
+          if (*time < interval_local_start (tz, i))
+            /* it doesn't exist.  fast-forward it. */
+            *time = interval_local_start (tz, i);
+        }
+
+      else if (interval_isdst (tz, i) != type)
+        /* it's in this interval, but dst flag doesn't match.
+         * check neighbours for a better fit. */
+        {
+          if (i && *time <= interval_local_end (tz, i - 1))
+            i--;
+
+          else if (i < tz->timecnt &&
+                   *time >= interval_local_start (tz, i + 1))
+            i++;
+        }
+    }
+
+  return i;
+}
+
+/**
+ * g_time_zone_find_interval:
+ * @tz: a #GTimeZone
+ * @type: the #GTimeType of @time
+ * @time: a number of seconds since January 1, 1970
+ *
+ * Finds an the interval within @tz that corresponds to the given @time.
+ * The meaning of @time depends on @type.
+ *
+ * If @type is %G_TIME_TYPE_UNIVERSAL then this function will always
+ * succeed (since universal time is monotonic and continuous).
+ *
+ * Otherwise @time is treated is local time.  The distinction between
+ * %G_TIME_TYPE_STANDARD and %G_TIME_TYPE_DAYLIGHT is ignored except in
+ * the case that the given @time is ambiguous.  In Toronto, for example,
+ * 01:30 on November 7th 2010 occured twice (once inside of daylight
+ * savings time and the next, an hour later, outside of daylight savings
+ * time).  In this case, the different value of @type would result in a
+ * different interval being returned.
+ *
+ * It is still possible for this function to fail.  In Toronto, for
+ * example, 02:00 on March 14th 2010 does not exist (due to the leap
+ * forward to begin daylight savings time).  -1 is returned in that
+ * case.
+ *
+ * Returns: the interval containing @time, or -1 in case of failure
+ *
+ * Since: 2.26
+ */
+gint
+g_time_zone_find_interval (GTimeZone *tz,
+                           GTimeType  type,
+                           gint64     time)
+{
+  gint i;
+
+  if (tz->zoneinfo == NULL)
+    return 0;
+
+  for (i = 0; i < tz->timecnt; i++)
+    if (time <= interval_end (tz, i))
+      break;
+
+  if (type == G_TIME_TYPE_UNIVERSAL)
+    return i;
+
+  if (time < interval_local_start (tz, i))
+    {
+      if (time > interval_local_end (tz, --i))
+        return -1;
+    }
+
+  else if (time > interval_local_end (tz, i))
+    {
+      if (time < interval_local_start (tz, ++i))
+        return -1;
+    }
+
+  else if (interval_isdst (tz, i) != type)
+    {
+      if (i && time <= interval_local_end (tz, i - 1))
+        i--;
+
+      else if (i < tz->timecnt && time >= interval_local_start (tz, i + 1))
+        i++;
+    }
+
+  return i;
+}
+
+/* Public API accessors {{{1 */
+
+/**
+ * g_time_zone_get_abbreviation:
+ * @tz: a #GTimeZone
+ * @interval: an interval within the timezone
+ *
+ * Determines the time zone abbreviation to be used during a particular
+ * @interval of time in the time zone @tz.
+ *
+ * For example, in Toronto this is currently "EST" during the winter
+ * months and "EDT" during the summer months when daylight savings time
+ * is in effect.
+ *
+ * Returns: the time zone abbreviation, which belongs to @tz
+ *
+ * Since: 2.26
+ **/
+const gchar *
+g_time_zone_get_abbreviation (GTimeZone *tz,
+                              gint       interval)
+{
+  g_return_val_if_fail (interval_valid (tz, interval), NULL);
+
+  if (tz->header == NULL)
+    return "UTC";
+
+  return tz->abbrs + interval_abbrind (tz, interval);
+}
+
+/**
+ * g_time_zone_get_offset:
+ * @tz: a #GTimeZone
+ * @interval: an interval within the timezone
+ *
+ * Determines the offset to UTC in effect during a particular @interval
+ * of time in the time zone @tz.
+ *
+ * The offset is the number of seconds that you add to UTC time to
+ * arrive at local time for @tz (ie: negative numbers for time zones
+ * west of GMT, positive numbers for east).
+ *
+ * Returns: the number of seconds that should be added to UTC to get the
+ *          local time in @tz
+ *
+ * Since: 2.26
+ **/
+gint32
+g_time_zone_get_offset (GTimeZone *tz,
+                        gint       interval)
+{
+  g_return_val_if_fail (interval_valid (tz, interval), 0);
+
+  if (tz->header == NULL)
+    return 0;
+
+  return interval_offset (tz, interval);
+}
+
+/**
+ * g_time_zone_is_dst:
+ * @tz: a #GTimeZone
+ * @interval: an interval within the timezone
+ *
+ * Determines if daylight savings time is in effect during a particular
+ * @interval of time in the time zone @tz.
+ *
+ * Returns: %TRUE if daylight savings time is in effect
+ *
+ * Since: 2.26
+ **/
+gboolean
+g_time_zone_is_dst (GTimeZone *tz,
+                    gint       interval)
+{
+  g_return_val_if_fail (interval_valid (tz, interval), FALSE);
+
+  if (tz->header == NULL)
+    return FALSE;
+
+  return interval_isdst (tz, interval);
+}
+
+/* Epilogue {{{1 */
+/* vim:set foldmethod=marker: */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gtimezone.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gtimezone.h
new file mode 100644 (file)
index 0000000..1032a3c
--- /dev/null
@@ -0,0 +1,44 @@
+/*
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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 of the
+ * licence, 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., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
+ * USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_TIME_ZONE_H__
+#define __G_TIME_ZONE_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GTimeZone GTimeZone;
+
+GTimeZone *             g_time_zone_new                                 (const gchar *identifier);
+GTimeZone *             g_time_zone_new_utc                             (void);
+GTimeZone *             g_time_zone_new_local                           (void);
+
+GTimeZone *             g_time_zone_ref                                 (GTimeZone   *tz);
+void                    g_time_zone_unref                               (GTimeZone   *tz);
+
+G_END_DECLS
+
+#endif /* __G_TIME_ZONE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gtimezoneprivate.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gtimezoneprivate.h
new file mode 100644 (file)
index 0000000..767d310
--- /dev/null
@@ -0,0 +1,48 @@
+#ifndef __G_TIME_ZONE_PRIVATE_H__
+#define __G_TIME_ZONE_PRIVATE_H__
+
+#include "gtimezone.h"
+
+/*< internal >
+ * GTimeType:
+ * @G_TIME_TYPE_STANDARD: the time is in local standard time
+ * @G_TIME_TYPE_DAYLIGHT: the time is in local daylight time
+ * @G_TIME_TYPE_UNIVERSAL: the time is in UTC
+ *
+ * Disambiguates a given time in two ways.
+ *
+ * First, specifies if the given time is in universal or local time.
+ *
+ * Second, if the time is in local time, specifies if it is local
+ * standard time or local daylight time.  This is important for the case
+ * where the same local time occurs twice (during daylight savings time
+ * transitions, for example).
+ */
+typedef enum
+{
+  G_TIME_TYPE_STANDARD,
+  G_TIME_TYPE_DAYLIGHT,
+  G_TIME_TYPE_UNIVERSAL
+} GTimeType;
+
+G_GNUC_INTERNAL
+gint                    g_time_zone_find_interval                       (GTimeZone   *tz,
+                                                                         GTimeType    type,
+                                                                         gint64       time);
+
+G_GNUC_INTERNAL
+gint                    g_time_zone_adjust_time                         (GTimeZone   *tz,
+                                                                         GTimeType    type,
+                                                                         gint64      *time);
+
+G_GNUC_INTERNAL
+const gchar *           g_time_zone_get_abbreviation                    (GTimeZone   *tz,
+                                                                         gint         interval);
+G_GNUC_INTERNAL
+gint32                  g_time_zone_get_offset                          (GTimeZone   *tz,
+                                                                         gint         interval);
+G_GNUC_INTERNAL
+gboolean                g_time_zone_is_dst                              (GTimeZone   *tz,
+                                                                         gint         interval);
+
+#endif /* __G_TIME_ZONE_PRIVATE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gtree.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gtree.c
new file mode 100644 (file)
index 0000000..8a4387f
--- /dev/null
@@ -0,0 +1,1414 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/* 
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "gtree.h"
+
+#include "gatomic.h"
+#include "gtestutils.h"
+
+/**
+ * SECTION: trees-binary
+ * @title: Balanced Binary Trees
+ * @short_description: a sorted collection of key/value pairs optimized
+ *                     for searching and traversing in order
+ *
+ * The #GTree structure and its associated functions provide a sorted
+ * collection of key/value pairs optimized for searching and traversing
+ * in order.
+ *
+ * To create a new #GTree use g_tree_new().
+ *
+ * To insert a key/value pair into a #GTree use g_tree_insert().
+ *
+ * To lookup the value corresponding to a given key, use
+ * g_tree_lookup() and g_tree_lookup_extended().
+ *
+ * To find out the number of nodes in a #GTree, use g_tree_nnodes(). To
+ * get the height of a #GTree, use g_tree_height().
+ *
+ * To traverse a #GTree, calling a function for each node visited in
+ * the traversal, use g_tree_foreach().
+ *
+ * To remove a key/value pair use g_tree_remove().
+ *
+ * To destroy a #GTree, use g_tree_destroy().
+ **/
+
+#undef G_TREE_DEBUG
+
+#define MAX_GTREE_HEIGHT 40
+
+typedef struct _GTreeNode  GTreeNode;
+
+/**
+ * GTree:
+ *
+ * The <structname>GTree</structname> struct is an opaque data
+ * structure representing a <link
+ * linkend="glib-Balanced-Binary-Trees">Balanced Binary Tree</link>. It
+ * should be accessed only by using the following functions.
+ **/
+struct _GTree
+{
+  GTreeNode        *root;
+  GCompareDataFunc  key_compare;
+  GDestroyNotify    key_destroy_func;
+  GDestroyNotify    value_destroy_func;
+  gpointer          key_compare_data;
+  guint             nnodes;
+  gint              ref_count;
+};
+
+struct _GTreeNode
+{
+  gpointer   key;         /* key for this node */
+  gpointer   value;       /* value stored at this node */
+  GTreeNode *left;        /* left subtree */
+  GTreeNode *right;       /* right subtree */
+  gint8      balance;     /* height (left) - height (right) */
+  guint8     left_child;  
+  guint8     right_child;
+};
+
+
+static GTreeNode* g_tree_node_new                   (gpointer       key,
+                                                    gpointer       value);
+static void       g_tree_insert_internal            (GTree         *tree,
+                                                    gpointer       key,
+                                                    gpointer       value,
+                                                    gboolean       replace);
+static gboolean   g_tree_remove_internal            (GTree         *tree,
+                                                    gconstpointer  key,
+                                                    gboolean       steal);
+static GTreeNode* g_tree_node_balance               (GTreeNode     *node);
+static GTreeNode *g_tree_find_node                  (GTree         *tree,
+                                                    gconstpointer  key);
+static gint       g_tree_node_pre_order             (GTreeNode     *node,
+                                                    GTraverseFunc  traverse_func,
+                                                    gpointer       data);
+static gint       g_tree_node_in_order              (GTreeNode     *node,
+                                                    GTraverseFunc  traverse_func,
+                                                    gpointer       data);
+static gint       g_tree_node_post_order            (GTreeNode     *node,
+                                                    GTraverseFunc  traverse_func,
+                                                    gpointer       data);
+static gpointer   g_tree_node_search                (GTreeNode     *node,
+                                                    GCompareFunc   search_func,
+                                                    gconstpointer  data);
+static GTreeNode* g_tree_node_rotate_left           (GTreeNode     *node);
+static GTreeNode* g_tree_node_rotate_right          (GTreeNode     *node);
+#ifdef G_TREE_DEBUG
+static void       g_tree_node_check                 (GTreeNode     *node);
+#endif
+
+
+static GTreeNode*
+g_tree_node_new (gpointer key,
+                gpointer value)
+{
+  GTreeNode *node = g_slice_new (GTreeNode);
+
+  node->balance = 0;
+  node->left = NULL;
+  node->right = NULL;
+  node->left_child = FALSE;
+  node->right_child = FALSE;
+  node->key = key;
+  node->value = value;
+
+  return node;
+}
+
+/**
+ * g_tree_new:
+ * @key_compare_func: the function used to order the nodes in the #GTree.
+ *   It should return values similar to the standard strcmp() function -
+ *   0 if the two arguments are equal, a negative value if the first argument 
+ *   comes before the second, or a positive value if the first argument comes 
+ *   after the second.
+ * 
+ * Creates a new #GTree.
+ * 
+ * Return value: a new #GTree.
+ **/
+GTree*
+g_tree_new (GCompareFunc key_compare_func)
+{
+  g_return_val_if_fail (key_compare_func != NULL, NULL);
+
+  return g_tree_new_full ((GCompareDataFunc) key_compare_func, NULL,
+                          NULL, NULL);
+}
+
+/**
+ * g_tree_new_with_data:
+ * @key_compare_func: qsort()-style comparison function.
+ * @key_compare_data: data to pass to comparison function.
+ * 
+ * Creates a new #GTree with a comparison function that accepts user data.
+ * See g_tree_new() for more details.
+ * 
+ * Return value: a new #GTree.
+ **/
+GTree*
+g_tree_new_with_data (GCompareDataFunc key_compare_func,
+                     gpointer         key_compare_data)
+{
+  g_return_val_if_fail (key_compare_func != NULL, NULL);
+  
+  return g_tree_new_full (key_compare_func, key_compare_data, 
+                         NULL, NULL);
+}
+
+/**
+ * g_tree_new_full:
+ * @key_compare_func: qsort()-style comparison function.
+ * @key_compare_data: data to pass to comparison function.
+ * @key_destroy_func: a function to free the memory allocated for the key 
+ *   used when removing the entry from the #GTree or %NULL if you don't
+ *   want to supply such a function.
+ * @value_destroy_func: a function to free the memory allocated for the 
+ *   value used when removing the entry from the #GTree or %NULL if you 
+ *   don't want to supply such a function.
+ * 
+ * Creates a new #GTree like g_tree_new() and allows to specify functions 
+ * to free the memory allocated for the key and value that get called when 
+ * removing the entry from the #GTree.
+ * 
+ * Return value: a new #GTree.
+ **/
+GTree*  
+g_tree_new_full (GCompareDataFunc key_compare_func,
+                gpointer         key_compare_data,              
+                 GDestroyNotify   key_destroy_func,
+                GDestroyNotify   value_destroy_func)
+{
+  GTree *tree;
+  
+  g_return_val_if_fail (key_compare_func != NULL, NULL);
+  
+  tree = g_slice_new (GTree);
+  tree->root               = NULL;
+  tree->key_compare        = key_compare_func;
+  tree->key_destroy_func   = key_destroy_func;
+  tree->value_destroy_func = value_destroy_func;
+  tree->key_compare_data   = key_compare_data;
+  tree->nnodes             = 0;
+  tree->ref_count          = 1;
+  
+  return tree;
+}
+
+static inline GTreeNode *
+g_tree_first_node (GTree *tree)
+{
+  GTreeNode *tmp;
+
+  if (!tree->root)
+    return NULL;
+
+  tmp = tree->root;
+
+  while (tmp->left_child)
+    tmp = tmp->left;
+
+  return tmp;
+} 
+
+static inline GTreeNode *
+g_tree_node_previous (GTreeNode *node)
+{
+  GTreeNode *tmp;
+
+  tmp = node->left;
+
+  if (node->left_child)
+    while (tmp->right_child)
+      tmp = tmp->right;
+
+  return tmp;
+}
+                 
+static inline GTreeNode *
+g_tree_node_next (GTreeNode *node)
+{
+  GTreeNode *tmp;
+
+  tmp = node->right;
+
+  if (node->right_child)
+    while (tmp->left_child)
+      tmp = tmp->left;
+
+  return tmp;
+}
+
+static void
+g_tree_remove_all (GTree *tree)
+{
+  GTreeNode *node;
+  GTreeNode *next;
+
+  g_return_if_fail (tree != NULL);
+
+  node = g_tree_first_node (tree);
+
+  while (node)
+    {
+      next = g_tree_node_next (node);
+
+      if (tree->key_destroy_func)
+       tree->key_destroy_func (node->key);
+      if (tree->value_destroy_func)
+       tree->value_destroy_func (node->value);
+      g_slice_free (GTreeNode, node);
+
+      node = next;
+    }
+
+  tree->root = NULL;
+  tree->nnodes = 0;
+}
+
+/**
+ * g_tree_ref:
+ * @tree: a #GTree.
+ *
+ * Increments the reference count of @tree by one.  It is safe to call
+ * this function from any thread.
+ *
+ * Return value: the passed in #GTree.
+ *
+ * Since: 2.22
+ **/
+GTree *
+g_tree_ref (GTree *tree)
+{
+  g_return_val_if_fail (tree != NULL, NULL);
+
+  g_atomic_int_inc (&tree->ref_count);
+
+  return tree;
+}
+
+/**
+ * g_tree_unref:
+ * @tree: a #GTree.
+ *
+ * Decrements the reference count of @tree by one.  If the reference count
+ * drops to 0, all keys and values will be destroyed (if destroy
+ * functions were specified) and all memory allocated by @tree will be
+ * released.
+ *
+ * It is safe to call this function from any thread.
+ *
+ * Since: 2.22
+ **/
+void
+g_tree_unref (GTree *tree)
+{
+  g_return_if_fail (tree != NULL);
+
+  if (g_atomic_int_dec_and_test (&tree->ref_count))
+    {
+      g_tree_remove_all (tree);
+      g_slice_free (GTree, tree);
+    }
+}
+
+/**
+ * g_tree_destroy:
+ * @tree: a #GTree.
+ * 
+ * Removes all keys and values from the #GTree and decreases its
+ * reference count by one. If keys and/or values are dynamically
+ * allocated, you should either free them first or create the #GTree
+ * using g_tree_new_full().  In the latter case the destroy functions
+ * you supplied will be called on all keys and values before destroying
+ * the #GTree.
+ **/
+void
+g_tree_destroy (GTree *tree)
+{
+  g_return_if_fail (tree != NULL);
+
+  g_tree_remove_all (tree);
+  g_tree_unref (tree);
+}
+
+/**
+ * g_tree_insert:
+ * @tree: a #GTree.
+ * @key: the key to insert.
+ * @value: the value corresponding to the key.
+ * 
+ * Inserts a key/value pair into a #GTree. If the given key already exists 
+ * in the #GTree its corresponding value is set to the new value. If you 
+ * supplied a value_destroy_func when creating the #GTree, the old value is 
+ * freed using that function. If you supplied a @key_destroy_func when 
+ * creating the #GTree, the passed key is freed using that function.
+ *
+ * The tree is automatically 'balanced' as new key/value pairs are added,
+ * so that the distance from the root to every leaf is as small as possible.
+ **/
+void
+g_tree_insert (GTree    *tree,
+              gpointer  key,
+              gpointer  value)
+{
+  g_return_if_fail (tree != NULL);
+
+  g_tree_insert_internal (tree, key, value, FALSE);
+
+#ifdef G_TREE_DEBUG
+  g_tree_node_check (tree->root);
+#endif
+}
+
+/**
+ * g_tree_replace:
+ * @tree: a #GTree.
+ * @key: the key to insert.
+ * @value: the value corresponding to the key.
+ * 
+ * Inserts a new key and value into a #GTree similar to g_tree_insert(). 
+ * The difference is that if the key already exists in the #GTree, it gets 
+ * replaced by the new key. If you supplied a @value_destroy_func when 
+ * creating the #GTree, the old value is freed using that function. If you 
+ * supplied a @key_destroy_func when creating the #GTree, the old key is 
+ * freed using that function. 
+ *
+ * The tree is automatically 'balanced' as new key/value pairs are added,
+ * so that the distance from the root to every leaf is as small as possible.
+ **/
+void
+g_tree_replace (GTree    *tree,
+               gpointer  key,
+               gpointer  value)
+{
+  g_return_if_fail (tree != NULL);
+
+  g_tree_insert_internal (tree, key, value, TRUE);
+
+#ifdef G_TREE_DEBUG
+  g_tree_node_check (tree->root);
+#endif
+}
+
+/* internal insert routine */
+static void
+g_tree_insert_internal (GTree    *tree,
+                        gpointer  key,
+                        gpointer  value,
+                        gboolean  replace)
+{
+  GTreeNode *node;
+  GTreeNode *path[MAX_GTREE_HEIGHT];
+  int idx;
+
+  g_return_if_fail (tree != NULL);
+
+  if (!tree->root)
+    {
+      tree->root = g_tree_node_new (key, value);
+      tree->nnodes++;
+      return;
+    }
+
+  idx = 0;
+  path[idx++] = NULL;
+  node = tree->root;
+
+  while (1)
+    {
+      int cmp = tree->key_compare (key, node->key, tree->key_compare_data);
+      
+      if (cmp == 0)
+        {
+          if (tree->value_destroy_func)
+            tree->value_destroy_func (node->value);
+
+          node->value = value;
+
+          if (replace)
+            {
+              if (tree->key_destroy_func)
+                tree->key_destroy_func (node->key);
+
+              node->key = key;
+            }
+          else
+            {
+              /* free the passed key */
+              if (tree->key_destroy_func)
+                tree->key_destroy_func (key);
+            }
+
+          return;
+        }
+      else if (cmp < 0)
+        {
+          if (node->left_child)
+            {
+              path[idx++] = node;
+              node = node->left;
+            }
+          else
+            {
+              GTreeNode *child = g_tree_node_new (key, value);
+
+              child->left = node->left;
+              child->right = node;
+              node->left = child;
+              node->left_child = TRUE;
+              node->balance -= 1;
+
+             tree->nnodes++;
+
+              break;
+            }
+        }
+      else
+        {
+          if (node->right_child)
+            {
+              path[idx++] = node;
+              node = node->right;
+            }
+          else
+            {
+              GTreeNode *child = g_tree_node_new (key, value);
+
+              child->right = node->right;
+              child->left = node;
+              node->right = child;
+              node->right_child = TRUE;
+              node->balance += 1;
+
+             tree->nnodes++;
+
+              break;
+            }
+        }
+    }
+
+  /* restore balance. This is the goodness of a non-recursive
+     implementation, when we are done with balancing we 'break'
+     the loop and we are done. */
+  while (1)
+    {
+      GTreeNode *bparent = path[--idx];
+      gboolean left_node = (bparent && node == bparent->left);
+      g_assert (!bparent || bparent->left == node || bparent->right == node);
+
+      if (node->balance < -1 || node->balance > 1)
+        {
+          node = g_tree_node_balance (node);
+          if (bparent == NULL)
+            tree->root = node;
+          else if (left_node)
+            bparent->left = node;
+          else
+            bparent->right = node;
+        }
+
+      if (node->balance == 0 || bparent == NULL)
+        break;
+      
+      if (left_node)
+        bparent->balance -= 1;
+      else
+        bparent->balance += 1;
+
+      node = bparent;
+    }
+}
+
+/**
+ * g_tree_remove:
+ * @tree: a #GTree.
+ * @key: the key to remove.
+ * 
+ * Removes a key/value pair from a #GTree.
+ *
+ * If the #GTree was created using g_tree_new_full(), the key and value 
+ * are freed using the supplied destroy functions, otherwise you have to 
+ * make sure that any dynamically allocated values are freed yourself.
+ * If the key does not exist in the #GTree, the function does nothing.
+ *
+ * Returns: %TRUE if the key was found (prior to 2.8, this function returned 
+ *   nothing)
+ **/
+gboolean
+g_tree_remove (GTree         *tree,
+              gconstpointer  key)
+{
+  gboolean removed;
+
+  g_return_val_if_fail (tree != NULL, FALSE);
+
+  removed = g_tree_remove_internal (tree, key, FALSE);
+
+#ifdef G_TREE_DEBUG
+  g_tree_node_check (tree->root);
+#endif
+
+  return removed;
+}
+
+/**
+ * g_tree_steal:
+ * @tree: a #GTree.
+ * @key: the key to remove.
+ * 
+ * Removes a key and its associated value from a #GTree without calling 
+ * the key and value destroy functions.
+ *
+ * If the key does not exist in the #GTree, the function does nothing.
+ *
+ * Returns: %TRUE if the key was found (prior to 2.8, this function returned 
+ *    nothing)
+ **/
+gboolean
+g_tree_steal (GTree         *tree,
+              gconstpointer  key)
+{
+  gboolean removed;
+
+  g_return_val_if_fail (tree != NULL, FALSE);
+
+  removed = g_tree_remove_internal (tree, key, TRUE);
+
+#ifdef G_TREE_DEBUG
+  g_tree_node_check (tree->root);
+#endif
+
+  return removed;
+}
+
+/* internal remove routine */
+static gboolean
+g_tree_remove_internal (GTree         *tree,
+                        gconstpointer  key,
+                        gboolean       steal)
+{
+  GTreeNode *node, *parent, *balance;
+  GTreeNode *path[MAX_GTREE_HEIGHT];
+  int idx;
+  gboolean left_node;
+
+  g_return_val_if_fail (tree != NULL, FALSE);
+
+  if (!tree->root)
+    return FALSE;
+
+  idx = 0;
+  path[idx++] = NULL;
+  node = tree->root;
+
+  while (1)
+    {
+      int cmp = tree->key_compare (key, node->key, tree->key_compare_data);
+      
+      if (cmp == 0)
+        break;
+      else if (cmp < 0)
+        {
+          if (!node->left_child)
+            return FALSE;
+         
+         path[idx++] = node;
+         node = node->left;
+        }
+      else
+        {
+          if (!node->right_child)
+            return FALSE;
+         
+         path[idx++] = node;
+         node = node->right;
+        }
+    }
+
+  /* the following code is almost equal to g_tree_remove_node,
+     except that we do not have to call g_tree_node_parent. */
+  balance = parent = path[--idx];
+  g_assert (!parent || parent->left == node || parent->right == node);
+  left_node = (parent && node == parent->left);
+
+  if (!node->left_child)
+    {
+      if (!node->right_child)
+        {
+          if (!parent)
+            tree->root = NULL;
+          else if (left_node)
+            {
+              parent->left_child = FALSE;
+              parent->left = node->left;
+              parent->balance += 1;
+            }
+          else
+            {
+              parent->right_child = FALSE;
+              parent->right = node->right;
+              parent->balance -= 1;
+            }
+        }
+      else /* node has a right child */
+        {
+          GTreeNode *tmp = g_tree_node_next (node);
+         tmp->left = node->left;
+
+          if (!parent)
+            tree->root = node->right;
+          else if (left_node)
+            {
+              parent->left = node->right;
+              parent->balance += 1;
+            }
+          else
+            {
+              parent->right = node->right;
+              parent->balance -= 1;
+            }
+        }
+    }
+  else /* node has a left child */
+    {
+      if (!node->right_child)
+        {
+          GTreeNode *tmp = g_tree_node_previous (node);
+          tmp->right = node->right;
+         
+          if (parent == NULL)
+            tree->root = node->left;
+          else if (left_node)
+            {
+              parent->left = node->left;
+              parent->balance += 1;
+            }
+          else
+            {
+              parent->right = node->left;
+              parent->balance -= 1;
+            }
+        }
+      else /* node has a both children (pant, pant!) */
+        {
+         GTreeNode *prev = node->left;
+         GTreeNode *next = node->right;
+         GTreeNode *nextp = node;
+         int old_idx = idx + 1;
+         idx++;
+         
+         /* path[idx] == parent */
+         /* find the immediately next node (and its parent) */
+         while (next->left_child)
+            {
+             path[++idx] = nextp = next;
+             next = next->left;
+            }
+         
+         path[old_idx] = next;
+         balance = path[idx];
+         
+         /* remove 'next' from the tree */
+         if (nextp != node)
+           {
+             if (next->right_child)
+               nextp->left = next->right;
+             else
+               nextp->left_child = FALSE;
+             nextp->balance += 1;
+             
+             next->right_child = TRUE;
+             next->right = node->right;
+           }
+         else
+           node->balance -= 1;
+           
+         /* set the prev to point to the right place */
+         while (prev->right_child)
+           prev = prev->right;
+         prev->right = next;
+           
+         /* prepare 'next' to replace 'node' */
+         next->left_child = TRUE;
+         next->left = node->left;
+         next->balance = node->balance;
+         
+         if (!parent)
+           tree->root = next;
+         else if (left_node)
+           parent->left = next;
+         else
+           parent->right = next;
+        }
+    }
+  
+  /* restore balance */
+  if (balance)
+    while (1)
+      {
+       GTreeNode *bparent = path[--idx];
+       g_assert (!bparent || bparent->left == balance || bparent->right == balance);
+       left_node = (bparent && balance == bparent->left);
+                             
+       if(balance->balance < -1 || balance->balance > 1)
+         {
+           balance = g_tree_node_balance (balance);
+           if (!bparent)
+             tree->root = balance;
+           else if (left_node)
+             bparent->left = balance;
+           else
+             bparent->right = balance;
+         }
+       
+       if (balance->balance != 0 || !bparent)
+         break;
+       
+       if (left_node)
+         bparent->balance += 1;
+       else
+         bparent->balance -= 1;
+       
+       balance = bparent;
+      }
+  
+  if (!steal)
+    {
+      if (tree->key_destroy_func)
+        tree->key_destroy_func (node->key);
+      if (tree->value_destroy_func)
+        tree->value_destroy_func (node->value);
+    }
+
+  g_slice_free (GTreeNode, node);
+
+  tree->nnodes--;
+
+  return TRUE;
+}
+
+/**
+ * g_tree_lookup:
+ * @tree: a #GTree.
+ * @key: the key to look up.
+ * 
+ * Gets the value corresponding to the given key. Since a #GTree is 
+ * automatically balanced as key/value pairs are added, key lookup is very 
+ * fast.
+ *
+ * Return value: the value corresponding to the key, or %NULL if the key was
+ * not found.
+ **/
+gpointer
+g_tree_lookup (GTree         *tree,
+              gconstpointer  key)
+{
+  GTreeNode *node;
+
+  g_return_val_if_fail (tree != NULL, NULL);
+
+  node = g_tree_find_node (tree, key);
+  
+  return node ? node->value : NULL;
+}
+
+/**
+ * g_tree_lookup_extended:
+ * @tree: a #GTree.
+ * @lookup_key: the key to look up.
+ * @orig_key: returns the original key.
+ * @value: returns the value associated with the key.
+ * 
+ * Looks up a key in the #GTree, returning the original key and the
+ * associated value and a #gboolean which is %TRUE if the key was found. This 
+ * is useful if you need to free the memory allocated for the original key, 
+ * for example before calling g_tree_remove().
+ * 
+ * Return value: %TRUE if the key was found in the #GTree.
+ **/
+gboolean
+g_tree_lookup_extended (GTree         *tree,
+                        gconstpointer  lookup_key,
+                        gpointer      *orig_key,
+                        gpointer      *value)
+{
+  GTreeNode *node;
+  
+  g_return_val_if_fail (tree != NULL, FALSE);
+  
+  node = g_tree_find_node (tree, lookup_key);
+  
+  if (node)
+    {
+      if (orig_key)
+        *orig_key = node->key;
+      if (value)
+        *value = node->value;
+      return TRUE;
+    }
+  else
+    return FALSE;
+}
+
+/**
+ * g_tree_foreach:
+ * @tree: a #GTree.
+ * @func: the function to call for each node visited. If this function
+ *   returns %TRUE, the traversal is stopped.
+ * @user_data: user data to pass to the function.
+ * 
+ * Calls the given function for each of the key/value pairs in the #GTree.
+ * The function is passed the key and value of each pair, and the given
+ * @data parameter. The tree is traversed in sorted order.
+ *
+ * The tree may not be modified while iterating over it (you can't 
+ * add/remove items). To remove all items matching a predicate, you need 
+ * to add each item to a list in your #GTraverseFunc as you walk over 
+ * the tree, then walk the list and remove each item.
+ **/
+void
+g_tree_foreach (GTree         *tree,
+                GTraverseFunc  func,
+                gpointer       user_data)
+{
+  GTreeNode *node;
+
+  g_return_if_fail (tree != NULL);
+  
+  if (!tree->root)
+    return;
+
+  node = g_tree_first_node (tree);
+  
+  while (node)
+    {
+      if ((*func) (node->key, node->value, user_data))
+       break;
+      
+      node = g_tree_node_next (node);
+    }
+}
+
+/**
+ * g_tree_traverse:
+ * @tree: a #GTree.
+ * @traverse_func: the function to call for each node visited. If this 
+ *   function returns %TRUE, the traversal is stopped.
+ * @traverse_type: the order in which nodes are visited, one of %G_IN_ORDER,
+ *   %G_PRE_ORDER and %G_POST_ORDER.
+ * @user_data: user data to pass to the function.
+ * 
+ * Calls the given function for each node in the #GTree. 
+ *
+ * Deprecated:2.2: The order of a balanced tree is somewhat arbitrary. If you 
+ * just want to visit all nodes in sorted order, use g_tree_foreach() 
+ * instead. If you really need to visit nodes in a different order, consider
+ * using an <link linkend="glib-N-ary-Trees">N-ary Tree</link>.
+ **/
+/**
+ * GTraverseFunc:
+ * @key: a key of a #GTree node.
+ * @value: the value corresponding to the key.
+ * @data: user data passed to g_tree_traverse().
+ * @Returns: %TRUE to stop the traversal.
+ *
+ * Specifies the type of function passed to g_tree_traverse(). It is
+ * passed the key and value of each node, together with the @user_data
+ * parameter passed to g_tree_traverse(). If the function returns
+ * %TRUE, the traversal is stopped.
+ **/
+/**
+ * GTraverseType:
+ * @G_IN_ORDER: vists a node's left child first, then the node itself,
+ *              then its right child. This is the one to use if you
+ *              want the output sorted according to the compare
+ *              function.
+ * @G_PRE_ORDER: visits a node, then its children.
+ * @G_POST_ORDER: visits the node's children, then the node itself.
+ * @G_LEVEL_ORDER: is not implemented for <link
+ *                 linkend="glib-Balanced-Binary-Trees">Balanced Binary
+ *                 Trees</link>.  For <link
+ *                 linkend="glib-N-ary-Trees">N-ary Trees</link>, it
+ *                 vists the root node first, then its children, then
+ *                 its grandchildren, and so on. Note that this is less
+ *                 efficient than the other orders.
+ *
+ * Specifies the type of traveral performed by g_tree_traverse(),
+ * g_node_traverse() and g_node_find().
+ **/
+void
+g_tree_traverse (GTree         *tree,
+                GTraverseFunc  traverse_func,
+                GTraverseType  traverse_type,
+                gpointer       user_data)
+{
+  g_return_if_fail (tree != NULL);
+
+  if (!tree->root)
+    return;
+
+  switch (traverse_type)
+    {
+    case G_PRE_ORDER:
+      g_tree_node_pre_order (tree->root, traverse_func, user_data);
+      break;
+
+    case G_IN_ORDER:
+      g_tree_node_in_order (tree->root, traverse_func, user_data);
+      break;
+
+    case G_POST_ORDER:
+      g_tree_node_post_order (tree->root, traverse_func, user_data);
+      break;
+    
+    case G_LEVEL_ORDER:
+      g_warning ("g_tree_traverse(): traverse type G_LEVEL_ORDER isn't implemented.");
+      break;
+    }
+}
+
+/**
+ * g_tree_search:
+ * @tree: a #GTree.
+ * @search_func: a function used to search the #GTree. 
+ * @user_data: the data passed as the second argument to the @search_func 
+ * function.
+ * 
+ * Searches a #GTree using @search_func.
+ *
+ * The @search_func is called with a pointer to the key of a key/value pair in 
+ * the tree, and the passed in @user_data. If @search_func returns 0 for a 
+ * key/value pair, then g_tree_search_func() will return the value of that 
+ * pair. If @search_func returns -1,  searching will proceed among the 
+ * key/value pairs that have a smaller key; if @search_func returns 1, 
+ * searching will proceed among the key/value pairs that have a larger key.
+ *
+ * Return value: the value corresponding to the found key, or %NULL if the key 
+ * was not found.
+ **/
+gpointer
+g_tree_search (GTree         *tree,
+              GCompareFunc   search_func,
+              gconstpointer  user_data)
+{
+  g_return_val_if_fail (tree != NULL, NULL);
+
+  if (tree->root)
+    return g_tree_node_search (tree->root, search_func, user_data);
+  else
+    return NULL;
+}
+
+/**
+ * g_tree_height:
+ * @tree: a #GTree.
+ * 
+ * Gets the height of a #GTree.
+ *
+ * If the #GTree contains no nodes, the height is 0.
+ * If the #GTree contains only one root node the height is 1.
+ * If the root node has children the height is 2, etc.
+ * 
+ * Return value: the height of the #GTree.
+ **/
+gint
+g_tree_height (GTree *tree)
+{
+  GTreeNode *node;
+  gint height;
+
+  g_return_val_if_fail (tree != NULL, 0);
+
+  if (!tree->root)
+    return 0;
+
+  height = 0;
+  node = tree->root;
+
+  while (1)
+    {
+      height += 1 + MAX(node->balance, 0);
+
+      if (!node->left_child)
+       return height;
+      
+      node = node->left;
+    }
+}
+
+/**
+ * g_tree_nnodes:
+ * @tree: a #GTree.
+ * 
+ * Gets the number of nodes in a #GTree.
+ * 
+ * Return value: the number of nodes in the #GTree.
+ **/
+gint
+g_tree_nnodes (GTree *tree)
+{
+  g_return_val_if_fail (tree != NULL, 0);
+
+  return tree->nnodes;
+}
+
+static GTreeNode*
+g_tree_node_balance (GTreeNode *node)
+{
+  if (node->balance < -1)
+    {
+      if (node->left->balance > 0)
+       node->left = g_tree_node_rotate_left (node->left);
+      node = g_tree_node_rotate_right (node);
+    }
+  else if (node->balance > 1)
+    {
+      if (node->right->balance < 0)
+       node->right = g_tree_node_rotate_right (node->right);
+      node = g_tree_node_rotate_left (node);
+    }
+
+  return node;
+}
+
+static GTreeNode *
+g_tree_find_node (GTree        *tree,
+                 gconstpointer key)
+{
+  GTreeNode *node;
+  gint cmp;
+
+  node = tree->root;
+  if (!node)
+    return NULL;
+
+  while (1)
+    {
+      cmp = tree->key_compare (key, node->key, tree->key_compare_data);
+      if (cmp == 0)
+       return node;
+      else if (cmp < 0)
+       {
+         if (!node->left_child)
+           return NULL;
+
+         node = node->left;
+       }
+      else
+       {
+         if (!node->right_child)
+           return NULL;
+
+         node = node->right;
+       }
+    }
+}
+
+static gint
+g_tree_node_pre_order (GTreeNode     *node,
+                      GTraverseFunc  traverse_func,
+                      gpointer       data)
+{
+  if ((*traverse_func) (node->key, node->value, data))
+    return TRUE;
+
+  if (node->left_child)
+    {
+      if (g_tree_node_pre_order (node->left, traverse_func, data))
+       return TRUE;
+    }
+
+  if (node->right_child)
+    {
+      if (g_tree_node_pre_order (node->right, traverse_func, data))
+       return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gint
+g_tree_node_in_order (GTreeNode     *node,
+                     GTraverseFunc  traverse_func,
+                     gpointer       data)
+{
+  if (node->left_child)
+    {
+      if (g_tree_node_in_order (node->left, traverse_func, data))
+       return TRUE;
+    }
+
+  if ((*traverse_func) (node->key, node->value, data))
+    return TRUE;
+
+  if (node->right_child)
+    {
+      if (g_tree_node_in_order (node->right, traverse_func, data))
+       return TRUE;
+    }
+  
+  return FALSE;
+}
+
+static gint
+g_tree_node_post_order (GTreeNode     *node,
+                       GTraverseFunc  traverse_func,
+                       gpointer       data)
+{
+  if (node->left_child)
+    {
+      if (g_tree_node_post_order (node->left, traverse_func, data))
+       return TRUE;
+    }
+
+  if (node->right_child)
+    {
+      if (g_tree_node_post_order (node->right, traverse_func, data))
+       return TRUE;
+    }
+
+  if ((*traverse_func) (node->key, node->value, data))
+    return TRUE;
+
+  return FALSE;
+}
+
+static gpointer
+g_tree_node_search (GTreeNode     *node,
+                   GCompareFunc   search_func,
+                   gconstpointer  data)
+{
+  gint dir;
+
+  if (!node)
+    return NULL;
+
+  while (1) 
+    {
+      dir = (* search_func) (node->key, data);
+      if (dir == 0)
+       return node->value;
+      else if (dir < 0) 
+       { 
+         if (!node->left_child)
+           return NULL;
+
+         node = node->left;
+       }
+      else
+       {
+         if (!node->right_child)
+           return NULL;
+         
+         node = node->right;
+       }
+    }
+}
+
+static GTreeNode*
+g_tree_node_rotate_left (GTreeNode *node)
+{
+  GTreeNode *right;
+  gint a_bal;
+  gint b_bal;
+
+  right = node->right;
+
+  if (right->left_child)
+    node->right = right->left;
+  else
+    {
+      node->right_child = FALSE;
+      node->right = right;
+      right->left_child = TRUE;
+    }
+  right->left = node;
+
+  a_bal = node->balance;
+  b_bal = right->balance;
+
+  if (b_bal <= 0)
+    {
+      if (a_bal >= 1)
+       right->balance = b_bal - 1;
+      else
+       right->balance = a_bal + b_bal - 2;
+      node->balance = a_bal - 1;
+    }
+  else
+    {
+      if (a_bal <= b_bal)
+       right->balance = a_bal - 2;
+      else
+       right->balance = b_bal - 1;
+      node->balance = a_bal - b_bal - 1;
+    }
+
+  return right;
+}
+
+static GTreeNode*
+g_tree_node_rotate_right (GTreeNode *node)
+{
+  GTreeNode *left;
+  gint a_bal;
+  gint b_bal;
+
+  left = node->left;
+
+  if (left->right_child)
+    node->left = left->right;
+  else
+    {
+      node->left_child = FALSE;
+      node->left = left;
+      left->right_child = TRUE;
+    }
+  left->right = node;
+
+  a_bal = node->balance;
+  b_bal = left->balance;
+
+  if (b_bal <= 0)
+    {
+      if (b_bal > a_bal)
+       left->balance = b_bal + 1;
+      else
+       left->balance = a_bal + 2;
+      node->balance = a_bal - b_bal + 1;
+    }
+  else
+    {
+      if (a_bal <= -1)
+       left->balance = b_bal + 1;
+      else
+       left->balance = a_bal + b_bal + 2;
+      node->balance = a_bal + 1;
+    }
+
+  return left;
+}
+
+#ifdef G_TREE_DEBUG
+static gint
+g_tree_node_height (GTreeNode *node)
+{
+  gint left_height;
+  gint right_height;
+
+  if (node)
+    {
+      left_height = 0;
+      right_height = 0;
+
+      if (node->left_child)
+       left_height = g_tree_node_height (node->left);
+
+      if (node->right_child)
+       right_height = g_tree_node_height (node->right);
+
+      return MAX (left_height, right_height) + 1;
+    }
+
+  return 0;
+}
+
+static void
+g_tree_node_check (GTreeNode *node)
+{
+  gint left_height;
+  gint right_height;
+  gint balance;
+  GTreeNode *tmp;
+
+  if (node)
+    {
+      if (node->left_child)
+       {
+         tmp = g_tree_node_previous (node);
+         g_assert (tmp->right == node);
+       }
+
+      if (node->right_child)
+       {
+         tmp = g_tree_node_next (node);
+         g_assert (tmp->left == node);
+       }
+
+      left_height = 0;
+      right_height = 0;
+      
+      if (node->left_child)
+       left_height = g_tree_node_height (node->left);
+      if (node->right_child)
+       right_height = g_tree_node_height (node->right);
+      
+      balance = right_height - left_height;
+      g_assert (balance == node->balance);
+      
+      if (node->left_child)
+       g_tree_node_check (node->left);
+      if (node->right_child)
+       g_tree_node_check (node->right);
+    }
+}
+
+static void
+g_tree_node_dump (GTreeNode *node, 
+                 gint       indent)
+{
+  g_print ("%*s%c\n", indent, "", *(char *)node->key);
+
+  if (node->left_child)
+    g_tree_node_dump (node->left, indent + 2);
+  else if (node->left)
+    g_print ("%*s<%c\n", indent + 2, "", *(char *)node->left->key);
+
+  if (node->right_child)
+    g_tree_node_dump (node->right, indent + 2);
+  else if (node->right)
+    g_print ("%*s>%c\n", indent + 2, "", *(char *)node->right->key);
+}
+
+
+void
+g_tree_dump (GTree *tree)
+{
+  if (tree->root)
+    g_tree_node_dump (tree->root, 0);
+}
+#endif
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gtree.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gtree.h
new file mode 100644 (file)
index 0000000..db06ba3
--- /dev/null
@@ -0,0 +1,91 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_TREE_H__
+#define __G_TREE_H__
+
+#include <glib/gnode.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GTree  GTree;
+
+typedef gboolean (*GTraverseFunc) (gpointer  key,
+                                   gpointer  value,
+                                   gpointer  data);
+
+/* Balanced binary trees
+ */
+GTree*   g_tree_new             (GCompareFunc      key_compare_func);
+GTree*   g_tree_new_with_data   (GCompareDataFunc  key_compare_func,
+                                 gpointer          key_compare_data);
+GTree*   g_tree_new_full        (GCompareDataFunc  key_compare_func,
+                                 gpointer          key_compare_data,
+                                 GDestroyNotify    key_destroy_func,
+                                 GDestroyNotify    value_destroy_func);
+GTree*   g_tree_ref             (GTree            *tree);
+void     g_tree_unref           (GTree            *tree);
+void     g_tree_destroy         (GTree            *tree);
+void     g_tree_insert          (GTree            *tree,
+                                 gpointer          key,
+                                 gpointer          value);
+void     g_tree_replace         (GTree            *tree,
+                                 gpointer          key,
+                                 gpointer          value);
+gboolean g_tree_remove          (GTree            *tree,
+                                 gconstpointer     key);
+gboolean g_tree_steal           (GTree            *tree,
+                                 gconstpointer     key);
+gpointer g_tree_lookup          (GTree            *tree,
+                                 gconstpointer     key);
+gboolean g_tree_lookup_extended (GTree            *tree,
+                                 gconstpointer     lookup_key,
+                                 gpointer         *orig_key,
+                                 gpointer         *value);
+void     g_tree_foreach         (GTree            *tree,
+                                 GTraverseFunc    func,
+                                 gpointer         user_data);
+
+#ifndef G_DISABLE_DEPRECATED
+void     g_tree_traverse        (GTree            *tree,
+                                 GTraverseFunc     traverse_func,
+                                 GTraverseType     traverse_type,
+                                 gpointer          user_data);
+#endif /* G_DISABLE_DEPRECATED */
+
+gpointer g_tree_search          (GTree            *tree,
+                                 GCompareFunc      search_func,
+                                 gconstpointer     user_data);
+gint     g_tree_height          (GTree            *tree);
+gint     g_tree_nnodes          (GTree            *tree);
+
+G_END_DECLS
+
+#endif /* __G_TREE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gtypes.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gtypes.h
new file mode 100644 (file)
index 0000000..e616f99
--- /dev/null
@@ -0,0 +1,451 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_TYPES_H__
+#define __G_TYPES_H__
+
+#include <glibconfig.h>
+#include <glib/gmacros.h>
+
+G_BEGIN_DECLS
+
+/* Provide type definitions for commonly used types.
+ *  These are useful because a "gint8" can be adjusted
+ *  to be 1 byte (8 bits) on all platforms. Similarly and
+ *  more importantly, "gint32" can be adjusted to be
+ *  4 bytes (32 bits) on all platforms.
+ */
+
+typedef char   gchar;
+typedef short  gshort;
+typedef long   glong;
+typedef int    gint;
+typedef gint   gboolean;
+
+typedef unsigned char   guchar;
+typedef unsigned short  gushort;
+typedef unsigned long   gulong;
+typedef unsigned int    guint;
+
+typedef float   gfloat;
+typedef double  gdouble;
+
+/* Define min and max constants for the fixed size numerical types */
+#define G_MININT8      ((gint8)  0x80)
+#define G_MAXINT8      ((gint8)  0x7f)
+#define G_MAXUINT8     ((guint8) 0xff)
+
+#define G_MININT16     ((gint16)  0x8000)
+#define G_MAXINT16     ((gint16)  0x7fff)
+#define G_MAXUINT16    ((guint16) 0xffff)
+
+#define G_MININT32     ((gint32)  0x80000000)
+#define G_MAXINT32     ((gint32)  0x7fffffff)
+#define G_MAXUINT32    ((guint32) 0xffffffff)
+
+#define G_MININT64     ((gint64) G_GINT64_CONSTANT(0x8000000000000000))
+#define G_MAXINT64     G_GINT64_CONSTANT(0x7fffffffffffffff)
+#define G_MAXUINT64    G_GINT64_CONSTANT(0xffffffffffffffffU)
+
+typedef void* gpointer;
+typedef const void *gconstpointer;
+
+typedef gint            (*GCompareFunc)         (gconstpointer  a,
+                                                 gconstpointer  b);
+typedef gint            (*GCompareDataFunc)     (gconstpointer  a,
+                                                 gconstpointer  b,
+                                                gpointer       user_data);
+typedef gboolean        (*GEqualFunc)           (gconstpointer  a,
+                                                 gconstpointer  b);
+typedef void            (*GDestroyNotify)       (gpointer       data);
+typedef void            (*GFunc)                (gpointer       data,
+                                                 gpointer       user_data);
+typedef guint           (*GHashFunc)            (gconstpointer  key);
+typedef void            (*GHFunc)               (gpointer       key,
+                                                 gpointer       value,
+                                                 gpointer       user_data);
+typedef void            (*GFreeFunc)            (gpointer       data);
+
+/**
+ * GTranslateFunc:
+ * @str: the untranslated string
+ * @data: user data specified when installing the function, e.g.
+ *  in g_option_group_set_translate_func()
+ * 
+ * The type of functions which are used to translate user-visible
+ * strings, for <option>--help</option> output.
+ * 
+ * Returns: a translation of the string for the current locale.
+ *  The returned string is owned by GLib and must not be freed.
+ */
+typedef const gchar *   (*GTranslateFunc)       (const gchar   *str,
+                                                gpointer       data);
+
+
+/* Define some mathematical constants that aren't available
+ * symbolically in some strict ISO C implementations.
+ *
+ * Note that the large number of digits used in these definitions
+ * doesn't imply that GLib or current computers in general would be
+ * able to handle floating point numbers with an accuracy like this.
+ * It's mostly an exercise in futility and future proofing. For
+ * extended precision floating point support, look somewhere else
+ * than GLib.
+ */
+#define G_E     2.7182818284590452353602874713526624977572470937000
+#define G_LN2   0.69314718055994530941723212145817656807550013436026
+#define G_LN10  2.3025850929940456840179914546843642076011014886288
+#define G_PI    3.1415926535897932384626433832795028841971693993751
+#define G_PI_2  1.5707963267948966192313216916397514420985846996876
+#define G_PI_4  0.78539816339744830961566084581987572104929234984378
+#define G_SQRT2 1.4142135623730950488016887242096980785696718753769
+
+/* Portable endian checks and conversions
+ *
+ * glibconfig.h defines G_BYTE_ORDER which expands to one of
+ * the below macros.
+ */
+#define G_LITTLE_ENDIAN 1234
+#define G_BIG_ENDIAN    4321
+#define G_PDP_ENDIAN    3412           /* unused, need specific PDP check */   
+
+
+/* Basic bit swapping functions
+ */
+#define GUINT16_SWAP_LE_BE_CONSTANT(val)       ((guint16) ( \
+    (guint16) ((guint16) (val) >> 8) | \
+    (guint16) ((guint16) (val) << 8)))
+
+#define GUINT32_SWAP_LE_BE_CONSTANT(val)       ((guint32) ( \
+    (((guint32) (val) & (guint32) 0x000000ffU) << 24) | \
+    (((guint32) (val) & (guint32) 0x0000ff00U) <<  8) | \
+    (((guint32) (val) & (guint32) 0x00ff0000U) >>  8) | \
+    (((guint32) (val) & (guint32) 0xff000000U) >> 24)))
+
+#define GUINT64_SWAP_LE_BE_CONSTANT(val)       ((guint64) ( \
+      (((guint64) (val) &                                              \
+       (guint64) G_GINT64_CONSTANT (0x00000000000000ffU)) << 56) |     \
+      (((guint64) (val) &                                              \
+       (guint64) G_GINT64_CONSTANT (0x000000000000ff00U)) << 40) |     \
+      (((guint64) (val) &                                              \
+       (guint64) G_GINT64_CONSTANT (0x0000000000ff0000U)) << 24) |     \
+      (((guint64) (val) &                                              \
+       (guint64) G_GINT64_CONSTANT (0x00000000ff000000U)) <<  8) |     \
+      (((guint64) (val) &                                              \
+       (guint64) G_GINT64_CONSTANT (0x000000ff00000000U)) >>  8) |     \
+      (((guint64) (val) &                                              \
+       (guint64) G_GINT64_CONSTANT (0x0000ff0000000000U)) >> 24) |     \
+      (((guint64) (val) &                                              \
+       (guint64) G_GINT64_CONSTANT (0x00ff000000000000U)) >> 40) |     \
+      (((guint64) (val) &                                              \
+       (guint64) G_GINT64_CONSTANT (0xff00000000000000U)) >> 56)))
+
+/* Arch specific stuff for speed
+ */
+#if defined (__GNUC__) && (__GNUC__ >= 2) && defined (__OPTIMIZE__)
+#  if defined (__i386__)
+#    define GUINT16_SWAP_LE_BE_IA32(val) \
+       (__extension__                                          \
+       ({ register guint16 __v, __x = ((guint16) (val));       \
+          if (__builtin_constant_p (__x))                      \
+            __v = GUINT16_SWAP_LE_BE_CONSTANT (__x);           \
+          else                                                 \
+            __asm__ ("rorw $8, %w0"                            \
+                     : "=r" (__v)                              \
+                     : "0" (__x)                               \
+                     : "cc");                                  \
+           __v; }))
+#    if !defined (__i486__) && !defined (__i586__) \
+       && !defined (__pentium__) && !defined (__i686__) \
+       && !defined (__pentiumpro__) && !defined (__pentium4__)
+#       define GUINT32_SWAP_LE_BE_IA32(val) \
+         (__extension__                                        \
+          ({ register guint32 __v, __x = ((guint32) (val));    \
+             if (__builtin_constant_p (__x))                   \
+               __v = GUINT32_SWAP_LE_BE_CONSTANT (__x);        \
+             else                                              \
+               __asm__ ("rorw $8, %w0\n\t"                     \
+                        "rorl $16, %0\n\t"                     \
+                        "rorw $8, %w0"                         \
+                        : "=r" (__v)                           \
+                        : "0" (__x)                            \
+                        : "cc");                               \
+             __v; }))
+#    else /* 486 and higher has bswap */
+#       define GUINT32_SWAP_LE_BE_IA32(val) \
+         (__extension__                                        \
+          ({ register guint32 __v, __x = ((guint32) (val));    \
+             if (__builtin_constant_p (__x))                   \
+               __v = GUINT32_SWAP_LE_BE_CONSTANT (__x);        \
+             else                                              \
+               __asm__ ("bswap %0"                             \
+                        : "=r" (__v)                           \
+                        : "0" (__x));                          \
+             __v; }))
+#    endif /* processor specific 32-bit stuff */
+#    define GUINT64_SWAP_LE_BE_IA32(val) \
+       (__extension__                                                  \
+       ({ union { guint64 __ll;                                        \
+                  guint32 __l[2]; } __w, __r;                          \
+          __w.__ll = ((guint64) (val));                                \
+          if (__builtin_constant_p (__w.__ll))                         \
+            __r.__ll = GUINT64_SWAP_LE_BE_CONSTANT (__w.__ll);         \
+          else                                                         \
+            {                                                          \
+              __r.__l[0] = GUINT32_SWAP_LE_BE (__w.__l[1]);            \
+              __r.__l[1] = GUINT32_SWAP_LE_BE (__w.__l[0]);            \
+            }                                                          \
+          __r.__ll; }))
+     /* Possibly just use the constant version and let gcc figure it out? */
+#    define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_IA32 (val))
+#    define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_IA32 (val))
+#    define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_IA32 (val))
+#  elif defined (__ia64__)
+#    define GUINT16_SWAP_LE_BE_IA64(val) \
+       (__extension__                                          \
+       ({ register guint16 __v, __x = ((guint16) (val));       \
+          if (__builtin_constant_p (__x))                      \
+            __v = GUINT16_SWAP_LE_BE_CONSTANT (__x);           \
+          else                                                 \
+            __asm__ __volatile__ ("shl %0 = %1, 48 ;;"         \
+                                  "mux1 %0 = %0, @rev ;;"      \
+                                   : "=r" (__v)                \
+                                   : "r" (__x));               \
+           __v; }))
+#    define GUINT32_SWAP_LE_BE_IA64(val) \
+       (__extension__                                          \
+        ({ register guint32 __v, __x = ((guint32) (val));      \
+           if (__builtin_constant_p (__x))                     \
+             __v = GUINT32_SWAP_LE_BE_CONSTANT (__x);          \
+           else                                                \
+            __asm__ __volatile__ ("shl %0 = %1, 32 ;;"         \
+                                  "mux1 %0 = %0, @rev ;;"      \
+                                   : "=r" (__v)                \
+                                   : "r" (__x));               \
+           __v; }))
+#    define GUINT64_SWAP_LE_BE_IA64(val) \
+       (__extension__                                          \
+       ({ register guint64 __v, __x = ((guint64) (val));       \
+          if (__builtin_constant_p (__x))                      \
+            __v = GUINT64_SWAP_LE_BE_CONSTANT (__x);           \
+          else                                                 \
+            __asm__ __volatile__ ("mux1 %0 = %1, @rev ;;"      \
+                                  : "=r" (__v)                 \
+                                  : "r" (__x));                \
+          __v; }))
+#    define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_IA64 (val))
+#    define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_IA64 (val))
+#    define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_IA64 (val))
+#  elif defined (__x86_64__)
+#    define GUINT32_SWAP_LE_BE_X86_64(val) \
+       (__extension__                                          \
+        ({ register guint32 __v, __x = ((guint32) (val));      \
+           if (__builtin_constant_p (__x))                     \
+             __v = GUINT32_SWAP_LE_BE_CONSTANT (__x);          \
+           else                                                \
+            __asm__ ("bswapl %0"                               \
+                     : "=r" (__v)                              \
+                     : "0" (__x));                             \
+           __v; }))
+#    define GUINT64_SWAP_LE_BE_X86_64(val) \
+       (__extension__                                          \
+       ({ register guint64 __v, __x = ((guint64) (val));       \
+          if (__builtin_constant_p (__x))                      \
+            __v = GUINT64_SWAP_LE_BE_CONSTANT (__x);           \
+          else                                                 \
+            __asm__ ("bswapq %0"                               \
+                     : "=r" (__v)                              \
+                     : "0" (__x));                             \
+          __v; }))
+     /* gcc seems to figure out optimal code for this on its own */
+#    define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val))
+#    define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_X86_64 (val))
+#    define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_X86_64 (val))
+#  else /* generic gcc */
+#    define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val))
+#    define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val))
+#    define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_CONSTANT (val))
+#  endif
+#else /* generic */
+#  define GUINT16_SWAP_LE_BE(val) (GUINT16_SWAP_LE_BE_CONSTANT (val))
+#  define GUINT32_SWAP_LE_BE(val) (GUINT32_SWAP_LE_BE_CONSTANT (val))
+#  define GUINT64_SWAP_LE_BE(val) (GUINT64_SWAP_LE_BE_CONSTANT (val))
+#endif /* generic */
+
+#define GUINT16_SWAP_LE_PDP(val)       ((guint16) (val))
+#define GUINT16_SWAP_BE_PDP(val)       (GUINT16_SWAP_LE_BE (val))
+#define GUINT32_SWAP_LE_PDP(val)       ((guint32) ( \
+    (((guint32) (val) & (guint32) 0x0000ffffU) << 16) | \
+    (((guint32) (val) & (guint32) 0xffff0000U) >> 16)))
+#define GUINT32_SWAP_BE_PDP(val)       ((guint32) ( \
+    (((guint32) (val) & (guint32) 0x00ff00ffU) << 8) | \
+    (((guint32) (val) & (guint32) 0xff00ff00U) >> 8)))
+
+/* The G*_TO_?E() macros are defined in glibconfig.h.
+ * The transformation is symmetric, so the FROM just maps to the TO.
+ */
+#define GINT16_FROM_LE(val)    (GINT16_TO_LE (val))
+#define GUINT16_FROM_LE(val)   (GUINT16_TO_LE (val))
+#define GINT16_FROM_BE(val)    (GINT16_TO_BE (val))
+#define GUINT16_FROM_BE(val)   (GUINT16_TO_BE (val))
+#define GINT32_FROM_LE(val)    (GINT32_TO_LE (val))
+#define GUINT32_FROM_LE(val)   (GUINT32_TO_LE (val))
+#define GINT32_FROM_BE(val)    (GINT32_TO_BE (val))
+#define GUINT32_FROM_BE(val)   (GUINT32_TO_BE (val))
+
+#define GINT64_FROM_LE(val)    (GINT64_TO_LE (val))
+#define GUINT64_FROM_LE(val)   (GUINT64_TO_LE (val))
+#define GINT64_FROM_BE(val)    (GINT64_TO_BE (val))
+#define GUINT64_FROM_BE(val)   (GUINT64_TO_BE (val))
+
+#define GLONG_FROM_LE(val)     (GLONG_TO_LE (val))
+#define GULONG_FROM_LE(val)    (GULONG_TO_LE (val))
+#define GLONG_FROM_BE(val)     (GLONG_TO_BE (val))
+#define GULONG_FROM_BE(val)    (GULONG_TO_BE (val))
+
+#define GINT_FROM_LE(val)      (GINT_TO_LE (val))
+#define GUINT_FROM_LE(val)     (GUINT_TO_LE (val))
+#define GINT_FROM_BE(val)      (GINT_TO_BE (val))
+#define GUINT_FROM_BE(val)     (GUINT_TO_BE (val))
+
+#define GSIZE_FROM_LE(val)     (GSIZE_TO_LE (val))
+#define GSSIZE_FROM_LE(val)    (GSSIZE_TO_LE (val))
+#define GSIZE_FROM_BE(val)     (GSIZE_TO_BE (val))
+#define GSSIZE_FROM_BE(val)    (GSSIZE_TO_BE (val))
+
+
+/* Portable versions of host-network order stuff
+ */
+#define g_ntohl(val) (GUINT32_FROM_BE (val))
+#define g_ntohs(val) (GUINT16_FROM_BE (val))
+#define g_htonl(val) (GUINT32_TO_BE (val))
+#define g_htons(val) (GUINT16_TO_BE (val))
+
+/* IEEE Standard 754 Single Precision Storage Format (gfloat):
+ *
+ *        31 30           23 22            0
+ * +--------+---------------+---------------+
+ * | s 1bit | e[30:23] 8bit | f[22:0] 23bit |
+ * +--------+---------------+---------------+
+ * B0------------------->B1------->B2-->B3-->
+ *
+ * IEEE Standard 754 Double Precision Storage Format (gdouble):
+ *
+ *        63 62            52 51            32   31            0
+ * +--------+----------------+----------------+ +---------------+
+ * | s 1bit | e[62:52] 11bit | f[51:32] 20bit | | f[31:0] 32bit |
+ * +--------+----------------+----------------+ +---------------+
+ * B0--------------->B1---------->B2--->B3---->  B4->B5->B6->B7->
+ */
+/* subtract from biased_exponent to form base2 exponent (normal numbers) */
+typedef union  _GDoubleIEEE754 GDoubleIEEE754;
+typedef union  _GFloatIEEE754  GFloatIEEE754;
+#define G_IEEE754_FLOAT_BIAS   (127)
+#define G_IEEE754_DOUBLE_BIAS  (1023)
+/* multiply with base2 exponent to get base10 exponent (normal numbers) */
+#define G_LOG_2_BASE_10                (0.30102999566398119521)
+#if G_BYTE_ORDER == G_LITTLE_ENDIAN
+union _GFloatIEEE754
+{
+  gfloat v_float;
+  struct {
+    guint mantissa : 23;
+    guint biased_exponent : 8;
+    guint sign : 1;
+  } mpn;
+};
+union _GDoubleIEEE754
+{
+  gdouble v_double;
+  struct {
+    guint mantissa_low : 32;
+    guint mantissa_high : 20;
+    guint biased_exponent : 11;
+    guint sign : 1;
+  } mpn;
+};
+#elif G_BYTE_ORDER == G_BIG_ENDIAN
+union _GFloatIEEE754
+{
+  gfloat v_float;
+  struct {
+    guint sign : 1;
+    guint biased_exponent : 8;
+    guint mantissa : 23;
+  } mpn;
+};
+union _GDoubleIEEE754
+{
+  gdouble v_double;
+  struct {
+    guint sign : 1;
+    guint biased_exponent : 11;
+    guint mantissa_high : 20;
+    guint mantissa_low : 32;
+  } mpn;
+};
+#else /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
+#error unknown ENDIAN type
+#endif /* !G_LITTLE_ENDIAN && !G_BIG_ENDIAN */
+
+typedef struct _GTimeVal                GTimeVal;
+
+struct _GTimeVal
+{
+  glong tv_sec;
+  glong tv_usec;
+};
+
+G_END_DECLS
+
+/* We prefix variable declarations so they can
+ * properly get exported in Windows DLLs.
+ */
+#ifndef GLIB_VAR
+#  ifdef G_PLATFORM_WIN32
+#    ifdef GLIB_STATIC_COMPILATION
+#      define GLIB_VAR extern
+#    else /* !GLIB_STATIC_COMPILATION */
+#      ifdef GLIB_COMPILATION
+#        ifdef DLL_EXPORT
+#          define GLIB_VAR __declspec(dllexport)
+#        else /* !DLL_EXPORT */
+#          define GLIB_VAR extern
+#        endif /* !DLL_EXPORT */
+#      else /* !GLIB_COMPILATION */
+#        define GLIB_VAR extern __declspec(dllimport)
+#      endif /* !GLIB_COMPILATION */
+#    endif /* !GLIB_STATIC_COMPILATION */
+#  else /* !G_PLATFORM_WIN32 */
+#    define GLIB_VAR extern
+#  endif /* !G_PLATFORM_WIN32 */
+#endif /* GLIB_VAR */
+
+#endif /* __G_TYPES_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gunibreak.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gunibreak.c
new file mode 100644 (file)
index 0000000..4b4f0e2
--- /dev/null
@@ -0,0 +1,61 @@
+/* gunibreak.c - line break properties
+ *
+ *  Copyright 2000 Red Hat, Inc.
+ *
+ * The Gnome 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 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *   Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+
+#include "gunibreak.h"
+
+#define TPROP_PART1(Page, Char) \
+  ((break_property_table_part1[Page] >= G_UNICODE_MAX_TABLE_INDEX) \
+   ? (break_property_table_part1[Page] - G_UNICODE_MAX_TABLE_INDEX) \
+   : (break_property_data[break_property_table_part1[Page]][Char]))
+
+#define TPROP_PART2(Page, Char) \
+  ((break_property_table_part2[Page] >= G_UNICODE_MAX_TABLE_INDEX) \
+   ? (break_property_table_part2[Page] - G_UNICODE_MAX_TABLE_INDEX) \
+   : (break_property_data[break_property_table_part2[Page]][Char]))
+
+#define PROP(Char) \
+  (((Char) <= G_UNICODE_LAST_CHAR_PART1) \
+   ? TPROP_PART1 ((Char) >> 8, (Char) & 0xff) \
+   : (((Char) >= 0xe0000 && (Char) <= G_UNICODE_LAST_CHAR) \
+      ? TPROP_PART2 (((Char) - 0xe0000) >> 8, (Char) & 0xff) \
+      : G_UNICODE_BREAK_UNKNOWN))
+
+/**
+ * g_unichar_break_type:
+ * @c: a Unicode character
+ * 
+ * Determines the break type of @c. @c should be a Unicode character
+ * (to derive a character from UTF-8 encoded text, use
+ * g_utf8_get_char()). The break type is used to find word and line
+ * breaks ("text boundaries"), Pango implements the Unicode boundary
+ * resolution algorithms and normally you would use a function such
+ * as pango_break() instead of caring about break types yourself.
+ * 
+ * Return value: the break type of @c
+ **/
+GUnicodeBreakType
+g_unichar_break_type (gunichar c)
+{
+  return PROP (c);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gunibreak.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gunibreak.h
new file mode 100644 (file)
index 0000000..37be2af
--- /dev/null
@@ -0,0 +1,17922 @@
+/* This file is automatically generated.  DO NOT EDIT!
+   Instead, edit gen-unicode-tables.pl and re-run.  */
+
+#ifndef BREAKTABLES_H
+#define BREAKTABLES_H
+
+#include <glib/gtypes.h>
+#include <glib/gunicode.h>
+
+#define G_UNICODE_DATA_VERSION "5.1.0"
+
+#define G_UNICODE_LAST_CHAR 0x10FFFF
+
+#define G_UNICODE_MAX_TABLE_INDEX 10000
+
+/* the last code point that should be looked up in break_property_table_part1 */
+#define G_UNICODE_LAST_CHAR_PART1 0x2FAFF
+
+static const gint8 break_property_data[][256] = {
+  { /* page 0, index 0 */
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_LINE_FEED, G_UNICODE_BREAK_MANDATORY, 
+    G_UNICODE_BREAK_MANDATORY, G_UNICODE_BREAK_CARRIAGE_RETURN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_SPACE, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_POSTFIX, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_HYPHEN, 
+    G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_SYMBOL, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_INFIX_SEPARATOR, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_NEXT_LINE, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_POSTFIX, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_BEFORE, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 2, index 1 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_BEFORE, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 3, index 2 */
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_NON_BREAKING_GLUE, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_NON_BREAKING_GLUE, 
+    G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_NON_BREAKING_GLUE, 
+    G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_NON_BREAKING_GLUE, 
+    G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 4, index 3 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 5, index 4 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_INFIX_SEPARATOR, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 6, index 5 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_POSTFIX, 
+    G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_POSTFIX, 
+    G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_INFIX_SEPARATOR, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 7, index 6 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 9, index 7 */
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 10, index 8 */
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 11, index 9 */
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 12, index 10 */
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 13, index 11 */
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_POSTFIX, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 14, index 12 */
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 15, index 13 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_BEFORE, 
+    G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_BEFORE, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_BEFORE, 
+    G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_NON_BREAKING_GLUE, 
+    G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_BEFORE, 
+    G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_BEFORE, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 16, index 14 */
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 17, index 15 */
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_L_JAMO, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_HANGUL_L_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_HANGUL_V_JAMO, 
+    G_UNICODE_BREAK_HANGUL_V_JAMO, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_HANGUL_T_JAMO, G_UNICODE_BREAK_HANGUL_T_JAMO, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 18, index 16 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 19, index 17 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 20, index 18 */
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 22, index 19 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 23, index 20 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 24, index 21 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_BEFORE, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_NON_BREAKING_GLUE, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 25, index 22 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMPLEX_CONTEXT, G_UNICODE_BREAK_COMPLEX_CONTEXT, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 26, index 23 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 27, index 24 */
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 28, index 25 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 29, index 26 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK
+  },
+  { /* page 31, index 27 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_BEFORE, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 32, index 28 */
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_NON_BREAKING_GLUE, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_ZERO_WIDTH_SPACE, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_BEFORE_AND_AFTER, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_INSEPARABLE, 
+    G_UNICODE_BREAK_INSEPARABLE, G_UNICODE_BREAK_INSEPARABLE, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_MANDATORY, 
+    G_UNICODE_BREAK_MANDATORY, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_NON_BREAKING_GLUE, G_UNICODE_BREAK_POSTFIX, 
+    G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_POSTFIX, 
+    G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_POSTFIX, 
+    G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_POSTFIX, 
+    G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_INFIX_SEPARATOR, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_WORD_JOINER, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 33, index 29 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_POSTFIX, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_POSTFIX, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 34, index 30 */
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 35, index 31 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 36, index 32 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 37, index 33 */
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 38, index 34 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 39, index 35 */
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_AMBIGUOUS, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 41, index 36 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 43, index 37 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 44, index 38 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_AFTER
+  },
+  { /* page 45, index 39 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK
+  },
+  { /* page 46, index 40 */
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_QUOTATION, 
+    G_UNICODE_BREAK_QUOTATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 47, index 41 */
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 48, index 42 */
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_IDEOGRAPHIC
+  },
+  { /* page 49, index 43 */
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER
+  },
+  { /* page 50, index 44 */
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 77, index 45 */
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 159, index 46 */
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 160, index 47 */
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC
+  },
+  { /* page 164, index 48 */
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 166, index 49 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 167, index 50 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 168, index 51 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_BEFORE, G_UNICODE_BREAK_BEFORE, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 169, index 52 */
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 170, index 53 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 172, index 54 */
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 173, index 55 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 174, index 56 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 175, index 57 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 176, index 58 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 177, index 59 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 178, index 60 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 179, index 61 */
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 180, index 62 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 181, index 63 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 182, index 64 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 183, index 65 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 184, index 66 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 185, index 67 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 186, index 68 */
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 187, index 69 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 188, index 70 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 189, index 71 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 190, index 72 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 191, index 73 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 192, index 74 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 193, index 75 */
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 194, index 76 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 195, index 77 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 196, index 78 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 197, index 79 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 198, index 80 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 199, index 81 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 200, index 82 */
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 201, index 83 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 202, index 84 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 203, index 85 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 204, index 86 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 205, index 87 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 206, index 88 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 207, index 89 */
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 208, index 90 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 209, index 91 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 210, index 92 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 211, index 93 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 212, index 94 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 213, index 95 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 214, index 96 */
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+  },
+  { /* page 215, index 97 */
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LV_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 250, index 98 */
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 251, index 99 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 253, index 100 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 254, index 101 */
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_INFIX_SEPARATOR, 
+    G_UNICODE_BREAK_INFIX_SEPARATOR, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_INSEPARABLE, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_EXCLAMATION, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_WORD_JOINER
+  },
+  { /* page 255, index 102 */
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_POSTFIX, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_EXCLAMATION, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_OPEN_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_OPEN_PUNCTUATION, G_UNICODE_BREAK_CLOSE_PUNCTUATION, 
+    G_UNICODE_BREAK_CLOSE_PUNCTUATION, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_NON_STARTER, G_UNICODE_BREAK_NON_STARTER, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_POSTFIX, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_PREFIX, 
+    G_UNICODE_BREAK_PREFIX, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_CONTINGENT, G_UNICODE_BREAK_AMBIGUOUS, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 256, index 103 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 257, index 104 */
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 258, index 105 */
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 259, index 106 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 260, index 107 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 264, index 108 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 265, index 109 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 266, index 110 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 291, index 111 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 292, index 112 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, G_UNICODE_BREAK_AFTER, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 464, index 113 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 465, index 114 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 466, index 115 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 467, index 116 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 468, index 117 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 469, index 118 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 470, index 119 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC
+  },
+  { /* page 471, index 120 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC, 
+    G_UNICODE_BREAK_NUMERIC, G_UNICODE_BREAK_NUMERIC
+  },
+  { /* page 496, index 121 */
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_ALPHABETIC, G_UNICODE_BREAK_ALPHABETIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 678, index 122 */
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 762, index 123 */
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_IDEOGRAPHIC, G_UNICODE_BREAK_IDEOGRAPHIC, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 3584, index 124 */
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  },
+  { /* page 3585, index 125 */
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_COMBINING_MARK, G_UNICODE_BREAK_COMBINING_MARK, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN, 
+    G_UNICODE_BREAK_UNKNOWN, G_UNICODE_BREAK_UNKNOWN
+  }
+};
+
+/* U+0000 through U+2FAFF */
+static const gint16 break_property_table_part1[763] = {
+  0 /* page 0 */,
+  G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX,
+  1 /* page 2 */,
+  2 /* page 3 */,
+  3 /* page 4 */,
+  4 /* page 5 */,
+  5 /* page 6 */,
+  6 /* page 7 */,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  7 /* page 9 */,
+  8 /* page 10 */,
+  9 /* page 11 */,
+  10 /* page 12 */,
+  11 /* page 13 */,
+  12 /* page 14 */,
+  13 /* page 15 */,
+  14 /* page 16 */,
+  15 /* page 17 */,
+  16 /* page 18 */,
+  17 /* page 19 */,
+  18 /* page 20 */,
+  G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX,
+  19 /* page 22 */,
+  20 /* page 23 */,
+  21 /* page 24 */,
+  22 /* page 25 */,
+  23 /* page 26 */,
+  24 /* page 27 */,
+  25 /* page 28 */,
+  26 /* page 29 */,
+  G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX,
+  27 /* page 31 */,
+  28 /* page 32 */,
+  29 /* page 33 */,
+  30 /* page 34 */,
+  31 /* page 35 */,
+  32 /* page 36 */,
+  33 /* page 37 */,
+  34 /* page 38 */,
+  35 /* page 39 */,
+  G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX,
+  36 /* page 41 */,
+  G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX,
+  37 /* page 43 */,
+  38 /* page 44 */,
+  39 /* page 45 */,
+  40 /* page 46 */,
+  41 /* page 47 */,
+  42 /* page 48 */,
+  43 /* page 49 */,
+  44 /* page 50 */,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  45 /* page 77 */,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  46 /* page 159 */,
+  47 /* page 160 */,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  48 /* page 164 */,
+  G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX,
+  49 /* page 166 */,
+  50 /* page 167 */,
+  51 /* page 168 */,
+  52 /* page 169 */,
+  53 /* page 170 */,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  54 /* page 172 */,
+  55 /* page 173 */,
+  56 /* page 174 */,
+  57 /* page 175 */,
+  58 /* page 176 */,
+  59 /* page 177 */,
+  60 /* page 178 */,
+  61 /* page 179 */,
+  62 /* page 180 */,
+  63 /* page 181 */,
+  64 /* page 182 */,
+  65 /* page 183 */,
+  66 /* page 184 */,
+  67 /* page 185 */,
+  68 /* page 186 */,
+  69 /* page 187 */,
+  70 /* page 188 */,
+  71 /* page 189 */,
+  72 /* page 190 */,
+  73 /* page 191 */,
+  74 /* page 192 */,
+  75 /* page 193 */,
+  76 /* page 194 */,
+  77 /* page 195 */,
+  78 /* page 196 */,
+  79 /* page 197 */,
+  80 /* page 198 */,
+  81 /* page 199 */,
+  82 /* page 200 */,
+  83 /* page 201 */,
+  84 /* page 202 */,
+  85 /* page 203 */,
+  86 /* page 204 */,
+  87 /* page 205 */,
+  88 /* page 206 */,
+  89 /* page 207 */,
+  90 /* page 208 */,
+  91 /* page 209 */,
+  92 /* page 210 */,
+  93 /* page 211 */,
+  94 /* page 212 */,
+  95 /* page 213 */,
+  96 /* page 214 */,
+  97 /* page 215 */,
+  G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  98 /* page 250 */,
+  99 /* page 251 */,
+  G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX,
+  100 /* page 253 */,
+  101 /* page 254 */,
+  102 /* page 255 */,
+  103 /* page 256 */,
+  104 /* page 257 */,
+  105 /* page 258 */,
+  106 /* page 259 */,
+  107 /* page 260 */,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  108 /* page 264 */,
+  109 /* page 265 */,
+  110 /* page 266 */,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_ALPHABETIC + G_UNICODE_MAX_TABLE_INDEX,
+  111 /* page 291 */,
+  112 /* page 292 */,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  113 /* page 464 */,
+  114 /* page 465 */,
+  115 /* page 466 */,
+  116 /* page 467 */,
+  117 /* page 468 */,
+  118 /* page 469 */,
+  119 /* page 470 */,
+  120 /* page 471 */,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  121 /* page 496 */,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  122 /* page 678 */,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_IDEOGRAPHIC + G_UNICODE_MAX_TABLE_INDEX,
+  123 /* page 762 */
+};
+
+/* U+E0000 through U+10FFFF */
+static const gint16 break_property_table_part2[768] = {
+  124 /* page 3584 */,
+  125 /* page 3585 */,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_BREAK_UNKNOWN + G_UNICODE_MAX_TABLE_INDEX
+};
+
+#endif /* BREAKTABLES_H */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gunichartables.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gunichartables.h
new file mode 100644 (file)
index 0000000..044a44f
--- /dev/null
@@ -0,0 +1,13060 @@
+/* This file is automatically generated.  DO NOT EDIT!
+   Instead, edit gen-unicode-tables.pl and re-run.  */
+
+#ifndef CHARTABLES_H
+#define CHARTABLES_H
+
+#define G_UNICODE_DATA_VERSION "5.1.0"
+
+#define G_UNICODE_LAST_CHAR 0x10ffff
+
+#define G_UNICODE_MAX_TABLE_INDEX 10000
+
+#define G_UNICODE_LAST_CHAR_PART1 0x2FAFF
+
+#define G_UNICODE_LAST_PAGE_PART1 762
+
+static const char type_data[][256] = {
+  { /* page 0, index 0 */
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_CONTROL, 
+    G_UNICODE_CONTROL, G_UNICODE_CONTROL, G_UNICODE_SPACE_SEPARATOR, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_FORMAT, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_FINAL_PUNCTUATION, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER
+  },
+  { /* page 1, index 1 */
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER
+  },
+  { /* page 2, index 2 */
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL
+  },
+  { /* page 3, index 3 */
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER
+  },
+  { /* page 4, index 4 */
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER
+  },
+  { /* page 5, index 5 */
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_DASH_PUNCTUATION, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 6, index 6 */
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_FORMAT, G_UNICODE_ENCLOSING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_LETTER
+  },
+  { /* page 7, index 7 */
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 9, index 8 */
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 10, index 9 */
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 11, index 10 */
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 12, index 11 */
+    G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 13, index 12 */
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 14, index 13 */
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 15, index 14 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 16, index 15 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 17, index 16 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 18, index 17 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER
+  },
+  { /* page 19, index 18 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 20, index 19 */
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER
+  },
+  { /* page 22, index 20 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 23, index 21 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 24, index 22 */
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_SPACE_SEPARATOR, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 25, index 23 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL
+  },
+  { /* page 26, index 24 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 27, index 25 */
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 28, index 26 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 29, index 27 */
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK
+  },
+  { /* page 30, index 28 */
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER
+  },
+  { /* page 31, index 29 */
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_TITLECASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_TITLECASE_LETTER, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UNASSIGNED
+  },
+  { /* page 32, index 30 */
+    G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, 
+    G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, 
+    G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, 
+    G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, 
+    G_UNICODE_SPACE_SEPARATOR, G_UNICODE_SPACE_SEPARATOR, 
+    G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, 
+    G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, 
+    G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, 
+    G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_LINE_SEPARATOR, G_UNICODE_PARAGRAPH_SEPARATOR, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_SPACE_SEPARATOR, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_OTHER_NUMBER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, 
+    G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_ENCLOSING_MARK, 
+    G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 33, index 31 */
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL
+  },
+  { /* page 35, index 32 */
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 36, index 33 */
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER
+  },
+  { /* page 37, index 34 */
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL
+  },
+  { /* page 38, index 35 */
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 39, index 36 */
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL
+  },
+  { /* page 41, index 37 */
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL
+  },
+  { /* page 43, index 38 */
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 44, index 39 */
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION
+  },
+  { /* page 45, index 40 */
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_MODIFIER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK
+  },
+  { /* page 46, index 41 */
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, 
+    G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_INITIAL_PUNCTUATION, 
+    G_UNICODE_FINAL_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_INITIAL_PUNCTUATION, G_UNICODE_FINAL_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 47, index 42 */
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 48, index 43 */
+    G_UNICODE_SPACE_SEPARATOR, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_DASH_PUNCTUATION, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_DASH_PUNCTUATION, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_OTHER_LETTER
+  },
+  { /* page 49, index 44 */
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER
+  },
+  { /* page 50, index 45 */
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 77, index 46 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL
+  },
+  { /* page 159, index 47 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 160, index 48 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER
+  },
+  { /* page 164, index 49 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 166, index 50 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_ENCLOSING_MARK, G_UNICODE_ENCLOSING_MARK, 
+    G_UNICODE_ENCLOSING_MARK, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 167, index 51 */
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER
+  },
+  { /* page 168, index 52 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 169, index 53 */
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 170, index 54 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 215, index 55 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 250, index 56 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 251, index 57 */
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER
+  },
+  { /* page 253, index 58 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 254, index 59 */
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_DASH_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, 
+    G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_CONNECT_PUNCTUATION, 
+    G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_DASH_PUNCTUATION, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT
+  },
+  { /* page 255, index 60 */
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_DASH_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_CONNECT_PUNCTUATION, G_UNICODE_MODIFIER_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OPEN_PUNCTUATION, G_UNICODE_CLOSE_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OPEN_PUNCTUATION, 
+    G_UNICODE_CLOSE_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_MODIFIER_LETTER, G_UNICODE_MODIFIER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MODIFIER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_CURRENCY_SYMBOL, G_UNICODE_CURRENCY_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 256, index 61 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 257, index 62 */
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 258, index 63 */
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 259, index 64 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 260, index 65 */
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 264, index 66 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 265, index 67 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 266, index 68 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 291, index 69 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 292, index 70 */
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_LETTER_NUMBER, 
+    G_UNICODE_LETTER_NUMBER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_OTHER_PUNCTUATION, 
+    G_UNICODE_OTHER_PUNCTUATION, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 464, index 71 */
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 465, index 72 */
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, 
+    G_UNICODE_COMBINING_MARK, G_UNICODE_COMBINING_MARK, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 466, index 73 */
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 467, index 74 */
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, G_UNICODE_OTHER_NUMBER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 468, index 75 */
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER
+  },
+  { /* page 469, index 76 */
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER
+  },
+  { /* page 470, index 77 */
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_MATH_SYMBOL, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER
+  },
+  { /* page 471, index 78 */
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_UPPERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_MATH_SYMBOL, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_LOWERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UPPERCASE_LETTER, G_UNICODE_LOWERCASE_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER, G_UNICODE_DECIMAL_NUMBER, 
+    G_UNICODE_DECIMAL_NUMBER
+  },
+  { /* page 496, index 79 */
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, G_UNICODE_OTHER_SYMBOL, 
+    G_UNICODE_OTHER_SYMBOL, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 678, index 80 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 762, index 81 */
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, G_UNICODE_OTHER_LETTER, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 3584, index 82 */
+    G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_FORMAT, G_UNICODE_FORMAT, G_UNICODE_FORMAT, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED
+  },
+  { /* page 3585, index 83 */
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_NON_SPACING_MARK, G_UNICODE_NON_SPACING_MARK, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 4095, index 84 */
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  },
+  { /* page 4351, index 85 */
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, 
+    G_UNICODE_PRIVATE_USE, G_UNICODE_PRIVATE_USE, G_UNICODE_UNASSIGNED, 
+    G_UNICODE_UNASSIGNED
+  }
+};
+
+/* U+0000 through U+2FAFF */
+static const gint16 type_table_part1[763] = {
+  0 /* page 0 */,
+  1 /* page 1 */,
+  2 /* page 2 */,
+  3 /* page 3 */,
+  4 /* page 4 */,
+  5 /* page 5 */,
+  6 /* page 6 */,
+  7 /* page 7 */,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  8 /* page 9 */,
+  9 /* page 10 */,
+  10 /* page 11 */,
+  11 /* page 12 */,
+  12 /* page 13 */,
+  13 /* page 14 */,
+  14 /* page 15 */,
+  15 /* page 16 */,
+  16 /* page 17 */,
+  17 /* page 18 */,
+  18 /* page 19 */,
+  19 /* page 20 */,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  20 /* page 22 */,
+  21 /* page 23 */,
+  22 /* page 24 */,
+  23 /* page 25 */,
+  24 /* page 26 */,
+  25 /* page 27 */,
+  26 /* page 28 */,
+  27 /* page 29 */,
+  28 /* page 30 */,
+  29 /* page 31 */,
+  30 /* page 32 */,
+  31 /* page 33 */,
+  G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX,
+  32 /* page 35 */,
+  33 /* page 36 */,
+  34 /* page 37 */,
+  35 /* page 38 */,
+  36 /* page 39 */,
+  G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX,
+  37 /* page 41 */,
+  G_UNICODE_MATH_SYMBOL + G_UNICODE_MAX_TABLE_INDEX,
+  38 /* page 43 */,
+  39 /* page 44 */,
+  40 /* page 45 */,
+  41 /* page 46 */,
+  42 /* page 47 */,
+  43 /* page 48 */,
+  44 /* page 49 */,
+  45 /* page 50 */,
+  G_UNICODE_OTHER_SYMBOL + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  46 /* page 77 */,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  47 /* page 159 */,
+  48 /* page 160 */,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  49 /* page 164 */,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  50 /* page 166 */,
+  51 /* page 167 */,
+  52 /* page 168 */,
+  53 /* page 169 */,
+  54 /* page 170 */,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  55 /* page 215 */,
+  G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_SURROGATE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  56 /* page 250 */,
+  57 /* page 251 */,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  58 /* page 253 */,
+  59 /* page 254 */,
+  60 /* page 255 */,
+  61 /* page 256 */,
+  62 /* page 257 */,
+  63 /* page 258 */,
+  64 /* page 259 */,
+  65 /* page 260 */,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  66 /* page 264 */,
+  67 /* page 265 */,
+  68 /* page 266 */,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  69 /* page 291 */,
+  70 /* page 292 */,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  71 /* page 464 */,
+  72 /* page 465 */,
+  73 /* page 466 */,
+  74 /* page 467 */,
+  75 /* page 468 */,
+  76 /* page 469 */,
+  77 /* page 470 */,
+  78 /* page 471 */,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  79 /* page 496 */,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  80 /* page 678 */,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_OTHER_LETTER + G_UNICODE_MAX_TABLE_INDEX,
+  81 /* page 762 */
+};
+
+/* U+E0000 through U+10FFFF */
+static const gint16 type_table_part2[768] = {
+  82 /* page 3584 */,
+  83 /* page 3585 */,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_UNASSIGNED + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  84 /* page 4095 */,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  G_UNICODE_PRIVATE_USE + G_UNICODE_MAX_TABLE_INDEX,
+  85 /* page 4351 */
+};
+
+static const gunichar attr_data[][256] = {
+  { /* page 0, index 0 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 
+    0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 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, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 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, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x039c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 
+    0x00e6, 0x00e7, 0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 
+    0x00ef, 0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x0000, 
+    0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x1000000, 
+    0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7, 0x00c8, 
+    0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x00d0, 0x00d1, 
+    0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x0000, 0x00d8, 0x00d9, 0x00da, 
+    0x00db, 0x00dc, 0x00dd, 0x00de, 0x0178
+  },
+  { /* page 1, index 1 */
+    0x0101, 0x0100, 0x0103, 0x0102, 0x0105, 0x0104, 0x0107, 0x0106, 0x0109, 
+    0x0108, 0x010b, 0x010a, 0x010d, 0x010c, 0x010f, 0x010e, 0x0111, 0x0110, 
+    0x0113, 0x0112, 0x0115, 0x0114, 0x0117, 0x0116, 0x0119, 0x0118, 0x011b, 
+    0x011a, 0x011d, 0x011c, 0x011f, 0x011e, 0x0121, 0x0120, 0x0123, 0x0122, 
+    0x0125, 0x0124, 0x0127, 0x0126, 0x0129, 0x0128, 0x012b, 0x012a, 0x012d, 
+    0x012c, 0x012f, 0x012e, 0x1000007, 0x0049, 0x0133, 0x0132, 0x0135, 
+    0x0134, 0x0137, 0x0136, 0x0000, 0x013a, 0x0139, 0x013c, 0x013b, 0x013e, 
+    0x013d, 0x0140, 0x013f, 0x0142, 0x0141, 0x0144, 0x0143, 0x0146, 0x0145, 
+    0x0148, 0x0147, 0x1000086, 0x014b, 0x014a, 0x014d, 0x014c, 0x014f, 
+    0x014e, 0x0151, 0x0150, 0x0153, 0x0152, 0x0155, 0x0154, 0x0157, 0x0156, 
+    0x0159, 0x0158, 0x015b, 0x015a, 0x015d, 0x015c, 0x015f, 0x015e, 0x0161, 
+    0x0160, 0x0163, 0x0162, 0x0165, 0x0164, 0x0167, 0x0166, 0x0169, 0x0168, 
+    0x016b, 0x016a, 0x016d, 0x016c, 0x016f, 0x016e, 0x0171, 0x0170, 0x0173, 
+    0x0172, 0x0175, 0x0174, 0x0177, 0x0176, 0x00ff, 0x017a, 0x0179, 0x017c, 
+    0x017b, 0x017e, 0x017d, 0x0053, 0x0243, 0x0253, 0x0183, 0x0182, 0x0185, 
+    0x0184, 0x0254, 0x0188, 0x0187, 0x0256, 0x0257, 0x018c, 0x018b, 0x0000, 
+    0x01dd, 0x0259, 0x025b, 0x0192, 0x0191, 0x0260, 0x0263, 0x01f6, 0x0269, 
+    0x0268, 0x0199, 0x0198, 0x023d, 0x0000, 0x026f, 0x0272, 0x0220, 0x0275, 
+    0x01a1, 0x01a0, 0x01a3, 0x01a2, 0x01a5, 0x01a4, 0x0280, 0x01a8, 0x01a7, 
+    0x0283, 0x0000, 0x0000, 0x01ad, 0x01ac, 0x0288, 0x01b0, 0x01af, 0x028a, 
+    0x028b, 0x01b4, 0x01b3, 0x01b6, 0x01b5, 0x0292, 0x01b9, 0x01b8, 0x0000, 
+    0x0000, 0x01bd, 0x01bc, 0x0000, 0x01f7, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x01c6, 0x0000, 0x01c4, 0x01c9, 0x0000, 0x01c7, 0x01cc, 0x0000, 0x01ca, 
+    0x01ce, 0x01cd, 0x01d0, 0x01cf, 0x01d2, 0x01d1, 0x01d4, 0x01d3, 0x01d6, 
+    0x01d5, 0x01d8, 0x01d7, 0x01da, 0x01d9, 0x01dc, 0x01db, 0x018e, 0x01df, 
+    0x01de, 0x01e1, 0x01e0, 0x01e3, 0x01e2, 0x01e5, 0x01e4, 0x01e7, 0x01e6, 
+    0x01e9, 0x01e8, 0x01eb, 0x01ea, 0x01ed, 0x01ec, 0x01ef, 0x01ee, 
+    0x10000ad, 0x01f3, 0x0000, 0x01f1, 0x01f5, 0x01f4, 0x0195, 0x01bf, 
+    0x01f9, 0x01f8, 0x01fb, 0x01fa, 0x01fd, 0x01fc, 0x01ff, 0x01fe
+  },
+  { /* page 2, index 2 */
+    0x0201, 0x0200, 0x0203, 0x0202, 0x0205, 0x0204, 0x0207, 0x0206, 0x0209, 
+    0x0208, 0x020b, 0x020a, 0x020d, 0x020c, 0x020f, 0x020e, 0x0211, 0x0210, 
+    0x0213, 0x0212, 0x0215, 0x0214, 0x0217, 0x0216, 0x0219, 0x0218, 0x021b, 
+    0x021a, 0x021d, 0x021c, 0x021f, 0x021e, 0x019e, 0x0000, 0x0223, 0x0222, 
+    0x0225, 0x0224, 0x0227, 0x0226, 0x0229, 0x0228, 0x022b, 0x022a, 0x022d, 
+    0x022c, 0x022f, 0x022e, 0x0231, 0x0230, 0x0233, 0x0232, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x2c65, 0x023c, 0x023b, 0x019a, 0x2c66, 
+    0x0000, 0x0000, 0x0242, 0x0241, 0x0180, 0x0289, 0x028c, 0x0247, 0x0246, 
+    0x0249, 0x0248, 0x024b, 0x024a, 0x024d, 0x024c, 0x024f, 0x024e, 0x2c6f, 
+    0x2c6d, 0x0000, 0x0181, 0x0186, 0x0000, 0x0189, 0x018a, 0x0000, 0x018f, 
+    0x0000, 0x0190, 0x0000, 0x0000, 0x0000, 0x0000, 0x0193, 0x0000, 0x0000, 
+    0x0194, 0x0000, 0x0000, 0x0000, 0x0000, 0x0197, 0x0196, 0x0000, 0x2c62, 
+    0x0000, 0x0000, 0x0000, 0x019c, 0x0000, 0x2c6e, 0x019d, 0x0000, 0x0000, 
+    0x019f, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2c64, 
+    0x0000, 0x0000, 0x01a6, 0x0000, 0x0000, 0x01a9, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x01ae, 0x0244, 0x01b1, 0x01b2, 0x0245, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x01b7, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 3, index 3 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0371, 0x0370, 0x0373, 0x0372, 0x0000, 
+    0x0000, 0x0377, 0x0376, 0x0000, 0x0000, 0x0000, 0x03fd, 0x03fe, 0x03ff, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x03ac, 
+    0x0000, 0x03ad, 0x03ae, 0x03af, 0x0000, 0x03cc, 0x0000, 0x03cd, 0x03ce, 
+    0x100008f, 0x03b1, 0x03b2, 0x03b3, 0x03b4, 0x03b5, 0x03b6, 0x03b7, 
+    0x03b8, 0x03b9, 0x03ba, 0x03bb, 0x03bc, 0x03bd, 0x03be, 0x03bf, 0x03c0, 
+    0x03c1, 0x0000, 0x03c3, 0x03c4, 0x03c5, 0x03c6, 0x03c7, 0x03c8, 0x03c9, 
+    0x03ca, 0x03cb, 0x0386, 0x0388, 0x0389, 0x038a, 0x100009e, 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, 0x03d7, 0x0392, 0x0398, 0x0000, 0x0000, 0x0000, 0x03a6, 
+    0x03a0, 0x03cf, 0x03d9, 0x03d8, 0x03db, 0x03da, 0x03dd, 0x03dc, 0x03df, 
+    0x03de, 0x03e1, 0x03e0, 0x03e3, 0x03e2, 0x03e5, 0x03e4, 0x03e7, 0x03e6, 
+    0x03e9, 0x03e8, 0x03eb, 0x03ea, 0x03ed, 0x03ec, 0x03ef, 0x03ee, 0x039a, 
+    0x03a1, 0x03f9, 0x0000, 0x03b8, 0x0395, 0x0000, 0x03f8, 0x03f7, 0x03f2, 
+    0x03fb, 0x03fa, 0x0000, 0x037b, 0x037c, 0x037d
+  },
+  { /* page 4, index 4 */
+    0x0450, 0x0451, 0x0452, 0x0453, 0x0454, 0x0455, 0x0456, 0x0457, 0x0458, 
+    0x0459, 0x045a, 0x045b, 0x045c, 0x045d, 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, 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, 0x0400, 
+    0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0406, 0x0407, 0x0408, 0x0409, 
+    0x040a, 0x040b, 0x040c, 0x040d, 0x040e, 0x040f, 0x0461, 0x0460, 0x0463, 
+    0x0462, 0x0465, 0x0464, 0x0467, 0x0466, 0x0469, 0x0468, 0x046b, 0x046a, 
+    0x046d, 0x046c, 0x046f, 0x046e, 0x0471, 0x0470, 0x0473, 0x0472, 0x0475, 
+    0x0474, 0x0477, 0x0476, 0x0479, 0x0478, 0x047b, 0x047a, 0x047d, 0x047c, 
+    0x047f, 0x047e, 0x0481, 0x0480, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x048b, 0x048a, 0x048d, 0x048c, 0x048f, 0x048e, 
+    0x0491, 0x0490, 0x0493, 0x0492, 0x0495, 0x0494, 0x0497, 0x0496, 0x0499, 
+    0x0498, 0x049b, 0x049a, 0x049d, 0x049c, 0x049f, 0x049e, 0x04a1, 0x04a0, 
+    0x04a3, 0x04a2, 0x04a5, 0x04a4, 0x04a7, 0x04a6, 0x04a9, 0x04a8, 0x04ab, 
+    0x04aa, 0x04ad, 0x04ac, 0x04af, 0x04ae, 0x04b1, 0x04b0, 0x04b3, 0x04b2, 
+    0x04b5, 0x04b4, 0x04b7, 0x04b6, 0x04b9, 0x04b8, 0x04bb, 0x04ba, 0x04bd, 
+    0x04bc, 0x04bf, 0x04be, 0x04cf, 0x04c2, 0x04c1, 0x04c4, 0x04c3, 0x04c6, 
+    0x04c5, 0x04c8, 0x04c7, 0x04ca, 0x04c9, 0x04cc, 0x04cb, 0x04ce, 0x04cd, 
+    0x04c0, 0x04d1, 0x04d0, 0x04d3, 0x04d2, 0x04d5, 0x04d4, 0x04d7, 0x04d6, 
+    0x04d9, 0x04d8, 0x04db, 0x04da, 0x04dd, 0x04dc, 0x04df, 0x04de, 0x04e1, 
+    0x04e0, 0x04e3, 0x04e2, 0x04e5, 0x04e4, 0x04e7, 0x04e6, 0x04e9, 0x04e8, 
+    0x04eb, 0x04ea, 0x04ed, 0x04ec, 0x04ef, 0x04ee, 0x04f1, 0x04f0, 0x04f3, 
+    0x04f2, 0x04f5, 0x04f4, 0x04f7, 0x04f6, 0x04f9, 0x04f8, 0x04fb, 0x04fa, 
+    0x04fd, 0x04fc, 0x04ff, 0x04fe
+  },
+  { /* page 5, index 5 */
+    0x0501, 0x0500, 0x0503, 0x0502, 0x0505, 0x0504, 0x0507, 0x0506, 0x0509, 
+    0x0508, 0x050b, 0x050a, 0x050d, 0x050c, 0x050f, 0x050e, 0x0511, 0x0510, 
+    0x0513, 0x0512, 0x0515, 0x0514, 0x0517, 0x0516, 0x0519, 0x0518, 0x051b, 
+    0x051a, 0x051d, 0x051c, 0x051f, 0x051e, 0x0521, 0x0520, 0x0523, 0x0522, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 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, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 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, 
+    0x1000044, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 6, index 6 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 
+    0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 
+    0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 7, index 7 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 
+    0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 9, index 8 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 
+    0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 
+    0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 10, index 9 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 
+    0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 
+    0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 11, index 10 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 
+    0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 
+    0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 12, index 11 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 
+    0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 
+    0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 13, index 12 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 
+    0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 14, index 13 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 
+    0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 15, index 14 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 
+    0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 16, index 15 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 
+    0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 
+    0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 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, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 23, index 16 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 24, index 17 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 
+    0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 25, index 18 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 
+    0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 
+    0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 27, index 19 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 
+    0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 28, index 20 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 
+    0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 29, index 21 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0xa77d, 0x0000, 0x0000, 0x0000, 0x2c63, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 30, index 22 */
+    0x1e01, 0x1e00, 0x1e03, 0x1e02, 0x1e05, 0x1e04, 0x1e07, 0x1e06, 0x1e09, 
+    0x1e08, 0x1e0b, 0x1e0a, 0x1e0d, 0x1e0c, 0x1e0f, 0x1e0e, 0x1e11, 0x1e10, 
+    0x1e13, 0x1e12, 0x1e15, 0x1e14, 0x1e17, 0x1e16, 0x1e19, 0x1e18, 0x1e1b, 
+    0x1e1a, 0x1e1d, 0x1e1c, 0x1e1f, 0x1e1e, 0x1e21, 0x1e20, 0x1e23, 0x1e22, 
+    0x1e25, 0x1e24, 0x1e27, 0x1e26, 0x1e29, 0x1e28, 0x1e2b, 0x1e2a, 0x1e2d, 
+    0x1e2c, 0x1e2f, 0x1e2e, 0x1e31, 0x1e30, 0x1e33, 0x1e32, 0x1e35, 0x1e34, 
+    0x1e37, 0x1e36, 0x1e39, 0x1e38, 0x1e3b, 0x1e3a, 0x1e3d, 0x1e3c, 0x1e3f, 
+    0x1e3e, 0x1e41, 0x1e40, 0x1e43, 0x1e42, 0x1e45, 0x1e44, 0x1e47, 0x1e46, 
+    0x1e49, 0x1e48, 0x1e4b, 0x1e4a, 0x1e4d, 0x1e4c, 0x1e4f, 0x1e4e, 0x1e51, 
+    0x1e50, 0x1e53, 0x1e52, 0x1e55, 0x1e54, 0x1e57, 0x1e56, 0x1e59, 0x1e58, 
+    0x1e5b, 0x1e5a, 0x1e5d, 0x1e5c, 0x1e5f, 0x1e5e, 0x1e61, 0x1e60, 0x1e63, 
+    0x1e62, 0x1e65, 0x1e64, 0x1e67, 0x1e66, 0x1e69, 0x1e68, 0x1e6b, 0x1e6a, 
+    0x1e6d, 0x1e6c, 0x1e6f, 0x1e6e, 0x1e71, 0x1e70, 0x1e73, 0x1e72, 0x1e75, 
+    0x1e74, 0x1e77, 0x1e76, 0x1e79, 0x1e78, 0x1e7b, 0x1e7a, 0x1e7d, 0x1e7c, 
+    0x1e7f, 0x1e7e, 0x1e81, 0x1e80, 0x1e83, 0x1e82, 0x1e85, 0x1e84, 0x1e87, 
+    0x1e86, 0x1e89, 0x1e88, 0x1e8b, 0x1e8a, 0x1e8d, 0x1e8c, 0x1e8f, 0x1e8e, 
+    0x1e91, 0x1e90, 0x1e93, 0x1e92, 0x1e95, 0x1e94, 0x10000b6, 0x10000bf, 
+    0x10000c8, 0x10000d1, 0x10000da, 0x1e60, 0x0000, 0x0000, 0x00df, 0x0000, 
+    0x1ea1, 0x1ea0, 0x1ea3, 0x1ea2, 0x1ea5, 0x1ea4, 0x1ea7, 0x1ea6, 0x1ea9, 
+    0x1ea8, 0x1eab, 0x1eaa, 0x1ead, 0x1eac, 0x1eaf, 0x1eae, 0x1eb1, 0x1eb0, 
+    0x1eb3, 0x1eb2, 0x1eb5, 0x1eb4, 0x1eb7, 0x1eb6, 0x1eb9, 0x1eb8, 0x1ebb, 
+    0x1eba, 0x1ebd, 0x1ebc, 0x1ebf, 0x1ebe, 0x1ec1, 0x1ec0, 0x1ec3, 0x1ec2, 
+    0x1ec5, 0x1ec4, 0x1ec7, 0x1ec6, 0x1ec9, 0x1ec8, 0x1ecb, 0x1eca, 0x1ecd, 
+    0x1ecc, 0x1ecf, 0x1ece, 0x1ed1, 0x1ed0, 0x1ed3, 0x1ed2, 0x1ed5, 0x1ed4, 
+    0x1ed7, 0x1ed6, 0x1ed9, 0x1ed8, 0x1edb, 0x1eda, 0x1edd, 0x1edc, 0x1edf, 
+    0x1ede, 0x1ee1, 0x1ee0, 0x1ee3, 0x1ee2, 0x1ee5, 0x1ee4, 0x1ee7, 0x1ee6, 
+    0x1ee9, 0x1ee8, 0x1eeb, 0x1eea, 0x1eed, 0x1eec, 0x1eef, 0x1eee, 0x1ef1, 
+    0x1ef0, 0x1ef3, 0x1ef2, 0x1ef5, 0x1ef4, 0x1ef7, 0x1ef6, 0x1ef9, 0x1ef8, 
+    0x1efb, 0x1efa, 0x1efd, 0x1efc, 0x1eff, 0x1efe
+  },
+  { /* page 31, index 23 */
+    0x1f08, 0x1f09, 0x1f0a, 0x1f0b, 0x1f0c, 0x1f0d, 0x1f0e, 0x1f0f, 0x1f00, 
+    0x1f01, 0x1f02, 0x1f03, 0x1f04, 0x1f05, 0x1f06, 0x1f07, 0x1f18, 0x1f19, 
+    0x1f1a, 0x1f1b, 0x1f1c, 0x1f1d, 0x0000, 0x0000, 0x1f10, 0x1f11, 0x1f12, 
+    0x1f13, 0x1f14, 0x1f15, 0x0000, 0x0000, 0x1f28, 0x1f29, 0x1f2a, 0x1f2b, 
+    0x1f2c, 0x1f2d, 0x1f2e, 0x1f2f, 0x1f20, 0x1f21, 0x1f22, 0x1f23, 0x1f24, 
+    0x1f25, 0x1f26, 0x1f27, 0x1f38, 0x1f39, 0x1f3a, 0x1f3b, 0x1f3c, 0x1f3d, 
+    0x1f3e, 0x1f3f, 0x1f30, 0x1f31, 0x1f32, 0x1f33, 0x1f34, 0x1f35, 0x1f36, 
+    0x1f37, 0x1f48, 0x1f49, 0x1f4a, 0x1f4b, 0x1f4c, 0x1f4d, 0x0000, 0x0000, 
+    0x1f40, 0x1f41, 0x1f42, 0x1f43, 0x1f44, 0x1f45, 0x0000, 0x0000, 
+    0x10000e3, 0x1f59, 0x10000ee, 0x1f5b, 0x10000fd, 0x1f5d, 0x100010c, 
+    0x1f5f, 0x0000, 0x1f51, 0x0000, 0x1f53, 0x0000, 0x1f55, 0x0000, 0x1f57, 
+    0x1f68, 0x1f69, 0x1f6a, 0x1f6b, 0x1f6c, 0x1f6d, 0x1f6e, 0x1f6f, 0x1f60, 
+    0x1f61, 0x1f62, 0x1f63, 0x1f64, 0x1f65, 0x1f66, 0x1f67, 0x1fba, 0x1fbb, 
+    0x1fc8, 0x1fc9, 0x1fca, 0x1fcb, 0x1fda, 0x1fdb, 0x1ff8, 0x1ff9, 0x1fea, 
+    0x1feb, 0x1ffa, 0x1ffb, 0x0000, 0x0000, 0x10001b7, 0x10001c4, 0x10001d1, 
+    0x10001de, 0x10001eb, 0x10001f8, 0x1000205, 0x1000212, 0x100021f, 
+    0x1000229, 0x1000233, 0x100023d, 0x1000247, 0x1000251, 0x100025b, 
+    0x1000265, 0x100026f, 0x100027c, 0x1000289, 0x1000296, 0x10002a3, 
+    0x10002b0, 0x10002bd, 0x10002ca, 0x10002d7, 0x10002e1, 0x10002eb, 
+    0x10002f5, 0x10002ff, 0x1000309, 0x1000313, 0x100031d, 0x1000327, 
+    0x1000334, 0x1000341, 0x100034e, 0x100035b, 0x1000368, 0x1000375, 
+    0x1000382, 0x100038f, 0x1000399, 0x10003a3, 0x10003ad, 0x10003b7, 
+    0x10003c1, 0x10003cb, 0x10003d5, 0x1fb8, 0x1fb9, 0x100041e, 0x10003df, 
+    0x100042b, 0x0000, 0x100011b, 0x1000466, 0x1fb0, 0x1fb1, 0x1f70, 0x1f71, 
+    0x10003eb, 0x0000, 0x0399, 0x0000, 0x0000, 0x0000, 0x1000436, 0x10003f4, 
+    0x1000443, 0x0000, 0x1000126, 0x1000475, 0x1f72, 0x1f73, 0x1f74, 0x1f75, 
+    0x1000400, 0x0000, 0x0000, 0x0000, 0x1fd8, 0x1fd9, 0x1000131, 0x1000140, 
+    0x0000, 0x0000, 0x100014f, 0x100015a, 0x1fd0, 0x1fd1, 0x1f76, 0x1f77, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x1fe8, 0x1fe9, 0x1000169, 0x1000178, 
+    0x1000187, 0x1fec, 0x1000192, 0x100019d, 0x1fe0, 0x1fe1, 0x1f7a, 0x1f7b, 
+    0x1fe5, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x100044e, 0x1000409, 
+    0x100045b, 0x0000, 0x10001ac, 0x1000484, 0x1f78, 0x1f79, 0x1f7c, 0x1f7d, 
+    0x1000415, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 33, index 24 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x03c9, 0x0000, 0x0000, 0x0000, 0x006b, 0x00e5, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x214e, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2132, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x2184, 0x2183, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 44, index 25 */
+    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, 0x0000, 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, 0x0000, 0x2c61, 0x2c60, 0x026b, 
+    0x1d7d, 0x027d, 0x023a, 0x023e, 0x2c68, 0x2c67, 0x2c6a, 0x2c69, 0x2c6c, 
+    0x2c6b, 0x0251, 0x0271, 0x0250, 0x0000, 0x0000, 0x2c73, 0x2c72, 0x0000, 
+    0x2c76, 0x2c75, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x2c81, 0x2c80, 0x2c83, 0x2c82, 0x2c85, 0x2c84, 0x2c87, 
+    0x2c86, 0x2c89, 0x2c88, 0x2c8b, 0x2c8a, 0x2c8d, 0x2c8c, 0x2c8f, 0x2c8e, 
+    0x2c91, 0x2c90, 0x2c93, 0x2c92, 0x2c95, 0x2c94, 0x2c97, 0x2c96, 0x2c99, 
+    0x2c98, 0x2c9b, 0x2c9a, 0x2c9d, 0x2c9c, 0x2c9f, 0x2c9e, 0x2ca1, 0x2ca0, 
+    0x2ca3, 0x2ca2, 0x2ca5, 0x2ca4, 0x2ca7, 0x2ca6, 0x2ca9, 0x2ca8, 0x2cab, 
+    0x2caa, 0x2cad, 0x2cac, 0x2caf, 0x2cae, 0x2cb1, 0x2cb0, 0x2cb3, 0x2cb2, 
+    0x2cb5, 0x2cb4, 0x2cb7, 0x2cb6, 0x2cb9, 0x2cb8, 0x2cbb, 0x2cba, 0x2cbd, 
+    0x2cbc, 0x2cbf, 0x2cbe, 0x2cc1, 0x2cc0, 0x2cc3, 0x2cc2, 0x2cc5, 0x2cc4, 
+    0x2cc7, 0x2cc6, 0x2cc9, 0x2cc8, 0x2ccb, 0x2cca, 0x2ccd, 0x2ccc, 0x2ccf, 
+    0x2cce, 0x2cd1, 0x2cd0, 0x2cd3, 0x2cd2, 0x2cd5, 0x2cd4, 0x2cd7, 0x2cd6, 
+    0x2cd9, 0x2cd8, 0x2cdb, 0x2cda, 0x2cdd, 0x2cdc, 0x2cdf, 0x2cde, 0x2ce1, 
+    0x2ce0, 0x2ce3, 0x2ce2, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 45, index 26 */
+    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, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 166, index 27 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 
+    0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0xa641, 0xa640, 0xa643, 0xa642, 0xa645, 0xa644, 0xa647, 0xa646, 
+    0xa649, 0xa648, 0xa64b, 0xa64a, 0xa64d, 0xa64c, 0xa64f, 0xa64e, 0xa651, 
+    0xa650, 0xa653, 0xa652, 0xa655, 0xa654, 0xa657, 0xa656, 0xa659, 0xa658, 
+    0xa65b, 0xa65a, 0xa65d, 0xa65c, 0xa65f, 0xa65e, 0x0000, 0x0000, 0xa663, 
+    0xa662, 0xa665, 0xa664, 0xa667, 0xa666, 0xa669, 0xa668, 0xa66b, 0xa66a, 
+    0xa66d, 0xa66c, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0xa681, 0xa680, 0xa683, 0xa682, 0xa685, 0xa684, 0xa687, 
+    0xa686, 0xa689, 0xa688, 0xa68b, 0xa68a, 0xa68d, 0xa68c, 0xa68f, 0xa68e, 
+    0xa691, 0xa690, 0xa693, 0xa692, 0xa695, 0xa694, 0xa697, 0xa696, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 167, index 28 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0xa723, 0xa722, 
+    0xa725, 0xa724, 0xa727, 0xa726, 0xa729, 0xa728, 0xa72b, 0xa72a, 0xa72d, 
+    0xa72c, 0xa72f, 0xa72e, 0x0000, 0x0000, 0xa733, 0xa732, 0xa735, 0xa734, 
+    0xa737, 0xa736, 0xa739, 0xa738, 0xa73b, 0xa73a, 0xa73d, 0xa73c, 0xa73f, 
+    0xa73e, 0xa741, 0xa740, 0xa743, 0xa742, 0xa745, 0xa744, 0xa747, 0xa746, 
+    0xa749, 0xa748, 0xa74b, 0xa74a, 0xa74d, 0xa74c, 0xa74f, 0xa74e, 0xa751, 
+    0xa750, 0xa753, 0xa752, 0xa755, 0xa754, 0xa757, 0xa756, 0xa759, 0xa758, 
+    0xa75b, 0xa75a, 0xa75d, 0xa75c, 0xa75f, 0xa75e, 0xa761, 0xa760, 0xa763, 
+    0xa762, 0xa765, 0xa764, 0xa767, 0xa766, 0xa769, 0xa768, 0xa76b, 0xa76a, 
+    0xa76d, 0xa76c, 0xa76f, 0xa76e, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0xa77a, 0xa779, 0xa77c, 0xa77b, 0x1d79, 
+    0xa77f, 0xa77e, 0xa781, 0xa780, 0xa783, 0xa782, 0xa785, 0xa784, 0xa787, 
+    0xa786, 0x0000, 0x0000, 0x0000, 0xa78c, 0xa78b, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 168, index 29 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 
+    0x0008, 0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 169, index 30 */
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 
+    0x0009, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 170, index 31 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 251, index 32 */
+    0x100000f, 0x1000016, 0x100001d, 0x1000024, 0x100002d, 0x1000036, 
+    0x100003d, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x100004f, 0x100005a, 0x1000065, 
+    0x1000070, 0x100007b, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000
+  },
+  { /* page 255, index 33 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0001, 
+    0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 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, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 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, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 260, index 34 */
+    0x10428, 0x10429, 0x1042a, 0x1042b, 0x1042c, 0x1042d, 0x1042e, 0x1042f, 
+    0x10430, 0x10431, 0x10432, 0x10433, 0x10434, 0x10435, 0x10436, 0x10437, 
+    0x10438, 0x10439, 0x1043a, 0x1043b, 0x1043c, 0x1043d, 0x1043e, 0x1043f, 
+    0x10440, 0x10441, 0x10442, 0x10443, 0x10444, 0x10445, 0x10446, 0x10447, 
+    0x10448, 0x10449, 0x1044a, 0x1044b, 0x1044c, 0x1044d, 0x1044e, 0x1044f, 
+    0x10400, 0x10401, 0x10402, 0x10403, 0x10404, 0x10405, 0x10406, 0x10407, 
+    0x10408, 0x10409, 0x1040a, 0x1040b, 0x1040c, 0x1040d, 0x1040e, 0x1040f, 
+    0x10410, 0x10411, 0x10412, 0x10413, 0x10414, 0x10415, 0x10416, 0x10417, 
+    0x10418, 0x10419, 0x1041a, 0x1041b, 0x1041c, 0x1041d, 0x1041e, 0x1041f, 
+    0x10420, 0x10421, 0x10422, 0x10423, 0x10424, 0x10425, 0x10426, 0x10427, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000
+  },
+  { /* page 471, index 35 */
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 0x0000, 
+    0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 0x0009, 
+    0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 0x0008, 
+    0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007, 
+    0x0008, 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 
+    0x0007, 0x0008, 0x0009, 0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 
+    0x0006, 0x0007, 0x0008, 0x0009
+  }
+};
+
+/* U+0000 through U+2FAFF */
+static const gint16 attr_table_part1[763] = {
+  0 /* page 0 */,
+  1 /* page 1 */,
+  2 /* page 2 */,
+  3 /* page 3 */,
+  4 /* page 4 */,
+  5 /* page 5 */,
+  6 /* page 6 */,
+  7 /* page 7 */,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  8 /* page 9 */,
+  9 /* page 10 */,
+  10 /* page 11 */,
+  11 /* page 12 */,
+  12 /* page 13 */,
+  13 /* page 14 */,
+  14 /* page 15 */,
+  15 /* page 16 */,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  16 /* page 23 */,
+  17 /* page 24 */,
+  18 /* page 25 */,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  19 /* page 27 */,
+  20 /* page 28 */,
+  21 /* page 29 */,
+  22 /* page 30 */,
+  23 /* page 31 */,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  24 /* page 33 */,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  25 /* page 44 */,
+  26 /* page 45 */,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  27 /* page 166 */,
+  28 /* page 167 */,
+  29 /* page 168 */,
+  30 /* page 169 */,
+  31 /* page 170 */,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  32 /* page 251 */,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  33 /* page 255 */,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  34 /* page 260 */,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  35 /* page 471 */,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX
+};
+
+/* U+E0000 through U+10FFFF */
+static const gint16 attr_table_part2[768] = {
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX,
+  0x0000 + G_UNICODE_MAX_TABLE_INDEX
+};
+
+static const gunichar title_table[][3] = {
+  { 0x01c5, 0x01c4, 0x01c6 },
+  { 0x01c8, 0x01c7, 0x01c9 },
+  { 0x01cb, 0x01ca, 0x01cc },
+  { 0x01f2, 0x01f1, 0x01f3 },
+  { 0x1f88, 0x0000, 0x1f80 },
+  { 0x1f89, 0x0000, 0x1f81 },
+  { 0x1f8a, 0x0000, 0x1f82 },
+  { 0x1f8b, 0x0000, 0x1f83 },
+  { 0x1f8c, 0x0000, 0x1f84 },
+  { 0x1f8d, 0x0000, 0x1f85 },
+  { 0x1f8e, 0x0000, 0x1f86 },
+  { 0x1f8f, 0x0000, 0x1f87 },
+  { 0x1f98, 0x0000, 0x1f90 },
+  { 0x1f99, 0x0000, 0x1f91 },
+  { 0x1f9a, 0x0000, 0x1f92 },
+  { 0x1f9b, 0x0000, 0x1f93 },
+  { 0x1f9c, 0x0000, 0x1f94 },
+  { 0x1f9d, 0x0000, 0x1f95 },
+  { 0x1f9e, 0x0000, 0x1f96 },
+  { 0x1f9f, 0x0000, 0x1f97 },
+  { 0x1fa8, 0x0000, 0x1fa0 },
+  { 0x1fa9, 0x0000, 0x1fa1 },
+  { 0x1faa, 0x0000, 0x1fa2 },
+  { 0x1fab, 0x0000, 0x1fa3 },
+  { 0x1fac, 0x0000, 0x1fa4 },
+  { 0x1fad, 0x0000, 0x1fa5 },
+  { 0x1fae, 0x0000, 0x1fa6 },
+  { 0x1faf, 0x0000, 0x1fa7 },
+  { 0x1fbc, 0x0000, 0x1fb3 },
+  { 0x1fcc, 0x0000, 0x1fc3 },
+  { 0x1ffc, 0x0000, 0x1ff3 }
+};
+
+
+/* Table of special cases for case conversion; each record contains
+ * First, the best single character mapping to lowercase if Lu, 
+ * and to uppercase if Ll, followed by the output mapping for the two cases 
+ * other than the case of the codepoint, in the order [Ll],[Lu],[Lt],
+ * encoded in UTF-8, separated and terminated by a null character.
+ */
+static const gchar special_case_table[] = {
+ "\x00\x53\x53\x00\x53\x73\0" /* offset 0 */
+ "\x69\x69\xcc\x87\x00\xc4\xb0\0" /* offset 7 */
+ "\x00\x46\x46\x00\x46\x66\0" /* offset 15 */
+ "\x00\x46\x49\x00\x46\x69\0" /* offset 22 */
+ "\x00\x46\x4c\x00\x46\x6c\0" /* offset 29 */
+ "\x00\x46\x46\x49\x00\x46\x66\x69\0" /* offset 36 */
+ "\x00\x46\x46\x4c\x00\x46\x66\x6c\0" /* offset 45 */
+ "\x00\x53\x54\x00\x53\x74\0" /* offset 54 */
+ "\x00\x53\x54\x00\x53\x74\0" /* offset 61 */
+ "\x00\xd4\xb5\xd5\x92\x00\xd4\xb5\xd6\x82\0" /* offset 68 */
+ "\x00\xd5\x84\xd5\x86\x00\xd5\x84\xd5\xb6\0" /* offset 79 */
+ "\x00\xd5\x84\xd4\xb5\x00\xd5\x84\xd5\xa5\0" /* offset 90 */
+ "\x00\xd5\x84\xd4\xbb\x00\xd5\x84\xd5\xab\0" /* offset 101 */
+ "\x00\xd5\x8e\xd5\x86\x00\xd5\x8e\xd5\xb6\0" /* offset 112 */
+ "\x00\xd5\x84\xd4\xbd\x00\xd5\x84\xd5\xad\0" /* offset 123 */
+ "\x00\xca\xbc\x4e\x00\xca\xbc\x4e\0" /* offset 134 */
+ "\x00\xce\x99\xcc\x88\xcc\x81\x00\xce\x99\xcc\x88\xcc\x81\0" /* offset 143 */
+ "\x00\xce\xa5\xcc\x88\xcc\x81\x00\xce\xa5\xcc\x88\xcc\x81\0" /* offset 158 */
+ "\x00\x4a\xcc\x8c\x00\x4a\xcc\x8c\0" /* offset 173 */
+ "\x00\x48\xcc\xb1\x00\x48\xcc\xb1\0" /* offset 182 */
+ "\x00\x54\xcc\x88\x00\x54\xcc\x88\0" /* offset 191 */
+ "\x00\x57\xcc\x8a\x00\x57\xcc\x8a\0" /* offset 200 */
+ "\x00\x59\xcc\x8a\x00\x59\xcc\x8a\0" /* offset 209 */
+ "\x00\x41\xca\xbe\x00\x41\xca\xbe\0" /* offset 218 */
+ "\x00\xce\xa5\xcc\x93\x00\xce\xa5\xcc\x93\0" /* offset 227 */
+ "\x00\xce\xa5\xcc\x93\xcc\x80\x00\xce\xa5\xcc\x93\xcc\x80\0" /* offset 238 */
+ "\x00\xce\xa5\xcc\x93\xcc\x81\x00\xce\xa5\xcc\x93\xcc\x81\0" /* offset 253 */
+ "\x00\xce\xa5\xcc\x93\xcd\x82\x00\xce\xa5\xcc\x93\xcd\x82\0" /* offset 268 */
+ "\x00\xce\x91\xcd\x82\x00\xce\x91\xcd\x82\0" /* offset 283 */
+ "\x00\xce\x97\xcd\x82\x00\xce\x97\xcd\x82\0" /* offset 294 */
+ "\x00\xce\x99\xcc\x88\xcc\x80\x00\xce\x99\xcc\x88\xcc\x80\0" /* offset 305 */
+ "\x00\xce\x99\xcc\x88\xcc\x81\x00\xce\x99\xcc\x88\xcc\x81\0" /* offset 320 */
+ "\x00\xce\x99\xcd\x82\x00\xce\x99\xcd\x82\0" /* offset 335 */
+ "\x00\xce\x99\xcc\x88\xcd\x82\x00\xce\x99\xcc\x88\xcd\x82\0" /* offset 346 */
+ "\x00\xce\xa5\xcc\x88\xcc\x80\x00\xce\xa5\xcc\x88\xcc\x80\0" /* offset 361 */
+ "\x00\xce\xa5\xcc\x88\xcc\x81\x00\xce\xa5\xcc\x88\xcc\x81\0" /* offset 376 */
+ "\x00\xce\xa1\xcc\x93\x00\xce\xa1\xcc\x93\0" /* offset 391 */
+ "\x00\xce\xa5\xcd\x82\x00\xce\xa5\xcd\x82\0" /* offset 402 */
+ "\x00\xce\xa5\xcc\x88\xcd\x82\x00\xce\xa5\xcc\x88\xcd\x82\0" /* offset 413 */
+ "\x00\xce\xa9\xcd\x82\x00\xce\xa9\xcd\x82\0" /* offset 428 */
+ "\xe1\xbe\x88\xe1\xbc\x88\xce\x99\x00\xe1\xbe\x88\0" /* offset 439 */
+ "\xe1\xbe\x89\xe1\xbc\x89\xce\x99\x00\xe1\xbe\x89\0" /* offset 452 */
+ "\xe1\xbe\x8a\xe1\xbc\x8a\xce\x99\x00\xe1\xbe\x8a\0" /* offset 465 */
+ "\xe1\xbe\x8b\xe1\xbc\x8b\xce\x99\x00\xe1\xbe\x8b\0" /* offset 478 */
+ "\xe1\xbe\x8c\xe1\xbc\x8c\xce\x99\x00\xe1\xbe\x8c\0" /* offset 491 */
+ "\xe1\xbe\x8d\xe1\xbc\x8d\xce\x99\x00\xe1\xbe\x8d\0" /* offset 504 */
+ "\xe1\xbe\x8e\xe1\xbc\x8e\xce\x99\x00\xe1\xbe\x8e\0" /* offset 517 */
+ "\xe1\xbe\x8f\xe1\xbc\x8f\xce\x99\x00\xe1\xbe\x8f\0" /* offset 530 */
+ "\xe1\xbe\x80\x00\xe1\xbc\x88\xce\x99\0" /* offset 543 */
+ "\xe1\xbe\x81\x00\xe1\xbc\x89\xce\x99\0" /* offset 553 */
+ "\xe1\xbe\x82\x00\xe1\xbc\x8a\xce\x99\0" /* offset 563 */
+ "\xe1\xbe\x83\x00\xe1\xbc\x8b\xce\x99\0" /* offset 573 */
+ "\xe1\xbe\x84\x00\xe1\xbc\x8c\xce\x99\0" /* offset 583 */
+ "\xe1\xbe\x85\x00\xe1\xbc\x8d\xce\x99\0" /* offset 593 */
+ "\xe1\xbe\x86\x00\xe1\xbc\x8e\xce\x99\0" /* offset 603 */
+ "\xe1\xbe\x87\x00\xe1\xbc\x8f\xce\x99\0" /* offset 613 */
+ "\xe1\xbe\x98\xe1\xbc\xa8\xce\x99\x00\xe1\xbe\x98\0" /* offset 623 */
+ "\xe1\xbe\x99\xe1\xbc\xa9\xce\x99\x00\xe1\xbe\x99\0" /* offset 636 */
+ "\xe1\xbe\x9a\xe1\xbc\xaa\xce\x99\x00\xe1\xbe\x9a\0" /* offset 649 */
+ "\xe1\xbe\x9b\xe1\xbc\xab\xce\x99\x00\xe1\xbe\x9b\0" /* offset 662 */
+ "\xe1\xbe\x9c\xe1\xbc\xac\xce\x99\x00\xe1\xbe\x9c\0" /* offset 675 */
+ "\xe1\xbe\x9d\xe1\xbc\xad\xce\x99\x00\xe1\xbe\x9d\0" /* offset 688 */
+ "\xe1\xbe\x9e\xe1\xbc\xae\xce\x99\x00\xe1\xbe\x9e\0" /* offset 701 */
+ "\xe1\xbe\x9f\xe1\xbc\xaf\xce\x99\x00\xe1\xbe\x9f\0" /* offset 714 */
+ "\xe1\xbe\x90\x00\xe1\xbc\xa8\xce\x99\0" /* offset 727 */
+ "\xe1\xbe\x91\x00\xe1\xbc\xa9\xce\x99\0" /* offset 737 */
+ "\xe1\xbe\x92\x00\xe1\xbc\xaa\xce\x99\0" /* offset 747 */
+ "\xe1\xbe\x93\x00\xe1\xbc\xab\xce\x99\0" /* offset 757 */
+ "\xe1\xbe\x94\x00\xe1\xbc\xac\xce\x99\0" /* offset 767 */
+ "\xe1\xbe\x95\x00\xe1\xbc\xad\xce\x99\0" /* offset 777 */
+ "\xe1\xbe\x96\x00\xe1\xbc\xae\xce\x99\0" /* offset 787 */
+ "\xe1\xbe\x97\x00\xe1\xbc\xaf\xce\x99\0" /* offset 797 */
+ "\xe1\xbe\xa8\xe1\xbd\xa8\xce\x99\x00\xe1\xbe\xa8\0" /* offset 807 */
+ "\xe1\xbe\xa9\xe1\xbd\xa9\xce\x99\x00\xe1\xbe\xa9\0" /* offset 820 */
+ "\xe1\xbe\xaa\xe1\xbd\xaa\xce\x99\x00\xe1\xbe\xaa\0" /* offset 833 */
+ "\xe1\xbe\xab\xe1\xbd\xab\xce\x99\x00\xe1\xbe\xab\0" /* offset 846 */
+ "\xe1\xbe\xac\xe1\xbd\xac\xce\x99\x00\xe1\xbe\xac\0" /* offset 859 */
+ "\xe1\xbe\xad\xe1\xbd\xad\xce\x99\x00\xe1\xbe\xad\0" /* offset 872 */
+ "\xe1\xbe\xae\xe1\xbd\xae\xce\x99\x00\xe1\xbe\xae\0" /* offset 885 */
+ "\xe1\xbe\xaf\xe1\xbd\xaf\xce\x99\x00\xe1\xbe\xaf\0" /* offset 898 */
+ "\xe1\xbe\xa0\x00\xe1\xbd\xa8\xce\x99\0" /* offset 911 */
+ "\xe1\xbe\xa1\x00\xe1\xbd\xa9\xce\x99\0" /* offset 921 */
+ "\xe1\xbe\xa2\x00\xe1\xbd\xaa\xce\x99\0" /* offset 931 */
+ "\xe1\xbe\xa3\x00\xe1\xbd\xab\xce\x99\0" /* offset 941 */
+ "\xe1\xbe\xa4\x00\xe1\xbd\xac\xce\x99\0" /* offset 951 */
+ "\xe1\xbe\xa5\x00\xe1\xbd\xad\xce\x99\0" /* offset 961 */
+ "\xe1\xbe\xa6\x00\xe1\xbd\xae\xce\x99\0" /* offset 971 */
+ "\xe1\xbe\xa7\x00\xe1\xbd\xaf\xce\x99\0" /* offset 981 */
+ "\xe1\xbe\xbc\xce\x91\xce\x99\x00\xe1\xbe\xbc\0" /* offset 991 */
+ "\xe1\xbe\xb3\x00\xce\x91\xce\x99\0" /* offset 1003 */
+ "\xe1\xbf\x8c\xce\x97\xce\x99\x00\xe1\xbf\x8c\0" /* offset 1012 */
+ "\xe1\xbf\x83\x00\xce\x97\xce\x99\0" /* offset 1024 */
+ "\xe1\xbf\xbc\xce\xa9\xce\x99\x00\xe1\xbf\xbc\0" /* offset 1033 */
+ "\xe1\xbf\xb3\x00\xce\xa9\xce\x99\0" /* offset 1045 */
+ "\x00\xe1\xbe\xba\xce\x99\x00\xe1\xbe\xba\xcd\x85\0" /* offset 1054 */
+ "\x00\xce\x86\xce\x99\x00\xce\x86\xcd\x85\0" /* offset 1067 */
+ "\x00\xe1\xbf\x8a\xce\x99\x00\xe1\xbf\x8a\xcd\x85\0" /* offset 1078 */
+ "\x00\xce\x89\xce\x99\x00\xce\x89\xcd\x85\0" /* offset 1091 */
+ "\x00\xe1\xbf\xba\xce\x99\x00\xe1\xbf\xba\xcd\x85\0" /* offset 1102 */
+ "\x00\xce\x8f\xce\x99\x00\xce\x8f\xcd\x85\0" /* offset 1115 */
+ "\x00\xce\x91\xcd\x82\xce\x99\x00\xce\x91\xcd\x82\xcd\x85\0" /* offset 1126 */
+ "\x00\xce\x97\xcd\x82\xce\x99\x00\xce\x97\xcd\x82\xcd\x85\0" /* offset 1141 */
+ "\x00\xce\xa9\xcd\x82\xce\x99\x00\xce\xa9\xcd\x82\xcd\x85\0" /* offset 1156 */
+};
+
+
+/* Table of casefolding cases that can't be derived by lowercasing
+ */
+static const struct {
+  guint16 ch;
+  gchar data[7];
+} casefold_table[] = {
+  { 0x00b5, "\xce\xbc" },
+  { 0x00df, "\x73\x73" },
+  { 0x0130, "\x69\xcc\x87" },
+  { 0x0149, "\xca\xbc\x6e" },
+  { 0x017f, "\x73" },
+  { 0x01f0, "\x6a\xcc\x8c" },
+  { 0x0345, "\xce\xb9" },
+  { 0x0390, "\xce\xb9\xcc\x88\xcc\x81" },
+  { 0x03b0, "\xcf\x85\xcc\x88\xcc\x81" },
+  { 0x03c2, "\xcf\x83" },
+  { 0x03d0, "\xce\xb2" },
+  { 0x03d1, "\xce\xb8" },
+  { 0x03d5, "\xcf\x86" },
+  { 0x03d6, "\xcf\x80" },
+  { 0x03f0, "\xce\xba" },
+  { 0x03f1, "\xcf\x81" },
+  { 0x03f5, "\xce\xb5" },
+  { 0x0587, "\xd5\xa5\xd6\x82" },
+  { 0x1e96, "\x68\xcc\xb1" },
+  { 0x1e97, "\x74\xcc\x88" },
+  { 0x1e98, "\x77\xcc\x8a" },
+  { 0x1e99, "\x79\xcc\x8a" },
+  { 0x1e9a, "\x61\xca\xbe" },
+  { 0x1e9b, "\xe1\xb9\xa1" },
+  { 0x1e9e, "\x73\x73" },
+  { 0x1f50, "\xcf\x85\xcc\x93" },
+  { 0x1f52, "\xcf\x85\xcc\x93\xcc\x80" },
+  { 0x1f54, "\xcf\x85\xcc\x93\xcc\x81" },
+  { 0x1f56, "\xcf\x85\xcc\x93\xcd\x82" },
+  { 0x1f80, "\xe1\xbc\x80\xce\xb9" },
+  { 0x1f81, "\xe1\xbc\x81\xce\xb9" },
+  { 0x1f82, "\xe1\xbc\x82\xce\xb9" },
+  { 0x1f83, "\xe1\xbc\x83\xce\xb9" },
+  { 0x1f84, "\xe1\xbc\x84\xce\xb9" },
+  { 0x1f85, "\xe1\xbc\x85\xce\xb9" },
+  { 0x1f86, "\xe1\xbc\x86\xce\xb9" },
+  { 0x1f87, "\xe1\xbc\x87\xce\xb9" },
+  { 0x1f88, "\xe1\xbc\x80\xce\xb9" },
+  { 0x1f89, "\xe1\xbc\x81\xce\xb9" },
+  { 0x1f8a, "\xe1\xbc\x82\xce\xb9" },
+  { 0x1f8b, "\xe1\xbc\x83\xce\xb9" },
+  { 0x1f8c, "\xe1\xbc\x84\xce\xb9" },
+  { 0x1f8d, "\xe1\xbc\x85\xce\xb9" },
+  { 0x1f8e, "\xe1\xbc\x86\xce\xb9" },
+  { 0x1f8f, "\xe1\xbc\x87\xce\xb9" },
+  { 0x1f90, "\xe1\xbc\xa0\xce\xb9" },
+  { 0x1f91, "\xe1\xbc\xa1\xce\xb9" },
+  { 0x1f92, "\xe1\xbc\xa2\xce\xb9" },
+  { 0x1f93, "\xe1\xbc\xa3\xce\xb9" },
+  { 0x1f94, "\xe1\xbc\xa4\xce\xb9" },
+  { 0x1f95, "\xe1\xbc\xa5\xce\xb9" },
+  { 0x1f96, "\xe1\xbc\xa6\xce\xb9" },
+  { 0x1f97, "\xe1\xbc\xa7\xce\xb9" },
+  { 0x1f98, "\xe1\xbc\xa0\xce\xb9" },
+  { 0x1f99, "\xe1\xbc\xa1\xce\xb9" },
+  { 0x1f9a, "\xe1\xbc\xa2\xce\xb9" },
+  { 0x1f9b, "\xe1\xbc\xa3\xce\xb9" },
+  { 0x1f9c, "\xe1\xbc\xa4\xce\xb9" },
+  { 0x1f9d, "\xe1\xbc\xa5\xce\xb9" },
+  { 0x1f9e, "\xe1\xbc\xa6\xce\xb9" },
+  { 0x1f9f, "\xe1\xbc\xa7\xce\xb9" },
+  { 0x1fa0, "\xe1\xbd\xa0\xce\xb9" },
+  { 0x1fa1, "\xe1\xbd\xa1\xce\xb9" },
+  { 0x1fa2, "\xe1\xbd\xa2\xce\xb9" },
+  { 0x1fa3, "\xe1\xbd\xa3\xce\xb9" },
+  { 0x1fa4, "\xe1\xbd\xa4\xce\xb9" },
+  { 0x1fa5, "\xe1\xbd\xa5\xce\xb9" },
+  { 0x1fa6, "\xe1\xbd\xa6\xce\xb9" },
+  { 0x1fa7, "\xe1\xbd\xa7\xce\xb9" },
+  { 0x1fa8, "\xe1\xbd\xa0\xce\xb9" },
+  { 0x1fa9, "\xe1\xbd\xa1\xce\xb9" },
+  { 0x1faa, "\xe1\xbd\xa2\xce\xb9" },
+  { 0x1fab, "\xe1\xbd\xa3\xce\xb9" },
+  { 0x1fac, "\xe1\xbd\xa4\xce\xb9" },
+  { 0x1fad, "\xe1\xbd\xa5\xce\xb9" },
+  { 0x1fae, "\xe1\xbd\xa6\xce\xb9" },
+  { 0x1faf, "\xe1\xbd\xa7\xce\xb9" },
+  { 0x1fb2, "\xe1\xbd\xb0\xce\xb9" },
+  { 0x1fb3, "\xce\xb1\xce\xb9" },
+  { 0x1fb4, "\xce\xac\xce\xb9" },
+  { 0x1fb6, "\xce\xb1\xcd\x82" },
+  { 0x1fb7, "\xce\xb1\xcd\x82\xce\xb9" },
+  { 0x1fbc, "\xce\xb1\xce\xb9" },
+  { 0x1fbe, "\xce\xb9" },
+  { 0x1fc2, "\xe1\xbd\xb4\xce\xb9" },
+  { 0x1fc3, "\xce\xb7\xce\xb9" },
+  { 0x1fc4, "\xce\xae\xce\xb9" },
+  { 0x1fc6, "\xce\xb7\xcd\x82" },
+  { 0x1fc7, "\xce\xb7\xcd\x82\xce\xb9" },
+  { 0x1fcc, "\xce\xb7\xce\xb9" },
+  { 0x1fd2, "\xce\xb9\xcc\x88\xcc\x80" },
+  { 0x1fd3, "\xce\xb9\xcc\x88\xcc\x81" },
+  { 0x1fd6, "\xce\xb9\xcd\x82" },
+  { 0x1fd7, "\xce\xb9\xcc\x88\xcd\x82" },
+  { 0x1fe2, "\xcf\x85\xcc\x88\xcc\x80" },
+  { 0x1fe3, "\xcf\x85\xcc\x88\xcc\x81" },
+  { 0x1fe4, "\xcf\x81\xcc\x93" },
+  { 0x1fe6, "\xcf\x85\xcd\x82" },
+  { 0x1fe7, "\xcf\x85\xcc\x88\xcd\x82" },
+  { 0x1ff2, "\xe1\xbd\xbc\xce\xb9" },
+  { 0x1ff3, "\xcf\x89\xce\xb9" },
+  { 0x1ff4, "\xcf\x8e\xce\xb9" },
+  { 0x1ff6, "\xcf\x89\xcd\x82" },
+  { 0x1ff7, "\xcf\x89\xcd\x82\xce\xb9" },
+  { 0x1ffc, "\xcf\x89\xce\xb9" },
+  { 0x2160, "\xe2\x85\xb0" },
+  { 0x2161, "\xe2\x85\xb1" },
+  { 0x2162, "\xe2\x85\xb2" },
+  { 0x2163, "\xe2\x85\xb3" },
+  { 0x2164, "\xe2\x85\xb4" },
+  { 0x2165, "\xe2\x85\xb5" },
+  { 0x2166, "\xe2\x85\xb6" },
+  { 0x2167, "\xe2\x85\xb7" },
+  { 0x2168, "\xe2\x85\xb8" },
+  { 0x2169, "\xe2\x85\xb9" },
+  { 0x216a, "\xe2\x85\xba" },
+  { 0x216b, "\xe2\x85\xbb" },
+  { 0x216c, "\xe2\x85\xbc" },
+  { 0x216d, "\xe2\x85\xbd" },
+  { 0x216e, "\xe2\x85\xbe" },
+  { 0x216f, "\xe2\x85\xbf" },
+  { 0x24b6, "\xe2\x93\x90" },
+  { 0x24b7, "\xe2\x93\x91" },
+  { 0x24b8, "\xe2\x93\x92" },
+  { 0x24b9, "\xe2\x93\x93" },
+  { 0x24ba, "\xe2\x93\x94" },
+  { 0x24bb, "\xe2\x93\x95" },
+  { 0x24bc, "\xe2\x93\x96" },
+  { 0x24bd, "\xe2\x93\x97" },
+  { 0x24be, "\xe2\x93\x98" },
+  { 0x24bf, "\xe2\x93\x99" },
+  { 0x24c0, "\xe2\x93\x9a" },
+  { 0x24c1, "\xe2\x93\x9b" },
+  { 0x24c2, "\xe2\x93\x9c" },
+  { 0x24c3, "\xe2\x93\x9d" },
+  { 0x24c4, "\xe2\x93\x9e" },
+  { 0x24c5, "\xe2\x93\x9f" },
+  { 0x24c6, "\xe2\x93\xa0" },
+  { 0x24c7, "\xe2\x93\xa1" },
+  { 0x24c8, "\xe2\x93\xa2" },
+  { 0x24c9, "\xe2\x93\xa3" },
+  { 0x24ca, "\xe2\x93\xa4" },
+  { 0x24cb, "\xe2\x93\xa5" },
+  { 0x24cc, "\xe2\x93\xa6" },
+  { 0x24cd, "\xe2\x93\xa7" },
+  { 0x24ce, "\xe2\x93\xa8" },
+  { 0x24cf, "\xe2\x93\xa9" },
+  { 0xfb00, "\x66\x66" },
+  { 0xfb01, "\x66\x69" },
+  { 0xfb02, "\x66\x6c" },
+  { 0xfb03, "\x66\x66\x69" },
+  { 0xfb04, "\x66\x66\x6c" },
+  { 0xfb05, "\x73\x74" },
+  { 0xfb06, "\x73\x74" },
+  { 0xfb13, "\xd5\xb4\xd5\xb6" },
+  { 0xfb14, "\xd5\xb4\xd5\xa5" },
+  { 0xfb15, "\xd5\xb4\xd5\xab" },
+  { 0xfb16, "\xd5\xbe\xd5\xb6" },
+  { 0xfb17, "\xd5\xb4\xd5\xad" },
+};
+
+#endif /* CHARTABLES_H */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gunicode.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gunicode.h
new file mode 100644 (file)
index 0000000..4ca7bd3
--- /dev/null
@@ -0,0 +1,421 @@
+/* gunicode.h - Unicode manipulation functions
+ *
+ *  Copyright (C) 1999, 2000 Tom Tromey
+ *  Copyright 2000, 2005 Red Hat, Inc.
+ *
+ * The Gnome 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 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *   Boston, MA 02111-1307, USA.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_UNICODE_H__
+#define __G_UNICODE_H__
+
+#include <glib/gerror.h>
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+typedef guint32 gunichar;
+typedef guint16 gunichar2;
+
+/* These are the possible character classifications.
+ * See http://www.unicode.org/Public/UNIDATA/UCD.html#General_Category_Values
+ */
+typedef enum
+{
+  G_UNICODE_CONTROL,
+  G_UNICODE_FORMAT,
+  G_UNICODE_UNASSIGNED,
+  G_UNICODE_PRIVATE_USE,
+  G_UNICODE_SURROGATE,
+  G_UNICODE_LOWERCASE_LETTER,
+  G_UNICODE_MODIFIER_LETTER,
+  G_UNICODE_OTHER_LETTER,
+  G_UNICODE_TITLECASE_LETTER,
+  G_UNICODE_UPPERCASE_LETTER,
+  G_UNICODE_COMBINING_MARK,
+  G_UNICODE_ENCLOSING_MARK,
+  G_UNICODE_NON_SPACING_MARK,
+  G_UNICODE_DECIMAL_NUMBER,
+  G_UNICODE_LETTER_NUMBER,
+  G_UNICODE_OTHER_NUMBER,
+  G_UNICODE_CONNECT_PUNCTUATION,
+  G_UNICODE_DASH_PUNCTUATION,
+  G_UNICODE_CLOSE_PUNCTUATION,
+  G_UNICODE_FINAL_PUNCTUATION,
+  G_UNICODE_INITIAL_PUNCTUATION,
+  G_UNICODE_OTHER_PUNCTUATION,
+  G_UNICODE_OPEN_PUNCTUATION,
+  G_UNICODE_CURRENCY_SYMBOL,
+  G_UNICODE_MODIFIER_SYMBOL,
+  G_UNICODE_MATH_SYMBOL,
+  G_UNICODE_OTHER_SYMBOL,
+  G_UNICODE_LINE_SEPARATOR,
+  G_UNICODE_PARAGRAPH_SEPARATOR,
+  G_UNICODE_SPACE_SEPARATOR
+} GUnicodeType;
+
+/* These are the possible line break classifications.
+ * Note that new types may be added in the future.
+ * Implementations may regard unknown values like G_UNICODE_BREAK_UNKNOWN
+ * See http://www.unicode.org/unicode/reports/tr14/
+ */
+typedef enum
+{
+  G_UNICODE_BREAK_MANDATORY,
+  G_UNICODE_BREAK_CARRIAGE_RETURN,
+  G_UNICODE_BREAK_LINE_FEED,
+  G_UNICODE_BREAK_COMBINING_MARK,
+  G_UNICODE_BREAK_SURROGATE,
+  G_UNICODE_BREAK_ZERO_WIDTH_SPACE,
+  G_UNICODE_BREAK_INSEPARABLE,
+  G_UNICODE_BREAK_NON_BREAKING_GLUE,
+  G_UNICODE_BREAK_CONTINGENT,
+  G_UNICODE_BREAK_SPACE,
+  G_UNICODE_BREAK_AFTER,
+  G_UNICODE_BREAK_BEFORE,
+  G_UNICODE_BREAK_BEFORE_AND_AFTER,
+  G_UNICODE_BREAK_HYPHEN,
+  G_UNICODE_BREAK_NON_STARTER,
+  G_UNICODE_BREAK_OPEN_PUNCTUATION,
+  G_UNICODE_BREAK_CLOSE_PUNCTUATION,
+  G_UNICODE_BREAK_QUOTATION,
+  G_UNICODE_BREAK_EXCLAMATION,
+  G_UNICODE_BREAK_IDEOGRAPHIC,
+  G_UNICODE_BREAK_NUMERIC,
+  G_UNICODE_BREAK_INFIX_SEPARATOR,
+  G_UNICODE_BREAK_SYMBOL,
+  G_UNICODE_BREAK_ALPHABETIC,
+  G_UNICODE_BREAK_PREFIX,
+  G_UNICODE_BREAK_POSTFIX,
+  G_UNICODE_BREAK_COMPLEX_CONTEXT,
+  G_UNICODE_BREAK_AMBIGUOUS,
+  G_UNICODE_BREAK_UNKNOWN,
+  G_UNICODE_BREAK_NEXT_LINE,
+  G_UNICODE_BREAK_WORD_JOINER,
+  G_UNICODE_BREAK_HANGUL_L_JAMO,
+  G_UNICODE_BREAK_HANGUL_V_JAMO,
+  G_UNICODE_BREAK_HANGUL_T_JAMO,
+  G_UNICODE_BREAK_HANGUL_LV_SYLLABLE,
+  G_UNICODE_BREAK_HANGUL_LVT_SYLLABLE
+} GUnicodeBreakType;
+
+typedef enum 
+{                         /* ISO 15924 code */
+  G_UNICODE_SCRIPT_INVALID_CODE = -1,
+  G_UNICODE_SCRIPT_COMMON       = 0,   /* Zyyy */
+  G_UNICODE_SCRIPT_INHERITED,          /* Qaai */
+  G_UNICODE_SCRIPT_ARABIC,             /* Arab */
+  G_UNICODE_SCRIPT_ARMENIAN,           /* Armn */
+  G_UNICODE_SCRIPT_BENGALI,            /* Beng */
+  G_UNICODE_SCRIPT_BOPOMOFO,           /* Bopo */
+  G_UNICODE_SCRIPT_CHEROKEE,           /* Cher */
+  G_UNICODE_SCRIPT_COPTIC,             /* Qaac */
+  G_UNICODE_SCRIPT_CYRILLIC,           /* Cyrl (Cyrs) */
+  G_UNICODE_SCRIPT_DESERET,            /* Dsrt */
+  G_UNICODE_SCRIPT_DEVANAGARI,         /* Deva */
+  G_UNICODE_SCRIPT_ETHIOPIC,           /* Ethi */
+  G_UNICODE_SCRIPT_GEORGIAN,           /* Geor (Geon, Geoa) */
+  G_UNICODE_SCRIPT_GOTHIC,             /* Goth */
+  G_UNICODE_SCRIPT_GREEK,              /* Grek */
+  G_UNICODE_SCRIPT_GUJARATI,           /* Gujr */
+  G_UNICODE_SCRIPT_GURMUKHI,           /* Guru */
+  G_UNICODE_SCRIPT_HAN,                /* Hani */
+  G_UNICODE_SCRIPT_HANGUL,             /* Hang */
+  G_UNICODE_SCRIPT_HEBREW,             /* Hebr */
+  G_UNICODE_SCRIPT_HIRAGANA,           /* Hira */
+  G_UNICODE_SCRIPT_KANNADA,            /* Knda */
+  G_UNICODE_SCRIPT_KATAKANA,           /* Kana */
+  G_UNICODE_SCRIPT_KHMER,              /* Khmr */
+  G_UNICODE_SCRIPT_LAO,                /* Laoo */
+  G_UNICODE_SCRIPT_LATIN,              /* Latn (Latf, Latg) */
+  G_UNICODE_SCRIPT_MALAYALAM,          /* Mlym */
+  G_UNICODE_SCRIPT_MONGOLIAN,          /* Mong */
+  G_UNICODE_SCRIPT_MYANMAR,            /* Mymr */
+  G_UNICODE_SCRIPT_OGHAM,              /* Ogam */
+  G_UNICODE_SCRIPT_OLD_ITALIC,         /* Ital */
+  G_UNICODE_SCRIPT_ORIYA,              /* Orya */
+  G_UNICODE_SCRIPT_RUNIC,              /* Runr */
+  G_UNICODE_SCRIPT_SINHALA,            /* Sinh */
+  G_UNICODE_SCRIPT_SYRIAC,             /* Syrc (Syrj, Syrn, Syre) */
+  G_UNICODE_SCRIPT_TAMIL,              /* Taml */
+  G_UNICODE_SCRIPT_TELUGU,             /* Telu */
+  G_UNICODE_SCRIPT_THAANA,             /* Thaa */
+  G_UNICODE_SCRIPT_THAI,               /* Thai */
+  G_UNICODE_SCRIPT_TIBETAN,            /* Tibt */
+  G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL, /* Cans */
+  G_UNICODE_SCRIPT_YI,                 /* Yiii */
+  G_UNICODE_SCRIPT_TAGALOG,            /* Tglg */
+  G_UNICODE_SCRIPT_HANUNOO,            /* Hano */
+  G_UNICODE_SCRIPT_BUHID,              /* Buhd */
+  G_UNICODE_SCRIPT_TAGBANWA,           /* Tagb */
+
+  /* Unicode-4.0 additions */
+  G_UNICODE_SCRIPT_BRAILLE,            /* Brai */
+  G_UNICODE_SCRIPT_CYPRIOT,            /* Cprt */
+  G_UNICODE_SCRIPT_LIMBU,              /* Limb */
+  G_UNICODE_SCRIPT_OSMANYA,            /* Osma */
+  G_UNICODE_SCRIPT_SHAVIAN,            /* Shaw */
+  G_UNICODE_SCRIPT_LINEAR_B,           /* Linb */
+  G_UNICODE_SCRIPT_TAI_LE,             /* Tale */
+  G_UNICODE_SCRIPT_UGARITIC,           /* Ugar */
+      
+  /* Unicode-4.1 additions */
+  G_UNICODE_SCRIPT_NEW_TAI_LUE,        /* Talu */
+  G_UNICODE_SCRIPT_BUGINESE,           /* Bugi */
+  G_UNICODE_SCRIPT_GLAGOLITIC,         /* Glag */
+  G_UNICODE_SCRIPT_TIFINAGH,           /* Tfng */
+  G_UNICODE_SCRIPT_SYLOTI_NAGRI,       /* Sylo */
+  G_UNICODE_SCRIPT_OLD_PERSIAN,        /* Xpeo */
+  G_UNICODE_SCRIPT_KHAROSHTHI,         /* Khar */
+
+  /* Unicode-5.0 additions */
+  G_UNICODE_SCRIPT_UNKNOWN,            /* Zzzz */
+  G_UNICODE_SCRIPT_BALINESE,           /* Bali */
+  G_UNICODE_SCRIPT_CUNEIFORM,          /* Xsux */
+  G_UNICODE_SCRIPT_PHOENICIAN,         /* Phnx */
+  G_UNICODE_SCRIPT_PHAGS_PA,           /* Phag */
+  G_UNICODE_SCRIPT_NKO,                /* Nkoo */
+
+  /* Unicode-5.1 additions */
+  G_UNICODE_SCRIPT_KAYAH_LI,           /* Kali */
+  G_UNICODE_SCRIPT_LEPCHA,             /* Lepc */
+  G_UNICODE_SCRIPT_REJANG,             /* Rjng */
+  G_UNICODE_SCRIPT_SUNDANESE,          /* Sund */
+  G_UNICODE_SCRIPT_SAURASHTRA,         /* Saur */
+  G_UNICODE_SCRIPT_CHAM,               /* Cham */
+  G_UNICODE_SCRIPT_OL_CHIKI,           /* Olck */
+  G_UNICODE_SCRIPT_VAI,                /* Vaii */
+  G_UNICODE_SCRIPT_CARIAN,             /* Cari */
+  G_UNICODE_SCRIPT_LYCIAN,             /* Lyci */
+  G_UNICODE_SCRIPT_LYDIAN,             /* Lydi */
+
+  /* Unicode-5.2 additions */
+  G_UNICODE_SCRIPT_AVESTAN,                /* Avestan */
+  G_UNICODE_SCRIPT_BAMUM,                  /* Bamum */
+  G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS,   /* Egyptian Hieroglyphs */
+  G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC,       /* Imperial Aramaic */
+  G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI,  /* Inscriptional Pahlavi */
+  G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN, /* Inscriptional Parthian */
+  G_UNICODE_SCRIPT_JAVANESE,               /* Javanese */
+  G_UNICODE_SCRIPT_KAITHI,                 /* Kaithi */
+  G_UNICODE_SCRIPT_LISU,                   /* Lisu */
+  G_UNICODE_SCRIPT_MEETEI_MAYEK,           /* Meetei Mayek */
+  G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN,      /* Old South Arabian */
+  G_UNICODE_SCRIPT_OLD_TURKISH,            /* Old Turkish */
+  G_UNICODE_SCRIPT_SAMARITAN,              /* Samaritan */
+  G_UNICODE_SCRIPT_TAI_THAM,               /* Tai Tham */
+  G_UNICODE_SCRIPT_TAI_VIET                /* Tai Viet */
+} GUnicodeScript;
+
+/* Returns TRUE if current locale uses UTF-8 charset.  If CHARSET is
+ * not null, sets *CHARSET to the name of the current locale's
+ * charset.  This value is statically allocated, and should be copied
+ * in case the locale's charset will be changed later using setlocale()
+ * or in some other way.
+ */
+gboolean g_get_charset (G_CONST_RETURN char **charset);
+
+/* These are all analogs of the <ctype.h> functions.
+ */
+gboolean g_unichar_isalnum   (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_isalpha   (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_iscntrl   (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_isdigit   (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_isgraph   (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_islower   (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_isprint   (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_ispunct   (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_isspace   (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_isupper   (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_isxdigit  (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_istitle   (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_isdefined (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_iswide    (gunichar c) G_GNUC_CONST;
+gboolean g_unichar_iswide_cjk(gunichar c) G_GNUC_CONST;
+gboolean g_unichar_iszerowidth(gunichar c) G_GNUC_CONST;
+gboolean g_unichar_ismark    (gunichar c) G_GNUC_CONST;
+
+/* More <ctype.h> functions.  These convert between the three cases.
+ * See the Unicode book to understand title case.  */
+gunichar g_unichar_toupper (gunichar c) G_GNUC_CONST;
+gunichar g_unichar_tolower (gunichar c) G_GNUC_CONST;
+gunichar g_unichar_totitle (gunichar c) G_GNUC_CONST;
+
+/* If C is a digit (according to `g_unichar_isdigit'), then return its
+   numeric value.  Otherwise return -1.  */
+gint g_unichar_digit_value (gunichar c) G_GNUC_CONST;
+
+gint g_unichar_xdigit_value (gunichar c) G_GNUC_CONST;
+
+/* Return the Unicode character type of a given character.  */
+GUnicodeType g_unichar_type (gunichar c) G_GNUC_CONST;
+
+/* Return the line break property for a given character */
+GUnicodeBreakType g_unichar_break_type (gunichar c) G_GNUC_CONST;
+
+/* Returns the combining class for a given character */
+gint g_unichar_combining_class (gunichar uc) G_GNUC_CONST;
+
+
+/* Compute canonical ordering of a string in-place.  This rearranges
+   decomposed characters in the string according to their combining
+   classes.  See the Unicode manual for more information.  */
+void g_unicode_canonical_ordering (gunichar *string,
+                                  gsize     len);
+
+/* Compute canonical decomposition of a character.  Returns g_malloc()d
+   string of Unicode characters.  RESULT_LEN is set to the resulting
+   length of the string.  */
+gunichar *g_unicode_canonical_decomposition (gunichar  ch,
+                                            gsize    *result_len) G_GNUC_MALLOC;
+
+/* Array of skip-bytes-per-initial character.
+ */
+GLIB_VAR const gchar * const g_utf8_skip;
+
+#define g_utf8_next_char(p) (char *)((p) + g_utf8_skip[*(const guchar *)(p)])
+
+gunichar g_utf8_get_char           (const gchar  *p) G_GNUC_PURE;
+gunichar g_utf8_get_char_validated (const  gchar *p,
+                                   gssize        max_len) G_GNUC_PURE;
+
+gchar*   g_utf8_offset_to_pointer (const gchar *str,
+                                   glong        offset) G_GNUC_PURE;
+glong    g_utf8_pointer_to_offset (const gchar *str,      
+                                  const gchar *pos) G_GNUC_PURE;
+gchar*   g_utf8_prev_char         (const gchar *p) G_GNUC_PURE;
+gchar*   g_utf8_find_next_char    (const gchar *p,
+                                  const gchar *end) G_GNUC_PURE;
+gchar*   g_utf8_find_prev_char    (const gchar *str,
+                                  const gchar *p) G_GNUC_PURE;
+
+glong g_utf8_strlen (const gchar *p,  
+                    gssize       max) G_GNUC_PURE;
+
+/* Copies n characters from src to dest */
+gchar* g_utf8_strncpy (gchar       *dest,
+                      const gchar *src,
+                      gsize        n);
+
+/* Find the UTF-8 character corresponding to ch, in string p. These
+   functions are equivalants to strchr and strrchr */
+gchar* g_utf8_strchr  (const gchar *p,
+                      gssize       len,
+                      gunichar     c);
+gchar* g_utf8_strrchr (const gchar *p,
+                      gssize       len,
+                      gunichar     c);
+gchar* g_utf8_strreverse (const gchar *str,
+                         gssize len);
+
+gunichar2 *g_utf8_to_utf16     (const gchar      *str,
+                               glong             len,            
+                               glong            *items_read,     
+                               glong            *items_written,  
+                               GError          **error) G_GNUC_MALLOC;
+gunichar * g_utf8_to_ucs4      (const gchar      *str,
+                               glong             len,            
+                               glong            *items_read,     
+                               glong            *items_written,  
+                               GError          **error) G_GNUC_MALLOC;
+gunichar * g_utf8_to_ucs4_fast (const gchar      *str,
+                               glong             len,            
+                               glong            *items_written) G_GNUC_MALLOC; 
+gunichar * g_utf16_to_ucs4     (const gunichar2  *str,
+                               glong             len,            
+                               glong            *items_read,     
+                               glong            *items_written,  
+                               GError          **error) G_GNUC_MALLOC;
+gchar*     g_utf16_to_utf8     (const gunichar2  *str,
+                               glong             len,            
+                               glong            *items_read,     
+                               glong            *items_written,  
+                               GError          **error) G_GNUC_MALLOC;
+gunichar2 *g_ucs4_to_utf16     (const gunichar   *str,
+                               glong             len,            
+                               glong            *items_read,     
+                               glong            *items_written,  
+                               GError          **error) G_GNUC_MALLOC;
+gchar*     g_ucs4_to_utf8      (const gunichar   *str,
+                               glong             len,            
+                               glong            *items_read,     
+                               glong            *items_written,  
+                               GError          **error) G_GNUC_MALLOC;
+
+/* Convert a single character into UTF-8. outbuf must have at
+ * least 6 bytes of space. Returns the number of bytes in the
+ * result.
+ */
+gint      g_unichar_to_utf8 (gunichar    c,
+                            gchar      *outbuf);
+
+/* Validate a UTF8 string, return TRUE if valid, put pointer to
+ * first invalid char in **end
+ */
+
+gboolean g_utf8_validate (const gchar  *str,
+                          gssize        max_len,  
+                          const gchar **end);
+
+/* Validate a Unicode character */
+gboolean g_unichar_validate (gunichar ch) G_GNUC_CONST;
+
+gchar *g_utf8_strup   (const gchar *str,
+                      gssize       len) G_GNUC_MALLOC;
+gchar *g_utf8_strdown (const gchar *str,
+                      gssize       len) G_GNUC_MALLOC;
+gchar *g_utf8_casefold (const gchar *str,
+                       gssize       len) G_GNUC_MALLOC;
+
+typedef enum {
+  G_NORMALIZE_DEFAULT,
+  G_NORMALIZE_NFD = G_NORMALIZE_DEFAULT,
+  G_NORMALIZE_DEFAULT_COMPOSE,
+  G_NORMALIZE_NFC = G_NORMALIZE_DEFAULT_COMPOSE,
+  G_NORMALIZE_ALL,
+  G_NORMALIZE_NFKD = G_NORMALIZE_ALL,
+  G_NORMALIZE_ALL_COMPOSE,
+  G_NORMALIZE_NFKC = G_NORMALIZE_ALL_COMPOSE
+} GNormalizeMode;
+
+gchar *g_utf8_normalize (const gchar   *str,
+                        gssize         len,
+                        GNormalizeMode mode) G_GNUC_MALLOC;
+
+gint   g_utf8_collate     (const gchar *str1,
+                          const gchar *str2) G_GNUC_PURE;
+gchar *g_utf8_collate_key (const gchar *str,
+                          gssize       len) G_GNUC_MALLOC;
+gchar *g_utf8_collate_key_for_filename (const gchar *str,
+                                       gssize       len) G_GNUC_MALLOC;
+
+gboolean g_unichar_get_mirror_char (gunichar ch,
+                                    gunichar *mirrored_ch);
+
+GUnicodeScript g_unichar_get_script (gunichar ch) G_GNUC_CONST;
+
+
+/* private */
+
+gchar *_g_utf8_make_valid (const gchar *name);
+
+G_END_DECLS
+
+#endif /* __G_UNICODE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gunicodeprivate.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gunicodeprivate.h
new file mode 100644 (file)
index 0000000..c6cca84
--- /dev/null
@@ -0,0 +1,35 @@
+/* gunicodeprivate.h
+ *
+ * Copyright (C) 2003 Noah Levitt
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_UNICODE_PRIVATE_H__
+#define __G_UNICODE_PRIVATE_H__
+
+#include "gtypes.h"
+
+G_BEGIN_DECLS
+
+G_GNUC_INTERNAL gunichar *_g_utf8_normalize_wc
+                               (const gchar    *str,
+                               gssize          max_len,
+                               GNormalizeMode  mode);
+
+G_END_DECLS
+
+#endif /* __G_UNICODE_PRIVATE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gunicollate.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gunicollate.c
new file mode 100644 (file)
index 0000000..165ecbc
--- /dev/null
@@ -0,0 +1,682 @@
+/* gunicollate.c - Collation
+ *
+ *  Copyright 2001,2005 Red Hat, Inc.
+ *
+ * The Gnome 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 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *   Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <locale.h>
+#include <string.h>
+#ifdef __STDC_ISO_10646__
+#include <wchar.h>
+#endif
+
+#ifdef HAVE_CARBON
+#include <CoreServices/CoreServices.h>
+#endif
+
+#include "gmem.h"
+#include "gunicode.h"
+#include "gunicodeprivate.h"
+#include "gstring.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#ifndef __STDC_ISO_10646__
+#include "gconvert.h"
+#endif
+
+
+#ifdef _MSC_VER
+/* Workaround for bug in MSVCR80.DLL */
+static gsize
+msc_strxfrm_wrapper (char       *string1,
+                    const char *string2,
+                    gsize       count)
+{
+  if (!string1 || count <= 0)
+    {
+      char tmp;
+
+      return strxfrm (&tmp, string2, 1);
+    }
+  return strxfrm (string1, string2, count);
+}
+#define strxfrm msc_strxfrm_wrapper
+#endif
+
+/**
+ * g_utf8_collate:
+ * @str1: a UTF-8 encoded string
+ * @str2: a UTF-8 encoded string
+ * 
+ * Compares two strings for ordering using the linguistically
+ * correct rules for the <link linkend="setlocale">current locale</link>. 
+ * When sorting a large number of strings, it will be significantly 
+ * faster to obtain collation keys with g_utf8_collate_key() and 
+ * compare the keys with strcmp() when sorting instead of sorting 
+ * the original strings.
+ * 
+ * Return value: &lt; 0 if @str1 compares before @str2, 
+ *   0 if they compare equal, &gt; 0 if @str1 compares after @str2.
+ **/
+gint
+g_utf8_collate (const gchar *str1,
+               const gchar *str2)
+{
+  gint result;
+
+#ifdef HAVE_CARBON
+
+  UniChar *str1_utf16;
+  UniChar *str2_utf16;
+  glong len1;
+  glong len2;
+  SInt32 retval = 0;
+
+  g_return_val_if_fail (str1 != NULL, 0);
+  g_return_val_if_fail (str2 != NULL, 0);
+
+  str1_utf16 = g_utf8_to_utf16 (str1, -1, NULL, &len1, NULL);
+  str2_utf16 = g_utf8_to_utf16 (str2, -1, NULL, &len2, NULL);
+
+  UCCompareTextDefault (kUCCollateStandardOptions,
+                        str1_utf16, len1, str2_utf16, len2,
+                        NULL, &retval);
+  result = retval;
+
+  g_free (str2_utf16);
+  g_free (str1_utf16);
+
+#elif defined(__STDC_ISO_10646__)
+
+  gunichar *str1_norm;
+  gunichar *str2_norm;
+
+  g_return_val_if_fail (str1 != NULL, 0);
+  g_return_val_if_fail (str2 != NULL, 0);
+
+  str1_norm = _g_utf8_normalize_wc (str1, -1, G_NORMALIZE_ALL_COMPOSE);
+  str2_norm = _g_utf8_normalize_wc (str2, -1, G_NORMALIZE_ALL_COMPOSE);
+
+  result = wcscoll ((wchar_t *)str1_norm, (wchar_t *)str2_norm);
+
+  g_free (str1_norm);
+  g_free (str2_norm);
+
+#else /* !__STDC_ISO_10646__ */
+
+  const gchar *charset;
+  gchar *str1_norm;
+  gchar *str2_norm;
+
+  g_return_val_if_fail (str1 != NULL, 0);
+  g_return_val_if_fail (str2 != NULL, 0);
+
+  str1_norm = g_utf8_normalize (str1, -1, G_NORMALIZE_ALL_COMPOSE);
+  str2_norm = g_utf8_normalize (str2, -1, G_NORMALIZE_ALL_COMPOSE);
+
+  if (g_get_charset (&charset))
+    {
+      result = strcoll (str1_norm, str2_norm);
+    }
+  else
+    {
+      gchar *str1_locale = g_convert (str1_norm, -1, charset, "UTF-8", NULL, NULL, NULL);
+      gchar *str2_locale = g_convert (str2_norm, -1, charset, "UTF-8", NULL, NULL, NULL);
+
+      if (str1_locale && str2_locale)
+       result =  strcoll (str1_locale, str2_locale);
+      else if (str1_locale)
+       result = -1;
+      else if (str2_locale)
+       result = 1;
+      else
+       result = strcmp (str1_norm, str2_norm);
+
+      g_free (str1_locale);
+      g_free (str2_locale);
+    }
+
+  g_free (str1_norm);
+  g_free (str2_norm);
+
+#endif /* __STDC_ISO_10646__ */
+
+  return result;
+}
+
+#if defined(__STDC_ISO_10646__) || defined(HAVE_CARBON)
+/* We need UTF-8 encoding of numbers to encode the weights if
+ * we are using wcsxfrm. However, we aren't encoding Unicode
+ * characters, so we can't simply use g_unichar_to_utf8.
+ *
+ * The following routine is taken (with modification) from GNU
+ * libc's strxfrm routine:
+ *
+ * Copyright (C) 1995-1999,2000,2001 Free Software Foundation, Inc.
+ * Written by Ulrich Drepper <drepper@cygnus.com>, 1995.
+ */
+static inline int
+utf8_encode (char *buf, wchar_t val)
+{
+  int retval;
+
+  if (val < 0x80)
+    {
+      if (buf)
+       *buf++ = (char) val;
+      retval = 1;
+    }
+  else
+    {
+      int step;
+
+      for (step = 2; step < 6; ++step)
+        if ((val & (~(guint32)0 << (5 * step + 1))) == 0)
+          break;
+      retval = step;
+
+      if (buf)
+       {
+         *buf = (unsigned char) (~0xff >> step);
+         --step;
+         do
+           {
+             buf[step] = 0x80 | (val & 0x3f);
+             val >>= 6;
+           }
+         while (--step > 0);
+         *buf |= val;
+       }
+    }
+
+  return retval;
+}
+#endif /* __STDC_ISO_10646__ || HAVE_CARBON */
+
+#ifdef HAVE_CARBON
+
+static gchar *
+collate_key_to_string (UCCollationValue *key,
+                       gsize             key_len)
+{
+  gchar *result;
+  gsize result_len;
+  gsize i;
+
+  /* Pretty smart algorithm here: ignore first eight bytes of the
+   * collation key. It doesn't produce results equivalent to
+   * UCCompareCollationKeys's, but the difference seems to be only
+   * that UCCompareCollationKeys in some cases produces 0 where our
+   * comparison gets -1 or 1. */
+
+  if (key_len * sizeof (UCCollationValue) <= 8)
+    return g_strdup ("");
+
+  result_len = 0;
+  for (i = 8; i < key_len * sizeof (UCCollationValue); i++)
+    /* there may be nul bytes, encode byteval+1 */
+    result_len += utf8_encode (NULL, *((guchar*)key + i) + 1);
+
+  result = g_malloc (result_len + 1);
+  result_len = 0;
+  for (i = 8; i < key_len * sizeof (UCCollationValue); i++)
+    result_len += utf8_encode (result + result_len, *((guchar*)key + i) + 1);
+
+  result[result_len] = 0;
+  return result;
+}
+
+static gchar *
+carbon_collate_key_with_collator (const gchar *str,
+                                  gssize       len,
+                                  CollatorRef  collator)
+{
+  UniChar *str_utf16 = NULL;
+  glong len_utf16;
+  OSStatus ret;
+  UCCollationValue staticbuf[512];
+  UCCollationValue *freeme = NULL;
+  UCCollationValue *buf;
+  ItemCount buf_len;
+  ItemCount key_len;
+  ItemCount try_len;
+  gchar *result = NULL;
+
+  str_utf16 = g_utf8_to_utf16 (str, len, NULL, &len_utf16, NULL);
+  try_len = len_utf16 * 5 + 2;
+
+  if (try_len <= sizeof staticbuf)
+    {
+      buf = staticbuf;
+      buf_len = sizeof staticbuf;
+    }
+  else
+    {
+      freeme = g_new (UCCollationValue, try_len);
+      buf = freeme;
+      buf_len = try_len;
+    }
+
+  ret = UCGetCollationKey (collator, str_utf16, len_utf16,
+                           buf_len, &key_len, buf);
+
+  if (ret == kCollateBufferTooSmall)
+    {
+      freeme = g_renew (UCCollationValue, freeme, try_len * 2);
+      buf = freeme;
+      buf_len = try_len * 2;
+      ret = UCGetCollationKey (collator, str_utf16, len_utf16,
+                               buf_len, &key_len, buf);
+    }
+
+  if (ret == 0)
+    result = collate_key_to_string (buf, key_len);
+  else
+    result = g_strdup ("");
+
+  g_free (freeme);
+  g_free (str_utf16);
+  return result;
+}
+
+static gchar *
+carbon_collate_key (const gchar *str,
+                    gssize       len)
+{
+  static CollatorRef collator;
+
+  if (G_UNLIKELY (!collator))
+    {
+      UCCreateCollator (NULL, 0, kUCCollateStandardOptions, &collator);
+
+      if (!collator)
+        {
+          static gboolean been_here;
+          if (!been_here)
+            g_warning ("%s: UCCreateCollator failed", G_STRLOC);
+          been_here = TRUE;
+          return g_strdup ("");
+        }
+    }
+
+  return carbon_collate_key_with_collator (str, len, collator);
+}
+
+static gchar *
+carbon_collate_key_for_filename (const gchar *str,
+                                 gssize       len)
+{
+  static CollatorRef collator;
+
+  if (G_UNLIKELY (!collator))
+    {
+      /* http://developer.apple.com/qa/qa2004/qa1159.html */
+      UCCreateCollator (NULL, 0,
+                        kUCCollateComposeInsensitiveMask
+                         | kUCCollateWidthInsensitiveMask
+                         | kUCCollateCaseInsensitiveMask
+                         | kUCCollateDigitsOverrideMask
+                         | kUCCollateDigitsAsNumberMask
+                         | kUCCollatePunctuationSignificantMask, 
+                        &collator);
+
+      if (!collator)
+        {
+          static gboolean been_here;
+          if (!been_here)
+            g_warning ("%s: UCCreateCollator failed", G_STRLOC);
+          been_here = TRUE;
+          return g_strdup ("");
+        }
+    }
+
+  return carbon_collate_key_with_collator (str, len, collator);
+}
+
+#endif /* HAVE_CARBON */
+
+/**
+ * g_utf8_collate_key:
+ * @str: a UTF-8 encoded string.
+ * @len: length of @str, in bytes, or -1 if @str is nul-terminated.
+ *
+ * Converts a string into a collation key that can be compared
+ * with other collation keys produced by the same function using 
+ * strcmp(). 
+ *
+ * The results of comparing the collation keys of two strings 
+ * with strcmp() will always be the same as comparing the two 
+ * original keys with g_utf8_collate().
+ * 
+ * Note that this function depends on the 
+ * <link linkend="setlocale">current locale</link>.
+ * 
+ * Return value: a newly allocated string. This string should
+ *   be freed with g_free() when you are done with it.
+ **/
+gchar *
+g_utf8_collate_key (const gchar *str,
+                   gssize       len)
+{
+  gchar *result;
+
+#ifdef HAVE_CARBON
+
+  g_return_val_if_fail (str != NULL, NULL);
+  result = carbon_collate_key (str, len);
+
+#elif defined(__STDC_ISO_10646__)
+
+  gsize xfrm_len;
+  gunichar *str_norm;
+  wchar_t *result_wc;
+  gsize i;
+  gsize result_len = 0;
+
+  g_return_val_if_fail (str != NULL, NULL);
+
+  str_norm = _g_utf8_normalize_wc (str, len, G_NORMALIZE_ALL_COMPOSE);
+
+  xfrm_len = wcsxfrm (NULL, (wchar_t *)str_norm, 0);
+  result_wc = g_new (wchar_t, xfrm_len + 1);
+  wcsxfrm (result_wc, (wchar_t *)str_norm, xfrm_len + 1);
+
+  for (i=0; i < xfrm_len; i++)
+    result_len += utf8_encode (NULL, result_wc[i]);
+
+  result = g_malloc (result_len + 1);
+  result_len = 0;
+  for (i=0; i < xfrm_len; i++)
+    result_len += utf8_encode (result + result_len, result_wc[i]);
+
+  result[result_len] = '\0';
+
+  g_free (result_wc);
+  g_free (str_norm);
+
+  return result;
+#else /* !__STDC_ISO_10646__ */
+
+  gsize xfrm_len;
+  const gchar *charset;
+  gchar *str_norm;
+
+  g_return_val_if_fail (str != NULL, NULL);
+
+  str_norm = g_utf8_normalize (str, len, G_NORMALIZE_ALL_COMPOSE);
+
+  result = NULL;
+
+  if (g_get_charset (&charset))
+    {
+      xfrm_len = strxfrm (NULL, str_norm, 0);
+      if (xfrm_len >= 0 && xfrm_len < G_MAXINT - 2)
+        {
+          result = g_malloc (xfrm_len + 1);
+          strxfrm (result, str_norm, xfrm_len + 1);
+        }
+    }
+  else
+    {
+      gchar *str_locale = g_convert (str_norm, -1, charset, "UTF-8", NULL, NULL, NULL);
+
+      if (str_locale)
+       {
+         xfrm_len = strxfrm (NULL, str_locale, 0);
+         if (xfrm_len < 0 || xfrm_len >= G_MAXINT - 2)
+           {
+             g_free (str_locale);
+             str_locale = NULL;
+           }
+       }
+      if (str_locale)
+       {
+         result = g_malloc (xfrm_len + 2);
+         result[0] = 'A';
+         strxfrm (result + 1, str_locale, xfrm_len + 1);
+         
+         g_free (str_locale);
+       }
+    }
+    
+  if (!result) 
+    {
+      xfrm_len = strlen (str_norm);
+      result = g_malloc (xfrm_len + 2);
+      result[0] = 'B';
+      memcpy (result + 1, str_norm, xfrm_len);
+      result[xfrm_len+1] = '\0';
+    }
+
+  g_free (str_norm);
+#endif /* __STDC_ISO_10646__ */
+
+  return result;
+}
+
+/* This is a collation key that is very very likely to sort before any
+   collation key that libc strxfrm generates. We use this before any
+   special case (dot or number) to make sure that its sorted before
+   anything else.
+ */
+#define COLLATION_SENTINEL "\1\1\1"
+
+/**
+ * g_utf8_collate_key_for_filename:
+ * @str: a UTF-8 encoded string.
+ * @len: length of @str, in bytes, or -1 if @str is nul-terminated.
+ *
+ * Converts a string into a collation key that can be compared
+ * with other collation keys produced by the same function using strcmp(). 
+ * 
+ * In order to sort filenames correctly, this function treats the dot '.' 
+ * as a special case. Most dictionary orderings seem to consider it
+ * insignificant, thus producing the ordering "event.c" "eventgenerator.c"
+ * "event.h" instead of "event.c" "event.h" "eventgenerator.c". Also, we
+ * would like to treat numbers intelligently so that "file1" "file10" "file5"
+ * is sorted as "file1" "file5" "file10".
+ * 
+ * Note that this function depends on the 
+ * <link linkend="setlocale">current locale</link>.
+ *
+ * Return value: a newly allocated string. This string should
+ *   be freed with g_free() when you are done with it.
+ *
+ * Since: 2.8
+ */
+gchar*
+g_utf8_collate_key_for_filename (const gchar *str,
+                                gssize       len)
+{
+#ifndef HAVE_CARBON
+  GString *result;
+  GString *append;
+  const gchar *p;
+  const gchar *prev;
+  const gchar *end;
+  gchar *collate_key;
+  gint digits;
+  gint leading_zeros;
+
+  /*
+   * How it works:
+   *
+   * Split the filename into collatable substrings which do
+   * not contain [.0-9] and special-cased substrings. The collatable 
+   * substrings are run through the normal g_utf8_collate_key() and the 
+   * resulting keys are concatenated with keys generated from the 
+   * special-cased substrings.
+   *
+   * Special cases: Dots are handled by replacing them with '\1' which 
+   * implies that short dot-delimited substrings are before long ones, 
+   * e.g.
+   * 
+   *   a\1a   (a.a)
+   *   a-\1a  (a-.a)
+   *   aa\1a  (aa.a)
+   * 
+   * Numbers are handled by prepending to each number d-1 superdigits 
+   * where d = number of digits in the number and SUPERDIGIT is a 
+   * character with an integer value higher than any digit (for instance 
+   * ':'). This ensures that single-digit numbers are sorted before 
+   * double-digit numbers which in turn are sorted separately from 
+   * triple-digit numbers, etc. To avoid strange side-effects when 
+   * sorting strings that already contain SUPERDIGITs, a '\2'
+   * is also prepended, like this
+   *
+   *   file\21      (file1)
+   *   file\25      (file5)
+   *   file\2:10    (file10)
+   *   file\2:26    (file26)
+   *   file\2::100  (file100)
+   *   file:foo     (file:foo)
+   * 
+   * This has the side-effect of sorting numbers before everything else (except
+   * dots), but this is probably OK.
+   *
+   * Leading digits are ignored when doing the above. To discriminate
+   * numbers which differ only in the number of leading digits, we append
+   * the number of leading digits as a byte at the very end of the collation
+   * key.
+   *
+   * To try avoid conflict with any collation key sequence generated by libc we
+   * start each switch to a special cased part with a sentinel that hopefully
+   * will sort before anything libc will generate.
+   */
+
+  if (len < 0)
+    len = strlen (str);
+
+  result = g_string_sized_new (len * 2);
+  append = g_string_sized_new (0);
+
+  end = str + len;
+
+  /* No need to use utf8 functions, since we're only looking for ascii chars */
+  for (prev = p = str; p < end; p++)
+    {
+      switch (*p)
+       {
+       case '.':
+         if (prev != p) 
+           {
+             collate_key = g_utf8_collate_key (prev, p - prev);
+             g_string_append (result, collate_key);
+             g_free (collate_key);
+           }
+         
+         g_string_append (result, COLLATION_SENTINEL "\1");
+         
+         /* skip the dot */
+         prev = p + 1;
+         break;
+         
+       case '0':
+       case '1':
+       case '2':
+       case '3':
+       case '4':
+       case '5':
+       case '6':
+       case '7':
+       case '8':
+       case '9':
+         if (prev != p) 
+           {
+             collate_key = g_utf8_collate_key (prev, p - prev);
+             g_string_append (result, collate_key);
+             g_free (collate_key);
+           }
+         
+         g_string_append (result, COLLATION_SENTINEL "\2");
+         
+         prev = p;
+         
+         /* write d-1 colons */
+         if (*p == '0')
+           {
+             leading_zeros = 1;
+             digits = 0;
+           }
+         else
+           {
+             leading_zeros = 0;
+             digits = 1;
+           }
+         
+         while (++p < end)
+           {
+             if (*p == '0' && !digits)
+               ++leading_zeros;
+             else if (g_ascii_isdigit(*p))
+               ++digits;
+             else
+                {
+                 /* count an all-zero sequence as
+                   * one digit plus leading zeros
+                   */
+                 if (!digits)
+                    {
+                      ++digits;
+                      --leading_zeros;
+                    }        
+                 break;
+                }
+           }
+
+         while (digits > 1)
+           {
+             g_string_append_c (result, ':');
+             --digits;
+           }
+
+         if (leading_zeros > 0)
+           {
+             g_string_append_c (append, (char)leading_zeros);
+             prev += leading_zeros;
+           }
+         
+         /* write the number itself */
+         g_string_append_len (result, prev, p - prev);
+         
+         prev = p;
+         --p;    /* go one step back to avoid disturbing outer loop */
+         break;
+         
+       default:
+         /* other characters just accumulate */
+         break;
+       }
+    }
+  
+  if (prev != p) 
+    {
+      collate_key = g_utf8_collate_key (prev, p - prev);
+      g_string_append (result, collate_key);
+      g_free (collate_key);
+    }
+  
+  g_string_append (result, append->str);
+  g_string_free (append, TRUE);
+
+  return g_string_free (result, FALSE);
+#else /* HAVE_CARBON */
+  return carbon_collate_key_for_filename (str, len);
+#endif
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gunicomp.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gunicomp.h
new file mode 100644 (file)
index 0000000..23a9087
--- /dev/null
@@ -0,0 +1,682 @@
+#define COMPOSE_FIRST_START 1
+#define COMPOSE_FIRST_SINGLE_START 147
+#define COMPOSE_SECOND_START 368
+#define COMPOSE_SECOND_SINGLE_START 399
+
+#define COMPOSE_TABLE_LAST 48
+
+static const guint16 compose_data[][256] = {
+  { /* page 0, index 0 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 147, 148, 149, 0, 0, 1, 2, 3, 4, 5, 
+    150, 6, 7, 8, 151, 9, 10, 11, 12, 13, 14, 0, 15, 16, 17, 18, 19, 20, 21, 
+    22, 23, 0, 0, 0, 0, 0, 0, 24, 25, 26, 27, 28, 152, 29, 30, 31, 32, 33, 
+    34, 35, 36, 37, 38, 0, 39, 40, 41, 42, 43, 44, 45, 46, 47, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 153, 154, 
+    50, 155, 0, 0, 51, 0, 0, 0, 0, 156, 0, 0, 0, 0, 52, 53, 157, 0, 158, 0, 
+    0, 0, 54, 0, 0, 0, 0, 0, 55, 0, 159, 160, 56, 161, 0, 0, 57, 0, 0, 0, 0, 
+    162, 0, 0, 0, 0, 58, 59, 163, 0, 164, 0, 0, 0, 60, 0, 0, 0
+  },
+  { /* page 1, index 1 */
+    0, 0, 61, 62, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 63, 64, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 65, 66, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 165, 166, 0, 
+    0, 0, 0, 167, 168, 0, 0, 0, 0, 0, 0, 169, 170, 171, 172, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 67, 
+    68, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 69, 70, 0, 0, 0, 0, 0, 0, 174, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 175, 176, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0
+  },
+  { /* page 2, index 2 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 177, 178, 179, 180, 0, 0, 0, 0, 
+    181, 182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 3, index 3 */
+    368, 369, 370, 371, 372, 0, 373, 374, 375, 376, 377, 378, 379, 0, 0, 380, 
+    0, 381, 0, 382, 383, 0, 0, 0, 0, 0, 0, 384, 0, 0, 0, 0, 0, 0, 0, 385, 
+    386, 387, 388, 389, 390, 0, 0, 0, 0, 391, 392, 0, 393, 394, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 395, 0, 0, 396, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 71, 0, 0, 0, 
+    72, 0, 73, 0, 74, 0, 0, 0, 0, 0, 75, 0, 184, 0, 0, 0, 76, 0, 0, 0, 77, 0, 
+    0, 185, 0, 186, 0, 0, 78, 0, 0, 0, 79, 0, 80, 0, 81, 0, 0, 0, 0, 0, 82, 
+    0, 83, 0, 0, 0, 84, 0, 0, 0, 85, 86, 87, 0, 0, 187, 0, 0, 0, 88, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 4, index 4 */
+    0, 0, 0, 0, 0, 0, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, 0, 189, 0, 90, 
+    91, 190, 92, 0, 191, 0, 0, 0, 192, 0, 0, 0, 0, 93, 0, 0, 0, 193, 0, 0, 0, 
+    194, 0, 195, 0, 0, 94, 0, 0, 196, 0, 95, 96, 197, 97, 0, 198, 0, 0, 0, 
+    199, 0, 0, 0, 0, 98, 0, 0, 0, 200, 0, 0, 0, 201, 0, 202, 0, 0, 0, 0, 0, 
+    0, 0, 0, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 204, 205, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 206, 207, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 208, 209, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 6, index 5 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    210, 0, 211, 0, 0, 0, 0, 0, 0, 0, 0, 399, 400, 401, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 212, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 213, 0, 
+    0, 214, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 9, index 6 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 0, 
+    216, 0, 0, 217, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 402, 
+    0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    403, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 11, index 7 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 404, 0, 0, 0, 0, 0, 0, 0, 0, 
+    101, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 405, 406, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 218, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 407, 0, 0, 0, 0, 0, 0, 0, 102, 219, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 408, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 12, index 8 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 221, 
+    0, 0, 409, 0, 0, 0, 103, 0, 0, 0, 222, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 410, 
+    411, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 13, index 9 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 412, 0, 0, 0, 0, 0, 0, 0, 104, 
+    223, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 413, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 414, 0, 0, 0, 0, 415, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 105, 0, 0, 224, 0, 0, 416, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 16, index 10 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 225, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 27, index 11 */
+    0, 0, 0, 0, 0, 226, 0, 227, 0, 228, 0, 229, 0, 230, 0, 0, 0, 231, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 232, 0, 233, 0, 234, 235, 0, 0, 
+    236, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 30, index 12 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 237, 238, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 239, 240, 0, 0, 
+    0, 0, 0, 0, 241, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 106, 107, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 243, 244, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 245, 246, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 31, index 13 */
+    108, 109, 247, 248, 249, 250, 251, 252, 110, 111, 253, 254, 255, 256, 
+    257, 258, 112, 113, 0, 0, 0, 0, 0, 0, 114, 115, 0, 0, 0, 0, 0, 0, 116, 
+    117, 259, 260, 261, 262, 263, 264, 118, 119, 265, 266, 267, 268, 269, 
+    270, 120, 121, 0, 0, 0, 0, 0, 0, 122, 123, 0, 0, 0, 0, 0, 0, 124, 125, 0, 
+    0, 0, 0, 0, 0, 126, 127, 0, 0, 0, 0, 0, 0, 128, 129, 0, 0, 0, 0, 0, 0, 0, 
+    130, 0, 0, 0, 0, 0, 0, 131, 132, 271, 272, 273, 274, 275, 276, 133, 134, 
+    277, 278, 279, 280, 281, 282, 283, 0, 0, 0, 284, 0, 0, 0, 0, 0, 0, 0, 
+    285, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 286, 0, 0, 0, 0, 0, 0, 0, 0, 135, 0, 0, 0, 
+    0, 0, 0, 287, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 288, 0, 0, 0, 0, 0, 0, 0, 136, 0
+  },
+  { /* page 33, index 14 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    289, 0, 290, 0, 291, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 292, 0, 293, 0, 
+    294, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 34, index 15 */
+    0, 0, 0, 295, 0, 0, 0, 0, 296, 0, 0, 297, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 298, 0, 299, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 300, 0, 0, 0, 0, 0, 0, 301, 
+    0, 302, 0, 0, 303, 0, 0, 0, 0, 304, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 305, 0, 0, 306, 307, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 308, 309, 0, 0, 310, 311, 0, 0, 312, 313, 314, 315, 0, 0, 0, 0, 
+    316, 317, 0, 0, 318, 319, 0, 0, 0, 0, 0, 0, 0, 0, 0, 320, 321, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 322, 0, 0, 0, 0, 0, 323, 324, 0, 325, 
+    0, 0, 0, 0, 0, 0, 326, 327, 328, 329, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 48, index 16 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 330, 0, 
+    0, 0, 0, 331, 0, 332, 0, 333, 0, 334, 0, 335, 0, 336, 0, 337, 0, 338, 0, 
+    339, 0, 340, 0, 341, 0, 342, 0, 0, 343, 0, 344, 0, 345, 0, 0, 0, 0, 0, 0, 
+    137, 0, 0, 138, 0, 0, 139, 0, 0, 140, 0, 0, 141, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 397, 398, 
+    0, 0, 346, 0, 0, 0, 0, 0, 0, 0, 0, 347, 0, 0, 0, 0, 348, 0, 349, 0, 350, 
+    0, 351, 0, 352, 0, 353, 0, 354, 0, 355, 0, 356, 0, 357, 0, 358, 0, 359, 
+    0, 0, 360, 0, 361, 0, 362, 0, 0, 0, 0, 0, 0, 142, 0, 0, 143, 0, 0, 144, 
+    0, 0, 145, 0, 0, 146, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 363, 364, 365, 366, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 367, 0, 0
+  }
+};
+
+static const gint16 compose_table[COMPOSE_TABLE_LAST + 1] = {
+  0 /* page 0 */,
+  1 /* page 1 */,
+  2 /* page 2 */,
+  3 /* page 3 */,
+  4 /* page 4 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  5 /* page 6 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  6 /* page 9 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  7 /* page 11 */,
+  8 /* page 12 */,
+  9 /* page 13 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  10 /* page 16 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  11 /* page 27 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  12 /* page 30 */,
+  13 /* page 31 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  14 /* page 33 */,
+  15 /* page 34 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  16 /* page 48 */
+};
+
+static const guint16 compose_first_single[][2] = {
+ { 0x0338, 0x226e },
+ { 0x0338, 0x2260 },
+ { 0x0338, 0x226f },
+ { 0x0307, 0x1e1e },
+ { 0x0302, 0x0134 },
+ { 0x0307, 0x1e1f },
+ { 0x0304, 0x01de },
+ { 0x0301, 0x01fa },
+ { 0x0301, 0x1e08 },
+ { 0x0301, 0x1e2e },
+ { 0x0304, 0x022a },
+ { 0x0301, 0x01fe },
+ { 0x0304, 0x01df },
+ { 0x0301, 0x01fb },
+ { 0x0301, 0x1e09 },
+ { 0x0301, 0x1e2f },
+ { 0x0304, 0x022b },
+ { 0x0301, 0x01ff },
+ { 0x0307, 0x1e64 },
+ { 0x0307, 0x1e65 },
+ { 0x0307, 0x1e66 },
+ { 0x0307, 0x1e67 },
+ { 0x0301, 0x1e78 },
+ { 0x0301, 0x1e79 },
+ { 0x0308, 0x1e7a },
+ { 0x0308, 0x1e7b },
+ { 0x0307, 0x1e9b },
+ { 0x030c, 0x01ee },
+ { 0x0304, 0x01ec },
+ { 0x0304, 0x01ed },
+ { 0x0304, 0x01e0 },
+ { 0x0304, 0x01e1 },
+ { 0x0306, 0x1e1c },
+ { 0x0306, 0x1e1d },
+ { 0x0304, 0x0230 },
+ { 0x0304, 0x0231 },
+ { 0x030c, 0x01ef },
+ { 0x0314, 0x1fec },
+ { 0x0345, 0x1fb4 },
+ { 0x0345, 0x1fc4 },
+ { 0x0345, 0x1ff4 },
+ { 0x0308, 0x0407 },
+ { 0x0301, 0x0403 },
+ { 0x0308, 0x04de },
+ { 0x0301, 0x040c },
+ { 0x0308, 0x04e6 },
+ { 0x0308, 0x04f4 },
+ { 0x0308, 0x04f8 },
+ { 0x0308, 0x04ec },
+ { 0x0301, 0x0453 },
+ { 0x0308, 0x04df },
+ { 0x0301, 0x045c },
+ { 0x0308, 0x04e7 },
+ { 0x0308, 0x04f5 },
+ { 0x0308, 0x04f9 },
+ { 0x0308, 0x04ed },
+ { 0x0308, 0x0457 },
+ { 0x030f, 0x0476 },
+ { 0x030f, 0x0477 },
+ { 0x0308, 0x04da },
+ { 0x0308, 0x04db },
+ { 0x0308, 0x04ea },
+ { 0x0308, 0x04eb },
+ { 0x0654, 0x0624 },
+ { 0x0654, 0x0626 },
+ { 0x0654, 0x06c2 },
+ { 0x0654, 0x06d3 },
+ { 0x0654, 0x06c0 },
+ { 0x093c, 0x0929 },
+ { 0x093c, 0x0931 },
+ { 0x093c, 0x0934 },
+ { 0x0bd7, 0x0b94 },
+ { 0x0bbe, 0x0bcb },
+ { 0x0c56, 0x0c48 },
+ { 0x0cd5, 0x0cc0 },
+ { 0x0cd5, 0x0ccb },
+ { 0x0d3e, 0x0d4b },
+ { 0x0dca, 0x0ddd },
+ { 0x102e, 0x1026 },
+ { 0x1b35, 0x1b06 },
+ { 0x1b35, 0x1b08 },
+ { 0x1b35, 0x1b0a },
+ { 0x1b35, 0x1b0c },
+ { 0x1b35, 0x1b0e },
+ { 0x1b35, 0x1b12 },
+ { 0x1b35, 0x1b3b },
+ { 0x1b35, 0x1b3d },
+ { 0x1b35, 0x1b40 },
+ { 0x1b35, 0x1b41 },
+ { 0x1b35, 0x1b43 },
+ { 0x0304, 0x1e38 },
+ { 0x0304, 0x1e39 },
+ { 0x0304, 0x1e5c },
+ { 0x0304, 0x1e5d },
+ { 0x0307, 0x1e68 },
+ { 0x0307, 0x1e69 },
+ { 0x0302, 0x1ec6 },
+ { 0x0302, 0x1ec7 },
+ { 0x0302, 0x1ed8 },
+ { 0x0302, 0x1ed9 },
+ { 0x0345, 0x1f82 },
+ { 0x0345, 0x1f83 },
+ { 0x0345, 0x1f84 },
+ { 0x0345, 0x1f85 },
+ { 0x0345, 0x1f86 },
+ { 0x0345, 0x1f87 },
+ { 0x0345, 0x1f8a },
+ { 0x0345, 0x1f8b },
+ { 0x0345, 0x1f8c },
+ { 0x0345, 0x1f8d },
+ { 0x0345, 0x1f8e },
+ { 0x0345, 0x1f8f },
+ { 0x0345, 0x1f92 },
+ { 0x0345, 0x1f93 },
+ { 0x0345, 0x1f94 },
+ { 0x0345, 0x1f95 },
+ { 0x0345, 0x1f96 },
+ { 0x0345, 0x1f97 },
+ { 0x0345, 0x1f9a },
+ { 0x0345, 0x1f9b },
+ { 0x0345, 0x1f9c },
+ { 0x0345, 0x1f9d },
+ { 0x0345, 0x1f9e },
+ { 0x0345, 0x1f9f },
+ { 0x0345, 0x1fa2 },
+ { 0x0345, 0x1fa3 },
+ { 0x0345, 0x1fa4 },
+ { 0x0345, 0x1fa5 },
+ { 0x0345, 0x1fa6 },
+ { 0x0345, 0x1fa7 },
+ { 0x0345, 0x1faa },
+ { 0x0345, 0x1fab },
+ { 0x0345, 0x1fac },
+ { 0x0345, 0x1fad },
+ { 0x0345, 0x1fae },
+ { 0x0345, 0x1faf },
+ { 0x0345, 0x1fb2 },
+ { 0x0345, 0x1fc2 },
+ { 0x0345, 0x1ff2 },
+ { 0x0345, 0x1fb7 },
+ { 0x0345, 0x1fc7 },
+ { 0x0345, 0x1ff7 },
+ { 0x0338, 0x219a },
+ { 0x0338, 0x219b },
+ { 0x0338, 0x21ae },
+ { 0x0338, 0x21cd },
+ { 0x0338, 0x21cf },
+ { 0x0338, 0x21ce },
+ { 0x0338, 0x2204 },
+ { 0x0338, 0x2209 },
+ { 0x0338, 0x220c },
+ { 0x0338, 0x2224 },
+ { 0x0338, 0x2226 },
+ { 0x0338, 0x2241 },
+ { 0x0338, 0x2244 },
+ { 0x0338, 0x2247 },
+ { 0x0338, 0x2249 },
+ { 0x0338, 0x226d },
+ { 0x0338, 0x2262 },
+ { 0x0338, 0x2270 },
+ { 0x0338, 0x2271 },
+ { 0x0338, 0x2274 },
+ { 0x0338, 0x2275 },
+ { 0x0338, 0x2278 },
+ { 0x0338, 0x2279 },
+ { 0x0338, 0x2280 },
+ { 0x0338, 0x2281 },
+ { 0x0338, 0x22e0 },
+ { 0x0338, 0x22e1 },
+ { 0x0338, 0x2284 },
+ { 0x0338, 0x2285 },
+ { 0x0338, 0x2288 },
+ { 0x0338, 0x2289 },
+ { 0x0338, 0x22e2 },
+ { 0x0338, 0x22e3 },
+ { 0x0338, 0x22ac },
+ { 0x0338, 0x22ad },
+ { 0x0338, 0x22ae },
+ { 0x0338, 0x22af },
+ { 0x0338, 0x22ea },
+ { 0x0338, 0x22eb },
+ { 0x0338, 0x22ec },
+ { 0x0338, 0x22ed },
+ { 0x3099, 0x3094 },
+ { 0x3099, 0x304c },
+ { 0x3099, 0x304e },
+ { 0x3099, 0x3050 },
+ { 0x3099, 0x3052 },
+ { 0x3099, 0x3054 },
+ { 0x3099, 0x3056 },
+ { 0x3099, 0x3058 },
+ { 0x3099, 0x305a },
+ { 0x3099, 0x305c },
+ { 0x3099, 0x305e },
+ { 0x3099, 0x3060 },
+ { 0x3099, 0x3062 },
+ { 0x3099, 0x3065 },
+ { 0x3099, 0x3067 },
+ { 0x3099, 0x3069 },
+ { 0x3099, 0x309e },
+ { 0x3099, 0x30f4 },
+ { 0x3099, 0x30ac },
+ { 0x3099, 0x30ae },
+ { 0x3099, 0x30b0 },
+ { 0x3099, 0x30b2 },
+ { 0x3099, 0x30b4 },
+ { 0x3099, 0x30b6 },
+ { 0x3099, 0x30b8 },
+ { 0x3099, 0x30ba },
+ { 0x3099, 0x30bc },
+ { 0x3099, 0x30be },
+ { 0x3099, 0x30c0 },
+ { 0x3099, 0x30c2 },
+ { 0x3099, 0x30c5 },
+ { 0x3099, 0x30c7 },
+ { 0x3099, 0x30c9 },
+ { 0x3099, 0x30f7 },
+ { 0x3099, 0x30f8 },
+ { 0x3099, 0x30f9 },
+ { 0x3099, 0x30fa },
+ { 0x3099, 0x30fe }
+};
+static const guint16 compose_second_single[][2] = {
+ { 0x0627, 0x0622 },
+ { 0x0627, 0x0623 },
+ { 0x0627, 0x0625 },
+ { 0x09c7, 0x09cb },
+ { 0x09c7, 0x09cc },
+ { 0x0b47, 0x0b4b },
+ { 0x0b47, 0x0b48 },
+ { 0x0b47, 0x0b4c },
+ { 0x0bc6, 0x0bca },
+ { 0x0bc6, 0x0bcc },
+ { 0x0cc6, 0x0cca },
+ { 0x0cc6, 0x0cc7 },
+ { 0x0cc6, 0x0cc8 },
+ { 0x0d46, 0x0d4a },
+ { 0x0d46, 0x0d4c },
+ { 0x0dd9, 0x0dda },
+ { 0x0dd9, 0x0ddc },
+ { 0x0dd9, 0x0dde }
+};
+static const guint16 compose_array[146][31] = {
+ { 0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x0100, 0x0102, 0x0226, 0x00c4, 0x1ea2, 0x00c5,      0, 0x01cd, 0x0200, 0x0202,      0,      0,      0, 0x1ea0,      0, 0x1e00,      0,      0, 0x0104,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0, 0x1e02,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e04,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e06,      0,      0,      0,      0 },
+ {      0, 0x0106, 0x0108,      0,      0,      0, 0x010a,      0,      0,      0,      0, 0x010c,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x00c7,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0, 0x1e0a,      0,      0,      0,      0, 0x010e,      0,      0,      0,      0,      0, 0x1e0c,      0,      0,      0, 0x1e10,      0, 0x1e12,      0,      0, 0x1e0e,      0,      0,      0,      0 },
+ { 0x00c8, 0x00c9, 0x00ca, 0x1ebc, 0x0112, 0x0114, 0x0116, 0x00cb, 0x1eba,      0,      0, 0x011a, 0x0204, 0x0206,      0,      0,      0, 0x1eb8,      0,      0,      0, 0x0228, 0x0118, 0x1e18,      0, 0x1e1a,      0,      0,      0,      0,      0 },
+ {      0, 0x01f4, 0x011c,      0, 0x1e20, 0x011e, 0x0120,      0,      0,      0,      0, 0x01e6,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x0122,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0, 0x0124,      0,      0,      0, 0x1e22, 0x1e26,      0,      0,      0, 0x021e,      0,      0,      0,      0,      0, 0x1e24,      0,      0,      0, 0x1e28,      0,      0, 0x1e2a,      0,      0,      0,      0,      0,      0 },
+ { 0x00cc, 0x00cd, 0x00ce, 0x0128, 0x012a, 0x012c, 0x0130, 0x00cf, 0x1ec8,      0,      0, 0x01cf, 0x0208, 0x020a,      0,      0,      0, 0x1eca,      0,      0,      0,      0, 0x012e,      0,      0, 0x1e2c,      0,      0,      0,      0,      0 },
+ {      0, 0x1e30,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x01e8,      0,      0,      0,      0,      0, 0x1e32,      0,      0,      0, 0x0136,      0,      0,      0,      0, 0x1e34,      0,      0,      0,      0 },
+ {      0, 0x0139,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x013d,      0,      0,      0,      0,      0, 0x1e36,      0,      0,      0, 0x013b,      0, 0x1e3c,      0,      0, 0x1e3a,      0,      0,      0,      0 },
+ {      0, 0x1e3e,      0,      0,      0,      0, 0x1e40,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e42,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x01f8, 0x0143,      0, 0x00d1,      0,      0, 0x1e44,      0,      0,      0,      0, 0x0147,      0,      0,      0,      0,      0, 0x1e46,      0,      0,      0, 0x0145,      0, 0x1e4a,      0,      0, 0x1e48,      0,      0,      0,      0 },
+ { 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x014c, 0x014e, 0x022e, 0x00d6, 0x1ece,      0, 0x0150, 0x01d1, 0x020c, 0x020e,      0,      0, 0x01a0, 0x1ecc,      0,      0,      0,      0, 0x01ea,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0, 0x1e54,      0,      0,      0,      0, 0x1e56,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0, 0x0154,      0,      0,      0,      0, 0x1e58,      0,      0,      0,      0, 0x0158, 0x0210, 0x0212,      0,      0,      0, 0x1e5a,      0,      0,      0, 0x0156,      0,      0,      0,      0, 0x1e5e,      0,      0,      0,      0 },
+ {      0, 0x015a, 0x015c,      0,      0,      0, 0x1e60,      0,      0,      0,      0, 0x0160,      0,      0,      0,      0,      0, 0x1e62,      0,      0, 0x0218, 0x015e,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0, 0x1e6a,      0,      0,      0,      0, 0x0164,      0,      0,      0,      0,      0, 0x1e6c,      0,      0, 0x021a, 0x0162,      0, 0x1e70,      0,      0, 0x1e6e,      0,      0,      0,      0 },
+ { 0x00d9, 0x00da, 0x00db, 0x0168, 0x016a, 0x016c,      0, 0x00dc, 0x1ee6, 0x016e, 0x0170, 0x01d3, 0x0214, 0x0216,      0,      0, 0x01af, 0x1ee4, 0x1e72,      0,      0,      0, 0x0172, 0x1e76,      0, 0x1e74,      0,      0,      0,      0,      0 },
+ {      0,      0,      0, 0x1e7c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e7e,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1e80, 0x1e82, 0x0174,      0,      0,      0, 0x1e86, 0x1e84,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e88,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0, 0x1e8a, 0x1e8c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1ef2, 0x00dd, 0x0176, 0x1ef8, 0x0232,      0, 0x1e8e, 0x0178, 0x1ef6,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ef4,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0, 0x0179, 0x1e90,      0,      0,      0, 0x017b,      0,      0,      0,      0, 0x017d,      0,      0,      0,      0,      0, 0x1e92,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e94,      0,      0,      0,      0 },
+ { 0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x0101, 0x0103, 0x0227, 0x00e4, 0x1ea3, 0x00e5,      0, 0x01ce, 0x0201, 0x0203,      0,      0,      0, 0x1ea1,      0, 0x1e01,      0,      0, 0x0105,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0, 0x1e03,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e05,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e07,      0,      0,      0,      0 },
+ {      0, 0x0107, 0x0109,      0,      0,      0, 0x010b,      0,      0,      0,      0, 0x010d,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x00e7,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0, 0x1e0b,      0,      0,      0,      0, 0x010f,      0,      0,      0,      0,      0, 0x1e0d,      0,      0,      0, 0x1e11,      0, 0x1e13,      0,      0, 0x1e0f,      0,      0,      0,      0 },
+ { 0x00e8, 0x00e9, 0x00ea, 0x1ebd, 0x0113, 0x0115, 0x0117, 0x00eb, 0x1ebb,      0,      0, 0x011b, 0x0205, 0x0207,      0,      0,      0, 0x1eb9,      0,      0,      0, 0x0229, 0x0119, 0x1e19,      0, 0x1e1b,      0,      0,      0,      0,      0 },
+ {      0, 0x01f5, 0x011d,      0, 0x1e21, 0x011f, 0x0121,      0,      0,      0,      0, 0x01e7,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x0123,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0, 0x0125,      0,      0,      0, 0x1e23, 0x1e27,      0,      0,      0, 0x021f,      0,      0,      0,      0,      0, 0x1e25,      0,      0,      0, 0x1e29,      0,      0, 0x1e2b,      0, 0x1e96,      0,      0,      0,      0 },
+ { 0x00ec, 0x00ed, 0x00ee, 0x0129, 0x012b, 0x012d,      0, 0x00ef, 0x1ec9,      0,      0, 0x01d0, 0x0209, 0x020b,      0,      0,      0, 0x1ecb,      0,      0,      0,      0, 0x012f,      0,      0, 0x1e2d,      0,      0,      0,      0,      0 },
+ {      0,      0, 0x0135,      0,      0,      0,      0,      0,      0,      0,      0, 0x01f0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0, 0x1e31,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x01e9,      0,      0,      0,      0,      0, 0x1e33,      0,      0,      0, 0x0137,      0,      0,      0,      0, 0x1e35,      0,      0,      0,      0 },
+ {      0, 0x013a,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x013e,      0,      0,      0,      0,      0, 0x1e37,      0,      0,      0, 0x013c,      0, 0x1e3d,      0,      0, 0x1e3b,      0,      0,      0,      0 },
+ {      0, 0x1e3f,      0,      0,      0,      0, 0x1e41,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e43,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x01f9, 0x0144,      0, 0x00f1,      0,      0, 0x1e45,      0,      0,      0,      0, 0x0148,      0,      0,      0,      0,      0, 0x1e47,      0,      0,      0, 0x0146,      0, 0x1e4b,      0,      0, 0x1e49,      0,      0,      0,      0 },
+ { 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x014d, 0x014f, 0x022f, 0x00f6, 0x1ecf,      0, 0x0151, 0x01d2, 0x020d, 0x020f,      0,      0, 0x01a1, 0x1ecd,      0,      0,      0,      0, 0x01eb,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0, 0x1e55,      0,      0,      0,      0, 0x1e57,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0, 0x0155,      0,      0,      0,      0, 0x1e59,      0,      0,      0,      0, 0x0159, 0x0211, 0x0213,      0,      0,      0, 0x1e5b,      0,      0,      0, 0x0157,      0,      0,      0,      0, 0x1e5f,      0,      0,      0,      0 },
+ {      0, 0x015b, 0x015d,      0,      0,      0, 0x1e61,      0,      0,      0,      0, 0x0161,      0,      0,      0,      0,      0, 0x1e63,      0,      0, 0x0219, 0x015f,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0, 0x1e6b, 0x1e97,      0,      0,      0, 0x0165,      0,      0,      0,      0,      0, 0x1e6d,      0,      0, 0x021b, 0x0163,      0, 0x1e71,      0,      0, 0x1e6f,      0,      0,      0,      0 },
+ { 0x00f9, 0x00fa, 0x00fb, 0x0169, 0x016b, 0x016d,      0, 0x00fc, 0x1ee7, 0x016f, 0x0171, 0x01d4, 0x0215, 0x0217,      0,      0, 0x01b0, 0x1ee5, 0x1e73,      0,      0,      0, 0x0173, 0x1e77,      0, 0x1e75,      0,      0,      0,      0,      0 },
+ {      0,      0,      0, 0x1e7d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e7f,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1e81, 0x1e83, 0x0175,      0,      0,      0, 0x1e87, 0x1e85,      0, 0x1e98,      0,      0,      0,      0,      0,      0,      0, 0x1e89,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0, 0x1e8b, 0x1e8d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1ef3, 0x00fd, 0x0177, 0x1ef9, 0x0233,      0, 0x1e8f, 0x00ff, 0x1ef7, 0x1e99,      0,      0,      0,      0,      0,      0,      0, 0x1ef5,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0, 0x017a, 0x1e91,      0,      0,      0, 0x017c,      0,      0,      0,      0, 0x017e,      0,      0,      0,      0,      0, 0x1e93,      0,      0,      0,      0,      0,      0,      0,      0, 0x1e95,      0,      0,      0,      0 },
+ { 0x1fed, 0x0385,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fc1,      0,      0,      0 },
+ { 0x1ea6, 0x1ea4,      0, 0x1eaa,      0,      0,      0,      0, 0x1ea8,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0, 0x01fc,      0,      0, 0x01e2,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1ec0, 0x1ebe,      0, 0x1ec4,      0,      0,      0,      0, 0x1ec2,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1ed2, 0x1ed0,      0, 0x1ed6,      0,      0,      0,      0, 0x1ed4,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0, 0x1e4c,      0,      0, 0x022c,      0,      0, 0x1e4e,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x01db, 0x01d7,      0,      0, 0x01d5,      0,      0,      0,      0,      0,      0, 0x01d9,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1ea7, 0x1ea5,      0, 0x1eab,      0,      0,      0,      0, 0x1ea9,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0, 0x01fd,      0,      0, 0x01e3,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1ec1, 0x1ebf,      0, 0x1ec5,      0,      0,      0,      0, 0x1ec3,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1ed3, 0x1ed1,      0, 0x1ed7,      0,      0,      0,      0, 0x1ed5,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0, 0x1e4d,      0,      0, 0x022d,      0,      0, 0x1e4f,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x01dc, 0x01d8,      0,      0, 0x01d6,      0,      0,      0,      0,      0,      0, 0x01da,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1eb0, 0x1eae,      0, 0x1eb4,      0,      0,      0,      0, 0x1eb2,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1eb1, 0x1eaf,      0, 0x1eb5,      0,      0,      0,      0, 0x1eb3,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1e14, 0x1e16,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1e15, 0x1e17,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1e50, 0x1e52,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1e51, 0x1e53,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1edc, 0x1eda,      0, 0x1ee0,      0,      0,      0,      0, 0x1ede,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ee2,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1edd, 0x1edb,      0, 0x1ee1,      0,      0,      0,      0, 0x1edf,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ee3,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1eea, 0x1ee8,      0, 0x1eee,      0,      0,      0,      0, 0x1eec,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ef0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1eeb, 0x1ee9,      0, 0x1eef,      0,      0,      0,      0, 0x1eed,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ef1,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1fba, 0x0386,      0,      0, 0x1fb9, 0x1fb8,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f08, 0x1f09,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fbc,      0,      0 },
+ { 0x1fc8, 0x0388,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f18, 0x1f19,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1fca, 0x0389,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f28, 0x1f29,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fcc,      0,      0 },
+ { 0x1fda, 0x038a,      0,      0, 0x1fd9, 0x1fd8,      0, 0x03aa,      0,      0,      0,      0,      0,      0, 0x1f38, 0x1f39,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1ff8, 0x038c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f48, 0x1f49,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1fea, 0x038e,      0,      0, 0x1fe9, 0x1fe8,      0, 0x03ab,      0,      0,      0,      0,      0,      0,      0, 0x1f59,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1ffa, 0x038f,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f68, 0x1f69,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ffc,      0,      0 },
+ { 0x1f70, 0x03ac,      0,      0, 0x1fb1, 0x1fb0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f00, 0x1f01,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fb6, 0x1fb3,      0,      0 },
+ { 0x1f72, 0x03ad,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f10, 0x1f11,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1f74, 0x03ae,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f20, 0x1f21,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fc6, 0x1fc3,      0,      0 },
+ { 0x1f76, 0x03af,      0,      0, 0x1fd1, 0x1fd0,      0, 0x03ca,      0,      0,      0,      0,      0,      0, 0x1f30, 0x1f31,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fd6,      0,      0,      0 },
+ { 0x1f78, 0x03cc,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f40, 0x1f41,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fe4, 0x1fe5,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1f7a, 0x03cd,      0,      0, 0x1fe1, 0x1fe0,      0, 0x03cb,      0,      0,      0,      0,      0,      0, 0x1f50, 0x1f51,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fe6,      0,      0,      0 },
+ { 0x1f7c, 0x03ce,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f60, 0x1f61,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1ff6, 0x1ff3,      0,      0 },
+ { 0x1fd2, 0x0390,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fd7,      0,      0,      0 },
+ { 0x1fe2, 0x03b0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fe7,      0,      0,      0 },
+ {      0, 0x03d3,      0,      0,      0,      0,      0, 0x03d4,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0, 0x04d0,      0, 0x04d2,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x0400,      0,      0,      0,      0, 0x04d6,      0, 0x0401,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0, 0x04c1,      0, 0x04dc,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x040d,      0,      0,      0, 0x04e2, 0x0419,      0, 0x04e4,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0, 0x04ee, 0x040e,      0, 0x04f0,      0,      0, 0x04f2,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0, 0x04d1,      0, 0x04d3,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x0450,      0,      0,      0,      0, 0x04d7,      0, 0x0451,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0, 0x04c2,      0, 0x04dd,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x045d,      0,      0,      0, 0x04e3, 0x0439,      0, 0x04e5,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0, 0x04ef, 0x045e,      0, 0x04f1,      0,      0, 0x04f3,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0, 0x1eac,      0,      0, 0x1eb6,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ {      0,      0, 0x1ead,      0,      0, 0x1eb7,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1f02, 0x1f04,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f06, 0x1f80,      0,      0 },
+ { 0x1f03, 0x1f05,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f07, 0x1f81,      0,      0 },
+ { 0x1f0a, 0x1f0c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f0e, 0x1f88,      0,      0 },
+ { 0x1f0b, 0x1f0d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f0f, 0x1f89,      0,      0 },
+ { 0x1f12, 0x1f14,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1f13, 0x1f15,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1f1a, 0x1f1c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1f1b, 0x1f1d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1f22, 0x1f24,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f26, 0x1f90,      0,      0 },
+ { 0x1f23, 0x1f25,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f27, 0x1f91,      0,      0 },
+ { 0x1f2a, 0x1f2c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f2e, 0x1f98,      0,      0 },
+ { 0x1f2b, 0x1f2d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f2f, 0x1f99,      0,      0 },
+ { 0x1f32, 0x1f34,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f36,      0,      0,      0 },
+ { 0x1f33, 0x1f35,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f37,      0,      0,      0 },
+ { 0x1f3a, 0x1f3c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f3e,      0,      0,      0 },
+ { 0x1f3b, 0x1f3d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f3f,      0,      0,      0 },
+ { 0x1f42, 0x1f44,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1f43, 0x1f45,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1f4a, 0x1f4c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1f4b, 0x1f4d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0 },
+ { 0x1f52, 0x1f54,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f56,      0,      0,      0 },
+ { 0x1f53, 0x1f55,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f57,      0,      0,      0 },
+ { 0x1f5b, 0x1f5d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f5f,      0,      0,      0 },
+ { 0x1f62, 0x1f64,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f66, 0x1fa0,      0,      0 },
+ { 0x1f63, 0x1f65,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f67, 0x1fa1,      0,      0 },
+ { 0x1f6a, 0x1f6c,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f6e, 0x1fa8,      0,      0 },
+ { 0x1f6b, 0x1f6d,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1f6f, 0x1fa9,      0,      0 },
+ { 0x1fcd, 0x1fce,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fcf,      0,      0,      0 },
+ { 0x1fdd, 0x1fde,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x1fdf,      0,      0,      0 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x3070, 0x3071 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x3073, 0x3074 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x3076, 0x3077 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x3079, 0x307a },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x307c, 0x307d },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x30d0, 0x30d1 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x30d3, 0x30d4 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x30d6, 0x30d7 },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x30d9, 0x30da },
+ {      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0,      0, 0x30dc, 0x30dd }
+};
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gunidecomp.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gunidecomp.c
new file mode 100644 (file)
index 0000000..0bd7ced
--- /dev/null
@@ -0,0 +1,532 @@
+/* decomp.c - Character decomposition.
+ *
+ *  Copyright (C) 1999, 2000 Tom Tromey
+ *  Copyright 2000 Red Hat, Inc.
+ *
+ * The Gnome 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 of the
+ * License, or (at your option) any later version.
+ *
+ * The Gnome 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 the Gnome Library; see the file COPYING.LIB.  If not,
+ * write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ *   Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+
+#include "gunicode.h"
+#include "gunidecomp.h"
+#include "gmem.h"
+#include "gunicomp.h"
+#include "gunicodeprivate.h"
+
+
+#define CC_PART1(Page, Char) \
+  ((combining_class_table_part1[Page] >= G_UNICODE_MAX_TABLE_INDEX) \
+   ? (combining_class_table_part1[Page] - G_UNICODE_MAX_TABLE_INDEX) \
+   : (cclass_data[combining_class_table_part1[Page]][Char]))
+
+#define CC_PART2(Page, Char) \
+  ((combining_class_table_part2[Page] >= G_UNICODE_MAX_TABLE_INDEX) \
+   ? (combining_class_table_part2[Page] - G_UNICODE_MAX_TABLE_INDEX) \
+   : (cclass_data[combining_class_table_part2[Page]][Char]))
+
+#define COMBINING_CLASS(Char) \
+  (((Char) <= G_UNICODE_LAST_CHAR_PART1) \
+   ? CC_PART1 ((Char) >> 8, (Char) & 0xff) \
+   : (((Char) >= 0xe0000 && (Char) <= G_UNICODE_LAST_CHAR) \
+      ? CC_PART2 (((Char) - 0xe0000) >> 8, (Char) & 0xff) \
+      : 0))
+
+/**
+ * g_unichar_combining_class:
+ * @uc: a Unicode character
+ * 
+ * Determines the canonical combining class of a Unicode character.
+ * 
+ * Return value: the combining class of the character
+ *
+ * Since: 2.14
+ **/
+gint
+g_unichar_combining_class (gunichar uc)
+{
+  return COMBINING_CLASS (uc);
+}
+
+/* constants for hangul syllable [de]composition */
+#define SBase 0xAC00 
+#define LBase 0x1100 
+#define VBase 0x1161 
+#define TBase 0x11A7
+#define LCount 19 
+#define VCount 21
+#define TCount 28
+#define NCount (VCount * TCount)
+#define SCount (LCount * NCount)
+
+/**
+ * g_unicode_canonical_ordering:
+ * @string: a UCS-4 encoded string.
+ * @len: the maximum length of @string to use.
+ *
+ * Computes the canonical ordering of a string in-place.  
+ * This rearranges decomposed characters in the string 
+ * according to their combining classes.  See the Unicode 
+ * manual for more information. 
+ **/
+void
+g_unicode_canonical_ordering (gunichar *string,
+                             gsize     len)
+{
+  gsize i;
+  int swap = 1;
+
+  while (swap)
+    {
+      int last;
+      swap = 0;
+      last = COMBINING_CLASS (string[0]);
+      for (i = 0; i < len - 1; ++i)
+       {
+         int next = COMBINING_CLASS (string[i + 1]);
+         if (next != 0 && last > next)
+           {
+             gsize j;
+             /* Percolate item leftward through string.  */
+             for (j = i + 1; j > 0; --j)
+               {
+                 gunichar t;
+                 if (COMBINING_CLASS (string[j - 1]) <= next)
+                   break;
+                 t = string[j];
+                 string[j] = string[j - 1];
+                 string[j - 1] = t;
+                 swap = 1;
+               }
+             /* We're re-entering the loop looking at the old
+                character again.  */
+             next = last;
+           }
+         last = next;
+       }
+    }
+}
+
+/* http://www.unicode.org/unicode/reports/tr15/#Hangul
+ * r should be null or have sufficient space. Calling with r == NULL will
+ * only calculate the result_len; however, a buffer with space for three
+ * characters will always be big enough. */
+static void
+decompose_hangul (gunichar s, 
+                  gunichar *r,
+                  gsize *result_len)
+{
+  gint SIndex = s - SBase;
+
+  /* not a hangul syllable */
+  if (SIndex < 0 || SIndex >= SCount)
+    {
+      if (r)
+        r[0] = s;
+      *result_len = 1;
+    }
+  else
+    {
+      gunichar L = LBase + SIndex / NCount;
+      gunichar V = VBase + (SIndex % NCount) / TCount;
+      gunichar T = TBase + SIndex % TCount;
+
+      if (r)
+        {
+          r[0] = L;
+          r[1] = V;
+        }
+
+      if (T != TBase) 
+        {
+          if (r)
+            r[2] = T;
+          *result_len = 3;
+        }
+      else
+        *result_len = 2;
+    }
+}
+
+/* returns a pointer to a null-terminated UTF-8 string */
+static const gchar *
+find_decomposition (gunichar ch,
+                   gboolean compat)
+{
+  int start = 0;
+  int end = G_N_ELEMENTS (decomp_table);
+  
+  if (ch >= decomp_table[start].ch &&
+      ch <= decomp_table[end - 1].ch)
+    {
+      while (TRUE)
+       {
+         int half = (start + end) / 2;
+         if (ch == decomp_table[half].ch)
+           {
+             int offset;
+
+             if (compat)
+               {
+                 offset = decomp_table[half].compat_offset;
+                 if (offset == G_UNICODE_NOT_PRESENT_OFFSET)
+                   offset = decomp_table[half].canon_offset;
+               }
+             else
+               {
+                 offset = decomp_table[half].canon_offset;
+                 if (offset == G_UNICODE_NOT_PRESENT_OFFSET)
+                   return NULL;
+               }
+             
+             return &(decomp_expansion_string[offset]);
+           }
+         else if (half == start)
+           break;
+         else if (ch > decomp_table[half].ch)
+           start = half;
+         else
+           end = half;
+       }
+    }
+
+  return NULL;
+}
+
+/**
+ * g_unicode_canonical_decomposition:
+ * @ch: a Unicode character.
+ * @result_len: location to store the length of the return value.
+ *
+ * Computes the canonical decomposition of a Unicode character.  
+ * 
+ * Return value: a newly allocated string of Unicode characters.
+ *   @result_len is set to the resulting length of the string.
+ **/
+gunichar *
+g_unicode_canonical_decomposition (gunichar ch,
+                                  gsize   *result_len)
+{
+  const gchar *decomp;
+  const gchar *p;
+  gunichar *r;
+
+  /* Hangul syllable */
+  if (ch >= 0xac00 && ch <= 0xd7a3)
+    {
+      decompose_hangul (ch, NULL, result_len);
+      r = g_malloc (*result_len * sizeof (gunichar));
+      decompose_hangul (ch, r, result_len);
+    }
+  else if ((decomp = find_decomposition (ch, FALSE)) != NULL)
+    {
+      /* Found it.  */
+      int i;
+      
+      *result_len = g_utf8_strlen (decomp, -1);
+      r = g_malloc (*result_len * sizeof (gunichar));
+      
+      for (p = decomp, i = 0; *p != '\0'; p = g_utf8_next_char (p), i++)
+        r[i] = g_utf8_get_char (p);
+    }
+  else
+    {
+      /* Not in our table.  */
+      r = g_malloc (sizeof (gunichar));
+      *r = ch;
+      *result_len = 1;
+    }
+
+  /* Supposedly following the Unicode 2.1.9 table means that the
+     decompositions come out in canonical order.  I haven't tested
+     this, but we rely on it here.  */
+  return r;
+}
+
+/* L,V => LV and LV,T => LVT  */
+static gboolean
+combine_hangul (gunichar a,
+                gunichar b,
+                gunichar *result)
+{
+  gint LIndex = a - LBase;
+  gint SIndex = a - SBase;
+
+  gint VIndex = b - VBase;
+  gint TIndex = b - TBase;
+
+  if (0 <= LIndex && LIndex < LCount
+      && 0 <= VIndex && VIndex < VCount)
+    {
+      *result = SBase + (LIndex * VCount + VIndex) * TCount;
+      return TRUE;
+    }
+  else if (0 <= SIndex && SIndex < SCount && (SIndex % TCount) == 0
+           && 0 < TIndex && TIndex < TCount)
+    {
+      *result = a + TIndex;
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+#define CI(Page, Char) \
+  ((compose_table[Page] >= G_UNICODE_MAX_TABLE_INDEX) \
+   ? (compose_table[Page] - G_UNICODE_MAX_TABLE_INDEX) \
+   : (compose_data[compose_table[Page]][Char]))
+
+#define COMPOSE_INDEX(Char) \
+     (((Char >> 8) > (COMPOSE_TABLE_LAST)) ? 0 : CI((Char) >> 8, (Char) & 0xff))
+
+static gboolean
+combine (gunichar  a,
+        gunichar  b,
+        gunichar *result)
+{
+  gushort index_a, index_b;
+
+  if (combine_hangul (a, b, result))
+    return TRUE;
+
+  index_a = COMPOSE_INDEX(a);
+
+  if (index_a >= COMPOSE_FIRST_SINGLE_START && index_a < COMPOSE_SECOND_START)
+    {
+      if (b == compose_first_single[index_a - COMPOSE_FIRST_SINGLE_START][0])
+       {
+         *result = compose_first_single[index_a - COMPOSE_FIRST_SINGLE_START][1];
+         return TRUE;
+       }
+      else
+        return FALSE;
+    }
+  
+  index_b = COMPOSE_INDEX(b);
+
+  if (index_b >= COMPOSE_SECOND_SINGLE_START)
+    {
+      if (a == compose_second_single[index_b - COMPOSE_SECOND_SINGLE_START][0])
+       {
+         *result = compose_second_single[index_b - COMPOSE_SECOND_SINGLE_START][1];
+         return TRUE;
+       }
+      else
+        return FALSE;
+    }
+
+  if (index_a >= COMPOSE_FIRST_START && index_a < COMPOSE_FIRST_SINGLE_START &&
+      index_b >= COMPOSE_SECOND_START && index_b < COMPOSE_SECOND_SINGLE_START)
+    {
+      gunichar res = compose_array[index_a - COMPOSE_FIRST_START][index_b - COMPOSE_SECOND_START];
+
+      if (res)
+       {
+         *result = res;
+         return TRUE;
+       }
+    }
+
+  return FALSE;
+}
+
+gunichar *
+_g_utf8_normalize_wc (const gchar    *str,
+                     gssize          max_len,
+                     GNormalizeMode  mode)
+{
+  gsize n_wc;
+  gunichar *wc_buffer;
+  const char *p;
+  gsize last_start;
+  gboolean do_compat = (mode == G_NORMALIZE_NFKC ||
+                       mode == G_NORMALIZE_NFKD);
+  gboolean do_compose = (mode == G_NORMALIZE_NFC ||
+                        mode == G_NORMALIZE_NFKC);
+
+  n_wc = 0;
+  p = str;
+  while ((max_len < 0 || p < str + max_len) && *p)
+    {
+      const gchar *decomp;
+      gunichar wc = g_utf8_get_char (p);
+
+      if (wc >= 0xac00 && wc <= 0xd7a3)
+        {
+          gsize result_len;
+          decompose_hangul (wc, NULL, &result_len);
+          n_wc += result_len;
+        }
+      else 
+        {
+          decomp = find_decomposition (wc, do_compat);
+
+          if (decomp)
+            n_wc += g_utf8_strlen (decomp, -1);
+          else
+            n_wc++;
+        }
+
+      p = g_utf8_next_char (p);
+    }
+
+  wc_buffer = g_new (gunichar, n_wc + 1);
+
+  last_start = 0;
+  n_wc = 0;
+  p = str;
+  while ((max_len < 0 || p < str + max_len) && *p)
+    {
+      gunichar wc = g_utf8_get_char (p);
+      const gchar *decomp;
+      int cc;
+      gsize old_n_wc = n_wc;
+         
+      if (wc >= 0xac00 && wc <= 0xd7a3)
+        {
+          gsize result_len;
+          decompose_hangul (wc, wc_buffer + n_wc, &result_len);
+          n_wc += result_len;
+        }
+      else
+        {
+          decomp = find_decomposition (wc, do_compat);
+          
+          if (decomp)
+            {
+              const char *pd;
+              for (pd = decomp; *pd != '\0'; pd = g_utf8_next_char (pd))
+                wc_buffer[n_wc++] = g_utf8_get_char (pd);
+            }
+          else
+            wc_buffer[n_wc++] = wc;
+        }
+
+      if (n_wc > 0)
+       {
+         cc = COMBINING_CLASS (wc_buffer[old_n_wc]);
+
+         if (cc == 0)
+           {
+             g_unicode_canonical_ordering (wc_buffer + last_start, n_wc - last_start);
+             last_start = old_n_wc;
+           }
+       }
+      
+      p = g_utf8_next_char (p);
+    }
+
+  if (n_wc > 0)
+    {
+      g_unicode_canonical_ordering (wc_buffer + last_start, n_wc - last_start);
+      last_start = n_wc;
+    }
+         
+  wc_buffer[n_wc] = 0;
+
+  /* All decomposed and reordered */ 
+
+  if (do_compose && n_wc > 0)
+    {
+      gsize i, j;
+      int last_cc = 0;
+      last_start = 0;
+      
+      for (i = 0; i < n_wc; i++)
+       {
+         int cc = COMBINING_CLASS (wc_buffer[i]);
+
+         if (i > 0 &&
+             (last_cc == 0 || last_cc < cc) &&
+             combine (wc_buffer[last_start], wc_buffer[i],
+                      &wc_buffer[last_start]))
+           {
+             for (j = i + 1; j < n_wc; j++)
+               wc_buffer[j-1] = wc_buffer[j];
+             n_wc--;
+             i--;
+             
+             if (i == last_start)
+               last_cc = 0;
+             else
+               last_cc = COMBINING_CLASS (wc_buffer[i-1]);
+             
+             continue;
+           }
+
+         if (cc == 0)
+           last_start = i;
+
+         last_cc = cc;
+       }
+    }
+
+  wc_buffer[n_wc] = 0;
+
+  return wc_buffer;
+}
+
+/**
+ * g_utf8_normalize:
+ * @str: a UTF-8 encoded string.
+ * @len: length of @str, in bytes, or -1 if @str is nul-terminated.
+ * @mode: the type of normalization to perform.
+ *
+ * Converts a string into canonical form, standardizing
+ * such issues as whether a character with an accent
+ * is represented as a base character and combining
+ * accent or as a single precomposed character. The
+ * string has to be valid UTF-8, otherwise %NULL is
+ * returned. You should generally call g_utf8_normalize()
+ * before comparing two Unicode strings.
+ *
+ * The normalization mode %G_NORMALIZE_DEFAULT only
+ * standardizes differences that do not affect the
+ * text content, such as the above-mentioned accent
+ * representation. %G_NORMALIZE_ALL also standardizes
+ * the "compatibility" characters in Unicode, such
+ * as SUPERSCRIPT THREE to the standard forms
+ * (in this case DIGIT THREE). Formatting information
+ * may be lost but for most text operations such
+ * characters should be considered the same.
+ *
+ * %G_NORMALIZE_DEFAULT_COMPOSE and %G_NORMALIZE_ALL_COMPOSE
+ * are like %G_NORMALIZE_DEFAULT and %G_NORMALIZE_ALL,
+ * but returned a result with composed forms rather
+ * than a maximally decomposed form. This is often
+ * useful if you intend to convert the string to
+ * a legacy encoding or pass it to a system with
+ * less capable Unicode handling.
+ *
+ * Return value: a newly allocated string, that is the
+ *   normalized form of @str, or %NULL if @str is not
+ *   valid UTF-8.
+ **/
+gchar *
+g_utf8_normalize (const gchar    *str,
+                 gssize          len,
+                 GNormalizeMode  mode)
+{
+  gunichar *result_wc = _g_utf8_normalize_wc (str, len, mode);
+  gchar *result;
+
+  result = g_ucs4_to_utf8 (result_wc, -1, NULL, NULL, NULL);
+  g_free (result_wc);
+
+  return result;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gunidecomp.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gunidecomp.h
new file mode 100644 (file)
index 0000000..135d107
--- /dev/null
@@ -0,0 +1,10870 @@
+/* This file is automatically generated.  DO NOT EDIT! */
+
+#ifndef DECOMP_H
+#define DECOMP_H
+
+#define G_UNICODE_LAST_CHAR 0x10ffff
+
+#define G_UNICODE_MAX_TABLE_INDEX (0x110000 / 256)
+
+#define G_UNICODE_LAST_CHAR_PART1 0x2FAFF
+
+#define G_UNICODE_LAST_PAGE_PART1 762
+
+#define G_UNICODE_NOT_PRESENT_OFFSET 65535
+
+static const guchar cclass_data[][256] = {
+  { /* page 3, index 0 */
+    230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 
+    230, 230, 230, 230, 230, 230, 230, 232, 220, 220, 220, 220, 232, 216, 
+    220, 220, 220, 220, 220, 202, 202, 220, 220, 220, 220, 202, 202, 220, 
+    220, 220, 220, 220, 220, 220, 220, 220, 220, 220, 1, 1, 1, 1, 1, 220, 
+    220, 220, 220, 230, 230, 230, 230, 230, 230, 230, 230, 240, 230, 220, 
+    220, 220, 230, 230, 230, 220, 220, 0, 230, 230, 230, 220, 220, 220, 220, 
+    230, 232, 220, 220, 230, 233, 234, 234, 233, 234, 234, 233, 230, 230, 
+    230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 4, index 1 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 5, index 2 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 220, 230, 230, 230, 230, 220, 230, 230, 230, 222, 220, 230, 230, 230, 
+    230, 230, 230, 220, 220, 220, 220, 220, 220, 230, 230, 220, 230, 230, 
+    222, 228, 230, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 19, 20, 21, 22, 0, 
+    23, 0, 24, 25, 0, 230, 220, 0, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 6, index 3 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 
+    230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 27, 28, 29, 30, 31, 32, 33, 34, 230, 230, 220, 220, 
+    230, 230, 230, 230, 230, 220, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 0, 
+    0, 230, 230, 230, 230, 220, 230, 0, 0, 230, 230, 0, 220, 230, 230, 220, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 7, index 4 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 36, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    230, 220, 230, 230, 220, 230, 230, 220, 220, 220, 230, 220, 220, 230, 
+    220, 230, 230, 230, 220, 230, 220, 230, 220, 230, 220, 230, 230, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 230, 230, 230, 
+    220, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 9, index 5 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 9, 0, 0, 0, 230, 220, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 10, index 6 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 11, index 7 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 12, index 8 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 84, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 13, index 9 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 14, index 10 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 103, 103, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 107, 107, 107, 107, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 118, 118, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 122, 122, 122, 122, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 15, index 11 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 220, 0, 220, 0, 216, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 129, 130, 0, 
+    132, 0, 0, 0, 0, 0, 130, 130, 130, 130, 0, 0, 130, 0, 230, 230, 9, 0, 
+    230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0
+  },
+  { /* page 16, index 12 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 7, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 19, index 13 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 23, index 14 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 24, index 15 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 228, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 25, index 16 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 222, 230, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 26, index 17 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 
+    220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 27, index 18 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220, 230, 230, 230, 230, 230, 230, 
+    230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 29, index 19 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    230, 230, 220, 230, 230, 230, 230, 230, 230, 230, 220, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 220
+  },
+  { /* page 32, index 20 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 1, 1, 230, 230, 
+    230, 230, 1, 1, 1, 230, 230, 0, 0, 0, 0, 230, 0, 0, 0, 1, 1, 230, 220, 
+    230, 1, 1, 220, 220, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0
+  },
+  { /* page 48, index 21 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 218, 228, 232, 222, 
+    224, 224, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 168, index 22 */
+    0, 0, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 251, index 23 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 254, index 24 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 266, index 25 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 220, 0, 230, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 1, 220, 0, 0, 0, 0, 9, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 465, index 26 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 216, 216, 1, 1, 1, 0, 0, 0, 226, 216, 216, 216, 216, 216, 
+    0, 0, 0, 0, 0, 0, 0, 0, 220, 220, 220, 220, 220, 220, 220, 220, 0, 0, 
+    230, 230, 230, 230, 230, 220, 220, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 230, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0
+  },
+  { /* page 466, index 27 */
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 230, 230, 230, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 
+    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
+  }
+};
+
+static const gint16 combining_class_table_part1[763] = {
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 /* page 3 */,
+  1 /* page 4 */,
+  2 /* page 5 */,
+  3 /* page 6 */,
+  4 /* page 7 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  5 /* page 9 */,
+  6 /* page 10 */,
+  7 /* page 11 */,
+  8 /* page 12 */,
+  9 /* page 13 */,
+  10 /* page 14 */,
+  11 /* page 15 */,
+  12 /* page 16 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  13 /* page 19 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  14 /* page 23 */,
+  15 /* page 24 */,
+  16 /* page 25 */,
+  17 /* page 26 */,
+  18 /* page 27 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  19 /* page 29 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  20 /* page 32 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  21 /* page 48 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  22 /* page 168 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  23 /* page 251 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  24 /* page 254 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  25 /* page 266 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  26 /* page 465 */,
+  27 /* page 466 */,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX
+};
+
+static const gint16 combining_class_table_part2[768] = {
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX,
+  0 + G_UNICODE_MAX_TABLE_INDEX
+};
+
+typedef struct
+{
+  gunichar ch;
+  guint16 canon_offset;
+  guint16 compat_offset;
+} decomposition;
+
+static const decomposition decomp_table[] =
+{
+  { 0x00a0, G_UNICODE_NOT_PRESENT_OFFSET, 0 },
+  { 0x00a8, G_UNICODE_NOT_PRESENT_OFFSET, 2 },
+  { 0x00aa, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x00af, G_UNICODE_NOT_PRESENT_OFFSET, 8 },
+  { 0x00b2, G_UNICODE_NOT_PRESENT_OFFSET, 12 },
+  { 0x00b3, G_UNICODE_NOT_PRESENT_OFFSET, 14 },
+  { 0x00b4, G_UNICODE_NOT_PRESENT_OFFSET, 16 },
+  { 0x00b5, G_UNICODE_NOT_PRESENT_OFFSET, 20 },
+  { 0x00b8, G_UNICODE_NOT_PRESENT_OFFSET, 23 },
+  { 0x00b9, G_UNICODE_NOT_PRESENT_OFFSET, 27 },
+  { 0x00ba, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x00bc, G_UNICODE_NOT_PRESENT_OFFSET, 31 },
+  { 0x00bd, G_UNICODE_NOT_PRESENT_OFFSET, 37 },
+  { 0x00be, G_UNICODE_NOT_PRESENT_OFFSET, 43 },
+  { 0x00c0, 49, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00c1, 53, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00c2, 57, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00c3, 61, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00c4, 65, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00c5, 69, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00c7, 73, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00c8, 77, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00c9, 81, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00ca, 85, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00cb, 89, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00cc, 93, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00cd, 97, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00ce, 101, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00cf, 105, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00d1, 109, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00d2, 113, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00d3, 117, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00d4, 121, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00d5, 125, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00d6, 129, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00d9, 133, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00da, 137, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00db, 141, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00dc, 145, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00dd, 149, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00e0, 153, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00e1, 157, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00e2, 161, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00e3, 165, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00e4, 169, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00e5, 173, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00e7, 177, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00e8, 181, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00e9, 185, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00ea, 189, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00eb, 193, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00ec, 197, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00ed, 201, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00ee, 205, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00ef, 209, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00f1, 213, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00f2, 217, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00f3, 221, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00f4, 225, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00f5, 229, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00f6, 233, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00f9, 237, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00fa, 241, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00fb, 245, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00fc, 249, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00fd, 253, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x00ff, 257, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0100, 261, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0101, 265, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0102, 269, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0103, 273, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0104, 277, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0105, 281, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0106, 285, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0107, 289, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0108, 293, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0109, 297, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x010a, 301, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x010b, 305, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x010c, 309, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x010d, 313, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x010e, 317, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x010f, 321, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0112, 325, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0113, 329, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0114, 333, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0115, 337, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0116, 341, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0117, 345, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0118, 349, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0119, 353, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x011a, 357, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x011b, 361, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x011c, 365, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x011d, 369, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x011e, 373, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x011f, 377, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0120, 381, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0121, 385, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0122, 389, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0123, 393, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0124, 397, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0125, 401, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0128, 405, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0129, 409, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x012a, 413, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x012b, 417, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x012c, 421, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x012d, 425, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x012e, 429, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x012f, 433, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0130, 437, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0132, G_UNICODE_NOT_PRESENT_OFFSET, 441 },
+  { 0x0133, G_UNICODE_NOT_PRESENT_OFFSET, 444 },
+  { 0x0134, 447, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0135, 451, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0136, 455, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0137, 459, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0139, 463, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x013a, 467, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x013b, 471, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x013c, 475, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x013d, 479, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x013e, 483, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x013f, G_UNICODE_NOT_PRESENT_OFFSET, 487 },
+  { 0x0140, G_UNICODE_NOT_PRESENT_OFFSET, 491 },
+  { 0x0143, 495, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0144, 499, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0145, 503, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0146, 507, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0147, 511, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0148, 515, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0149, G_UNICODE_NOT_PRESENT_OFFSET, 519 },
+  { 0x014c, 523, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x014d, 527, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x014e, 531, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x014f, 535, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0150, 539, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0151, 543, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0154, 547, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0155, 551, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0156, 555, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0157, 559, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0158, 563, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0159, 567, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x015a, 571, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x015b, 575, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x015c, 579, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x015d, 583, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x015e, 587, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x015f, 591, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0160, 595, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0161, 599, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0162, 603, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0163, 607, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0164, 611, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0165, 615, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0168, 619, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0169, 623, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x016a, 627, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x016b, 631, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x016c, 635, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x016d, 639, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x016e, 643, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x016f, 647, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0170, 651, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0171, 655, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0172, 659, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0173, 663, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0174, 667, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0175, 671, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0176, 675, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0177, 679, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0178, 683, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0179, 687, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x017a, 691, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x017b, 695, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x017c, 699, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x017d, 703, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x017e, 707, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x017f, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x01a0, 713, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01a1, 717, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01af, 721, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01b0, 725, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01c4, G_UNICODE_NOT_PRESENT_OFFSET, 729 },
+  { 0x01c5, G_UNICODE_NOT_PRESENT_OFFSET, 734 },
+  { 0x01c6, G_UNICODE_NOT_PRESENT_OFFSET, 739 },
+  { 0x01c7, G_UNICODE_NOT_PRESENT_OFFSET, 744 },
+  { 0x01c8, G_UNICODE_NOT_PRESENT_OFFSET, 747 },
+  { 0x01c9, G_UNICODE_NOT_PRESENT_OFFSET, 750 },
+  { 0x01ca, G_UNICODE_NOT_PRESENT_OFFSET, 753 },
+  { 0x01cb, G_UNICODE_NOT_PRESENT_OFFSET, 756 },
+  { 0x01cc, G_UNICODE_NOT_PRESENT_OFFSET, 759 },
+  { 0x01cd, 762, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01ce, 766, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01cf, 770, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01d0, 774, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01d1, 778, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01d2, 782, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01d3, 786, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01d4, 790, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01d5, 794, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01d6, 800, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01d7, 806, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01d8, 812, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01d9, 818, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01da, 824, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01db, 830, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01dc, 836, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01de, 842, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01df, 848, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01e0, 854, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01e1, 860, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01e2, 866, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01e3, 871, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01e6, 876, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01e7, 880, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01e8, 884, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01e9, 888, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01ea, 892, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01eb, 896, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01ec, 900, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01ed, 906, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01ee, 912, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01ef, 917, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01f0, 922, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01f1, G_UNICODE_NOT_PRESENT_OFFSET, 926 },
+  { 0x01f2, G_UNICODE_NOT_PRESENT_OFFSET, 929 },
+  { 0x01f3, G_UNICODE_NOT_PRESENT_OFFSET, 932 },
+  { 0x01f4, 935, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01f5, 939, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01f8, 943, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01f9, 947, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01fa, 951, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01fb, 957, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01fc, 963, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01fd, 968, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01fe, 973, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x01ff, 978, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0200, 983, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0201, 987, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0202, 991, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0203, 995, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0204, 999, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0205, 1003, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0206, 1007, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0207, 1011, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0208, 1015, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0209, 1019, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x020a, 1023, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x020b, 1027, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x020c, 1031, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x020d, 1035, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x020e, 1039, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x020f, 1043, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0210, 1047, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0211, 1051, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0212, 1055, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0213, 1059, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0214, 1063, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0215, 1067, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0216, 1071, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0217, 1075, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0218, 1079, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0219, 1083, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x021a, 1087, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x021b, 1091, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x021e, 1095, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x021f, 1099, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0226, 1103, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0227, 1107, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0228, 1111, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0229, 1115, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x022a, 1119, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x022b, 1125, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x022c, 1131, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x022d, 1137, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x022e, 1143, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x022f, 1147, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0230, 1151, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0231, 1157, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0232, 1163, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0233, 1167, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x02b0, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x02b1, G_UNICODE_NOT_PRESENT_OFFSET, 1173 },
+  { 0x02b2, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x02b3, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x02b4, G_UNICODE_NOT_PRESENT_OFFSET, 1180 },
+  { 0x02b5, G_UNICODE_NOT_PRESENT_OFFSET, 1183 },
+  { 0x02b6, G_UNICODE_NOT_PRESENT_OFFSET, 1186 },
+  { 0x02b7, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x02b8, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x02d8, G_UNICODE_NOT_PRESENT_OFFSET, 1193 },
+  { 0x02d9, G_UNICODE_NOT_PRESENT_OFFSET, 1197 },
+  { 0x02da, G_UNICODE_NOT_PRESENT_OFFSET, 1201 },
+  { 0x02db, G_UNICODE_NOT_PRESENT_OFFSET, 1205 },
+  { 0x02dc, G_UNICODE_NOT_PRESENT_OFFSET, 1209 },
+  { 0x02dd, G_UNICODE_NOT_PRESENT_OFFSET, 1213 },
+  { 0x02e0, G_UNICODE_NOT_PRESENT_OFFSET, 1217 },
+  { 0x02e1, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x02e2, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x02e3, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x02e4, G_UNICODE_NOT_PRESENT_OFFSET, 1224 },
+  { 0x0340, 1227, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0341, 1230, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0343, 1233, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0344, 1236, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0374, 1241, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x037a, G_UNICODE_NOT_PRESENT_OFFSET, 1244 },
+  { 0x037e, 1248, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0384, G_UNICODE_NOT_PRESENT_OFFSET, 16 },
+  { 0x0385, 1250, 1255 },
+  { 0x0386, 1261, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0387, 1266, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0388, 1269, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0389, 1274, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x038a, 1279, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x038c, 1284, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x038e, 1289, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x038f, 1294, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0390, 1299, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x03aa, 1306, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x03ab, 1311, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x03ac, 1316, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x03ad, 1321, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x03ae, 1326, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x03af, 1331, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x03b0, 1336, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x03ca, 1343, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x03cb, 1348, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x03cc, 1353, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x03cd, 1358, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x03ce, 1363, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x03d0, G_UNICODE_NOT_PRESENT_OFFSET, 1368 },
+  { 0x03d1, G_UNICODE_NOT_PRESENT_OFFSET, 1371 },
+  { 0x03d2, G_UNICODE_NOT_PRESENT_OFFSET, 1374 },
+  { 0x03d3, 1377, 1289 },
+  { 0x03d4, 1382, 1311 },
+  { 0x03d5, G_UNICODE_NOT_PRESENT_OFFSET, 1387 },
+  { 0x03d6, G_UNICODE_NOT_PRESENT_OFFSET, 1390 },
+  { 0x03f0, G_UNICODE_NOT_PRESENT_OFFSET, 1393 },
+  { 0x03f1, G_UNICODE_NOT_PRESENT_OFFSET, 1396 },
+  { 0x03f2, G_UNICODE_NOT_PRESENT_OFFSET, 1399 },
+  { 0x03f4, G_UNICODE_NOT_PRESENT_OFFSET, 1402 },
+  { 0x03f5, G_UNICODE_NOT_PRESENT_OFFSET, 1405 },
+  { 0x03f9, G_UNICODE_NOT_PRESENT_OFFSET, 1408 },
+  { 0x0400, 1411, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0401, 1416, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0403, 1421, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0407, 1426, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x040c, 1431, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x040d, 1436, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x040e, 1441, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0419, 1446, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0439, 1451, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0450, 1456, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0451, 1461, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0453, 1466, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0457, 1471, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x045c, 1476, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x045d, 1481, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x045e, 1486, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0476, 1491, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0477, 1496, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04c1, 1501, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04c2, 1506, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04d0, 1511, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04d1, 1516, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04d2, 1521, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04d3, 1526, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04d6, 1531, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04d7, 1536, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04da, 1541, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04db, 1546, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04dc, 1551, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04dd, 1556, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04de, 1561, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04df, 1566, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04e2, 1571, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04e3, 1576, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04e4, 1581, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04e5, 1586, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04e6, 1591, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04e7, 1596, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04ea, 1601, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04eb, 1606, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04ec, 1611, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04ed, 1616, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04ee, 1621, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04ef, 1626, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04f0, 1631, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04f1, 1636, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04f2, 1641, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04f3, 1646, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04f4, 1651, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04f5, 1656, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04f8, 1661, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x04f9, 1666, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0587, G_UNICODE_NOT_PRESENT_OFFSET, 1671 },
+  { 0x0622, 1676, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0623, 1681, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0624, 1686, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0625, 1691, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0626, 1696, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0675, G_UNICODE_NOT_PRESENT_OFFSET, 1701 },
+  { 0x0676, G_UNICODE_NOT_PRESENT_OFFSET, 1706 },
+  { 0x0677, G_UNICODE_NOT_PRESENT_OFFSET, 1711 },
+  { 0x0678, G_UNICODE_NOT_PRESENT_OFFSET, 1716 },
+  { 0x06c0, 1721, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x06c2, 1726, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x06d3, 1731, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0929, 1736, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0931, 1743, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0934, 1750, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0958, 1757, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0959, 1764, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x095a, 1771, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x095b, 1778, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x095c, 1785, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x095d, 1792, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x095e, 1799, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x095f, 1806, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x09cb, 1813, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x09cc, 1820, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x09dc, 1827, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x09dd, 1834, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x09df, 1841, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0a33, 1848, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0a36, 1855, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0a59, 1862, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0a5a, 1869, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0a5b, 1876, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0a5e, 1883, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0b48, 1890, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0b4b, 1897, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0b4c, 1904, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0b5c, 1911, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0b5d, 1918, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0b94, 1925, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0bca, 1932, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0bcb, 1939, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0bcc, 1946, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0c48, 1953, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0cc0, 1960, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0cc7, 1967, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0cc8, 1974, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0cca, 1981, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0ccb, 1988, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0d4a, 1998, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0d4b, 2005, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0d4c, 2012, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0dda, 2019, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0ddc, 2026, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0ddd, 2033, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0dde, 2043, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0e33, G_UNICODE_NOT_PRESENT_OFFSET, 2050 },
+  { 0x0eb3, G_UNICODE_NOT_PRESENT_OFFSET, 2057 },
+  { 0x0edc, G_UNICODE_NOT_PRESENT_OFFSET, 2064 },
+  { 0x0edd, G_UNICODE_NOT_PRESENT_OFFSET, 2071 },
+  { 0x0f0c, G_UNICODE_NOT_PRESENT_OFFSET, 2078 },
+  { 0x0f43, 2082, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0f4d, 2089, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0f52, 2096, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0f57, 2103, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0f5c, 2110, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0f69, 2117, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0f73, 2124, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0f75, 2131, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0f76, 2138, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0f77, G_UNICODE_NOT_PRESENT_OFFSET, 2145 },
+  { 0x0f78, 2155, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0f79, G_UNICODE_NOT_PRESENT_OFFSET, 2162 },
+  { 0x0f81, 2172, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0f93, 2179, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0f9d, 2186, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0fa2, 2193, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0fa7, 2200, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0fac, 2207, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x0fb9, 2214, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1026, 2221, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x10fc, G_UNICODE_NOT_PRESENT_OFFSET, 2228 },
+  { 0x1b06, 2232, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1b08, 2239, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1b0a, 2246, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1b0c, 2253, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1b0e, 2260, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1b12, 2267, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1b3b, 2274, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1b3d, 2281, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1b40, 2288, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1b41, 2295, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1b43, 2302, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d2c, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d2d, G_UNICODE_NOT_PRESENT_OFFSET, 2311 },
+  { 0x1d2e, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x1d30, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d31, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x1d32, G_UNICODE_NOT_PRESENT_OFFSET, 2320 },
+  { 0x1d33, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d34, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x1d35, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x1d36, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d37, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d38, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x1d39, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x1d3a, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x1d3c, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d3d, G_UNICODE_NOT_PRESENT_OFFSET, 2341 },
+  { 0x1d3e, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x1d3f, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x1d40, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d41, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d42, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d43, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d44, G_UNICODE_NOT_PRESENT_OFFSET, 2354 },
+  { 0x1d45, G_UNICODE_NOT_PRESENT_OFFSET, 2357 },
+  { 0x1d46, G_UNICODE_NOT_PRESENT_OFFSET, 2360 },
+  { 0x1d47, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d48, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d49, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x1d4a, G_UNICODE_NOT_PRESENT_OFFSET, 2370 },
+  { 0x1d4b, G_UNICODE_NOT_PRESENT_OFFSET, 2373 },
+  { 0x1d4c, G_UNICODE_NOT_PRESENT_OFFSET, 2376 },
+  { 0x1d4d, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x1d4f, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d50, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d51, G_UNICODE_NOT_PRESENT_OFFSET, 2385 },
+  { 0x1d52, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x1d53, G_UNICODE_NOT_PRESENT_OFFSET, 2388 },
+  { 0x1d54, G_UNICODE_NOT_PRESENT_OFFSET, 2391 },
+  { 0x1d55, G_UNICODE_NOT_PRESENT_OFFSET, 2395 },
+  { 0x1d56, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d57, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d58, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d59, G_UNICODE_NOT_PRESENT_OFFSET, 2405 },
+  { 0x1d5a, G_UNICODE_NOT_PRESENT_OFFSET, 2409 },
+  { 0x1d5b, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d5c, G_UNICODE_NOT_PRESENT_OFFSET, 2414 },
+  { 0x1d5d, G_UNICODE_NOT_PRESENT_OFFSET, 1368 },
+  { 0x1d5e, G_UNICODE_NOT_PRESENT_OFFSET, 2418 },
+  { 0x1d5f, G_UNICODE_NOT_PRESENT_OFFSET, 2421 },
+  { 0x1d60, G_UNICODE_NOT_PRESENT_OFFSET, 1387 },
+  { 0x1d61, G_UNICODE_NOT_PRESENT_OFFSET, 2424 },
+  { 0x1d62, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d63, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d64, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d65, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d66, G_UNICODE_NOT_PRESENT_OFFSET, 1368 },
+  { 0x1d67, G_UNICODE_NOT_PRESENT_OFFSET, 2418 },
+  { 0x1d68, G_UNICODE_NOT_PRESENT_OFFSET, 1396 },
+  { 0x1d69, G_UNICODE_NOT_PRESENT_OFFSET, 1387 },
+  { 0x1d6a, G_UNICODE_NOT_PRESENT_OFFSET, 2424 },
+  { 0x1d78, G_UNICODE_NOT_PRESENT_OFFSET, 2429 },
+  { 0x1d9b, G_UNICODE_NOT_PRESENT_OFFSET, 2432 },
+  { 0x1d9c, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d9d, G_UNICODE_NOT_PRESENT_OFFSET, 2437 },
+  { 0x1d9e, G_UNICODE_NOT_PRESENT_OFFSET, 2440 },
+  { 0x1d9f, G_UNICODE_NOT_PRESENT_OFFSET, 2376 },
+  { 0x1da0, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1da1, G_UNICODE_NOT_PRESENT_OFFSET, 2445 },
+  { 0x1da2, G_UNICODE_NOT_PRESENT_OFFSET, 2448 },
+  { 0x1da3, G_UNICODE_NOT_PRESENT_OFFSET, 2451 },
+  { 0x1da4, G_UNICODE_NOT_PRESENT_OFFSET, 2454 },
+  { 0x1da5, G_UNICODE_NOT_PRESENT_OFFSET, 2457 },
+  { 0x1da6, G_UNICODE_NOT_PRESENT_OFFSET, 2460 },
+  { 0x1da7, G_UNICODE_NOT_PRESENT_OFFSET, 2463 },
+  { 0x1da8, G_UNICODE_NOT_PRESENT_OFFSET, 2467 },
+  { 0x1da9, G_UNICODE_NOT_PRESENT_OFFSET, 2470 },
+  { 0x1daa, G_UNICODE_NOT_PRESENT_OFFSET, 2473 },
+  { 0x1dab, G_UNICODE_NOT_PRESENT_OFFSET, 2477 },
+  { 0x1dac, G_UNICODE_NOT_PRESENT_OFFSET, 2480 },
+  { 0x1dad, G_UNICODE_NOT_PRESENT_OFFSET, 2483 },
+  { 0x1dae, G_UNICODE_NOT_PRESENT_OFFSET, 2486 },
+  { 0x1daf, G_UNICODE_NOT_PRESENT_OFFSET, 2489 },
+  { 0x1db0, G_UNICODE_NOT_PRESENT_OFFSET, 2492 },
+  { 0x1db1, G_UNICODE_NOT_PRESENT_OFFSET, 2495 },
+  { 0x1db2, G_UNICODE_NOT_PRESENT_OFFSET, 2498 },
+  { 0x1db3, G_UNICODE_NOT_PRESENT_OFFSET, 2501 },
+  { 0x1db4, G_UNICODE_NOT_PRESENT_OFFSET, 2504 },
+  { 0x1db5, G_UNICODE_NOT_PRESENT_OFFSET, 2507 },
+  { 0x1db6, G_UNICODE_NOT_PRESENT_OFFSET, 2510 },
+  { 0x1db7, G_UNICODE_NOT_PRESENT_OFFSET, 2513 },
+  { 0x1db8, G_UNICODE_NOT_PRESENT_OFFSET, 2516 },
+  { 0x1db9, G_UNICODE_NOT_PRESENT_OFFSET, 2520 },
+  { 0x1dba, G_UNICODE_NOT_PRESENT_OFFSET, 2523 },
+  { 0x1dbb, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1dbc, G_UNICODE_NOT_PRESENT_OFFSET, 2528 },
+  { 0x1dbd, G_UNICODE_NOT_PRESENT_OFFSET, 2531 },
+  { 0x1dbe, G_UNICODE_NOT_PRESENT_OFFSET, 2534 },
+  { 0x1dbf, G_UNICODE_NOT_PRESENT_OFFSET, 1371 },
+  { 0x1e00, 2537, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e01, 2541, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e02, 2545, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e03, 2549, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e04, 2553, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e05, 2557, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e06, 2561, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e07, 2565, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e08, 2569, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e09, 2575, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e0a, 2581, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e0b, 2585, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e0c, 2589, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e0d, 2593, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e0e, 2597, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e0f, 2601, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e10, 2605, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e11, 2609, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e12, 2613, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e13, 2617, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e14, 2621, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e15, 2627, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e16, 2633, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e17, 2639, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e18, 2645, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e19, 2649, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e1a, 2653, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e1b, 2657, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e1c, 2661, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e1d, 2667, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e1e, 2673, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e1f, 2677, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e20, 2681, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e21, 2685, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e22, 2689, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e23, 2693, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e24, 2697, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e25, 2701, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e26, 2705, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e27, 2709, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e28, 2713, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e29, 2717, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e2a, 2721, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e2b, 2725, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e2c, 2729, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e2d, 2733, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e2e, 2737, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e2f, 2743, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e30, 2749, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e31, 2753, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e32, 2757, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e33, 2761, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e34, 2765, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e35, 2769, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e36, 2773, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e37, 2777, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e38, 2781, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e39, 2787, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e3a, 2793, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e3b, 2797, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e3c, 2801, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e3d, 2805, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e3e, 2809, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e3f, 2813, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e40, 2817, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e41, 2821, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e42, 2825, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e43, 2829, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e44, 2833, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e45, 2837, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e46, 2841, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e47, 2845, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e48, 2849, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e49, 2853, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e4a, 2857, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e4b, 2861, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e4c, 2865, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e4d, 2871, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e4e, 2877, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e4f, 2883, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e50, 2889, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e51, 2895, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e52, 2901, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e53, 2907, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e54, 2913, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e55, 2917, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e56, 2921, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e57, 2925, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e58, 2929, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e59, 2933, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e5a, 2937, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e5b, 2941, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e5c, 2945, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e5d, 2951, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e5e, 2957, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e5f, 2961, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e60, 2965, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e61, 2969, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e62, 2973, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e63, 2977, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e64, 2981, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e65, 2987, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e66, 2993, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e67, 2999, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e68, 3005, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e69, 3011, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e6a, 3017, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e6b, 3021, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e6c, 3025, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e6d, 3029, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e6e, 3033, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e6f, 3037, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e70, 3041, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e71, 3045, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e72, 3049, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e73, 3053, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e74, 3057, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e75, 3061, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e76, 3065, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e77, 3069, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e78, 3073, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e79, 3079, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e7a, 3085, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e7b, 3091, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e7c, 3097, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e7d, 3101, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e7e, 3105, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e7f, 3109, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e80, 3113, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e81, 3117, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e82, 3121, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e83, 3125, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e84, 3129, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e85, 3133, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e86, 3137, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e87, 3141, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e88, 3145, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e89, 3149, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e8a, 3153, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e8b, 3157, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e8c, 3161, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e8d, 3165, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e8e, 3169, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e8f, 3173, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e90, 3177, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e91, 3181, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e92, 3185, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e93, 3189, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e94, 3193, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e95, 3197, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e96, 3201, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e97, 3205, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e98, 3209, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e99, 3213, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1e9a, G_UNICODE_NOT_PRESENT_OFFSET, 3217 },
+  { 0x1e9b, 3221, 2969 },
+  { 0x1ea0, 3226, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ea1, 3230, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ea2, 3234, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ea3, 3238, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ea4, 3242, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ea5, 3248, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ea6, 3254, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ea7, 3260, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ea8, 3266, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ea9, 3272, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eaa, 3278, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eab, 3284, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eac, 3290, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ead, 3296, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eae, 3302, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eaf, 3308, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eb0, 3314, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eb1, 3320, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eb2, 3326, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eb3, 3332, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eb4, 3338, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eb5, 3344, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eb6, 3350, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eb7, 3356, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eb8, 3362, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eb9, 3366, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eba, 3370, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ebb, 3374, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ebc, 3378, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ebd, 3382, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ebe, 3386, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ebf, 3392, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ec0, 3398, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ec1, 3404, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ec2, 3410, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ec3, 3416, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ec4, 3422, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ec5, 3428, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ec6, 3434, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ec7, 3440, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ec8, 3446, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ec9, 3450, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eca, 3454, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ecb, 3458, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ecc, 3462, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ecd, 3466, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ece, 3470, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ecf, 3474, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ed0, 3478, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ed1, 3484, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ed2, 3490, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ed3, 3496, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ed4, 3502, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ed5, 3508, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ed6, 3514, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ed7, 3520, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ed8, 3526, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ed9, 3532, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eda, 3538, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1edb, 3544, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1edc, 3550, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1edd, 3556, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ede, 3562, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1edf, 3568, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ee0, 3574, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ee1, 3580, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ee2, 3586, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ee3, 3592, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ee4, 3598, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ee5, 3602, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ee6, 3606, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ee7, 3610, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ee8, 3614, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ee9, 3620, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eea, 3626, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eeb, 3632, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eec, 3638, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eed, 3644, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eee, 3650, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1eef, 3656, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ef0, 3662, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ef1, 3668, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ef2, 3674, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ef3, 3678, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ef4, 3682, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ef5, 3686, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ef6, 3690, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ef7, 3694, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ef8, 3698, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ef9, 3702, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f00, 3706, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f01, 3711, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f02, 3716, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f03, 3723, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f04, 3730, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f05, 3737, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f06, 3744, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f07, 3751, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f08, 3758, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f09, 3763, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f0a, 3768, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f0b, 3775, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f0c, 3782, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f0d, 3789, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f0e, 3796, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f0f, 3803, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f10, 3810, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f11, 3815, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f12, 3820, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f13, 3827, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f14, 3834, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f15, 3841, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f18, 3848, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f19, 3853, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f1a, 3858, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f1b, 3865, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f1c, 3872, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f1d, 3879, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f20, 3886, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f21, 3891, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f22, 3896, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f23, 3903, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f24, 3910, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f25, 3917, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f26, 3924, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f27, 3931, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f28, 3938, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f29, 3943, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f2a, 3948, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f2b, 3955, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f2c, 3962, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f2d, 3969, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f2e, 3976, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f2f, 3983, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f30, 3990, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f31, 3995, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f32, 4000, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f33, 4007, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f34, 4014, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f35, 4021, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f36, 4028, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f37, 4035, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f38, 4042, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f39, 4047, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f3a, 4052, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f3b, 4059, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f3c, 4066, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f3d, 4073, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f3e, 4080, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f3f, 4087, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f40, 4094, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f41, 4099, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f42, 4104, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f43, 4111, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f44, 4118, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f45, 4125, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f48, 4132, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f49, 4137, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f4a, 4142, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f4b, 4149, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f4c, 4156, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f4d, 4163, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f50, 4170, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f51, 4175, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f52, 4180, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f53, 4187, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f54, 4194, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f55, 4201, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f56, 4208, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f57, 4215, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f59, 4222, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f5b, 4227, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f5d, 4234, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f5f, 4241, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f60, 4248, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f61, 4253, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f62, 4258, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f63, 4265, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f64, 4272, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f65, 4279, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f66, 4286, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f67, 4293, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f68, 4300, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f69, 4305, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f6a, 4310, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f6b, 4317, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f6c, 4324, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f6d, 4331, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f6e, 4338, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f6f, 4345, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f70, 4352, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f71, 1316, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f72, 4357, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f73, 1321, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f74, 4362, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f75, 1326, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f76, 4367, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f77, 1331, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f78, 4372, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f79, 1353, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f7a, 4377, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f7b, 1358, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f7c, 4382, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f7d, 1363, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f80, 4387, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f81, 4394, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f82, 4401, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f83, 4410, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f84, 4419, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f85, 4428, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f86, 4437, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f87, 4446, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f88, 4455, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f89, 4462, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f8a, 4469, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f8b, 4478, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f8c, 4487, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f8d, 4496, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f8e, 4505, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f8f, 4514, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f90, 4523, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f91, 4530, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f92, 4537, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f93, 4546, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f94, 4555, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f95, 4564, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f96, 4573, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f97, 4582, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f98, 4591, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f99, 4598, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f9a, 4605, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f9b, 4614, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f9c, 4623, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f9d, 4632, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f9e, 4641, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1f9f, 4650, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fa0, 4659, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fa1, 4666, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fa2, 4673, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fa3, 4682, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fa4, 4691, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fa5, 4700, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fa6, 4709, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fa7, 4718, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fa8, 4727, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fa9, 4734, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1faa, 4741, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fab, 4750, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fac, 4759, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fad, 4768, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fae, 4777, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1faf, 4786, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fb0, 4795, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fb1, 4800, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fb2, 4805, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fb3, 4812, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fb4, 4817, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fb6, 4824, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fb7, 4829, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fb8, 4836, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fb9, 4841, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fba, 4846, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fbb, 1261, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fbc, 4851, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fbd, G_UNICODE_NOT_PRESENT_OFFSET, 4856 },
+  { 0x1fbe, 4860, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fbf, G_UNICODE_NOT_PRESENT_OFFSET, 4856 },
+  { 0x1fc0, G_UNICODE_NOT_PRESENT_OFFSET, 4863 },
+  { 0x1fc1, 4867, 4872 },
+  { 0x1fc2, 4878, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fc3, 4885, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fc4, 4890, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fc6, 4897, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fc7, 4902, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fc8, 4909, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fc9, 1269, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fca, 4914, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fcb, 1274, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fcc, 4919, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fcd, 4924, 4930 },
+  { 0x1fce, 4936, 4942 },
+  { 0x1fcf, 4948, 4954 },
+  { 0x1fd0, 4960, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fd1, 4965, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fd2, 4970, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fd3, 1299, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fd6, 4977, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fd7, 4982, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fd8, 4989, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fd9, 4994, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fda, 4999, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fdb, 1279, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fdd, 5004, 5010 },
+  { 0x1fde, 5016, 5022 },
+  { 0x1fdf, 5028, 5034 },
+  { 0x1fe0, 5040, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fe1, 5045, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fe2, 5050, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fe3, 1336, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fe4, 5057, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fe5, 5062, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fe6, 5067, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fe7, 5072, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fe8, 5079, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fe9, 5084, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fea, 5089, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1feb, 1289, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fec, 5094, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1fed, 5099, 5104 },
+  { 0x1fee, 1250, 1255 },
+  { 0x1fef, 5110, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ff2, 5112, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ff3, 5119, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ff4, 5124, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ff6, 5131, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ff7, 5136, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ff8, 5143, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ff9, 1284, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ffa, 5148, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ffb, 1294, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ffc, 5153, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1ffd, 5158, 16 },
+  { 0x1ffe, G_UNICODE_NOT_PRESENT_OFFSET, 5161 },
+  { 0x2000, 5165, 0 },
+  { 0x2001, 5169, 0 },
+  { 0x2002, G_UNICODE_NOT_PRESENT_OFFSET, 0 },
+  { 0x2003, G_UNICODE_NOT_PRESENT_OFFSET, 0 },
+  { 0x2004, G_UNICODE_NOT_PRESENT_OFFSET, 0 },
+  { 0x2005, G_UNICODE_NOT_PRESENT_OFFSET, 0 },
+  { 0x2006, G_UNICODE_NOT_PRESENT_OFFSET, 0 },
+  { 0x2007, G_UNICODE_NOT_PRESENT_OFFSET, 0 },
+  { 0x2008, G_UNICODE_NOT_PRESENT_OFFSET, 0 },
+  { 0x2009, G_UNICODE_NOT_PRESENT_OFFSET, 0 },
+  { 0x200a, G_UNICODE_NOT_PRESENT_OFFSET, 0 },
+  { 0x2011, G_UNICODE_NOT_PRESENT_OFFSET, 5173 },
+  { 0x2017, G_UNICODE_NOT_PRESENT_OFFSET, 5177 },
+  { 0x2024, G_UNICODE_NOT_PRESENT_OFFSET, 5181 },
+  { 0x2025, G_UNICODE_NOT_PRESENT_OFFSET, 5183 },
+  { 0x2026, G_UNICODE_NOT_PRESENT_OFFSET, 5186 },
+  { 0x202f, G_UNICODE_NOT_PRESENT_OFFSET, 0 },
+  { 0x2033, G_UNICODE_NOT_PRESENT_OFFSET, 5190 },
+  { 0x2034, G_UNICODE_NOT_PRESENT_OFFSET, 5197 },
+  { 0x2036, G_UNICODE_NOT_PRESENT_OFFSET, 5207 },
+  { 0x2037, G_UNICODE_NOT_PRESENT_OFFSET, 5214 },
+  { 0x203c, G_UNICODE_NOT_PRESENT_OFFSET, 5224 },
+  { 0x203e, G_UNICODE_NOT_PRESENT_OFFSET, 5227 },
+  { 0x2047, G_UNICODE_NOT_PRESENT_OFFSET, 5231 },
+  { 0x2048, G_UNICODE_NOT_PRESENT_OFFSET, 5234 },
+  { 0x2049, G_UNICODE_NOT_PRESENT_OFFSET, 5237 },
+  { 0x2057, G_UNICODE_NOT_PRESENT_OFFSET, 5240 },
+  { 0x205f, G_UNICODE_NOT_PRESENT_OFFSET, 0 },
+  { 0x2070, G_UNICODE_NOT_PRESENT_OFFSET, 5253 },
+  { 0x2071, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x2074, G_UNICODE_NOT_PRESENT_OFFSET, 5255 },
+  { 0x2075, G_UNICODE_NOT_PRESENT_OFFSET, 5257 },
+  { 0x2076, G_UNICODE_NOT_PRESENT_OFFSET, 5259 },
+  { 0x2077, G_UNICODE_NOT_PRESENT_OFFSET, 5261 },
+  { 0x2078, G_UNICODE_NOT_PRESENT_OFFSET, 5263 },
+  { 0x2079, G_UNICODE_NOT_PRESENT_OFFSET, 5265 },
+  { 0x207a, G_UNICODE_NOT_PRESENT_OFFSET, 5267 },
+  { 0x207b, G_UNICODE_NOT_PRESENT_OFFSET, 5269 },
+  { 0x207c, G_UNICODE_NOT_PRESENT_OFFSET, 5273 },
+  { 0x207d, G_UNICODE_NOT_PRESENT_OFFSET, 5275 },
+  { 0x207e, G_UNICODE_NOT_PRESENT_OFFSET, 5277 },
+  { 0x207f, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x2080, G_UNICODE_NOT_PRESENT_OFFSET, 5253 },
+  { 0x2081, G_UNICODE_NOT_PRESENT_OFFSET, 27 },
+  { 0x2082, G_UNICODE_NOT_PRESENT_OFFSET, 12 },
+  { 0x2083, G_UNICODE_NOT_PRESENT_OFFSET, 14 },
+  { 0x2084, G_UNICODE_NOT_PRESENT_OFFSET, 5255 },
+  { 0x2085, G_UNICODE_NOT_PRESENT_OFFSET, 5257 },
+  { 0x2086, G_UNICODE_NOT_PRESENT_OFFSET, 5259 },
+  { 0x2087, G_UNICODE_NOT_PRESENT_OFFSET, 5261 },
+  { 0x2088, G_UNICODE_NOT_PRESENT_OFFSET, 5263 },
+  { 0x2089, G_UNICODE_NOT_PRESENT_OFFSET, 5265 },
+  { 0x208a, G_UNICODE_NOT_PRESENT_OFFSET, 5267 },
+  { 0x208b, G_UNICODE_NOT_PRESENT_OFFSET, 5269 },
+  { 0x208c, G_UNICODE_NOT_PRESENT_OFFSET, 5273 },
+  { 0x208d, G_UNICODE_NOT_PRESENT_OFFSET, 5275 },
+  { 0x208e, G_UNICODE_NOT_PRESENT_OFFSET, 5277 },
+  { 0x2090, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x2091, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x2092, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x2093, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x2094, G_UNICODE_NOT_PRESENT_OFFSET, 2370 },
+  { 0x20a8, G_UNICODE_NOT_PRESENT_OFFSET, 5281 },
+  { 0x2100, G_UNICODE_NOT_PRESENT_OFFSET, 5284 },
+  { 0x2101, G_UNICODE_NOT_PRESENT_OFFSET, 5288 },
+  { 0x2102, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x2103, G_UNICODE_NOT_PRESENT_OFFSET, 5294 },
+  { 0x2105, G_UNICODE_NOT_PRESENT_OFFSET, 5298 },
+  { 0x2106, G_UNICODE_NOT_PRESENT_OFFSET, 5302 },
+  { 0x2107, G_UNICODE_NOT_PRESENT_OFFSET, 5306 },
+  { 0x2109, G_UNICODE_NOT_PRESENT_OFFSET, 5309 },
+  { 0x210a, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x210b, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x210c, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x210d, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x210e, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x210f, G_UNICODE_NOT_PRESENT_OFFSET, 5313 },
+  { 0x2110, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x2111, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x2112, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x2113, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x2115, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x2116, G_UNICODE_NOT_PRESENT_OFFSET, 5316 },
+  { 0x2119, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x211a, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x211b, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x211c, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x211d, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x2120, G_UNICODE_NOT_PRESENT_OFFSET, 5321 },
+  { 0x2121, G_UNICODE_NOT_PRESENT_OFFSET, 5324 },
+  { 0x2122, G_UNICODE_NOT_PRESENT_OFFSET, 5328 },
+  { 0x2124, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x2126, 5333, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2128, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x212a, 2331, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x212b, 69, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x212c, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x212d, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x212f, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x2130, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x2131, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x2133, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x2134, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x2135, G_UNICODE_NOT_PRESENT_OFFSET, 5338 },
+  { 0x2136, G_UNICODE_NOT_PRESENT_OFFSET, 5341 },
+  { 0x2137, G_UNICODE_NOT_PRESENT_OFFSET, 5344 },
+  { 0x2138, G_UNICODE_NOT_PRESENT_OFFSET, 5347 },
+  { 0x2139, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x213b, G_UNICODE_NOT_PRESENT_OFFSET, 5350 },
+  { 0x213c, G_UNICODE_NOT_PRESENT_OFFSET, 1390 },
+  { 0x213d, G_UNICODE_NOT_PRESENT_OFFSET, 2418 },
+  { 0x213e, G_UNICODE_NOT_PRESENT_OFFSET, 5354 },
+  { 0x213f, G_UNICODE_NOT_PRESENT_OFFSET, 5357 },
+  { 0x2140, G_UNICODE_NOT_PRESENT_OFFSET, 5360 },
+  { 0x2145, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x2146, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x2147, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x2148, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x2149, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x2153, G_UNICODE_NOT_PRESENT_OFFSET, 5364 },
+  { 0x2154, G_UNICODE_NOT_PRESENT_OFFSET, 5370 },
+  { 0x2155, G_UNICODE_NOT_PRESENT_OFFSET, 5376 },
+  { 0x2156, G_UNICODE_NOT_PRESENT_OFFSET, 5382 },
+  { 0x2157, G_UNICODE_NOT_PRESENT_OFFSET, 5388 },
+  { 0x2158, G_UNICODE_NOT_PRESENT_OFFSET, 5394 },
+  { 0x2159, G_UNICODE_NOT_PRESENT_OFFSET, 5400 },
+  { 0x215a, G_UNICODE_NOT_PRESENT_OFFSET, 5406 },
+  { 0x215b, G_UNICODE_NOT_PRESENT_OFFSET, 5412 },
+  { 0x215c, G_UNICODE_NOT_PRESENT_OFFSET, 5418 },
+  { 0x215d, G_UNICODE_NOT_PRESENT_OFFSET, 5424 },
+  { 0x215e, G_UNICODE_NOT_PRESENT_OFFSET, 5430 },
+  { 0x215f, G_UNICODE_NOT_PRESENT_OFFSET, 5436 },
+  { 0x2160, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x2161, G_UNICODE_NOT_PRESENT_OFFSET, 5441 },
+  { 0x2162, G_UNICODE_NOT_PRESENT_OFFSET, 5444 },
+  { 0x2163, G_UNICODE_NOT_PRESENT_OFFSET, 5448 },
+  { 0x2164, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x2165, G_UNICODE_NOT_PRESENT_OFFSET, 5453 },
+  { 0x2166, G_UNICODE_NOT_PRESENT_OFFSET, 5456 },
+  { 0x2167, G_UNICODE_NOT_PRESENT_OFFSET, 5460 },
+  { 0x2168, G_UNICODE_NOT_PRESENT_OFFSET, 5465 },
+  { 0x2169, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x216a, G_UNICODE_NOT_PRESENT_OFFSET, 5470 },
+  { 0x216b, G_UNICODE_NOT_PRESENT_OFFSET, 5473 },
+  { 0x216c, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x216d, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x216e, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x216f, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x2170, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x2171, G_UNICODE_NOT_PRESENT_OFFSET, 5477 },
+  { 0x2172, G_UNICODE_NOT_PRESENT_OFFSET, 5480 },
+  { 0x2173, G_UNICODE_NOT_PRESENT_OFFSET, 5484 },
+  { 0x2174, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x2175, G_UNICODE_NOT_PRESENT_OFFSET, 5487 },
+  { 0x2176, G_UNICODE_NOT_PRESENT_OFFSET, 5490 },
+  { 0x2177, G_UNICODE_NOT_PRESENT_OFFSET, 5494 },
+  { 0x2178, G_UNICODE_NOT_PRESENT_OFFSET, 5499 },
+  { 0x2179, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x217a, G_UNICODE_NOT_PRESENT_OFFSET, 5502 },
+  { 0x217b, G_UNICODE_NOT_PRESENT_OFFSET, 5505 },
+  { 0x217c, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x217d, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x217e, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x217f, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x219a, 5509, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x219b, 5515, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x21ae, 5521, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x21cd, 5527, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x21ce, 5533, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x21cf, 5539, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2204, 5545, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2209, 5551, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x220c, 5557, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2224, 5563, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2226, 5569, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x222c, G_UNICODE_NOT_PRESENT_OFFSET, 5575 },
+  { 0x222d, G_UNICODE_NOT_PRESENT_OFFSET, 5582 },
+  { 0x222f, G_UNICODE_NOT_PRESENT_OFFSET, 5592 },
+  { 0x2230, G_UNICODE_NOT_PRESENT_OFFSET, 5599 },
+  { 0x2241, 5609, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2244, 5615, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2247, 5621, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2249, 5627, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2260, 5633, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2262, 5637, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x226d, 5643, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x226e, 5649, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x226f, 5653, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2270, 5657, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2271, 5663, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2274, 5669, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2275, 5675, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2278, 5681, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2279, 5687, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2280, 5693, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2281, 5699, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2284, 5705, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2285, 5711, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2288, 5717, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2289, 5723, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x22ac, 5729, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x22ad, 5735, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x22ae, 5741, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x22af, 5747, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x22e0, 5753, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x22e1, 5759, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x22e2, 5765, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x22e3, 5771, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x22ea, 5777, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x22eb, 5783, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x22ec, 5789, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x22ed, 5795, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2329, 5801, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x232a, 5805, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2460, G_UNICODE_NOT_PRESENT_OFFSET, 27 },
+  { 0x2461, G_UNICODE_NOT_PRESENT_OFFSET, 12 },
+  { 0x2462, G_UNICODE_NOT_PRESENT_OFFSET, 14 },
+  { 0x2463, G_UNICODE_NOT_PRESENT_OFFSET, 5255 },
+  { 0x2464, G_UNICODE_NOT_PRESENT_OFFSET, 5257 },
+  { 0x2465, G_UNICODE_NOT_PRESENT_OFFSET, 5259 },
+  { 0x2466, G_UNICODE_NOT_PRESENT_OFFSET, 5261 },
+  { 0x2467, G_UNICODE_NOT_PRESENT_OFFSET, 5263 },
+  { 0x2468, G_UNICODE_NOT_PRESENT_OFFSET, 5265 },
+  { 0x2469, G_UNICODE_NOT_PRESENT_OFFSET, 5809 },
+  { 0x246a, G_UNICODE_NOT_PRESENT_OFFSET, 5812 },
+  { 0x246b, G_UNICODE_NOT_PRESENT_OFFSET, 5815 },
+  { 0x246c, G_UNICODE_NOT_PRESENT_OFFSET, 5818 },
+  { 0x246d, G_UNICODE_NOT_PRESENT_OFFSET, 5821 },
+  { 0x246e, G_UNICODE_NOT_PRESENT_OFFSET, 5824 },
+  { 0x246f, G_UNICODE_NOT_PRESENT_OFFSET, 5827 },
+  { 0x2470, G_UNICODE_NOT_PRESENT_OFFSET, 5830 },
+  { 0x2471, G_UNICODE_NOT_PRESENT_OFFSET, 5833 },
+  { 0x2472, G_UNICODE_NOT_PRESENT_OFFSET, 5836 },
+  { 0x2473, G_UNICODE_NOT_PRESENT_OFFSET, 5839 },
+  { 0x2474, G_UNICODE_NOT_PRESENT_OFFSET, 5842 },
+  { 0x2475, G_UNICODE_NOT_PRESENT_OFFSET, 5846 },
+  { 0x2476, G_UNICODE_NOT_PRESENT_OFFSET, 5850 },
+  { 0x2477, G_UNICODE_NOT_PRESENT_OFFSET, 5854 },
+  { 0x2478, G_UNICODE_NOT_PRESENT_OFFSET, 5858 },
+  { 0x2479, G_UNICODE_NOT_PRESENT_OFFSET, 5862 },
+  { 0x247a, G_UNICODE_NOT_PRESENT_OFFSET, 5866 },
+  { 0x247b, G_UNICODE_NOT_PRESENT_OFFSET, 5870 },
+  { 0x247c, G_UNICODE_NOT_PRESENT_OFFSET, 5874 },
+  { 0x247d, G_UNICODE_NOT_PRESENT_OFFSET, 5878 },
+  { 0x247e, G_UNICODE_NOT_PRESENT_OFFSET, 5883 },
+  { 0x247f, G_UNICODE_NOT_PRESENT_OFFSET, 5888 },
+  { 0x2480, G_UNICODE_NOT_PRESENT_OFFSET, 5893 },
+  { 0x2481, G_UNICODE_NOT_PRESENT_OFFSET, 5898 },
+  { 0x2482, G_UNICODE_NOT_PRESENT_OFFSET, 5903 },
+  { 0x2483, G_UNICODE_NOT_PRESENT_OFFSET, 5908 },
+  { 0x2484, G_UNICODE_NOT_PRESENT_OFFSET, 5913 },
+  { 0x2485, G_UNICODE_NOT_PRESENT_OFFSET, 5918 },
+  { 0x2486, G_UNICODE_NOT_PRESENT_OFFSET, 5923 },
+  { 0x2487, G_UNICODE_NOT_PRESENT_OFFSET, 5928 },
+  { 0x2488, G_UNICODE_NOT_PRESENT_OFFSET, 5933 },
+  { 0x2489, G_UNICODE_NOT_PRESENT_OFFSET, 5936 },
+  { 0x248a, G_UNICODE_NOT_PRESENT_OFFSET, 5939 },
+  { 0x248b, G_UNICODE_NOT_PRESENT_OFFSET, 5942 },
+  { 0x248c, G_UNICODE_NOT_PRESENT_OFFSET, 5945 },
+  { 0x248d, G_UNICODE_NOT_PRESENT_OFFSET, 5948 },
+  { 0x248e, G_UNICODE_NOT_PRESENT_OFFSET, 5951 },
+  { 0x248f, G_UNICODE_NOT_PRESENT_OFFSET, 5954 },
+  { 0x2490, G_UNICODE_NOT_PRESENT_OFFSET, 5957 },
+  { 0x2491, G_UNICODE_NOT_PRESENT_OFFSET, 5960 },
+  { 0x2492, G_UNICODE_NOT_PRESENT_OFFSET, 5964 },
+  { 0x2493, G_UNICODE_NOT_PRESENT_OFFSET, 5968 },
+  { 0x2494, G_UNICODE_NOT_PRESENT_OFFSET, 5972 },
+  { 0x2495, G_UNICODE_NOT_PRESENT_OFFSET, 5976 },
+  { 0x2496, G_UNICODE_NOT_PRESENT_OFFSET, 5980 },
+  { 0x2497, G_UNICODE_NOT_PRESENT_OFFSET, 5984 },
+  { 0x2498, G_UNICODE_NOT_PRESENT_OFFSET, 5988 },
+  { 0x2499, G_UNICODE_NOT_PRESENT_OFFSET, 5992 },
+  { 0x249a, G_UNICODE_NOT_PRESENT_OFFSET, 5996 },
+  { 0x249b, G_UNICODE_NOT_PRESENT_OFFSET, 6000 },
+  { 0x249c, G_UNICODE_NOT_PRESENT_OFFSET, 6004 },
+  { 0x249d, G_UNICODE_NOT_PRESENT_OFFSET, 6008 },
+  { 0x249e, G_UNICODE_NOT_PRESENT_OFFSET, 6012 },
+  { 0x249f, G_UNICODE_NOT_PRESENT_OFFSET, 6016 },
+  { 0x24a0, G_UNICODE_NOT_PRESENT_OFFSET, 6020 },
+  { 0x24a1, G_UNICODE_NOT_PRESENT_OFFSET, 6024 },
+  { 0x24a2, G_UNICODE_NOT_PRESENT_OFFSET, 6028 },
+  { 0x24a3, G_UNICODE_NOT_PRESENT_OFFSET, 6032 },
+  { 0x24a4, G_UNICODE_NOT_PRESENT_OFFSET, 6036 },
+  { 0x24a5, G_UNICODE_NOT_PRESENT_OFFSET, 6040 },
+  { 0x24a6, G_UNICODE_NOT_PRESENT_OFFSET, 6044 },
+  { 0x24a7, G_UNICODE_NOT_PRESENT_OFFSET, 6048 },
+  { 0x24a8, G_UNICODE_NOT_PRESENT_OFFSET, 6052 },
+  { 0x24a9, G_UNICODE_NOT_PRESENT_OFFSET, 6056 },
+  { 0x24aa, G_UNICODE_NOT_PRESENT_OFFSET, 6060 },
+  { 0x24ab, G_UNICODE_NOT_PRESENT_OFFSET, 6064 },
+  { 0x24ac, G_UNICODE_NOT_PRESENT_OFFSET, 6068 },
+  { 0x24ad, G_UNICODE_NOT_PRESENT_OFFSET, 6072 },
+  { 0x24ae, G_UNICODE_NOT_PRESENT_OFFSET, 6076 },
+  { 0x24af, G_UNICODE_NOT_PRESENT_OFFSET, 6080 },
+  { 0x24b0, G_UNICODE_NOT_PRESENT_OFFSET, 6084 },
+  { 0x24b1, G_UNICODE_NOT_PRESENT_OFFSET, 6088 },
+  { 0x24b2, G_UNICODE_NOT_PRESENT_OFFSET, 6092 },
+  { 0x24b3, G_UNICODE_NOT_PRESENT_OFFSET, 6096 },
+  { 0x24b4, G_UNICODE_NOT_PRESENT_OFFSET, 6100 },
+  { 0x24b5, G_UNICODE_NOT_PRESENT_OFFSET, 6104 },
+  { 0x24b6, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x24b7, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x24b8, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x24b9, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x24ba, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x24bb, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x24bc, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x24bd, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x24be, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x24bf, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x24c0, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x24c1, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x24c2, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x24c3, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x24c4, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x24c5, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x24c6, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x24c7, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x24c8, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x24c9, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x24ca, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x24cb, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x24cc, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x24cd, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x24ce, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x24cf, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x24d0, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x24d1, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x24d2, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x24d3, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x24d4, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x24d5, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x24d6, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x24d7, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x24d8, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x24d9, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x24da, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x24db, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x24dc, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x24dd, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x24de, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x24df, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x24e0, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x24e1, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x24e2, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x24e3, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x24e4, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x24e5, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x24e6, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x24e7, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x24e8, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x24e9, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x24ea, G_UNICODE_NOT_PRESENT_OFFSET, 5253 },
+  { 0x2a0c, G_UNICODE_NOT_PRESENT_OFFSET, 6114 },
+  { 0x2a74, G_UNICODE_NOT_PRESENT_OFFSET, 6127 },
+  { 0x2a75, G_UNICODE_NOT_PRESENT_OFFSET, 6131 },
+  { 0x2a76, G_UNICODE_NOT_PRESENT_OFFSET, 6134 },
+  { 0x2adc, 6138, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2d6f, G_UNICODE_NOT_PRESENT_OFFSET, 6144 },
+  { 0x2e9f, G_UNICODE_NOT_PRESENT_OFFSET, 6148 },
+  { 0x2ef3, G_UNICODE_NOT_PRESENT_OFFSET, 6152 },
+  { 0x2f00, G_UNICODE_NOT_PRESENT_OFFSET, 6156 },
+  { 0x2f01, G_UNICODE_NOT_PRESENT_OFFSET, 6160 },
+  { 0x2f02, G_UNICODE_NOT_PRESENT_OFFSET, 6164 },
+  { 0x2f03, G_UNICODE_NOT_PRESENT_OFFSET, 6168 },
+  { 0x2f04, G_UNICODE_NOT_PRESENT_OFFSET, 6172 },
+  { 0x2f05, G_UNICODE_NOT_PRESENT_OFFSET, 6176 },
+  { 0x2f06, G_UNICODE_NOT_PRESENT_OFFSET, 6180 },
+  { 0x2f07, G_UNICODE_NOT_PRESENT_OFFSET, 6184 },
+  { 0x2f08, G_UNICODE_NOT_PRESENT_OFFSET, 6188 },
+  { 0x2f09, G_UNICODE_NOT_PRESENT_OFFSET, 6192 },
+  { 0x2f0a, G_UNICODE_NOT_PRESENT_OFFSET, 6196 },
+  { 0x2f0b, G_UNICODE_NOT_PRESENT_OFFSET, 6200 },
+  { 0x2f0c, G_UNICODE_NOT_PRESENT_OFFSET, 6204 },
+  { 0x2f0d, G_UNICODE_NOT_PRESENT_OFFSET, 6208 },
+  { 0x2f0e, G_UNICODE_NOT_PRESENT_OFFSET, 6212 },
+  { 0x2f0f, G_UNICODE_NOT_PRESENT_OFFSET, 6216 },
+  { 0x2f10, G_UNICODE_NOT_PRESENT_OFFSET, 6220 },
+  { 0x2f11, G_UNICODE_NOT_PRESENT_OFFSET, 6224 },
+  { 0x2f12, G_UNICODE_NOT_PRESENT_OFFSET, 6228 },
+  { 0x2f13, G_UNICODE_NOT_PRESENT_OFFSET, 6232 },
+  { 0x2f14, G_UNICODE_NOT_PRESENT_OFFSET, 6236 },
+  { 0x2f15, G_UNICODE_NOT_PRESENT_OFFSET, 6240 },
+  { 0x2f16, G_UNICODE_NOT_PRESENT_OFFSET, 6244 },
+  { 0x2f17, G_UNICODE_NOT_PRESENT_OFFSET, 6248 },
+  { 0x2f18, G_UNICODE_NOT_PRESENT_OFFSET, 6252 },
+  { 0x2f19, G_UNICODE_NOT_PRESENT_OFFSET, 6256 },
+  { 0x2f1a, G_UNICODE_NOT_PRESENT_OFFSET, 6260 },
+  { 0x2f1b, G_UNICODE_NOT_PRESENT_OFFSET, 6264 },
+  { 0x2f1c, G_UNICODE_NOT_PRESENT_OFFSET, 6268 },
+  { 0x2f1d, G_UNICODE_NOT_PRESENT_OFFSET, 6272 },
+  { 0x2f1e, G_UNICODE_NOT_PRESENT_OFFSET, 6276 },
+  { 0x2f1f, G_UNICODE_NOT_PRESENT_OFFSET, 6280 },
+  { 0x2f20, G_UNICODE_NOT_PRESENT_OFFSET, 6284 },
+  { 0x2f21, G_UNICODE_NOT_PRESENT_OFFSET, 6288 },
+  { 0x2f22, G_UNICODE_NOT_PRESENT_OFFSET, 6292 },
+  { 0x2f23, G_UNICODE_NOT_PRESENT_OFFSET, 6296 },
+  { 0x2f24, G_UNICODE_NOT_PRESENT_OFFSET, 6300 },
+  { 0x2f25, G_UNICODE_NOT_PRESENT_OFFSET, 6304 },
+  { 0x2f26, G_UNICODE_NOT_PRESENT_OFFSET, 6308 },
+  { 0x2f27, G_UNICODE_NOT_PRESENT_OFFSET, 6312 },
+  { 0x2f28, G_UNICODE_NOT_PRESENT_OFFSET, 6316 },
+  { 0x2f29, G_UNICODE_NOT_PRESENT_OFFSET, 6320 },
+  { 0x2f2a, G_UNICODE_NOT_PRESENT_OFFSET, 6324 },
+  { 0x2f2b, G_UNICODE_NOT_PRESENT_OFFSET, 6328 },
+  { 0x2f2c, G_UNICODE_NOT_PRESENT_OFFSET, 6332 },
+  { 0x2f2d, G_UNICODE_NOT_PRESENT_OFFSET, 6336 },
+  { 0x2f2e, G_UNICODE_NOT_PRESENT_OFFSET, 6340 },
+  { 0x2f2f, G_UNICODE_NOT_PRESENT_OFFSET, 6344 },
+  { 0x2f30, G_UNICODE_NOT_PRESENT_OFFSET, 6348 },
+  { 0x2f31, G_UNICODE_NOT_PRESENT_OFFSET, 6352 },
+  { 0x2f32, G_UNICODE_NOT_PRESENT_OFFSET, 6356 },
+  { 0x2f33, G_UNICODE_NOT_PRESENT_OFFSET, 6360 },
+  { 0x2f34, G_UNICODE_NOT_PRESENT_OFFSET, 6364 },
+  { 0x2f35, G_UNICODE_NOT_PRESENT_OFFSET, 6368 },
+  { 0x2f36, G_UNICODE_NOT_PRESENT_OFFSET, 6372 },
+  { 0x2f37, G_UNICODE_NOT_PRESENT_OFFSET, 6376 },
+  { 0x2f38, G_UNICODE_NOT_PRESENT_OFFSET, 6380 },
+  { 0x2f39, G_UNICODE_NOT_PRESENT_OFFSET, 6384 },
+  { 0x2f3a, G_UNICODE_NOT_PRESENT_OFFSET, 6388 },
+  { 0x2f3b, G_UNICODE_NOT_PRESENT_OFFSET, 6392 },
+  { 0x2f3c, G_UNICODE_NOT_PRESENT_OFFSET, 6396 },
+  { 0x2f3d, G_UNICODE_NOT_PRESENT_OFFSET, 6400 },
+  { 0x2f3e, G_UNICODE_NOT_PRESENT_OFFSET, 6404 },
+  { 0x2f3f, G_UNICODE_NOT_PRESENT_OFFSET, 6408 },
+  { 0x2f40, G_UNICODE_NOT_PRESENT_OFFSET, 6412 },
+  { 0x2f41, G_UNICODE_NOT_PRESENT_OFFSET, 6416 },
+  { 0x2f42, G_UNICODE_NOT_PRESENT_OFFSET, 6420 },
+  { 0x2f43, G_UNICODE_NOT_PRESENT_OFFSET, 6424 },
+  { 0x2f44, G_UNICODE_NOT_PRESENT_OFFSET, 6428 },
+  { 0x2f45, G_UNICODE_NOT_PRESENT_OFFSET, 6432 },
+  { 0x2f46, G_UNICODE_NOT_PRESENT_OFFSET, 6436 },
+  { 0x2f47, G_UNICODE_NOT_PRESENT_OFFSET, 6440 },
+  { 0x2f48, G_UNICODE_NOT_PRESENT_OFFSET, 6444 },
+  { 0x2f49, G_UNICODE_NOT_PRESENT_OFFSET, 6448 },
+  { 0x2f4a, G_UNICODE_NOT_PRESENT_OFFSET, 6452 },
+  { 0x2f4b, G_UNICODE_NOT_PRESENT_OFFSET, 6456 },
+  { 0x2f4c, G_UNICODE_NOT_PRESENT_OFFSET, 6460 },
+  { 0x2f4d, G_UNICODE_NOT_PRESENT_OFFSET, 6464 },
+  { 0x2f4e, G_UNICODE_NOT_PRESENT_OFFSET, 6468 },
+  { 0x2f4f, G_UNICODE_NOT_PRESENT_OFFSET, 6472 },
+  { 0x2f50, G_UNICODE_NOT_PRESENT_OFFSET, 6476 },
+  { 0x2f51, G_UNICODE_NOT_PRESENT_OFFSET, 6480 },
+  { 0x2f52, G_UNICODE_NOT_PRESENT_OFFSET, 6484 },
+  { 0x2f53, G_UNICODE_NOT_PRESENT_OFFSET, 6488 },
+  { 0x2f54, G_UNICODE_NOT_PRESENT_OFFSET, 6492 },
+  { 0x2f55, G_UNICODE_NOT_PRESENT_OFFSET, 6496 },
+  { 0x2f56, G_UNICODE_NOT_PRESENT_OFFSET, 6500 },
+  { 0x2f57, G_UNICODE_NOT_PRESENT_OFFSET, 6504 },
+  { 0x2f58, G_UNICODE_NOT_PRESENT_OFFSET, 6508 },
+  { 0x2f59, G_UNICODE_NOT_PRESENT_OFFSET, 6512 },
+  { 0x2f5a, G_UNICODE_NOT_PRESENT_OFFSET, 6516 },
+  { 0x2f5b, G_UNICODE_NOT_PRESENT_OFFSET, 6520 },
+  { 0x2f5c, G_UNICODE_NOT_PRESENT_OFFSET, 6524 },
+  { 0x2f5d, G_UNICODE_NOT_PRESENT_OFFSET, 6528 },
+  { 0x2f5e, G_UNICODE_NOT_PRESENT_OFFSET, 6532 },
+  { 0x2f5f, G_UNICODE_NOT_PRESENT_OFFSET, 6536 },
+  { 0x2f60, G_UNICODE_NOT_PRESENT_OFFSET, 6540 },
+  { 0x2f61, G_UNICODE_NOT_PRESENT_OFFSET, 6544 },
+  { 0x2f62, G_UNICODE_NOT_PRESENT_OFFSET, 6548 },
+  { 0x2f63, G_UNICODE_NOT_PRESENT_OFFSET, 6552 },
+  { 0x2f64, G_UNICODE_NOT_PRESENT_OFFSET, 6556 },
+  { 0x2f65, G_UNICODE_NOT_PRESENT_OFFSET, 6560 },
+  { 0x2f66, G_UNICODE_NOT_PRESENT_OFFSET, 6564 },
+  { 0x2f67, G_UNICODE_NOT_PRESENT_OFFSET, 6568 },
+  { 0x2f68, G_UNICODE_NOT_PRESENT_OFFSET, 6572 },
+  { 0x2f69, G_UNICODE_NOT_PRESENT_OFFSET, 6576 },
+  { 0x2f6a, G_UNICODE_NOT_PRESENT_OFFSET, 6580 },
+  { 0x2f6b, G_UNICODE_NOT_PRESENT_OFFSET, 6584 },
+  { 0x2f6c, G_UNICODE_NOT_PRESENT_OFFSET, 6588 },
+  { 0x2f6d, G_UNICODE_NOT_PRESENT_OFFSET, 6592 },
+  { 0x2f6e, G_UNICODE_NOT_PRESENT_OFFSET, 6596 },
+  { 0x2f6f, G_UNICODE_NOT_PRESENT_OFFSET, 6600 },
+  { 0x2f70, G_UNICODE_NOT_PRESENT_OFFSET, 6604 },
+  { 0x2f71, G_UNICODE_NOT_PRESENT_OFFSET, 6608 },
+  { 0x2f72, G_UNICODE_NOT_PRESENT_OFFSET, 6612 },
+  { 0x2f73, G_UNICODE_NOT_PRESENT_OFFSET, 6616 },
+  { 0x2f74, G_UNICODE_NOT_PRESENT_OFFSET, 6620 },
+  { 0x2f75, G_UNICODE_NOT_PRESENT_OFFSET, 6624 },
+  { 0x2f76, G_UNICODE_NOT_PRESENT_OFFSET, 6628 },
+  { 0x2f77, G_UNICODE_NOT_PRESENT_OFFSET, 6632 },
+  { 0x2f78, G_UNICODE_NOT_PRESENT_OFFSET, 6636 },
+  { 0x2f79, G_UNICODE_NOT_PRESENT_OFFSET, 6640 },
+  { 0x2f7a, G_UNICODE_NOT_PRESENT_OFFSET, 6644 },
+  { 0x2f7b, G_UNICODE_NOT_PRESENT_OFFSET, 6648 },
+  { 0x2f7c, G_UNICODE_NOT_PRESENT_OFFSET, 6652 },
+  { 0x2f7d, G_UNICODE_NOT_PRESENT_OFFSET, 6656 },
+  { 0x2f7e, G_UNICODE_NOT_PRESENT_OFFSET, 6660 },
+  { 0x2f7f, G_UNICODE_NOT_PRESENT_OFFSET, 6664 },
+  { 0x2f80, G_UNICODE_NOT_PRESENT_OFFSET, 6668 },
+  { 0x2f81, G_UNICODE_NOT_PRESENT_OFFSET, 6672 },
+  { 0x2f82, G_UNICODE_NOT_PRESENT_OFFSET, 6676 },
+  { 0x2f83, G_UNICODE_NOT_PRESENT_OFFSET, 6680 },
+  { 0x2f84, G_UNICODE_NOT_PRESENT_OFFSET, 6684 },
+  { 0x2f85, G_UNICODE_NOT_PRESENT_OFFSET, 6688 },
+  { 0x2f86, G_UNICODE_NOT_PRESENT_OFFSET, 6692 },
+  { 0x2f87, G_UNICODE_NOT_PRESENT_OFFSET, 6696 },
+  { 0x2f88, G_UNICODE_NOT_PRESENT_OFFSET, 6700 },
+  { 0x2f89, G_UNICODE_NOT_PRESENT_OFFSET, 6704 },
+  { 0x2f8a, G_UNICODE_NOT_PRESENT_OFFSET, 6708 },
+  { 0x2f8b, G_UNICODE_NOT_PRESENT_OFFSET, 6712 },
+  { 0x2f8c, G_UNICODE_NOT_PRESENT_OFFSET, 6716 },
+  { 0x2f8d, G_UNICODE_NOT_PRESENT_OFFSET, 6720 },
+  { 0x2f8e, G_UNICODE_NOT_PRESENT_OFFSET, 6724 },
+  { 0x2f8f, G_UNICODE_NOT_PRESENT_OFFSET, 6728 },
+  { 0x2f90, G_UNICODE_NOT_PRESENT_OFFSET, 6732 },
+  { 0x2f91, G_UNICODE_NOT_PRESENT_OFFSET, 6736 },
+  { 0x2f92, G_UNICODE_NOT_PRESENT_OFFSET, 6740 },
+  { 0x2f93, G_UNICODE_NOT_PRESENT_OFFSET, 6744 },
+  { 0x2f94, G_UNICODE_NOT_PRESENT_OFFSET, 6748 },
+  { 0x2f95, G_UNICODE_NOT_PRESENT_OFFSET, 6752 },
+  { 0x2f96, G_UNICODE_NOT_PRESENT_OFFSET, 6756 },
+  { 0x2f97, G_UNICODE_NOT_PRESENT_OFFSET, 6760 },
+  { 0x2f98, G_UNICODE_NOT_PRESENT_OFFSET, 6764 },
+  { 0x2f99, G_UNICODE_NOT_PRESENT_OFFSET, 6768 },
+  { 0x2f9a, G_UNICODE_NOT_PRESENT_OFFSET, 6772 },
+  { 0x2f9b, G_UNICODE_NOT_PRESENT_OFFSET, 6776 },
+  { 0x2f9c, G_UNICODE_NOT_PRESENT_OFFSET, 6780 },
+  { 0x2f9d, G_UNICODE_NOT_PRESENT_OFFSET, 6784 },
+  { 0x2f9e, G_UNICODE_NOT_PRESENT_OFFSET, 6788 },
+  { 0x2f9f, G_UNICODE_NOT_PRESENT_OFFSET, 6792 },
+  { 0x2fa0, G_UNICODE_NOT_PRESENT_OFFSET, 6796 },
+  { 0x2fa1, G_UNICODE_NOT_PRESENT_OFFSET, 6800 },
+  { 0x2fa2, G_UNICODE_NOT_PRESENT_OFFSET, 6804 },
+  { 0x2fa3, G_UNICODE_NOT_PRESENT_OFFSET, 6808 },
+  { 0x2fa4, G_UNICODE_NOT_PRESENT_OFFSET, 6812 },
+  { 0x2fa5, G_UNICODE_NOT_PRESENT_OFFSET, 6816 },
+  { 0x2fa6, G_UNICODE_NOT_PRESENT_OFFSET, 6820 },
+  { 0x2fa7, G_UNICODE_NOT_PRESENT_OFFSET, 6824 },
+  { 0x2fa8, G_UNICODE_NOT_PRESENT_OFFSET, 6828 },
+  { 0x2fa9, G_UNICODE_NOT_PRESENT_OFFSET, 6832 },
+  { 0x2faa, G_UNICODE_NOT_PRESENT_OFFSET, 6836 },
+  { 0x2fab, G_UNICODE_NOT_PRESENT_OFFSET, 6840 },
+  { 0x2fac, G_UNICODE_NOT_PRESENT_OFFSET, 6844 },
+  { 0x2fad, G_UNICODE_NOT_PRESENT_OFFSET, 6848 },
+  { 0x2fae, G_UNICODE_NOT_PRESENT_OFFSET, 6852 },
+  { 0x2faf, G_UNICODE_NOT_PRESENT_OFFSET, 6856 },
+  { 0x2fb0, G_UNICODE_NOT_PRESENT_OFFSET, 6860 },
+  { 0x2fb1, G_UNICODE_NOT_PRESENT_OFFSET, 6864 },
+  { 0x2fb2, G_UNICODE_NOT_PRESENT_OFFSET, 6868 },
+  { 0x2fb3, G_UNICODE_NOT_PRESENT_OFFSET, 6872 },
+  { 0x2fb4, G_UNICODE_NOT_PRESENT_OFFSET, 6876 },
+  { 0x2fb5, G_UNICODE_NOT_PRESENT_OFFSET, 6880 },
+  { 0x2fb6, G_UNICODE_NOT_PRESENT_OFFSET, 6884 },
+  { 0x2fb7, G_UNICODE_NOT_PRESENT_OFFSET, 6888 },
+  { 0x2fb8, G_UNICODE_NOT_PRESENT_OFFSET, 6892 },
+  { 0x2fb9, G_UNICODE_NOT_PRESENT_OFFSET, 6896 },
+  { 0x2fba, G_UNICODE_NOT_PRESENT_OFFSET, 6900 },
+  { 0x2fbb, G_UNICODE_NOT_PRESENT_OFFSET, 6904 },
+  { 0x2fbc, G_UNICODE_NOT_PRESENT_OFFSET, 6908 },
+  { 0x2fbd, G_UNICODE_NOT_PRESENT_OFFSET, 6912 },
+  { 0x2fbe, G_UNICODE_NOT_PRESENT_OFFSET, 6916 },
+  { 0x2fbf, G_UNICODE_NOT_PRESENT_OFFSET, 6920 },
+  { 0x2fc0, G_UNICODE_NOT_PRESENT_OFFSET, 6924 },
+  { 0x2fc1, G_UNICODE_NOT_PRESENT_OFFSET, 6928 },
+  { 0x2fc2, G_UNICODE_NOT_PRESENT_OFFSET, 6932 },
+  { 0x2fc3, G_UNICODE_NOT_PRESENT_OFFSET, 6936 },
+  { 0x2fc4, G_UNICODE_NOT_PRESENT_OFFSET, 6940 },
+  { 0x2fc5, G_UNICODE_NOT_PRESENT_OFFSET, 6944 },
+  { 0x2fc6, G_UNICODE_NOT_PRESENT_OFFSET, 6948 },
+  { 0x2fc7, G_UNICODE_NOT_PRESENT_OFFSET, 6952 },
+  { 0x2fc8, G_UNICODE_NOT_PRESENT_OFFSET, 6956 },
+  { 0x2fc9, G_UNICODE_NOT_PRESENT_OFFSET, 6960 },
+  { 0x2fca, G_UNICODE_NOT_PRESENT_OFFSET, 6964 },
+  { 0x2fcb, G_UNICODE_NOT_PRESENT_OFFSET, 6968 },
+  { 0x2fcc, G_UNICODE_NOT_PRESENT_OFFSET, 6972 },
+  { 0x2fcd, G_UNICODE_NOT_PRESENT_OFFSET, 6976 },
+  { 0x2fce, G_UNICODE_NOT_PRESENT_OFFSET, 6980 },
+  { 0x2fcf, G_UNICODE_NOT_PRESENT_OFFSET, 6984 },
+  { 0x2fd0, G_UNICODE_NOT_PRESENT_OFFSET, 6988 },
+  { 0x2fd1, G_UNICODE_NOT_PRESENT_OFFSET, 6992 },
+  { 0x2fd2, G_UNICODE_NOT_PRESENT_OFFSET, 6996 },
+  { 0x2fd3, G_UNICODE_NOT_PRESENT_OFFSET, 7000 },
+  { 0x2fd4, G_UNICODE_NOT_PRESENT_OFFSET, 7004 },
+  { 0x2fd5, G_UNICODE_NOT_PRESENT_OFFSET, 7008 },
+  { 0x3000, G_UNICODE_NOT_PRESENT_OFFSET, 0 },
+  { 0x3036, G_UNICODE_NOT_PRESENT_OFFSET, 7012 },
+  { 0x3038, G_UNICODE_NOT_PRESENT_OFFSET, 6248 },
+  { 0x3039, G_UNICODE_NOT_PRESENT_OFFSET, 7016 },
+  { 0x303a, G_UNICODE_NOT_PRESENT_OFFSET, 7020 },
+  { 0x304c, 7024, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x304e, 7031, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3050, 7038, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3052, 7045, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3054, 7052, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3056, 7059, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3058, 7066, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x305a, 7073, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x305c, 7080, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x305e, 7087, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3060, 7094, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3062, 7101, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3065, 7108, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3067, 7115, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3069, 7122, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3070, 7129, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3071, 7136, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3073, 7143, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3074, 7150, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3076, 7157, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3077, 7164, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3079, 7171, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x307a, 7178, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x307c, 7185, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x307d, 7192, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x3094, 7199, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x309b, G_UNICODE_NOT_PRESENT_OFFSET, 7206 },
+  { 0x309c, G_UNICODE_NOT_PRESENT_OFFSET, 7211 },
+  { 0x309e, 7216, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x309f, G_UNICODE_NOT_PRESENT_OFFSET, 7223 },
+  { 0x30ac, 7230, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30ae, 7237, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30b0, 7244, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30b2, 7251, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30b4, 7258, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30b6, 7265, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30b8, 7272, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30ba, 7279, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30bc, 7286, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30be, 7293, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30c0, 7300, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30c2, 7307, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30c5, 7314, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30c7, 7321, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30c9, 7328, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30d0, 7335, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30d1, 7342, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30d3, 7349, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30d4, 7356, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30d6, 7363, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30d7, 7370, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30d9, 7377, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30da, 7384, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30dc, 7391, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30dd, 7398, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30f4, 7405, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30f7, 7412, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30f8, 7419, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30f9, 7426, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30fa, 7433, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30fe, 7440, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x30ff, G_UNICODE_NOT_PRESENT_OFFSET, 7447 },
+  { 0x3131, G_UNICODE_NOT_PRESENT_OFFSET, 7454 },
+  { 0x3132, G_UNICODE_NOT_PRESENT_OFFSET, 7458 },
+  { 0x3133, G_UNICODE_NOT_PRESENT_OFFSET, 7462 },
+  { 0x3134, G_UNICODE_NOT_PRESENT_OFFSET, 7466 },
+  { 0x3135, G_UNICODE_NOT_PRESENT_OFFSET, 7470 },
+  { 0x3136, G_UNICODE_NOT_PRESENT_OFFSET, 7474 },
+  { 0x3137, G_UNICODE_NOT_PRESENT_OFFSET, 7478 },
+  { 0x3138, G_UNICODE_NOT_PRESENT_OFFSET, 7482 },
+  { 0x3139, G_UNICODE_NOT_PRESENT_OFFSET, 7486 },
+  { 0x313a, G_UNICODE_NOT_PRESENT_OFFSET, 7490 },
+  { 0x313b, G_UNICODE_NOT_PRESENT_OFFSET, 7494 },
+  { 0x313c, G_UNICODE_NOT_PRESENT_OFFSET, 7498 },
+  { 0x313d, G_UNICODE_NOT_PRESENT_OFFSET, 7502 },
+  { 0x313e, G_UNICODE_NOT_PRESENT_OFFSET, 7506 },
+  { 0x313f, G_UNICODE_NOT_PRESENT_OFFSET, 7510 },
+  { 0x3140, G_UNICODE_NOT_PRESENT_OFFSET, 7514 },
+  { 0x3141, G_UNICODE_NOT_PRESENT_OFFSET, 7518 },
+  { 0x3142, G_UNICODE_NOT_PRESENT_OFFSET, 7522 },
+  { 0x3143, G_UNICODE_NOT_PRESENT_OFFSET, 7526 },
+  { 0x3144, G_UNICODE_NOT_PRESENT_OFFSET, 7530 },
+  { 0x3145, G_UNICODE_NOT_PRESENT_OFFSET, 7534 },
+  { 0x3146, G_UNICODE_NOT_PRESENT_OFFSET, 7538 },
+  { 0x3147, G_UNICODE_NOT_PRESENT_OFFSET, 7542 },
+  { 0x3148, G_UNICODE_NOT_PRESENT_OFFSET, 7546 },
+  { 0x3149, G_UNICODE_NOT_PRESENT_OFFSET, 7550 },
+  { 0x314a, G_UNICODE_NOT_PRESENT_OFFSET, 7554 },
+  { 0x314b, G_UNICODE_NOT_PRESENT_OFFSET, 7558 },
+  { 0x314c, G_UNICODE_NOT_PRESENT_OFFSET, 7562 },
+  { 0x314d, G_UNICODE_NOT_PRESENT_OFFSET, 7566 },
+  { 0x314e, G_UNICODE_NOT_PRESENT_OFFSET, 7570 },
+  { 0x314f, G_UNICODE_NOT_PRESENT_OFFSET, 7574 },
+  { 0x3150, G_UNICODE_NOT_PRESENT_OFFSET, 7578 },
+  { 0x3151, G_UNICODE_NOT_PRESENT_OFFSET, 7582 },
+  { 0x3152, G_UNICODE_NOT_PRESENT_OFFSET, 7586 },
+  { 0x3153, G_UNICODE_NOT_PRESENT_OFFSET, 7590 },
+  { 0x3154, G_UNICODE_NOT_PRESENT_OFFSET, 7594 },
+  { 0x3155, G_UNICODE_NOT_PRESENT_OFFSET, 7598 },
+  { 0x3156, G_UNICODE_NOT_PRESENT_OFFSET, 7602 },
+  { 0x3157, G_UNICODE_NOT_PRESENT_OFFSET, 7606 },
+  { 0x3158, G_UNICODE_NOT_PRESENT_OFFSET, 7610 },
+  { 0x3159, G_UNICODE_NOT_PRESENT_OFFSET, 7614 },
+  { 0x315a, G_UNICODE_NOT_PRESENT_OFFSET, 7618 },
+  { 0x315b, G_UNICODE_NOT_PRESENT_OFFSET, 7622 },
+  { 0x315c, G_UNICODE_NOT_PRESENT_OFFSET, 7626 },
+  { 0x315d, G_UNICODE_NOT_PRESENT_OFFSET, 7630 },
+  { 0x315e, G_UNICODE_NOT_PRESENT_OFFSET, 7634 },
+  { 0x315f, G_UNICODE_NOT_PRESENT_OFFSET, 7638 },
+  { 0x3160, G_UNICODE_NOT_PRESENT_OFFSET, 7642 },
+  { 0x3161, G_UNICODE_NOT_PRESENT_OFFSET, 7646 },
+  { 0x3162, G_UNICODE_NOT_PRESENT_OFFSET, 7650 },
+  { 0x3163, G_UNICODE_NOT_PRESENT_OFFSET, 7654 },
+  { 0x3164, G_UNICODE_NOT_PRESENT_OFFSET, 7658 },
+  { 0x3165, G_UNICODE_NOT_PRESENT_OFFSET, 7662 },
+  { 0x3166, G_UNICODE_NOT_PRESENT_OFFSET, 7666 },
+  { 0x3167, G_UNICODE_NOT_PRESENT_OFFSET, 7670 },
+  { 0x3168, G_UNICODE_NOT_PRESENT_OFFSET, 7674 },
+  { 0x3169, G_UNICODE_NOT_PRESENT_OFFSET, 7678 },
+  { 0x316a, G_UNICODE_NOT_PRESENT_OFFSET, 7682 },
+  { 0x316b, G_UNICODE_NOT_PRESENT_OFFSET, 7686 },
+  { 0x316c, G_UNICODE_NOT_PRESENT_OFFSET, 7690 },
+  { 0x316d, G_UNICODE_NOT_PRESENT_OFFSET, 7694 },
+  { 0x316e, G_UNICODE_NOT_PRESENT_OFFSET, 7698 },
+  { 0x316f, G_UNICODE_NOT_PRESENT_OFFSET, 7702 },
+  { 0x3170, G_UNICODE_NOT_PRESENT_OFFSET, 7706 },
+  { 0x3171, G_UNICODE_NOT_PRESENT_OFFSET, 7710 },
+  { 0x3172, G_UNICODE_NOT_PRESENT_OFFSET, 7714 },
+  { 0x3173, G_UNICODE_NOT_PRESENT_OFFSET, 7718 },
+  { 0x3174, G_UNICODE_NOT_PRESENT_OFFSET, 7722 },
+  { 0x3175, G_UNICODE_NOT_PRESENT_OFFSET, 7726 },
+  { 0x3176, G_UNICODE_NOT_PRESENT_OFFSET, 7730 },
+  { 0x3177, G_UNICODE_NOT_PRESENT_OFFSET, 7734 },
+  { 0x3178, G_UNICODE_NOT_PRESENT_OFFSET, 7738 },
+  { 0x3179, G_UNICODE_NOT_PRESENT_OFFSET, 7742 },
+  { 0x317a, G_UNICODE_NOT_PRESENT_OFFSET, 7746 },
+  { 0x317b, G_UNICODE_NOT_PRESENT_OFFSET, 7750 },
+  { 0x317c, G_UNICODE_NOT_PRESENT_OFFSET, 7754 },
+  { 0x317d, G_UNICODE_NOT_PRESENT_OFFSET, 7758 },
+  { 0x317e, G_UNICODE_NOT_PRESENT_OFFSET, 7762 },
+  { 0x317f, G_UNICODE_NOT_PRESENT_OFFSET, 7766 },
+  { 0x3180, G_UNICODE_NOT_PRESENT_OFFSET, 7770 },
+  { 0x3181, G_UNICODE_NOT_PRESENT_OFFSET, 7774 },
+  { 0x3182, G_UNICODE_NOT_PRESENT_OFFSET, 7778 },
+  { 0x3183, G_UNICODE_NOT_PRESENT_OFFSET, 7782 },
+  { 0x3184, G_UNICODE_NOT_PRESENT_OFFSET, 7786 },
+  { 0x3185, G_UNICODE_NOT_PRESENT_OFFSET, 7790 },
+  { 0x3186, G_UNICODE_NOT_PRESENT_OFFSET, 7794 },
+  { 0x3187, G_UNICODE_NOT_PRESENT_OFFSET, 7798 },
+  { 0x3188, G_UNICODE_NOT_PRESENT_OFFSET, 7802 },
+  { 0x3189, G_UNICODE_NOT_PRESENT_OFFSET, 7806 },
+  { 0x318a, G_UNICODE_NOT_PRESENT_OFFSET, 7810 },
+  { 0x318b, G_UNICODE_NOT_PRESENT_OFFSET, 7814 },
+  { 0x318c, G_UNICODE_NOT_PRESENT_OFFSET, 7818 },
+  { 0x318d, G_UNICODE_NOT_PRESENT_OFFSET, 7822 },
+  { 0x318e, G_UNICODE_NOT_PRESENT_OFFSET, 7826 },
+  { 0x3192, G_UNICODE_NOT_PRESENT_OFFSET, 6156 },
+  { 0x3193, G_UNICODE_NOT_PRESENT_OFFSET, 6180 },
+  { 0x3194, G_UNICODE_NOT_PRESENT_OFFSET, 7830 },
+  { 0x3195, G_UNICODE_NOT_PRESENT_OFFSET, 7834 },
+  { 0x3196, G_UNICODE_NOT_PRESENT_OFFSET, 7838 },
+  { 0x3197, G_UNICODE_NOT_PRESENT_OFFSET, 7842 },
+  { 0x3198, G_UNICODE_NOT_PRESENT_OFFSET, 7846 },
+  { 0x3199, G_UNICODE_NOT_PRESENT_OFFSET, 7850 },
+  { 0x319a, G_UNICODE_NOT_PRESENT_OFFSET, 6172 },
+  { 0x319b, G_UNICODE_NOT_PRESENT_OFFSET, 7854 },
+  { 0x319c, G_UNICODE_NOT_PRESENT_OFFSET, 7858 },
+  { 0x319d, G_UNICODE_NOT_PRESENT_OFFSET, 7862 },
+  { 0x319e, G_UNICODE_NOT_PRESENT_OFFSET, 7866 },
+  { 0x319f, G_UNICODE_NOT_PRESENT_OFFSET, 6188 },
+  { 0x3200, G_UNICODE_NOT_PRESENT_OFFSET, 7870 },
+  { 0x3201, G_UNICODE_NOT_PRESENT_OFFSET, 7876 },
+  { 0x3202, G_UNICODE_NOT_PRESENT_OFFSET, 7882 },
+  { 0x3203, G_UNICODE_NOT_PRESENT_OFFSET, 7888 },
+  { 0x3204, G_UNICODE_NOT_PRESENT_OFFSET, 7894 },
+  { 0x3205, G_UNICODE_NOT_PRESENT_OFFSET, 7900 },
+  { 0x3206, G_UNICODE_NOT_PRESENT_OFFSET, 7906 },
+  { 0x3207, G_UNICODE_NOT_PRESENT_OFFSET, 7912 },
+  { 0x3208, G_UNICODE_NOT_PRESENT_OFFSET, 7918 },
+  { 0x3209, G_UNICODE_NOT_PRESENT_OFFSET, 7924 },
+  { 0x320a, G_UNICODE_NOT_PRESENT_OFFSET, 7930 },
+  { 0x320b, G_UNICODE_NOT_PRESENT_OFFSET, 7936 },
+  { 0x320c, G_UNICODE_NOT_PRESENT_OFFSET, 7942 },
+  { 0x320d, G_UNICODE_NOT_PRESENT_OFFSET, 7948 },
+  { 0x320e, G_UNICODE_NOT_PRESENT_OFFSET, 7954 },
+  { 0x320f, G_UNICODE_NOT_PRESENT_OFFSET, 7963 },
+  { 0x3210, G_UNICODE_NOT_PRESENT_OFFSET, 7972 },
+  { 0x3211, G_UNICODE_NOT_PRESENT_OFFSET, 7981 },
+  { 0x3212, G_UNICODE_NOT_PRESENT_OFFSET, 7990 },
+  { 0x3213, G_UNICODE_NOT_PRESENT_OFFSET, 7999 },
+  { 0x3214, G_UNICODE_NOT_PRESENT_OFFSET, 8008 },
+  { 0x3215, G_UNICODE_NOT_PRESENT_OFFSET, 8017 },
+  { 0x3216, G_UNICODE_NOT_PRESENT_OFFSET, 8026 },
+  { 0x3217, G_UNICODE_NOT_PRESENT_OFFSET, 8035 },
+  { 0x3218, G_UNICODE_NOT_PRESENT_OFFSET, 8044 },
+  { 0x3219, G_UNICODE_NOT_PRESENT_OFFSET, 8053 },
+  { 0x321a, G_UNICODE_NOT_PRESENT_OFFSET, 8062 },
+  { 0x321b, G_UNICODE_NOT_PRESENT_OFFSET, 8071 },
+  { 0x321c, G_UNICODE_NOT_PRESENT_OFFSET, 8080 },
+  { 0x321d, G_UNICODE_NOT_PRESENT_OFFSET, 8089 },
+  { 0x321e, G_UNICODE_NOT_PRESENT_OFFSET, 8107 },
+  { 0x3220, G_UNICODE_NOT_PRESENT_OFFSET, 8122 },
+  { 0x3221, G_UNICODE_NOT_PRESENT_OFFSET, 8128 },
+  { 0x3222, G_UNICODE_NOT_PRESENT_OFFSET, 8134 },
+  { 0x3223, G_UNICODE_NOT_PRESENT_OFFSET, 8140 },
+  { 0x3224, G_UNICODE_NOT_PRESENT_OFFSET, 8146 },
+  { 0x3225, G_UNICODE_NOT_PRESENT_OFFSET, 8152 },
+  { 0x3226, G_UNICODE_NOT_PRESENT_OFFSET, 8158 },
+  { 0x3227, G_UNICODE_NOT_PRESENT_OFFSET, 8164 },
+  { 0x3228, G_UNICODE_NOT_PRESENT_OFFSET, 8170 },
+  { 0x3229, G_UNICODE_NOT_PRESENT_OFFSET, 8176 },
+  { 0x322a, G_UNICODE_NOT_PRESENT_OFFSET, 8182 },
+  { 0x322b, G_UNICODE_NOT_PRESENT_OFFSET, 8188 },
+  { 0x322c, G_UNICODE_NOT_PRESENT_OFFSET, 8194 },
+  { 0x322d, G_UNICODE_NOT_PRESENT_OFFSET, 8200 },
+  { 0x322e, G_UNICODE_NOT_PRESENT_OFFSET, 8206 },
+  { 0x322f, G_UNICODE_NOT_PRESENT_OFFSET, 8212 },
+  { 0x3230, G_UNICODE_NOT_PRESENT_OFFSET, 8218 },
+  { 0x3231, G_UNICODE_NOT_PRESENT_OFFSET, 8224 },
+  { 0x3232, G_UNICODE_NOT_PRESENT_OFFSET, 8230 },
+  { 0x3233, G_UNICODE_NOT_PRESENT_OFFSET, 8236 },
+  { 0x3234, G_UNICODE_NOT_PRESENT_OFFSET, 8242 },
+  { 0x3235, G_UNICODE_NOT_PRESENT_OFFSET, 8248 },
+  { 0x3236, G_UNICODE_NOT_PRESENT_OFFSET, 8254 },
+  { 0x3237, G_UNICODE_NOT_PRESENT_OFFSET, 8260 },
+  { 0x3238, G_UNICODE_NOT_PRESENT_OFFSET, 8266 },
+  { 0x3239, G_UNICODE_NOT_PRESENT_OFFSET, 8272 },
+  { 0x323a, G_UNICODE_NOT_PRESENT_OFFSET, 8278 },
+  { 0x323b, G_UNICODE_NOT_PRESENT_OFFSET, 8284 },
+  { 0x323c, G_UNICODE_NOT_PRESENT_OFFSET, 8290 },
+  { 0x323d, G_UNICODE_NOT_PRESENT_OFFSET, 8296 },
+  { 0x323e, G_UNICODE_NOT_PRESENT_OFFSET, 8302 },
+  { 0x323f, G_UNICODE_NOT_PRESENT_OFFSET, 8308 },
+  { 0x3240, G_UNICODE_NOT_PRESENT_OFFSET, 8314 },
+  { 0x3241, G_UNICODE_NOT_PRESENT_OFFSET, 8320 },
+  { 0x3242, G_UNICODE_NOT_PRESENT_OFFSET, 8326 },
+  { 0x3243, G_UNICODE_NOT_PRESENT_OFFSET, 8332 },
+  { 0x3250, G_UNICODE_NOT_PRESENT_OFFSET, 8338 },
+  { 0x3251, G_UNICODE_NOT_PRESENT_OFFSET, 8342 },
+  { 0x3252, G_UNICODE_NOT_PRESENT_OFFSET, 8345 },
+  { 0x3253, G_UNICODE_NOT_PRESENT_OFFSET, 8348 },
+  { 0x3254, G_UNICODE_NOT_PRESENT_OFFSET, 8351 },
+  { 0x3255, G_UNICODE_NOT_PRESENT_OFFSET, 8354 },
+  { 0x3256, G_UNICODE_NOT_PRESENT_OFFSET, 8357 },
+  { 0x3257, G_UNICODE_NOT_PRESENT_OFFSET, 8360 },
+  { 0x3258, G_UNICODE_NOT_PRESENT_OFFSET, 8363 },
+  { 0x3259, G_UNICODE_NOT_PRESENT_OFFSET, 8366 },
+  { 0x325a, G_UNICODE_NOT_PRESENT_OFFSET, 8369 },
+  { 0x325b, G_UNICODE_NOT_PRESENT_OFFSET, 8372 },
+  { 0x325c, G_UNICODE_NOT_PRESENT_OFFSET, 8375 },
+  { 0x325d, G_UNICODE_NOT_PRESENT_OFFSET, 8378 },
+  { 0x325e, G_UNICODE_NOT_PRESENT_OFFSET, 8381 },
+  { 0x325f, G_UNICODE_NOT_PRESENT_OFFSET, 8384 },
+  { 0x3260, G_UNICODE_NOT_PRESENT_OFFSET, 7454 },
+  { 0x3261, G_UNICODE_NOT_PRESENT_OFFSET, 7466 },
+  { 0x3262, G_UNICODE_NOT_PRESENT_OFFSET, 7478 },
+  { 0x3263, G_UNICODE_NOT_PRESENT_OFFSET, 7486 },
+  { 0x3264, G_UNICODE_NOT_PRESENT_OFFSET, 7518 },
+  { 0x3265, G_UNICODE_NOT_PRESENT_OFFSET, 7522 },
+  { 0x3266, G_UNICODE_NOT_PRESENT_OFFSET, 7534 },
+  { 0x3267, G_UNICODE_NOT_PRESENT_OFFSET, 7542 },
+  { 0x3268, G_UNICODE_NOT_PRESENT_OFFSET, 7546 },
+  { 0x3269, G_UNICODE_NOT_PRESENT_OFFSET, 7554 },
+  { 0x326a, G_UNICODE_NOT_PRESENT_OFFSET, 7558 },
+  { 0x326b, G_UNICODE_NOT_PRESENT_OFFSET, 7562 },
+  { 0x326c, G_UNICODE_NOT_PRESENT_OFFSET, 7566 },
+  { 0x326d, G_UNICODE_NOT_PRESENT_OFFSET, 7570 },
+  { 0x326e, G_UNICODE_NOT_PRESENT_OFFSET, 8387 },
+  { 0x326f, G_UNICODE_NOT_PRESENT_OFFSET, 8394 },
+  { 0x3270, G_UNICODE_NOT_PRESENT_OFFSET, 8401 },
+  { 0x3271, G_UNICODE_NOT_PRESENT_OFFSET, 8408 },
+  { 0x3272, G_UNICODE_NOT_PRESENT_OFFSET, 8415 },
+  { 0x3273, G_UNICODE_NOT_PRESENT_OFFSET, 8422 },
+  { 0x3274, G_UNICODE_NOT_PRESENT_OFFSET, 8429 },
+  { 0x3275, G_UNICODE_NOT_PRESENT_OFFSET, 8436 },
+  { 0x3276, G_UNICODE_NOT_PRESENT_OFFSET, 8443 },
+  { 0x3277, G_UNICODE_NOT_PRESENT_OFFSET, 8450 },
+  { 0x3278, G_UNICODE_NOT_PRESENT_OFFSET, 8457 },
+  { 0x3279, G_UNICODE_NOT_PRESENT_OFFSET, 8464 },
+  { 0x327a, G_UNICODE_NOT_PRESENT_OFFSET, 8471 },
+  { 0x327b, G_UNICODE_NOT_PRESENT_OFFSET, 8478 },
+  { 0x327c, G_UNICODE_NOT_PRESENT_OFFSET, 8485 },
+  { 0x327d, G_UNICODE_NOT_PRESENT_OFFSET, 8501 },
+  { 0x327e, G_UNICODE_NOT_PRESENT_OFFSET, 8514 },
+  { 0x3280, G_UNICODE_NOT_PRESENT_OFFSET, 6156 },
+  { 0x3281, G_UNICODE_NOT_PRESENT_OFFSET, 6180 },
+  { 0x3282, G_UNICODE_NOT_PRESENT_OFFSET, 7830 },
+  { 0x3283, G_UNICODE_NOT_PRESENT_OFFSET, 7834 },
+  { 0x3284, G_UNICODE_NOT_PRESENT_OFFSET, 8521 },
+  { 0x3285, G_UNICODE_NOT_PRESENT_OFFSET, 8525 },
+  { 0x3286, G_UNICODE_NOT_PRESENT_OFFSET, 8529 },
+  { 0x3287, G_UNICODE_NOT_PRESENT_OFFSET, 6200 },
+  { 0x3288, G_UNICODE_NOT_PRESENT_OFFSET, 8533 },
+  { 0x3289, G_UNICODE_NOT_PRESENT_OFFSET, 6248 },
+  { 0x328a, G_UNICODE_NOT_PRESENT_OFFSET, 6448 },
+  { 0x328b, G_UNICODE_NOT_PRESENT_OFFSET, 6496 },
+  { 0x328c, G_UNICODE_NOT_PRESENT_OFFSET, 6492 },
+  { 0x328d, G_UNICODE_NOT_PRESENT_OFFSET, 6452 },
+  { 0x328e, G_UNICODE_NOT_PRESENT_OFFSET, 6820 },
+  { 0x328f, G_UNICODE_NOT_PRESENT_OFFSET, 6280 },
+  { 0x3290, G_UNICODE_NOT_PRESENT_OFFSET, 6440 },
+  { 0x3291, G_UNICODE_NOT_PRESENT_OFFSET, 8537 },
+  { 0x3292, G_UNICODE_NOT_PRESENT_OFFSET, 8541 },
+  { 0x3293, G_UNICODE_NOT_PRESENT_OFFSET, 8545 },
+  { 0x3294, G_UNICODE_NOT_PRESENT_OFFSET, 8549 },
+  { 0x3295, G_UNICODE_NOT_PRESENT_OFFSET, 8553 },
+  { 0x3296, G_UNICODE_NOT_PRESENT_OFFSET, 8557 },
+  { 0x3297, G_UNICODE_NOT_PRESENT_OFFSET, 8561 },
+  { 0x3298, G_UNICODE_NOT_PRESENT_OFFSET, 8565 },
+  { 0x3299, G_UNICODE_NOT_PRESENT_OFFSET, 8569 },
+  { 0x329a, G_UNICODE_NOT_PRESENT_OFFSET, 8573 },
+  { 0x329b, G_UNICODE_NOT_PRESENT_OFFSET, 6304 },
+  { 0x329c, G_UNICODE_NOT_PRESENT_OFFSET, 8577 },
+  { 0x329d, G_UNICODE_NOT_PRESENT_OFFSET, 8581 },
+  { 0x329e, G_UNICODE_NOT_PRESENT_OFFSET, 8585 },
+  { 0x329f, G_UNICODE_NOT_PRESENT_OFFSET, 8589 },
+  { 0x32a0, G_UNICODE_NOT_PRESENT_OFFSET, 8593 },
+  { 0x32a1, G_UNICODE_NOT_PRESENT_OFFSET, 8597 },
+  { 0x32a2, G_UNICODE_NOT_PRESENT_OFFSET, 8601 },
+  { 0x32a3, G_UNICODE_NOT_PRESENT_OFFSET, 8605 },
+  { 0x32a4, G_UNICODE_NOT_PRESENT_OFFSET, 7838 },
+  { 0x32a5, G_UNICODE_NOT_PRESENT_OFFSET, 7842 },
+  { 0x32a6, G_UNICODE_NOT_PRESENT_OFFSET, 7846 },
+  { 0x32a7, G_UNICODE_NOT_PRESENT_OFFSET, 8609 },
+  { 0x32a8, G_UNICODE_NOT_PRESENT_OFFSET, 8613 },
+  { 0x32a9, G_UNICODE_NOT_PRESENT_OFFSET, 8617 },
+  { 0x32aa, G_UNICODE_NOT_PRESENT_OFFSET, 8621 },
+  { 0x32ab, G_UNICODE_NOT_PRESENT_OFFSET, 8625 },
+  { 0x32ac, G_UNICODE_NOT_PRESENT_OFFSET, 8629 },
+  { 0x32ad, G_UNICODE_NOT_PRESENT_OFFSET, 8633 },
+  { 0x32ae, G_UNICODE_NOT_PRESENT_OFFSET, 8637 },
+  { 0x32af, G_UNICODE_NOT_PRESENT_OFFSET, 8641 },
+  { 0x32b0, G_UNICODE_NOT_PRESENT_OFFSET, 8645 },
+  { 0x32b1, G_UNICODE_NOT_PRESENT_OFFSET, 8649 },
+  { 0x32b2, G_UNICODE_NOT_PRESENT_OFFSET, 8652 },
+  { 0x32b3, G_UNICODE_NOT_PRESENT_OFFSET, 8655 },
+  { 0x32b4, G_UNICODE_NOT_PRESENT_OFFSET, 8658 },
+  { 0x32b5, G_UNICODE_NOT_PRESENT_OFFSET, 8661 },
+  { 0x32b6, G_UNICODE_NOT_PRESENT_OFFSET, 8664 },
+  { 0x32b7, G_UNICODE_NOT_PRESENT_OFFSET, 8667 },
+  { 0x32b8, G_UNICODE_NOT_PRESENT_OFFSET, 8670 },
+  { 0x32b9, G_UNICODE_NOT_PRESENT_OFFSET, 8673 },
+  { 0x32ba, G_UNICODE_NOT_PRESENT_OFFSET, 8676 },
+  { 0x32bb, G_UNICODE_NOT_PRESENT_OFFSET, 8679 },
+  { 0x32bc, G_UNICODE_NOT_PRESENT_OFFSET, 8682 },
+  { 0x32bd, G_UNICODE_NOT_PRESENT_OFFSET, 8685 },
+  { 0x32be, G_UNICODE_NOT_PRESENT_OFFSET, 8688 },
+  { 0x32bf, G_UNICODE_NOT_PRESENT_OFFSET, 8691 },
+  { 0x32c0, G_UNICODE_NOT_PRESENT_OFFSET, 8694 },
+  { 0x32c1, G_UNICODE_NOT_PRESENT_OFFSET, 8699 },
+  { 0x32c2, G_UNICODE_NOT_PRESENT_OFFSET, 8704 },
+  { 0x32c3, G_UNICODE_NOT_PRESENT_OFFSET, 8709 },
+  { 0x32c4, G_UNICODE_NOT_PRESENT_OFFSET, 8714 },
+  { 0x32c5, G_UNICODE_NOT_PRESENT_OFFSET, 8719 },
+  { 0x32c6, G_UNICODE_NOT_PRESENT_OFFSET, 8724 },
+  { 0x32c7, G_UNICODE_NOT_PRESENT_OFFSET, 8729 },
+  { 0x32c8, G_UNICODE_NOT_PRESENT_OFFSET, 8734 },
+  { 0x32c9, G_UNICODE_NOT_PRESENT_OFFSET, 8739 },
+  { 0x32ca, G_UNICODE_NOT_PRESENT_OFFSET, 8745 },
+  { 0x32cb, G_UNICODE_NOT_PRESENT_OFFSET, 8751 },
+  { 0x32cc, G_UNICODE_NOT_PRESENT_OFFSET, 8757 },
+  { 0x32cd, G_UNICODE_NOT_PRESENT_OFFSET, 8760 },
+  { 0x32ce, G_UNICODE_NOT_PRESENT_OFFSET, 8764 },
+  { 0x32cf, G_UNICODE_NOT_PRESENT_OFFSET, 8767 },
+  { 0x32d0, G_UNICODE_NOT_PRESENT_OFFSET, 8771 },
+  { 0x32d1, G_UNICODE_NOT_PRESENT_OFFSET, 8775 },
+  { 0x32d2, G_UNICODE_NOT_PRESENT_OFFSET, 8779 },
+  { 0x32d3, G_UNICODE_NOT_PRESENT_OFFSET, 8783 },
+  { 0x32d4, G_UNICODE_NOT_PRESENT_OFFSET, 8787 },
+  { 0x32d5, G_UNICODE_NOT_PRESENT_OFFSET, 8791 },
+  { 0x32d6, G_UNICODE_NOT_PRESENT_OFFSET, 8795 },
+  { 0x32d7, G_UNICODE_NOT_PRESENT_OFFSET, 8799 },
+  { 0x32d8, G_UNICODE_NOT_PRESENT_OFFSET, 8803 },
+  { 0x32d9, G_UNICODE_NOT_PRESENT_OFFSET, 8807 },
+  { 0x32da, G_UNICODE_NOT_PRESENT_OFFSET, 8811 },
+  { 0x32db, G_UNICODE_NOT_PRESENT_OFFSET, 8815 },
+  { 0x32dc, G_UNICODE_NOT_PRESENT_OFFSET, 8819 },
+  { 0x32dd, G_UNICODE_NOT_PRESENT_OFFSET, 8823 },
+  { 0x32de, G_UNICODE_NOT_PRESENT_OFFSET, 8827 },
+  { 0x32df, G_UNICODE_NOT_PRESENT_OFFSET, 8831 },
+  { 0x32e0, G_UNICODE_NOT_PRESENT_OFFSET, 8835 },
+  { 0x32e1, G_UNICODE_NOT_PRESENT_OFFSET, 8839 },
+  { 0x32e2, G_UNICODE_NOT_PRESENT_OFFSET, 8843 },
+  { 0x32e3, G_UNICODE_NOT_PRESENT_OFFSET, 8847 },
+  { 0x32e4, G_UNICODE_NOT_PRESENT_OFFSET, 8851 },
+  { 0x32e5, G_UNICODE_NOT_PRESENT_OFFSET, 8855 },
+  { 0x32e6, G_UNICODE_NOT_PRESENT_OFFSET, 8859 },
+  { 0x32e7, G_UNICODE_NOT_PRESENT_OFFSET, 8863 },
+  { 0x32e8, G_UNICODE_NOT_PRESENT_OFFSET, 8867 },
+  { 0x32e9, G_UNICODE_NOT_PRESENT_OFFSET, 8871 },
+  { 0x32ea, G_UNICODE_NOT_PRESENT_OFFSET, 8875 },
+  { 0x32eb, G_UNICODE_NOT_PRESENT_OFFSET, 8879 },
+  { 0x32ec, G_UNICODE_NOT_PRESENT_OFFSET, 8883 },
+  { 0x32ed, G_UNICODE_NOT_PRESENT_OFFSET, 8887 },
+  { 0x32ee, G_UNICODE_NOT_PRESENT_OFFSET, 8891 },
+  { 0x32ef, G_UNICODE_NOT_PRESENT_OFFSET, 8895 },
+  { 0x32f0, G_UNICODE_NOT_PRESENT_OFFSET, 8899 },
+  { 0x32f1, G_UNICODE_NOT_PRESENT_OFFSET, 8903 },
+  { 0x32f2, G_UNICODE_NOT_PRESENT_OFFSET, 8907 },
+  { 0x32f3, G_UNICODE_NOT_PRESENT_OFFSET, 8911 },
+  { 0x32f4, G_UNICODE_NOT_PRESENT_OFFSET, 8915 },
+  { 0x32f5, G_UNICODE_NOT_PRESENT_OFFSET, 8919 },
+  { 0x32f6, G_UNICODE_NOT_PRESENT_OFFSET, 8923 },
+  { 0x32f7, G_UNICODE_NOT_PRESENT_OFFSET, 8927 },
+  { 0x32f8, G_UNICODE_NOT_PRESENT_OFFSET, 8931 },
+  { 0x32f9, G_UNICODE_NOT_PRESENT_OFFSET, 8935 },
+  { 0x32fa, G_UNICODE_NOT_PRESENT_OFFSET, 8939 },
+  { 0x32fb, G_UNICODE_NOT_PRESENT_OFFSET, 8943 },
+  { 0x32fc, G_UNICODE_NOT_PRESENT_OFFSET, 8947 },
+  { 0x32fd, G_UNICODE_NOT_PRESENT_OFFSET, 8951 },
+  { 0x32fe, G_UNICODE_NOT_PRESENT_OFFSET, 8955 },
+  { 0x3300, G_UNICODE_NOT_PRESENT_OFFSET, 8959 },
+  { 0x3301, G_UNICODE_NOT_PRESENT_OFFSET, 8975 },
+  { 0x3302, G_UNICODE_NOT_PRESENT_OFFSET, 8988 },
+  { 0x3303, G_UNICODE_NOT_PRESENT_OFFSET, 9004 },
+  { 0x3304, G_UNICODE_NOT_PRESENT_OFFSET, 9014 },
+  { 0x3305, G_UNICODE_NOT_PRESENT_OFFSET, 9030 },
+  { 0x3306, G_UNICODE_NOT_PRESENT_OFFSET, 9040 },
+  { 0x3307, G_UNICODE_NOT_PRESENT_OFFSET, 9050 },
+  { 0x3308, G_UNICODE_NOT_PRESENT_OFFSET, 9069 },
+  { 0x3309, G_UNICODE_NOT_PRESENT_OFFSET, 9082 },
+  { 0x330a, G_UNICODE_NOT_PRESENT_OFFSET, 9092 },
+  { 0x330b, G_UNICODE_NOT_PRESENT_OFFSET, 9102 },
+  { 0x330c, G_UNICODE_NOT_PRESENT_OFFSET, 9112 },
+  { 0x330d, G_UNICODE_NOT_PRESENT_OFFSET, 9125 },
+  { 0x330e, G_UNICODE_NOT_PRESENT_OFFSET, 9138 },
+  { 0x330f, G_UNICODE_NOT_PRESENT_OFFSET, 9151 },
+  { 0x3310, G_UNICODE_NOT_PRESENT_OFFSET, 9164 },
+  { 0x3311, G_UNICODE_NOT_PRESENT_OFFSET, 9177 },
+  { 0x3312, G_UNICODE_NOT_PRESENT_OFFSET, 9190 },
+  { 0x3313, G_UNICODE_NOT_PRESENT_OFFSET, 9203 },
+  { 0x3314, G_UNICODE_NOT_PRESENT_OFFSET, 9222 },
+  { 0x3315, G_UNICODE_NOT_PRESENT_OFFSET, 9229 },
+  { 0x3316, G_UNICODE_NOT_PRESENT_OFFSET, 9248 },
+  { 0x3317, G_UNICODE_NOT_PRESENT_OFFSET, 9267 },
+  { 0x3318, G_UNICODE_NOT_PRESENT_OFFSET, 9283 },
+  { 0x3319, G_UNICODE_NOT_PRESENT_OFFSET, 9296 },
+  { 0x331a, G_UNICODE_NOT_PRESENT_OFFSET, 9315 },
+  { 0x331b, G_UNICODE_NOT_PRESENT_OFFSET, 9334 },
+  { 0x331c, G_UNICODE_NOT_PRESENT_OFFSET, 9347 },
+  { 0x331d, G_UNICODE_NOT_PRESENT_OFFSET, 9357 },
+  { 0x331e, G_UNICODE_NOT_PRESENT_OFFSET, 9367 },
+  { 0x331f, G_UNICODE_NOT_PRESENT_OFFSET, 9380 },
+  { 0x3320, G_UNICODE_NOT_PRESENT_OFFSET, 9393 },
+  { 0x3321, G_UNICODE_NOT_PRESENT_OFFSET, 9409 },
+  { 0x3322, G_UNICODE_NOT_PRESENT_OFFSET, 9425 },
+  { 0x3323, G_UNICODE_NOT_PRESENT_OFFSET, 9435 },
+  { 0x3324, G_UNICODE_NOT_PRESENT_OFFSET, 9445 },
+  { 0x3325, G_UNICODE_NOT_PRESENT_OFFSET, 9458 },
+  { 0x3326, G_UNICODE_NOT_PRESENT_OFFSET, 9468 },
+  { 0x3327, G_UNICODE_NOT_PRESENT_OFFSET, 9478 },
+  { 0x3328, G_UNICODE_NOT_PRESENT_OFFSET, 9485 },
+  { 0x3329, G_UNICODE_NOT_PRESENT_OFFSET, 9492 },
+  { 0x332a, G_UNICODE_NOT_PRESENT_OFFSET, 9502 },
+  { 0x332b, G_UNICODE_NOT_PRESENT_OFFSET, 9512 },
+  { 0x332c, G_UNICODE_NOT_PRESENT_OFFSET, 9531 },
+  { 0x332d, G_UNICODE_NOT_PRESENT_OFFSET, 9544 },
+  { 0x332e, G_UNICODE_NOT_PRESENT_OFFSET, 9560 },
+  { 0x332f, G_UNICODE_NOT_PRESENT_OFFSET, 9579 },
+  { 0x3330, G_UNICODE_NOT_PRESENT_OFFSET, 9592 },
+  { 0x3331, G_UNICODE_NOT_PRESENT_OFFSET, 9602 },
+  { 0x3332, G_UNICODE_NOT_PRESENT_OFFSET, 9612 },
+  { 0x3333, G_UNICODE_NOT_PRESENT_OFFSET, 9631 },
+  { 0x3334, G_UNICODE_NOT_PRESENT_OFFSET, 9644 },
+  { 0x3335, G_UNICODE_NOT_PRESENT_OFFSET, 9663 },
+  { 0x3336, G_UNICODE_NOT_PRESENT_OFFSET, 9673 },
+  { 0x3337, G_UNICODE_NOT_PRESENT_OFFSET, 9689 },
+  { 0x3338, G_UNICODE_NOT_PRESENT_OFFSET, 9699 },
+  { 0x3339, G_UNICODE_NOT_PRESENT_OFFSET, 9712 },
+  { 0x333a, G_UNICODE_NOT_PRESENT_OFFSET, 9722 },
+  { 0x333b, G_UNICODE_NOT_PRESENT_OFFSET, 9735 },
+  { 0x333c, G_UNICODE_NOT_PRESENT_OFFSET, 9751 },
+  { 0x333d, G_UNICODE_NOT_PRESENT_OFFSET, 9764 },
+  { 0x333e, G_UNICODE_NOT_PRESENT_OFFSET, 9780 },
+  { 0x333f, G_UNICODE_NOT_PRESENT_OFFSET, 9793 },
+  { 0x3340, G_UNICODE_NOT_PRESENT_OFFSET, 9800 },
+  { 0x3341, G_UNICODE_NOT_PRESENT_OFFSET, 9816 },
+  { 0x3342, G_UNICODE_NOT_PRESENT_OFFSET, 9826 },
+  { 0x3343, G_UNICODE_NOT_PRESENT_OFFSET, 9836 },
+  { 0x3344, G_UNICODE_NOT_PRESENT_OFFSET, 9849 },
+  { 0x3345, G_UNICODE_NOT_PRESENT_OFFSET, 9859 },
+  { 0x3346, G_UNICODE_NOT_PRESENT_OFFSET, 9869 },
+  { 0x3347, G_UNICODE_NOT_PRESENT_OFFSET, 9879 },
+  { 0x3348, G_UNICODE_NOT_PRESENT_OFFSET, 9895 },
+  { 0x3349, G_UNICODE_NOT_PRESENT_OFFSET, 9908 },
+  { 0x334a, G_UNICODE_NOT_PRESENT_OFFSET, 9915 },
+  { 0x334b, G_UNICODE_NOT_PRESENT_OFFSET, 9934 },
+  { 0x334c, G_UNICODE_NOT_PRESENT_OFFSET, 9944 },
+  { 0x334d, G_UNICODE_NOT_PRESENT_OFFSET, 9960 },
+  { 0x334e, G_UNICODE_NOT_PRESENT_OFFSET, 9973 },
+  { 0x334f, G_UNICODE_NOT_PRESENT_OFFSET, 9986 },
+  { 0x3350, G_UNICODE_NOT_PRESENT_OFFSET, 9996 },
+  { 0x3351, G_UNICODE_NOT_PRESENT_OFFSET, 10006 },
+  { 0x3352, G_UNICODE_NOT_PRESENT_OFFSET, 10019 },
+  { 0x3353, G_UNICODE_NOT_PRESENT_OFFSET, 10026 },
+  { 0x3354, G_UNICODE_NOT_PRESENT_OFFSET, 10039 },
+  { 0x3355, G_UNICODE_NOT_PRESENT_OFFSET, 10055 },
+  { 0x3356, G_UNICODE_NOT_PRESENT_OFFSET, 10062 },
+  { 0x3357, G_UNICODE_NOT_PRESENT_OFFSET, 10081 },
+  { 0x3358, G_UNICODE_NOT_PRESENT_OFFSET, 10091 },
+  { 0x3359, G_UNICODE_NOT_PRESENT_OFFSET, 10096 },
+  { 0x335a, G_UNICODE_NOT_PRESENT_OFFSET, 10101 },
+  { 0x335b, G_UNICODE_NOT_PRESENT_OFFSET, 10106 },
+  { 0x335c, G_UNICODE_NOT_PRESENT_OFFSET, 10111 },
+  { 0x335d, G_UNICODE_NOT_PRESENT_OFFSET, 10116 },
+  { 0x335e, G_UNICODE_NOT_PRESENT_OFFSET, 10121 },
+  { 0x335f, G_UNICODE_NOT_PRESENT_OFFSET, 10126 },
+  { 0x3360, G_UNICODE_NOT_PRESENT_OFFSET, 10131 },
+  { 0x3361, G_UNICODE_NOT_PRESENT_OFFSET, 10136 },
+  { 0x3362, G_UNICODE_NOT_PRESENT_OFFSET, 10141 },
+  { 0x3363, G_UNICODE_NOT_PRESENT_OFFSET, 10147 },
+  { 0x3364, G_UNICODE_NOT_PRESENT_OFFSET, 10153 },
+  { 0x3365, G_UNICODE_NOT_PRESENT_OFFSET, 10159 },
+  { 0x3366, G_UNICODE_NOT_PRESENT_OFFSET, 10165 },
+  { 0x3367, G_UNICODE_NOT_PRESENT_OFFSET, 10171 },
+  { 0x3368, G_UNICODE_NOT_PRESENT_OFFSET, 10177 },
+  { 0x3369, G_UNICODE_NOT_PRESENT_OFFSET, 10183 },
+  { 0x336a, G_UNICODE_NOT_PRESENT_OFFSET, 10189 },
+  { 0x336b, G_UNICODE_NOT_PRESENT_OFFSET, 10195 },
+  { 0x336c, G_UNICODE_NOT_PRESENT_OFFSET, 10201 },
+  { 0x336d, G_UNICODE_NOT_PRESENT_OFFSET, 10207 },
+  { 0x336e, G_UNICODE_NOT_PRESENT_OFFSET, 10213 },
+  { 0x336f, G_UNICODE_NOT_PRESENT_OFFSET, 10219 },
+  { 0x3370, G_UNICODE_NOT_PRESENT_OFFSET, 10225 },
+  { 0x3371, G_UNICODE_NOT_PRESENT_OFFSET, 10231 },
+  { 0x3372, G_UNICODE_NOT_PRESENT_OFFSET, 10235 },
+  { 0x3373, G_UNICODE_NOT_PRESENT_OFFSET, 10238 },
+  { 0x3374, G_UNICODE_NOT_PRESENT_OFFSET, 10241 },
+  { 0x3375, G_UNICODE_NOT_PRESENT_OFFSET, 10245 },
+  { 0x3376, G_UNICODE_NOT_PRESENT_OFFSET, 10248 },
+  { 0x3377, G_UNICODE_NOT_PRESENT_OFFSET, 10251 },
+  { 0x3378, G_UNICODE_NOT_PRESENT_OFFSET, 10254 },
+  { 0x3379, G_UNICODE_NOT_PRESENT_OFFSET, 10258 },
+  { 0x337a, G_UNICODE_NOT_PRESENT_OFFSET, 10262 },
+  { 0x337b, G_UNICODE_NOT_PRESENT_OFFSET, 10265 },
+  { 0x337c, G_UNICODE_NOT_PRESENT_OFFSET, 10272 },
+  { 0x337d, G_UNICODE_NOT_PRESENT_OFFSET, 10279 },
+  { 0x337e, G_UNICODE_NOT_PRESENT_OFFSET, 10286 },
+  { 0x337f, G_UNICODE_NOT_PRESENT_OFFSET, 10293 },
+  { 0x3380, G_UNICODE_NOT_PRESENT_OFFSET, 10306 },
+  { 0x3381, G_UNICODE_NOT_PRESENT_OFFSET, 10309 },
+  { 0x3382, G_UNICODE_NOT_PRESENT_OFFSET, 10312 },
+  { 0x3383, G_UNICODE_NOT_PRESENT_OFFSET, 10316 },
+  { 0x3384, G_UNICODE_NOT_PRESENT_OFFSET, 10319 },
+  { 0x3385, G_UNICODE_NOT_PRESENT_OFFSET, 10322 },
+  { 0x3386, G_UNICODE_NOT_PRESENT_OFFSET, 10325 },
+  { 0x3387, G_UNICODE_NOT_PRESENT_OFFSET, 10328 },
+  { 0x3388, G_UNICODE_NOT_PRESENT_OFFSET, 10331 },
+  { 0x3389, G_UNICODE_NOT_PRESENT_OFFSET, 10335 },
+  { 0x338a, G_UNICODE_NOT_PRESENT_OFFSET, 10340 },
+  { 0x338b, G_UNICODE_NOT_PRESENT_OFFSET, 10343 },
+  { 0x338c, G_UNICODE_NOT_PRESENT_OFFSET, 10346 },
+  { 0x338d, G_UNICODE_NOT_PRESENT_OFFSET, 10350 },
+  { 0x338e, G_UNICODE_NOT_PRESENT_OFFSET, 10354 },
+  { 0x338f, G_UNICODE_NOT_PRESENT_OFFSET, 10357 },
+  { 0x3390, G_UNICODE_NOT_PRESENT_OFFSET, 10360 },
+  { 0x3391, G_UNICODE_NOT_PRESENT_OFFSET, 10363 },
+  { 0x3392, G_UNICODE_NOT_PRESENT_OFFSET, 10367 },
+  { 0x3393, G_UNICODE_NOT_PRESENT_OFFSET, 10371 },
+  { 0x3394, G_UNICODE_NOT_PRESENT_OFFSET, 10375 },
+  { 0x3395, G_UNICODE_NOT_PRESENT_OFFSET, 10379 },
+  { 0x3396, G_UNICODE_NOT_PRESENT_OFFSET, 10383 },
+  { 0x3397, G_UNICODE_NOT_PRESENT_OFFSET, 10386 },
+  { 0x3398, G_UNICODE_NOT_PRESENT_OFFSET, 10389 },
+  { 0x3399, G_UNICODE_NOT_PRESENT_OFFSET, 10392 },
+  { 0x339a, G_UNICODE_NOT_PRESENT_OFFSET, 10395 },
+  { 0x339b, G_UNICODE_NOT_PRESENT_OFFSET, 10398 },
+  { 0x339c, G_UNICODE_NOT_PRESENT_OFFSET, 10402 },
+  { 0x339d, G_UNICODE_NOT_PRESENT_OFFSET, 10405 },
+  { 0x339e, G_UNICODE_NOT_PRESENT_OFFSET, 10408 },
+  { 0x339f, G_UNICODE_NOT_PRESENT_OFFSET, 10411 },
+  { 0x33a0, G_UNICODE_NOT_PRESENT_OFFSET, 10415 },
+  { 0x33a1, G_UNICODE_NOT_PRESENT_OFFSET, 10419 },
+  { 0x33a2, G_UNICODE_NOT_PRESENT_OFFSET, 10422 },
+  { 0x33a3, G_UNICODE_NOT_PRESENT_OFFSET, 10426 },
+  { 0x33a4, G_UNICODE_NOT_PRESENT_OFFSET, 10430 },
+  { 0x33a5, G_UNICODE_NOT_PRESENT_OFFSET, 10434 },
+  { 0x33a6, G_UNICODE_NOT_PRESENT_OFFSET, 10437 },
+  { 0x33a7, G_UNICODE_NOT_PRESENT_OFFSET, 10441 },
+  { 0x33a8, G_UNICODE_NOT_PRESENT_OFFSET, 10447 },
+  { 0x33a9, G_UNICODE_NOT_PRESENT_OFFSET, 10454 },
+  { 0x33aa, G_UNICODE_NOT_PRESENT_OFFSET, 10457 },
+  { 0x33ab, G_UNICODE_NOT_PRESENT_OFFSET, 10461 },
+  { 0x33ac, G_UNICODE_NOT_PRESENT_OFFSET, 10465 },
+  { 0x33ad, G_UNICODE_NOT_PRESENT_OFFSET, 10469 },
+  { 0x33ae, G_UNICODE_NOT_PRESENT_OFFSET, 10473 },
+  { 0x33af, G_UNICODE_NOT_PRESENT_OFFSET, 10481 },
+  { 0x33b0, G_UNICODE_NOT_PRESENT_OFFSET, 10490 },
+  { 0x33b1, G_UNICODE_NOT_PRESENT_OFFSET, 10493 },
+  { 0x33b2, G_UNICODE_NOT_PRESENT_OFFSET, 10496 },
+  { 0x33b3, G_UNICODE_NOT_PRESENT_OFFSET, 10500 },
+  { 0x33b4, G_UNICODE_NOT_PRESENT_OFFSET, 10503 },
+  { 0x33b5, G_UNICODE_NOT_PRESENT_OFFSET, 10506 },
+  { 0x33b6, G_UNICODE_NOT_PRESENT_OFFSET, 10509 },
+  { 0x33b7, G_UNICODE_NOT_PRESENT_OFFSET, 10513 },
+  { 0x33b8, G_UNICODE_NOT_PRESENT_OFFSET, 10516 },
+  { 0x33b9, G_UNICODE_NOT_PRESENT_OFFSET, 10519 },
+  { 0x33ba, G_UNICODE_NOT_PRESENT_OFFSET, 10522 },
+  { 0x33bb, G_UNICODE_NOT_PRESENT_OFFSET, 10525 },
+  { 0x33bc, G_UNICODE_NOT_PRESENT_OFFSET, 10528 },
+  { 0x33bd, G_UNICODE_NOT_PRESENT_OFFSET, 10532 },
+  { 0x33be, G_UNICODE_NOT_PRESENT_OFFSET, 10535 },
+  { 0x33bf, G_UNICODE_NOT_PRESENT_OFFSET, 10538 },
+  { 0x33c0, G_UNICODE_NOT_PRESENT_OFFSET, 10541 },
+  { 0x33c1, G_UNICODE_NOT_PRESENT_OFFSET, 10545 },
+  { 0x33c2, G_UNICODE_NOT_PRESENT_OFFSET, 10549 },
+  { 0x33c3, G_UNICODE_NOT_PRESENT_OFFSET, 10554 },
+  { 0x33c4, G_UNICODE_NOT_PRESENT_OFFSET, 10557 },
+  { 0x33c5, G_UNICODE_NOT_PRESENT_OFFSET, 10560 },
+  { 0x33c6, G_UNICODE_NOT_PRESENT_OFFSET, 10563 },
+  { 0x33c7, G_UNICODE_NOT_PRESENT_OFFSET, 10570 },
+  { 0x33c8, G_UNICODE_NOT_PRESENT_OFFSET, 10574 },
+  { 0x33c9, G_UNICODE_NOT_PRESENT_OFFSET, 10577 },
+  { 0x33ca, G_UNICODE_NOT_PRESENT_OFFSET, 10580 },
+  { 0x33cb, G_UNICODE_NOT_PRESENT_OFFSET, 10583 },
+  { 0x33cc, G_UNICODE_NOT_PRESENT_OFFSET, 10586 },
+  { 0x33cd, G_UNICODE_NOT_PRESENT_OFFSET, 10589 },
+  { 0x33ce, G_UNICODE_NOT_PRESENT_OFFSET, 10592 },
+  { 0x33cf, G_UNICODE_NOT_PRESENT_OFFSET, 10595 },
+  { 0x33d0, G_UNICODE_NOT_PRESENT_OFFSET, 10598 },
+  { 0x33d1, G_UNICODE_NOT_PRESENT_OFFSET, 10601 },
+  { 0x33d2, G_UNICODE_NOT_PRESENT_OFFSET, 10604 },
+  { 0x33d3, G_UNICODE_NOT_PRESENT_OFFSET, 10608 },
+  { 0x33d4, G_UNICODE_NOT_PRESENT_OFFSET, 10611 },
+  { 0x33d5, G_UNICODE_NOT_PRESENT_OFFSET, 10614 },
+  { 0x33d6, G_UNICODE_NOT_PRESENT_OFFSET, 10618 },
+  { 0x33d7, G_UNICODE_NOT_PRESENT_OFFSET, 10622 },
+  { 0x33d8, G_UNICODE_NOT_PRESENT_OFFSET, 10625 },
+  { 0x33d9, G_UNICODE_NOT_PRESENT_OFFSET, 10630 },
+  { 0x33da, G_UNICODE_NOT_PRESENT_OFFSET, 10634 },
+  { 0x33db, G_UNICODE_NOT_PRESENT_OFFSET, 10637 },
+  { 0x33dc, G_UNICODE_NOT_PRESENT_OFFSET, 10640 },
+  { 0x33dd, G_UNICODE_NOT_PRESENT_OFFSET, 10643 },
+  { 0x33de, G_UNICODE_NOT_PRESENT_OFFSET, 10646 },
+  { 0x33df, G_UNICODE_NOT_PRESENT_OFFSET, 10652 },
+  { 0x33e0, G_UNICODE_NOT_PRESENT_OFFSET, 10658 },
+  { 0x33e1, G_UNICODE_NOT_PRESENT_OFFSET, 10663 },
+  { 0x33e2, G_UNICODE_NOT_PRESENT_OFFSET, 10668 },
+  { 0x33e3, G_UNICODE_NOT_PRESENT_OFFSET, 10673 },
+  { 0x33e4, G_UNICODE_NOT_PRESENT_OFFSET, 10678 },
+  { 0x33e5, G_UNICODE_NOT_PRESENT_OFFSET, 10683 },
+  { 0x33e6, G_UNICODE_NOT_PRESENT_OFFSET, 10688 },
+  { 0x33e7, G_UNICODE_NOT_PRESENT_OFFSET, 10693 },
+  { 0x33e8, G_UNICODE_NOT_PRESENT_OFFSET, 10698 },
+  { 0x33e9, G_UNICODE_NOT_PRESENT_OFFSET, 10703 },
+  { 0x33ea, G_UNICODE_NOT_PRESENT_OFFSET, 10709 },
+  { 0x33eb, G_UNICODE_NOT_PRESENT_OFFSET, 10715 },
+  { 0x33ec, G_UNICODE_NOT_PRESENT_OFFSET, 10721 },
+  { 0x33ed, G_UNICODE_NOT_PRESENT_OFFSET, 10727 },
+  { 0x33ee, G_UNICODE_NOT_PRESENT_OFFSET, 10733 },
+  { 0x33ef, G_UNICODE_NOT_PRESENT_OFFSET, 10739 },
+  { 0x33f0, G_UNICODE_NOT_PRESENT_OFFSET, 10745 },
+  { 0x33f1, G_UNICODE_NOT_PRESENT_OFFSET, 10751 },
+  { 0x33f2, G_UNICODE_NOT_PRESENT_OFFSET, 10757 },
+  { 0x33f3, G_UNICODE_NOT_PRESENT_OFFSET, 10763 },
+  { 0x33f4, G_UNICODE_NOT_PRESENT_OFFSET, 10769 },
+  { 0x33f5, G_UNICODE_NOT_PRESENT_OFFSET, 10775 },
+  { 0x33f6, G_UNICODE_NOT_PRESENT_OFFSET, 10781 },
+  { 0x33f7, G_UNICODE_NOT_PRESENT_OFFSET, 10787 },
+  { 0x33f8, G_UNICODE_NOT_PRESENT_OFFSET, 10793 },
+  { 0x33f9, G_UNICODE_NOT_PRESENT_OFFSET, 10799 },
+  { 0x33fa, G_UNICODE_NOT_PRESENT_OFFSET, 10805 },
+  { 0x33fb, G_UNICODE_NOT_PRESENT_OFFSET, 10811 },
+  { 0x33fc, G_UNICODE_NOT_PRESENT_OFFSET, 10817 },
+  { 0x33fd, G_UNICODE_NOT_PRESENT_OFFSET, 10823 },
+  { 0x33fe, G_UNICODE_NOT_PRESENT_OFFSET, 10829 },
+  { 0x33ff, G_UNICODE_NOT_PRESENT_OFFSET, 10835 },
+  { 0xf900, 10839, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf901, 10843, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf902, 6788, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf903, 10847, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf904, 10851, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf905, 10855, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf906, 10859, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf907, 7004, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf908, 7004, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf909, 10863, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf90a, 6820, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf90b, 10867, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf90c, 10871, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf90d, 10875, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf90e, 10879, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf90f, 10883, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf910, 10887, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf911, 10891, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf912, 10895, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf913, 10899, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf914, 10903, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf915, 10907, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf916, 10911, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf917, 10915, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf918, 10919, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf919, 10923, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf91a, 10927, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf91b, 10931, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf91c, 10935, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf91d, 10939, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf91e, 10943, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf91f, 10947, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf920, 10951, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf921, 10955, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf922, 10959, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf923, 10963, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf924, 10967, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf925, 10971, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf926, 10975, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf927, 10979, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf928, 10983, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf929, 10987, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf92a, 10991, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf92b, 10995, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf92c, 10999, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf92d, 11003, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf92e, 11007, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf92f, 11011, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf930, 11015, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf931, 11019, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf932, 11023, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf933, 11027, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf934, 6652, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf935, 11031, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf936, 11035, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf937, 11039, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf938, 11043, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf939, 11047, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf93a, 11051, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf93b, 11055, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf93c, 11059, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf93d, 11063, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf93e, 11067, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf93f, 11071, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf940, 6944, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf941, 11075, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf942, 11079, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf943, 11083, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf944, 11087, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf945, 11091, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf946, 11095, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf947, 11099, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf948, 11103, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf949, 11107, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf94a, 11111, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf94b, 11115, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf94c, 11119, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf94d, 11123, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf94e, 11127, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf94f, 11131, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf950, 11135, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf951, 11139, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf952, 11143, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf953, 11147, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf954, 11151, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf955, 11155, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf956, 11159, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf957, 11163, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf958, 11167, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf959, 11171, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf95a, 11175, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf95b, 11179, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf95c, 10903, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf95d, 11183, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf95e, 11187, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf95f, 11191, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf960, 11195, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf961, 11199, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf962, 11203, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf963, 11207, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf964, 11211, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf965, 11215, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf966, 11219, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf967, 11223, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf968, 11227, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf969, 11231, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf96a, 11235, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf96b, 11239, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf96c, 11243, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf96d, 11247, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf96e, 11251, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf96f, 11255, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf970, 11259, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf971, 6796, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf972, 11263, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf973, 11267, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf974, 11271, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf975, 11275, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf976, 11279, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf977, 11283, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf978, 11287, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf979, 11291, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf97a, 11295, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf97b, 11299, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf97c, 11303, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf97d, 11307, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf97e, 11311, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf97f, 11315, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf980, 11319, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf981, 6304, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf982, 11323, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf983, 11327, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf984, 11331, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf985, 11335, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf986, 11339, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf987, 11343, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf988, 11347, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf989, 11351, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf98a, 6228, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf98b, 11355, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf98c, 11359, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf98d, 11363, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf98e, 11367, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf98f, 11371, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf990, 11375, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf991, 11379, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf992, 11383, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf993, 11387, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf994, 11391, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf995, 11395, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf996, 11399, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf997, 11403, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf998, 11407, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf999, 11411, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf99a, 11415, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf99b, 11419, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf99c, 11423, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf99d, 11427, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf99e, 11431, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf99f, 11435, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9a0, 11439, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9a1, 11255, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9a2, 11443, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9a3, 11447, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9a4, 11451, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9a5, 11455, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9a6, 11459, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9a7, 11463, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9a8, 11467, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9a9, 11471, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9aa, 11191, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9ab, 11475, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9ac, 11479, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9ad, 11483, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9ae, 11487, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9af, 11491, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9b0, 11495, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9b1, 11499, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9b2, 11503, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9b3, 11507, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9b4, 11511, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9b5, 11515, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9b6, 11519, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9b7, 11523, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9b8, 11527, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9b9, 11531, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9ba, 11535, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9bb, 11539, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9bc, 11543, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9bd, 11547, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9be, 11551, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9bf, 10903, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9c0, 11555, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9c1, 11559, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9c2, 11563, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9c3, 11567, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9c4, 7000, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9c5, 11571, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9c6, 11575, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9c7, 11579, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9c8, 11583, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9c9, 11587, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9ca, 11591, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9cb, 11595, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9cc, 11599, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9cd, 11603, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9ce, 11607, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9cf, 11611, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9d0, 11615, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9d1, 8525, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9d2, 11619, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9d3, 11623, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9d4, 11627, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9d5, 11631, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9d6, 11635, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9d7, 11639, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9d8, 11643, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9d9, 11647, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9da, 11651, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9db, 11199, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9dc, 11655, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9dd, 11659, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9de, 11663, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9df, 11667, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9e0, 11671, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9e1, 11675, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9e2, 11679, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9e3, 11683, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9e4, 11687, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9e5, 11691, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9e6, 11695, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9e7, 11699, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9e8, 11703, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9e9, 6816, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9ea, 11707, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9eb, 11711, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9ec, 11715, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9ed, 11719, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9ee, 11723, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9ef, 11727, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9f0, 11731, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9f1, 11735, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9f2, 11739, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9f3, 11743, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9f4, 11747, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9f5, 11751, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9f6, 11755, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9f7, 6620, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9f8, 11759, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9f9, 11763, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9fa, 11767, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9fb, 11771, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9fc, 11775, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9fd, 11779, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9fe, 11783, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xf9ff, 11787, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa00, 11791, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa01, 11795, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa02, 11799, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa03, 11803, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa04, 11807, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa05, 11811, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa06, 11815, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa07, 11819, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa08, 6728, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa09, 11823, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa0a, 6740, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa0b, 11827, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa0c, 11831, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa0d, 11835, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa10, 11839, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa12, 11843, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa15, 11847, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa16, 11851, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa17, 11855, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa18, 11859, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa19, 11863, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa1a, 11867, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa1b, 11871, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa1c, 11875, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa1d, 11879, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa1e, 6648, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa20, 11883, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa22, 11887, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa25, 11891, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa26, 11895, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa2a, 11899, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa2b, 11903, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa2c, 11907, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa2d, 11911, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa30, 11915, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa31, 11919, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa32, 11923, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa33, 11927, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa34, 11931, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa35, 11935, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa36, 11939, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa37, 11943, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa38, 11947, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa39, 11951, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa3a, 11955, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa3b, 11959, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa3c, 6332, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa3d, 11963, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa3e, 11967, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa3f, 11971, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa40, 11975, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa41, 11979, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa42, 11983, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa43, 11987, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa44, 11991, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa45, 11995, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa46, 11999, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa47, 12003, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa48, 12007, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa49, 12011, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa4a, 12015, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa4b, 12019, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa4c, 8545, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa4d, 12023, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa4e, 12027, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa4f, 12031, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa50, 12035, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa51, 8561, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa52, 12039, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa53, 12043, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa54, 12047, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa55, 12051, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa56, 12055, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa57, 11399, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa58, 12059, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa59, 12063, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa5a, 12067, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa5b, 12071, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa5c, 12075, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa5d, 12079, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa5e, 12079, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa5f, 12083, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa60, 12087, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa61, 12091, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa62, 12095, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa63, 12099, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa64, 12103, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa65, 12107, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa66, 12111, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa67, 11891, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa68, 12115, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa69, 12119, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa6a, 12123, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa70, 12127, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa71, 12131, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa72, 12135, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa73, 12139, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa74, 12143, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa75, 12147, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa76, 12151, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa77, 12155, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa78, 11939, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa79, 12159, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa7a, 12163, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa7b, 12167, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa7c, 11839, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa7d, 12171, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa7e, 12175, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa7f, 12179, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa80, 12183, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa81, 12187, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa82, 12191, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa83, 12195, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa84, 12199, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa85, 12203, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa86, 12207, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa87, 12211, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa88, 12215, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa89, 11971, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa8a, 12219, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa8b, 11975, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa8c, 12223, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa8d, 12227, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa8e, 12231, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa8f, 12235, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa90, 12239, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa91, 11843, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa92, 10987, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa93, 12243, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa94, 12247, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa95, 6464, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa96, 11259, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa97, 11591, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa98, 12251, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa99, 12255, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa9a, 12003, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa9b, 12259, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa9c, 12007, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa9d, 12263, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa9e, 12267, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfa9f, 12271, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaa0, 11851, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaa1, 12275, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaa2, 12279, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaa3, 12283, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaa4, 12287, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaa5, 12291, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaa6, 11855, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaa7, 12295, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaa8, 12299, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaa9, 12303, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaaa, 12307, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaab, 12311, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaac, 12315, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaad, 12055, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaae, 12319, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaaf, 12323, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfab0, 11399, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfab1, 12327, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfab2, 12071, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfab3, 12331, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfab4, 12335, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfab5, 12339, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfab6, 12343, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfab7, 12347, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfab8, 12091, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfab9, 12351, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaba, 11887, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfabb, 12355, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfabc, 12095, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfabd, 11183, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfabe, 12359, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfabf, 12099, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfac0, 12363, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfac1, 12107, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfac2, 12367, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfac3, 12371, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfac4, 12375, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfac5, 12379, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfac6, 12383, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfac7, 12115, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfac8, 11875, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfac9, 12387, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfaca, 12119, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfacb, 12391, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfacc, 12123, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfacd, 12395, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xface, 7004, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfacf, 12399, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfad0, 12404, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfad1, 12409, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfad2, 12414, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfad3, 12418, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfad4, 12422, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfad5, 12426, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfad6, 12431, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfad7, 12436, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfad8, 12441, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfad9, 12445, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb00, G_UNICODE_NOT_PRESENT_OFFSET, 12449 },
+  { 0xfb01, G_UNICODE_NOT_PRESENT_OFFSET, 12452 },
+  { 0xfb02, G_UNICODE_NOT_PRESENT_OFFSET, 12455 },
+  { 0xfb03, G_UNICODE_NOT_PRESENT_OFFSET, 12458 },
+  { 0xfb04, G_UNICODE_NOT_PRESENT_OFFSET, 12462 },
+  { 0xfb05, G_UNICODE_NOT_PRESENT_OFFSET, 12466 },
+  { 0xfb06, G_UNICODE_NOT_PRESENT_OFFSET, 12466 },
+  { 0xfb13, G_UNICODE_NOT_PRESENT_OFFSET, 12469 },
+  { 0xfb14, G_UNICODE_NOT_PRESENT_OFFSET, 12474 },
+  { 0xfb15, G_UNICODE_NOT_PRESENT_OFFSET, 12479 },
+  { 0xfb16, G_UNICODE_NOT_PRESENT_OFFSET, 12484 },
+  { 0xfb17, G_UNICODE_NOT_PRESENT_OFFSET, 12489 },
+  { 0xfb1d, 12494, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb1f, 12499, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb20, G_UNICODE_NOT_PRESENT_OFFSET, 12504 },
+  { 0xfb21, G_UNICODE_NOT_PRESENT_OFFSET, 5338 },
+  { 0xfb22, G_UNICODE_NOT_PRESENT_OFFSET, 5347 },
+  { 0xfb23, G_UNICODE_NOT_PRESENT_OFFSET, 12507 },
+  { 0xfb24, G_UNICODE_NOT_PRESENT_OFFSET, 12510 },
+  { 0xfb25, G_UNICODE_NOT_PRESENT_OFFSET, 12513 },
+  { 0xfb26, G_UNICODE_NOT_PRESENT_OFFSET, 12516 },
+  { 0xfb27, G_UNICODE_NOT_PRESENT_OFFSET, 12519 },
+  { 0xfb28, G_UNICODE_NOT_PRESENT_OFFSET, 12522 },
+  { 0xfb29, G_UNICODE_NOT_PRESENT_OFFSET, 5267 },
+  { 0xfb2a, 12525, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb2b, 12530, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb2c, 12535, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb2d, 12542, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb2e, 12549, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb2f, 12554, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb30, 12559, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb31, 12564, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb32, 12569, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb33, 12574, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb34, 12579, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb35, 12584, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb36, 12589, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb38, 12594, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb39, 12599, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb3a, 12604, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb3b, 12609, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb3c, 12614, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb3e, 12619, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb40, 12624, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb41, 12629, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb43, 12634, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb44, 12639, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb46, 12644, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb47, 12649, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb48, 12654, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb49, 12659, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb4a, 12664, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb4b, 12669, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb4c, 12674, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb4d, 12679, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb4e, 12684, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0xfb4f, G_UNICODE_NOT_PRESENT_OFFSET, 12689 },
+  { 0xfb50, G_UNICODE_NOT_PRESENT_OFFSET, 12694 },
+  { 0xfb51, G_UNICODE_NOT_PRESENT_OFFSET, 12694 },
+  { 0xfb52, G_UNICODE_NOT_PRESENT_OFFSET, 12697 },
+  { 0xfb53, G_UNICODE_NOT_PRESENT_OFFSET, 12697 },
+  { 0xfb54, G_UNICODE_NOT_PRESENT_OFFSET, 12697 },
+  { 0xfb55, G_UNICODE_NOT_PRESENT_OFFSET, 12697 },
+  { 0xfb56, G_UNICODE_NOT_PRESENT_OFFSET, 12700 },
+  { 0xfb57, G_UNICODE_NOT_PRESENT_OFFSET, 12700 },
+  { 0xfb58, G_UNICODE_NOT_PRESENT_OFFSET, 12700 },
+  { 0xfb59, G_UNICODE_NOT_PRESENT_OFFSET, 12700 },
+  { 0xfb5a, G_UNICODE_NOT_PRESENT_OFFSET, 12703 },
+  { 0xfb5b, G_UNICODE_NOT_PRESENT_OFFSET, 12703 },
+  { 0xfb5c, G_UNICODE_NOT_PRESENT_OFFSET, 12703 },
+  { 0xfb5d, G_UNICODE_NOT_PRESENT_OFFSET, 12703 },
+  { 0xfb5e, G_UNICODE_NOT_PRESENT_OFFSET, 12706 },
+  { 0xfb5f, G_UNICODE_NOT_PRESENT_OFFSET, 12706 },
+  { 0xfb60, G_UNICODE_NOT_PRESENT_OFFSET, 12706 },
+  { 0xfb61, G_UNICODE_NOT_PRESENT_OFFSET, 12706 },
+  { 0xfb62, G_UNICODE_NOT_PRESENT_OFFSET, 12709 },
+  { 0xfb63, G_UNICODE_NOT_PRESENT_OFFSET, 12709 },
+  { 0xfb64, G_UNICODE_NOT_PRESENT_OFFSET, 12709 },
+  { 0xfb65, G_UNICODE_NOT_PRESENT_OFFSET, 12709 },
+  { 0xfb66, G_UNICODE_NOT_PRESENT_OFFSET, 12712 },
+  { 0xfb67, G_UNICODE_NOT_PRESENT_OFFSET, 12712 },
+  { 0xfb68, G_UNICODE_NOT_PRESENT_OFFSET, 12712 },
+  { 0xfb69, G_UNICODE_NOT_PRESENT_OFFSET, 12712 },
+  { 0xfb6a, G_UNICODE_NOT_PRESENT_OFFSET, 12715 },
+  { 0xfb6b, G_UNICODE_NOT_PRESENT_OFFSET, 12715 },
+  { 0xfb6c, G_UNICODE_NOT_PRESENT_OFFSET, 12715 },
+  { 0xfb6d, G_UNICODE_NOT_PRESENT_OFFSET, 12715 },
+  { 0xfb6e, G_UNICODE_NOT_PRESENT_OFFSET, 12718 },
+  { 0xfb6f, G_UNICODE_NOT_PRESENT_OFFSET, 12718 },
+  { 0xfb70, G_UNICODE_NOT_PRESENT_OFFSET, 12718 },
+  { 0xfb71, G_UNICODE_NOT_PRESENT_OFFSET, 12718 },
+  { 0xfb72, G_UNICODE_NOT_PRESENT_OFFSET, 12721 },
+  { 0xfb73, G_UNICODE_NOT_PRESENT_OFFSET, 12721 },
+  { 0xfb74, G_UNICODE_NOT_PRESENT_OFFSET, 12721 },
+  { 0xfb75, G_UNICODE_NOT_PRESENT_OFFSET, 12721 },
+  { 0xfb76, G_UNICODE_NOT_PRESENT_OFFSET, 12724 },
+  { 0xfb77, G_UNICODE_NOT_PRESENT_OFFSET, 12724 },
+  { 0xfb78, G_UNICODE_NOT_PRESENT_OFFSET, 12724 },
+  { 0xfb79, G_UNICODE_NOT_PRESENT_OFFSET, 12724 },
+  { 0xfb7a, G_UNICODE_NOT_PRESENT_OFFSET, 12727 },
+  { 0xfb7b, G_UNICODE_NOT_PRESENT_OFFSET, 12727 },
+  { 0xfb7c, G_UNICODE_NOT_PRESENT_OFFSET, 12727 },
+  { 0xfb7d, G_UNICODE_NOT_PRESENT_OFFSET, 12727 },
+  { 0xfb7e, G_UNICODE_NOT_PRESENT_OFFSET, 12730 },
+  { 0xfb7f, G_UNICODE_NOT_PRESENT_OFFSET, 12730 },
+  { 0xfb80, G_UNICODE_NOT_PRESENT_OFFSET, 12730 },
+  { 0xfb81, G_UNICODE_NOT_PRESENT_OFFSET, 12730 },
+  { 0xfb82, G_UNICODE_NOT_PRESENT_OFFSET, 12733 },
+  { 0xfb83, G_UNICODE_NOT_PRESENT_OFFSET, 12733 },
+  { 0xfb84, G_UNICODE_NOT_PRESENT_OFFSET, 12736 },
+  { 0xfb85, G_UNICODE_NOT_PRESENT_OFFSET, 12736 },
+  { 0xfb86, G_UNICODE_NOT_PRESENT_OFFSET, 12739 },
+  { 0xfb87, G_UNICODE_NOT_PRESENT_OFFSET, 12739 },
+  { 0xfb88, G_UNICODE_NOT_PRESENT_OFFSET, 12742 },
+  { 0xfb89, G_UNICODE_NOT_PRESENT_OFFSET, 12742 },
+  { 0xfb8a, G_UNICODE_NOT_PRESENT_OFFSET, 12745 },
+  { 0xfb8b, G_UNICODE_NOT_PRESENT_OFFSET, 12745 },
+  { 0xfb8c, G_UNICODE_NOT_PRESENT_OFFSET, 12748 },
+  { 0xfb8d, G_UNICODE_NOT_PRESENT_OFFSET, 12748 },
+  { 0xfb8e, G_UNICODE_NOT_PRESENT_OFFSET, 12751 },
+  { 0xfb8f, G_UNICODE_NOT_PRESENT_OFFSET, 12751 },
+  { 0xfb90, G_UNICODE_NOT_PRESENT_OFFSET, 12751 },
+  { 0xfb91, G_UNICODE_NOT_PRESENT_OFFSET, 12751 },
+  { 0xfb92, G_UNICODE_NOT_PRESENT_OFFSET, 12754 },
+  { 0xfb93, G_UNICODE_NOT_PRESENT_OFFSET, 12754 },
+  { 0xfb94, G_UNICODE_NOT_PRESENT_OFFSET, 12754 },
+  { 0xfb95, G_UNICODE_NOT_PRESENT_OFFSET, 12754 },
+  { 0xfb96, G_UNICODE_NOT_PRESENT_OFFSET, 12757 },
+  { 0xfb97, G_UNICODE_NOT_PRESENT_OFFSET, 12757 },
+  { 0xfb98, G_UNICODE_NOT_PRESENT_OFFSET, 12757 },
+  { 0xfb99, G_UNICODE_NOT_PRESENT_OFFSET, 12757 },
+  { 0xfb9a, G_UNICODE_NOT_PRESENT_OFFSET, 12760 },
+  { 0xfb9b, G_UNICODE_NOT_PRESENT_OFFSET, 12760 },
+  { 0xfb9c, G_UNICODE_NOT_PRESENT_OFFSET, 12760 },
+  { 0xfb9d, G_UNICODE_NOT_PRESENT_OFFSET, 12760 },
+  { 0xfb9e, G_UNICODE_NOT_PRESENT_OFFSET, 12763 },
+  { 0xfb9f, G_UNICODE_NOT_PRESENT_OFFSET, 12763 },
+  { 0xfba0, G_UNICODE_NOT_PRESENT_OFFSET, 12766 },
+  { 0xfba1, G_UNICODE_NOT_PRESENT_OFFSET, 12766 },
+  { 0xfba2, G_UNICODE_NOT_PRESENT_OFFSET, 12766 },
+  { 0xfba3, G_UNICODE_NOT_PRESENT_OFFSET, 12766 },
+  { 0xfba4, G_UNICODE_NOT_PRESENT_OFFSET, 1721 },
+  { 0xfba5, G_UNICODE_NOT_PRESENT_OFFSET, 1721 },
+  { 0xfba6, G_UNICODE_NOT_PRESENT_OFFSET, 12769 },
+  { 0xfba7, G_UNICODE_NOT_PRESENT_OFFSET, 12769 },
+  { 0xfba8, G_UNICODE_NOT_PRESENT_OFFSET, 12769 },
+  { 0xfba9, G_UNICODE_NOT_PRESENT_OFFSET, 12769 },
+  { 0xfbaa, G_UNICODE_NOT_PRESENT_OFFSET, 12772 },
+  { 0xfbab, G_UNICODE_NOT_PRESENT_OFFSET, 12772 },
+  { 0xfbac, G_UNICODE_NOT_PRESENT_OFFSET, 12772 },
+  { 0xfbad, G_UNICODE_NOT_PRESENT_OFFSET, 12772 },
+  { 0xfbae, G_UNICODE_NOT_PRESENT_OFFSET, 12775 },
+  { 0xfbaf, G_UNICODE_NOT_PRESENT_OFFSET, 12775 },
+  { 0xfbb0, G_UNICODE_NOT_PRESENT_OFFSET, 1731 },
+  { 0xfbb1, G_UNICODE_NOT_PRESENT_OFFSET, 1731 },
+  { 0xfbd3, G_UNICODE_NOT_PRESENT_OFFSET, 12778 },
+  { 0xfbd4, G_UNICODE_NOT_PRESENT_OFFSET, 12778 },
+  { 0xfbd5, G_UNICODE_NOT_PRESENT_OFFSET, 12778 },
+  { 0xfbd6, G_UNICODE_NOT_PRESENT_OFFSET, 12778 },
+  { 0xfbd7, G_UNICODE_NOT_PRESENT_OFFSET, 12781 },
+  { 0xfbd8, G_UNICODE_NOT_PRESENT_OFFSET, 12781 },
+  { 0xfbd9, G_UNICODE_NOT_PRESENT_OFFSET, 12784 },
+  { 0xfbda, G_UNICODE_NOT_PRESENT_OFFSET, 12784 },
+  { 0xfbdb, G_UNICODE_NOT_PRESENT_OFFSET, 12787 },
+  { 0xfbdc, G_UNICODE_NOT_PRESENT_OFFSET, 12787 },
+  { 0xfbdd, G_UNICODE_NOT_PRESENT_OFFSET, 1711 },
+  { 0xfbde, G_UNICODE_NOT_PRESENT_OFFSET, 12790 },
+  { 0xfbdf, G_UNICODE_NOT_PRESENT_OFFSET, 12790 },
+  { 0xfbe0, G_UNICODE_NOT_PRESENT_OFFSET, 12793 },
+  { 0xfbe1, G_UNICODE_NOT_PRESENT_OFFSET, 12793 },
+  { 0xfbe2, G_UNICODE_NOT_PRESENT_OFFSET, 12796 },
+  { 0xfbe3, G_UNICODE_NOT_PRESENT_OFFSET, 12796 },
+  { 0xfbe4, G_UNICODE_NOT_PRESENT_OFFSET, 12799 },
+  { 0xfbe5, G_UNICODE_NOT_PRESENT_OFFSET, 12799 },
+  { 0xfbe6, G_UNICODE_NOT_PRESENT_OFFSET, 12799 },
+  { 0xfbe7, G_UNICODE_NOT_PRESENT_OFFSET, 12799 },
+  { 0xfbe8, G_UNICODE_NOT_PRESENT_OFFSET, 12802 },
+  { 0xfbe9, G_UNICODE_NOT_PRESENT_OFFSET, 12802 },
+  { 0xfbea, G_UNICODE_NOT_PRESENT_OFFSET, 12805 },
+  { 0xfbeb, G_UNICODE_NOT_PRESENT_OFFSET, 12805 },
+  { 0xfbec, G_UNICODE_NOT_PRESENT_OFFSET, 12812 },
+  { 0xfbed, G_UNICODE_NOT_PRESENT_OFFSET, 12812 },
+  { 0xfbee, G_UNICODE_NOT_PRESENT_OFFSET, 12819 },
+  { 0xfbef, G_UNICODE_NOT_PRESENT_OFFSET, 12819 },
+  { 0xfbf0, G_UNICODE_NOT_PRESENT_OFFSET, 12826 },
+  { 0xfbf1, G_UNICODE_NOT_PRESENT_OFFSET, 12826 },
+  { 0xfbf2, G_UNICODE_NOT_PRESENT_OFFSET, 12833 },
+  { 0xfbf3, G_UNICODE_NOT_PRESENT_OFFSET, 12833 },
+  { 0xfbf4, G_UNICODE_NOT_PRESENT_OFFSET, 12840 },
+  { 0xfbf5, G_UNICODE_NOT_PRESENT_OFFSET, 12840 },
+  { 0xfbf6, G_UNICODE_NOT_PRESENT_OFFSET, 12847 },
+  { 0xfbf7, G_UNICODE_NOT_PRESENT_OFFSET, 12847 },
+  { 0xfbf8, G_UNICODE_NOT_PRESENT_OFFSET, 12847 },
+  { 0xfbf9, G_UNICODE_NOT_PRESENT_OFFSET, 12854 },
+  { 0xfbfa, G_UNICODE_NOT_PRESENT_OFFSET, 12854 },
+  { 0xfbfb, G_UNICODE_NOT_PRESENT_OFFSET, 12854 },
+  { 0xfbfc, G_UNICODE_NOT_PRESENT_OFFSET, 12861 },
+  { 0xfbfd, G_UNICODE_NOT_PRESENT_OFFSET, 12861 },
+  { 0xfbfe, G_UNICODE_NOT_PRESENT_OFFSET, 12861 },
+  { 0xfbff, G_UNICODE_NOT_PRESENT_OFFSET, 12861 },
+  { 0xfc00, G_UNICODE_NOT_PRESENT_OFFSET, 12864 },
+  { 0xfc01, G_UNICODE_NOT_PRESENT_OFFSET, 12871 },
+  { 0xfc02, G_UNICODE_NOT_PRESENT_OFFSET, 12878 },
+  { 0xfc03, G_UNICODE_NOT_PRESENT_OFFSET, 12854 },
+  { 0xfc04, G_UNICODE_NOT_PRESENT_OFFSET, 12885 },
+  { 0xfc05, G_UNICODE_NOT_PRESENT_OFFSET, 12892 },
+  { 0xfc06, G_UNICODE_NOT_PRESENT_OFFSET, 12897 },
+  { 0xfc07, G_UNICODE_NOT_PRESENT_OFFSET, 12902 },
+  { 0xfc08, G_UNICODE_NOT_PRESENT_OFFSET, 12907 },
+  { 0xfc09, G_UNICODE_NOT_PRESENT_OFFSET, 12912 },
+  { 0xfc0a, G_UNICODE_NOT_PRESENT_OFFSET, 12917 },
+  { 0xfc0b, G_UNICODE_NOT_PRESENT_OFFSET, 12922 },
+  { 0xfc0c, G_UNICODE_NOT_PRESENT_OFFSET, 12927 },
+  { 0xfc0d, G_UNICODE_NOT_PRESENT_OFFSET, 12932 },
+  { 0xfc0e, G_UNICODE_NOT_PRESENT_OFFSET, 12937 },
+  { 0xfc0f, G_UNICODE_NOT_PRESENT_OFFSET, 12942 },
+  { 0xfc10, G_UNICODE_NOT_PRESENT_OFFSET, 12947 },
+  { 0xfc11, G_UNICODE_NOT_PRESENT_OFFSET, 12952 },
+  { 0xfc12, G_UNICODE_NOT_PRESENT_OFFSET, 12957 },
+  { 0xfc13, G_UNICODE_NOT_PRESENT_OFFSET, 12962 },
+  { 0xfc14, G_UNICODE_NOT_PRESENT_OFFSET, 12967 },
+  { 0xfc15, G_UNICODE_NOT_PRESENT_OFFSET, 12972 },
+  { 0xfc16, G_UNICODE_NOT_PRESENT_OFFSET, 12977 },
+  { 0xfc17, G_UNICODE_NOT_PRESENT_OFFSET, 12982 },
+  { 0xfc18, G_UNICODE_NOT_PRESENT_OFFSET, 12987 },
+  { 0xfc19, G_UNICODE_NOT_PRESENT_OFFSET, 12992 },
+  { 0xfc1a, G_UNICODE_NOT_PRESENT_OFFSET, 12997 },
+  { 0xfc1b, G_UNICODE_NOT_PRESENT_OFFSET, 13002 },
+  { 0xfc1c, G_UNICODE_NOT_PRESENT_OFFSET, 13007 },
+  { 0xfc1d, G_UNICODE_NOT_PRESENT_OFFSET, 13012 },
+  { 0xfc1e, G_UNICODE_NOT_PRESENT_OFFSET, 13017 },
+  { 0xfc1f, G_UNICODE_NOT_PRESENT_OFFSET, 13022 },
+  { 0xfc20, G_UNICODE_NOT_PRESENT_OFFSET, 13027 },
+  { 0xfc21, G_UNICODE_NOT_PRESENT_OFFSET, 13032 },
+  { 0xfc22, G_UNICODE_NOT_PRESENT_OFFSET, 13037 },
+  { 0xfc23, G_UNICODE_NOT_PRESENT_OFFSET, 13042 },
+  { 0xfc24, G_UNICODE_NOT_PRESENT_OFFSET, 13047 },
+  { 0xfc25, G_UNICODE_NOT_PRESENT_OFFSET, 13052 },
+  { 0xfc26, G_UNICODE_NOT_PRESENT_OFFSET, 13057 },
+  { 0xfc27, G_UNICODE_NOT_PRESENT_OFFSET, 13062 },
+  { 0xfc28, G_UNICODE_NOT_PRESENT_OFFSET, 13067 },
+  { 0xfc29, G_UNICODE_NOT_PRESENT_OFFSET, 13072 },
+  { 0xfc2a, G_UNICODE_NOT_PRESENT_OFFSET, 13077 },
+  { 0xfc2b, G_UNICODE_NOT_PRESENT_OFFSET, 13082 },
+  { 0xfc2c, G_UNICODE_NOT_PRESENT_OFFSET, 13087 },
+  { 0xfc2d, G_UNICODE_NOT_PRESENT_OFFSET, 13092 },
+  { 0xfc2e, G_UNICODE_NOT_PRESENT_OFFSET, 13097 },
+  { 0xfc2f, G_UNICODE_NOT_PRESENT_OFFSET, 13102 },
+  { 0xfc30, G_UNICODE_NOT_PRESENT_OFFSET, 13107 },
+  { 0xfc31, G_UNICODE_NOT_PRESENT_OFFSET, 13112 },
+  { 0xfc32, G_UNICODE_NOT_PRESENT_OFFSET, 13117 },
+  { 0xfc33, G_UNICODE_NOT_PRESENT_OFFSET, 13122 },
+  { 0xfc34, G_UNICODE_NOT_PRESENT_OFFSET, 13127 },
+  { 0xfc35, G_UNICODE_NOT_PRESENT_OFFSET, 13132 },
+  { 0xfc36, G_UNICODE_NOT_PRESENT_OFFSET, 13137 },
+  { 0xfc37, G_UNICODE_NOT_PRESENT_OFFSET, 13142 },
+  { 0xfc38, G_UNICODE_NOT_PRESENT_OFFSET, 13147 },
+  { 0xfc39, G_UNICODE_NOT_PRESENT_OFFSET, 13152 },
+  { 0xfc3a, G_UNICODE_NOT_PRESENT_OFFSET, 13157 },
+  { 0xfc3b, G_UNICODE_NOT_PRESENT_OFFSET, 13162 },
+  { 0xfc3c, G_UNICODE_NOT_PRESENT_OFFSET, 13167 },
+  { 0xfc3d, G_UNICODE_NOT_PRESENT_OFFSET, 13172 },
+  { 0xfc3e, G_UNICODE_NOT_PRESENT_OFFSET, 13177 },
+  { 0xfc3f, G_UNICODE_NOT_PRESENT_OFFSET, 13182 },
+  { 0xfc40, G_UNICODE_NOT_PRESENT_OFFSET, 13187 },
+  { 0xfc41, G_UNICODE_NOT_PRESENT_OFFSET, 13192 },
+  { 0xfc42, G_UNICODE_NOT_PRESENT_OFFSET, 13197 },
+  { 0xfc43, G_UNICODE_NOT_PRESENT_OFFSET, 13202 },
+  { 0xfc44, G_UNICODE_NOT_PRESENT_OFFSET, 13207 },
+  { 0xfc45, G_UNICODE_NOT_PRESENT_OFFSET, 13212 },
+  { 0xfc46, G_UNICODE_NOT_PRESENT_OFFSET, 13217 },
+  { 0xfc47, G_UNICODE_NOT_PRESENT_OFFSET, 13222 },
+  { 0xfc48, G_UNICODE_NOT_PRESENT_OFFSET, 13227 },
+  { 0xfc49, G_UNICODE_NOT_PRESENT_OFFSET, 13232 },
+  { 0xfc4a, G_UNICODE_NOT_PRESENT_OFFSET, 13237 },
+  { 0xfc4b, G_UNICODE_NOT_PRESENT_OFFSET, 13242 },
+  { 0xfc4c, G_UNICODE_NOT_PRESENT_OFFSET, 13247 },
+  { 0xfc4d, G_UNICODE_NOT_PRESENT_OFFSET, 13252 },
+  { 0xfc4e, G_UNICODE_NOT_PRESENT_OFFSET, 13257 },
+  { 0xfc4f, G_UNICODE_NOT_PRESENT_OFFSET, 13262 },
+  { 0xfc50, G_UNICODE_NOT_PRESENT_OFFSET, 13267 },
+  { 0xfc51, G_UNICODE_NOT_PRESENT_OFFSET, 13272 },
+  { 0xfc52, G_UNICODE_NOT_PRESENT_OFFSET, 13277 },
+  { 0xfc53, G_UNICODE_NOT_PRESENT_OFFSET, 13282 },
+  { 0xfc54, G_UNICODE_NOT_PRESENT_OFFSET, 13287 },
+  { 0xfc55, G_UNICODE_NOT_PRESENT_OFFSET, 13292 },
+  { 0xfc56, G_UNICODE_NOT_PRESENT_OFFSET, 13297 },
+  { 0xfc57, G_UNICODE_NOT_PRESENT_OFFSET, 13302 },
+  { 0xfc58, G_UNICODE_NOT_PRESENT_OFFSET, 13307 },
+  { 0xfc59, G_UNICODE_NOT_PRESENT_OFFSET, 13312 },
+  { 0xfc5a, G_UNICODE_NOT_PRESENT_OFFSET, 13317 },
+  { 0xfc5b, G_UNICODE_NOT_PRESENT_OFFSET, 13322 },
+  { 0xfc5c, G_UNICODE_NOT_PRESENT_OFFSET, 13327 },
+  { 0xfc5d, G_UNICODE_NOT_PRESENT_OFFSET, 13332 },
+  { 0xfc5e, G_UNICODE_NOT_PRESENT_OFFSET, 13337 },
+  { 0xfc5f, G_UNICODE_NOT_PRESENT_OFFSET, 13343 },
+  { 0xfc60, G_UNICODE_NOT_PRESENT_OFFSET, 13349 },
+  { 0xfc61, G_UNICODE_NOT_PRESENT_OFFSET, 13355 },
+  { 0xfc62, G_UNICODE_NOT_PRESENT_OFFSET, 13361 },
+  { 0xfc63, G_UNICODE_NOT_PRESENT_OFFSET, 13367 },
+  { 0xfc64, G_UNICODE_NOT_PRESENT_OFFSET, 13373 },
+  { 0xfc65, G_UNICODE_NOT_PRESENT_OFFSET, 13380 },
+  { 0xfc66, G_UNICODE_NOT_PRESENT_OFFSET, 12878 },
+  { 0xfc67, G_UNICODE_NOT_PRESENT_OFFSET, 13387 },
+  { 0xfc68, G_UNICODE_NOT_PRESENT_OFFSET, 12854 },
+  { 0xfc69, G_UNICODE_NOT_PRESENT_OFFSET, 12885 },
+  { 0xfc6a, G_UNICODE_NOT_PRESENT_OFFSET, 13394 },
+  { 0xfc6b, G_UNICODE_NOT_PRESENT_OFFSET, 13399 },
+  { 0xfc6c, G_UNICODE_NOT_PRESENT_OFFSET, 12907 },
+  { 0xfc6d, G_UNICODE_NOT_PRESENT_OFFSET, 13404 },
+  { 0xfc6e, G_UNICODE_NOT_PRESENT_OFFSET, 12912 },
+  { 0xfc6f, G_UNICODE_NOT_PRESENT_OFFSET, 12917 },
+  { 0xfc70, G_UNICODE_NOT_PRESENT_OFFSET, 13409 },
+  { 0xfc71, G_UNICODE_NOT_PRESENT_OFFSET, 13414 },
+  { 0xfc72, G_UNICODE_NOT_PRESENT_OFFSET, 12937 },
+  { 0xfc73, G_UNICODE_NOT_PRESENT_OFFSET, 13419 },
+  { 0xfc74, G_UNICODE_NOT_PRESENT_OFFSET, 12942 },
+  { 0xfc75, G_UNICODE_NOT_PRESENT_OFFSET, 12947 },
+  { 0xfc76, G_UNICODE_NOT_PRESENT_OFFSET, 13424 },
+  { 0xfc77, G_UNICODE_NOT_PRESENT_OFFSET, 13429 },
+  { 0xfc78, G_UNICODE_NOT_PRESENT_OFFSET, 12957 },
+  { 0xfc79, G_UNICODE_NOT_PRESENT_OFFSET, 13434 },
+  { 0xfc7a, G_UNICODE_NOT_PRESENT_OFFSET, 12962 },
+  { 0xfc7b, G_UNICODE_NOT_PRESENT_OFFSET, 12967 },
+  { 0xfc7c, G_UNICODE_NOT_PRESENT_OFFSET, 13112 },
+  { 0xfc7d, G_UNICODE_NOT_PRESENT_OFFSET, 13117 },
+  { 0xfc7e, G_UNICODE_NOT_PRESENT_OFFSET, 13132 },
+  { 0xfc7f, G_UNICODE_NOT_PRESENT_OFFSET, 13137 },
+  { 0xfc80, G_UNICODE_NOT_PRESENT_OFFSET, 13142 },
+  { 0xfc81, G_UNICODE_NOT_PRESENT_OFFSET, 13162 },
+  { 0xfc82, G_UNICODE_NOT_PRESENT_OFFSET, 13167 },
+  { 0xfc83, G_UNICODE_NOT_PRESENT_OFFSET, 13172 },
+  { 0xfc84, G_UNICODE_NOT_PRESENT_OFFSET, 13177 },
+  { 0xfc85, G_UNICODE_NOT_PRESENT_OFFSET, 13197 },
+  { 0xfc86, G_UNICODE_NOT_PRESENT_OFFSET, 13202 },
+  { 0xfc87, G_UNICODE_NOT_PRESENT_OFFSET, 13207 },
+  { 0xfc88, G_UNICODE_NOT_PRESENT_OFFSET, 13439 },
+  { 0xfc89, G_UNICODE_NOT_PRESENT_OFFSET, 13227 },
+  { 0xfc8a, G_UNICODE_NOT_PRESENT_OFFSET, 13444 },
+  { 0xfc8b, G_UNICODE_NOT_PRESENT_OFFSET, 13449 },
+  { 0xfc8c, G_UNICODE_NOT_PRESENT_OFFSET, 13257 },
+  { 0xfc8d, G_UNICODE_NOT_PRESENT_OFFSET, 13454 },
+  { 0xfc8e, G_UNICODE_NOT_PRESENT_OFFSET, 13262 },
+  { 0xfc8f, G_UNICODE_NOT_PRESENT_OFFSET, 13267 },
+  { 0xfc90, G_UNICODE_NOT_PRESENT_OFFSET, 13332 },
+  { 0xfc91, G_UNICODE_NOT_PRESENT_OFFSET, 13459 },
+  { 0xfc92, G_UNICODE_NOT_PRESENT_OFFSET, 13464 },
+  { 0xfc93, G_UNICODE_NOT_PRESENT_OFFSET, 13307 },
+  { 0xfc94, G_UNICODE_NOT_PRESENT_OFFSET, 13469 },
+  { 0xfc95, G_UNICODE_NOT_PRESENT_OFFSET, 13312 },
+  { 0xfc96, G_UNICODE_NOT_PRESENT_OFFSET, 13317 },
+  { 0xfc97, G_UNICODE_NOT_PRESENT_OFFSET, 12864 },
+  { 0xfc98, G_UNICODE_NOT_PRESENT_OFFSET, 12871 },
+  { 0xfc99, G_UNICODE_NOT_PRESENT_OFFSET, 13474 },
+  { 0xfc9a, G_UNICODE_NOT_PRESENT_OFFSET, 12878 },
+  { 0xfc9b, G_UNICODE_NOT_PRESENT_OFFSET, 13481 },
+  { 0xfc9c, G_UNICODE_NOT_PRESENT_OFFSET, 12892 },
+  { 0xfc9d, G_UNICODE_NOT_PRESENT_OFFSET, 12897 },
+  { 0xfc9e, G_UNICODE_NOT_PRESENT_OFFSET, 12902 },
+  { 0xfc9f, G_UNICODE_NOT_PRESENT_OFFSET, 12907 },
+  { 0xfca0, G_UNICODE_NOT_PRESENT_OFFSET, 13488 },
+  { 0xfca1, G_UNICODE_NOT_PRESENT_OFFSET, 12922 },
+  { 0xfca2, G_UNICODE_NOT_PRESENT_OFFSET, 12927 },
+  { 0xfca3, G_UNICODE_NOT_PRESENT_OFFSET, 12932 },
+  { 0xfca4, G_UNICODE_NOT_PRESENT_OFFSET, 12937 },
+  { 0xfca5, G_UNICODE_NOT_PRESENT_OFFSET, 13493 },
+  { 0xfca6, G_UNICODE_NOT_PRESENT_OFFSET, 12957 },
+  { 0xfca7, G_UNICODE_NOT_PRESENT_OFFSET, 12972 },
+  { 0xfca8, G_UNICODE_NOT_PRESENT_OFFSET, 12977 },
+  { 0xfca9, G_UNICODE_NOT_PRESENT_OFFSET, 12982 },
+  { 0xfcaa, G_UNICODE_NOT_PRESENT_OFFSET, 12987 },
+  { 0xfcab, G_UNICODE_NOT_PRESENT_OFFSET, 12992 },
+  { 0xfcac, G_UNICODE_NOT_PRESENT_OFFSET, 13002 },
+  { 0xfcad, G_UNICODE_NOT_PRESENT_OFFSET, 13007 },
+  { 0xfcae, G_UNICODE_NOT_PRESENT_OFFSET, 13012 },
+  { 0xfcaf, G_UNICODE_NOT_PRESENT_OFFSET, 13017 },
+  { 0xfcb0, G_UNICODE_NOT_PRESENT_OFFSET, 13022 },
+  { 0xfcb1, G_UNICODE_NOT_PRESENT_OFFSET, 13027 },
+  { 0xfcb2, G_UNICODE_NOT_PRESENT_OFFSET, 13498 },
+  { 0xfcb3, G_UNICODE_NOT_PRESENT_OFFSET, 13032 },
+  { 0xfcb4, G_UNICODE_NOT_PRESENT_OFFSET, 13037 },
+  { 0xfcb5, G_UNICODE_NOT_PRESENT_OFFSET, 13042 },
+  { 0xfcb6, G_UNICODE_NOT_PRESENT_OFFSET, 13047 },
+  { 0xfcb7, G_UNICODE_NOT_PRESENT_OFFSET, 13052 },
+  { 0xfcb8, G_UNICODE_NOT_PRESENT_OFFSET, 13057 },
+  { 0xfcb9, G_UNICODE_NOT_PRESENT_OFFSET, 13067 },
+  { 0xfcba, G_UNICODE_NOT_PRESENT_OFFSET, 13072 },
+  { 0xfcbb, G_UNICODE_NOT_PRESENT_OFFSET, 13077 },
+  { 0xfcbc, G_UNICODE_NOT_PRESENT_OFFSET, 13082 },
+  { 0xfcbd, G_UNICODE_NOT_PRESENT_OFFSET, 13087 },
+  { 0xfcbe, G_UNICODE_NOT_PRESENT_OFFSET, 13092 },
+  { 0xfcbf, G_UNICODE_NOT_PRESENT_OFFSET, 13097 },
+  { 0xfcc0, G_UNICODE_NOT_PRESENT_OFFSET, 13102 },
+  { 0xfcc1, G_UNICODE_NOT_PRESENT_OFFSET, 13107 },
+  { 0xfcc2, G_UNICODE_NOT_PRESENT_OFFSET, 13122 },
+  { 0xfcc3, G_UNICODE_NOT_PRESENT_OFFSET, 13127 },
+  { 0xfcc4, G_UNICODE_NOT_PRESENT_OFFSET, 13147 },
+  { 0xfcc5, G_UNICODE_NOT_PRESENT_OFFSET, 13152 },
+  { 0xfcc6, G_UNICODE_NOT_PRESENT_OFFSET, 13157 },
+  { 0xfcc7, G_UNICODE_NOT_PRESENT_OFFSET, 13162 },
+  { 0xfcc8, G_UNICODE_NOT_PRESENT_OFFSET, 13167 },
+  { 0xfcc9, G_UNICODE_NOT_PRESENT_OFFSET, 13182 },
+  { 0xfcca, G_UNICODE_NOT_PRESENT_OFFSET, 13187 },
+  { 0xfccb, G_UNICODE_NOT_PRESENT_OFFSET, 13192 },
+  { 0xfccc, G_UNICODE_NOT_PRESENT_OFFSET, 13197 },
+  { 0xfccd, G_UNICODE_NOT_PRESENT_OFFSET, 13503 },
+  { 0xfcce, G_UNICODE_NOT_PRESENT_OFFSET, 13212 },
+  { 0xfccf, G_UNICODE_NOT_PRESENT_OFFSET, 13217 },
+  { 0xfcd0, G_UNICODE_NOT_PRESENT_OFFSET, 13222 },
+  { 0xfcd1, G_UNICODE_NOT_PRESENT_OFFSET, 13227 },
+  { 0xfcd2, G_UNICODE_NOT_PRESENT_OFFSET, 13242 },
+  { 0xfcd3, G_UNICODE_NOT_PRESENT_OFFSET, 13247 },
+  { 0xfcd4, G_UNICODE_NOT_PRESENT_OFFSET, 13252 },
+  { 0xfcd5, G_UNICODE_NOT_PRESENT_OFFSET, 13257 },
+  { 0xfcd6, G_UNICODE_NOT_PRESENT_OFFSET, 13508 },
+  { 0xfcd7, G_UNICODE_NOT_PRESENT_OFFSET, 13272 },
+  { 0xfcd8, G_UNICODE_NOT_PRESENT_OFFSET, 13277 },
+  { 0xfcd9, G_UNICODE_NOT_PRESENT_OFFSET, 13513 },
+  { 0xfcda, G_UNICODE_NOT_PRESENT_OFFSET, 13292 },
+  { 0xfcdb, G_UNICODE_NOT_PRESENT_OFFSET, 13297 },
+  { 0xfcdc, G_UNICODE_NOT_PRESENT_OFFSET, 13302 },
+  { 0xfcdd, G_UNICODE_NOT_PRESENT_OFFSET, 13307 },
+  { 0xfcde, G_UNICODE_NOT_PRESENT_OFFSET, 13518 },
+  { 0xfcdf, G_UNICODE_NOT_PRESENT_OFFSET, 12878 },
+  { 0xfce0, G_UNICODE_NOT_PRESENT_OFFSET, 13481 },
+  { 0xfce1, G_UNICODE_NOT_PRESENT_OFFSET, 12907 },
+  { 0xfce2, G_UNICODE_NOT_PRESENT_OFFSET, 13488 },
+  { 0xfce3, G_UNICODE_NOT_PRESENT_OFFSET, 12937 },
+  { 0xfce4, G_UNICODE_NOT_PRESENT_OFFSET, 13493 },
+  { 0xfce5, G_UNICODE_NOT_PRESENT_OFFSET, 12957 },
+  { 0xfce6, G_UNICODE_NOT_PRESENT_OFFSET, 13523 },
+  { 0xfce7, G_UNICODE_NOT_PRESENT_OFFSET, 13022 },
+  { 0xfce8, G_UNICODE_NOT_PRESENT_OFFSET, 13528 },
+  { 0xfce9, G_UNICODE_NOT_PRESENT_OFFSET, 13533 },
+  { 0xfcea, G_UNICODE_NOT_PRESENT_OFFSET, 13538 },
+  { 0xfceb, G_UNICODE_NOT_PRESENT_OFFSET, 13162 },
+  { 0xfcec, G_UNICODE_NOT_PRESENT_OFFSET, 13167 },
+  { 0xfced, G_UNICODE_NOT_PRESENT_OFFSET, 13197 },
+  { 0xfcee, G_UNICODE_NOT_PRESENT_OFFSET, 13257 },
+  { 0xfcef, G_UNICODE_NOT_PRESENT_OFFSET, 13508 },
+  { 0xfcf0, G_UNICODE_NOT_PRESENT_OFFSET, 13307 },
+  { 0xfcf1, G_UNICODE_NOT_PRESENT_OFFSET, 13518 },
+  { 0xfcf2, G_UNICODE_NOT_PRESENT_OFFSET, 13543 },
+  { 0xfcf3, G_UNICODE_NOT_PRESENT_OFFSET, 13550 },
+  { 0xfcf4, G_UNICODE_NOT_PRESENT_OFFSET, 13557 },
+  { 0xfcf5, G_UNICODE_NOT_PRESENT_OFFSET, 13564 },
+  { 0xfcf6, G_UNICODE_NOT_PRESENT_OFFSET, 13569 },
+  { 0xfcf7, G_UNICODE_NOT_PRESENT_OFFSET, 13574 },
+  { 0xfcf8, G_UNICODE_NOT_PRESENT_OFFSET, 13579 },
+  { 0xfcf9, G_UNICODE_NOT_PRESENT_OFFSET, 13584 },
+  { 0xfcfa, G_UNICODE_NOT_PRESENT_OFFSET, 13589 },
+  { 0xfcfb, G_UNICODE_NOT_PRESENT_OFFSET, 13594 },
+  { 0xfcfc, G_UNICODE_NOT_PRESENT_OFFSET, 13599 },
+  { 0xfcfd, G_UNICODE_NOT_PRESENT_OFFSET, 13604 },
+  { 0xfcfe, G_UNICODE_NOT_PRESENT_OFFSET, 13609 },
+  { 0xfcff, G_UNICODE_NOT_PRESENT_OFFSET, 13614 },
+  { 0xfd00, G_UNICODE_NOT_PRESENT_OFFSET, 13619 },
+  { 0xfd01, G_UNICODE_NOT_PRESENT_OFFSET, 13624 },
+  { 0xfd02, G_UNICODE_NOT_PRESENT_OFFSET, 13629 },
+  { 0xfd03, G_UNICODE_NOT_PRESENT_OFFSET, 13634 },
+  { 0xfd04, G_UNICODE_NOT_PRESENT_OFFSET, 13639 },
+  { 0xfd05, G_UNICODE_NOT_PRESENT_OFFSET, 13644 },
+  { 0xfd06, G_UNICODE_NOT_PRESENT_OFFSET, 13649 },
+  { 0xfd07, G_UNICODE_NOT_PRESENT_OFFSET, 13654 },
+  { 0xfd08, G_UNICODE_NOT_PRESENT_OFFSET, 13659 },
+  { 0xfd09, G_UNICODE_NOT_PRESENT_OFFSET, 13664 },
+  { 0xfd0a, G_UNICODE_NOT_PRESENT_OFFSET, 13669 },
+  { 0xfd0b, G_UNICODE_NOT_PRESENT_OFFSET, 13674 },
+  { 0xfd0c, G_UNICODE_NOT_PRESENT_OFFSET, 13533 },
+  { 0xfd0d, G_UNICODE_NOT_PRESENT_OFFSET, 13679 },
+  { 0xfd0e, G_UNICODE_NOT_PRESENT_OFFSET, 13684 },
+  { 0xfd0f, G_UNICODE_NOT_PRESENT_OFFSET, 13689 },
+  { 0xfd10, G_UNICODE_NOT_PRESENT_OFFSET, 13694 },
+  { 0xfd11, G_UNICODE_NOT_PRESENT_OFFSET, 13564 },
+  { 0xfd12, G_UNICODE_NOT_PRESENT_OFFSET, 13569 },
+  { 0xfd13, G_UNICODE_NOT_PRESENT_OFFSET, 13574 },
+  { 0xfd14, G_UNICODE_NOT_PRESENT_OFFSET, 13579 },
+  { 0xfd15, G_UNICODE_NOT_PRESENT_OFFSET, 13584 },
+  { 0xfd16, G_UNICODE_NOT_PRESENT_OFFSET, 13589 },
+  { 0xfd17, G_UNICODE_NOT_PRESENT_OFFSET, 13594 },
+  { 0xfd18, G_UNICODE_NOT_PRESENT_OFFSET, 13599 },
+  { 0xfd19, G_UNICODE_NOT_PRESENT_OFFSET, 13604 },
+  { 0xfd1a, G_UNICODE_NOT_PRESENT_OFFSET, 13609 },
+  { 0xfd1b, G_UNICODE_NOT_PRESENT_OFFSET, 13614 },
+  { 0xfd1c, G_UNICODE_NOT_PRESENT_OFFSET, 13619 },
+  { 0xfd1d, G_UNICODE_NOT_PRESENT_OFFSET, 13624 },
+  { 0xfd1e, G_UNICODE_NOT_PRESENT_OFFSET, 13629 },
+  { 0xfd1f, G_UNICODE_NOT_PRESENT_OFFSET, 13634 },
+  { 0xfd20, G_UNICODE_NOT_PRESENT_OFFSET, 13639 },
+  { 0xfd21, G_UNICODE_NOT_PRESENT_OFFSET, 13644 },
+  { 0xfd22, G_UNICODE_NOT_PRESENT_OFFSET, 13649 },
+  { 0xfd23, G_UNICODE_NOT_PRESENT_OFFSET, 13654 },
+  { 0xfd24, G_UNICODE_NOT_PRESENT_OFFSET, 13659 },
+  { 0xfd25, G_UNICODE_NOT_PRESENT_OFFSET, 13664 },
+  { 0xfd26, G_UNICODE_NOT_PRESENT_OFFSET, 13669 },
+  { 0xfd27, G_UNICODE_NOT_PRESENT_OFFSET, 13674 },
+  { 0xfd28, G_UNICODE_NOT_PRESENT_OFFSET, 13533 },
+  { 0xfd29, G_UNICODE_NOT_PRESENT_OFFSET, 13679 },
+  { 0xfd2a, G_UNICODE_NOT_PRESENT_OFFSET, 13684 },
+  { 0xfd2b, G_UNICODE_NOT_PRESENT_OFFSET, 13689 },
+  { 0xfd2c, G_UNICODE_NOT_PRESENT_OFFSET, 13694 },
+  { 0xfd2d, G_UNICODE_NOT_PRESENT_OFFSET, 13664 },
+  { 0xfd2e, G_UNICODE_NOT_PRESENT_OFFSET, 13669 },
+  { 0xfd2f, G_UNICODE_NOT_PRESENT_OFFSET, 13674 },
+  { 0xfd30, G_UNICODE_NOT_PRESENT_OFFSET, 13533 },
+  { 0xfd31, G_UNICODE_NOT_PRESENT_OFFSET, 13528 },
+  { 0xfd32, G_UNICODE_NOT_PRESENT_OFFSET, 13538 },
+  { 0xfd33, G_UNICODE_NOT_PRESENT_OFFSET, 13062 },
+  { 0xfd34, G_UNICODE_NOT_PRESENT_OFFSET, 13007 },
+  { 0xfd35, G_UNICODE_NOT_PRESENT_OFFSET, 13012 },
+  { 0xfd36, G_UNICODE_NOT_PRESENT_OFFSET, 13017 },
+  { 0xfd37, G_UNICODE_NOT_PRESENT_OFFSET, 13664 },
+  { 0xfd38, G_UNICODE_NOT_PRESENT_OFFSET, 13669 },
+  { 0xfd39, G_UNICODE_NOT_PRESENT_OFFSET, 13674 },
+  { 0xfd3a, G_UNICODE_NOT_PRESENT_OFFSET, 13062 },
+  { 0xfd3b, G_UNICODE_NOT_PRESENT_OFFSET, 13067 },
+  { 0xfd3c, G_UNICODE_NOT_PRESENT_OFFSET, 13699 },
+  { 0xfd3d, G_UNICODE_NOT_PRESENT_OFFSET, 13699 },
+  { 0xfd50, G_UNICODE_NOT_PRESENT_OFFSET, 13704 },
+  { 0xfd51, G_UNICODE_NOT_PRESENT_OFFSET, 13711 },
+  { 0xfd52, G_UNICODE_NOT_PRESENT_OFFSET, 13711 },
+  { 0xfd53, G_UNICODE_NOT_PRESENT_OFFSET, 13718 },
+  { 0xfd54, G_UNICODE_NOT_PRESENT_OFFSET, 13725 },
+  { 0xfd55, G_UNICODE_NOT_PRESENT_OFFSET, 13732 },
+  { 0xfd56, G_UNICODE_NOT_PRESENT_OFFSET, 13739 },
+  { 0xfd57, G_UNICODE_NOT_PRESENT_OFFSET, 13746 },
+  { 0xfd58, G_UNICODE_NOT_PRESENT_OFFSET, 13753 },
+  { 0xfd59, G_UNICODE_NOT_PRESENT_OFFSET, 13753 },
+  { 0xfd5a, G_UNICODE_NOT_PRESENT_OFFSET, 13760 },
+  { 0xfd5b, G_UNICODE_NOT_PRESENT_OFFSET, 13767 },
+  { 0xfd5c, G_UNICODE_NOT_PRESENT_OFFSET, 13774 },
+  { 0xfd5d, G_UNICODE_NOT_PRESENT_OFFSET, 13781 },
+  { 0xfd5e, G_UNICODE_NOT_PRESENT_OFFSET, 13788 },
+  { 0xfd5f, G_UNICODE_NOT_PRESENT_OFFSET, 13795 },
+  { 0xfd60, G_UNICODE_NOT_PRESENT_OFFSET, 13795 },
+  { 0xfd61, G_UNICODE_NOT_PRESENT_OFFSET, 13802 },
+  { 0xfd62, G_UNICODE_NOT_PRESENT_OFFSET, 13809 },
+  { 0xfd63, G_UNICODE_NOT_PRESENT_OFFSET, 13809 },
+  { 0xfd64, G_UNICODE_NOT_PRESENT_OFFSET, 13816 },
+  { 0xfd65, G_UNICODE_NOT_PRESENT_OFFSET, 13816 },
+  { 0xfd66, G_UNICODE_NOT_PRESENT_OFFSET, 13823 },
+  { 0xfd67, G_UNICODE_NOT_PRESENT_OFFSET, 13830 },
+  { 0xfd68, G_UNICODE_NOT_PRESENT_OFFSET, 13830 },
+  { 0xfd69, G_UNICODE_NOT_PRESENT_OFFSET, 13837 },
+  { 0xfd6a, G_UNICODE_NOT_PRESENT_OFFSET, 13844 },
+  { 0xfd6b, G_UNICODE_NOT_PRESENT_OFFSET, 13844 },
+  { 0xfd6c, G_UNICODE_NOT_PRESENT_OFFSET, 13851 },
+  { 0xfd6d, G_UNICODE_NOT_PRESENT_OFFSET, 13851 },
+  { 0xfd6e, G_UNICODE_NOT_PRESENT_OFFSET, 13858 },
+  { 0xfd6f, G_UNICODE_NOT_PRESENT_OFFSET, 13865 },
+  { 0xfd70, G_UNICODE_NOT_PRESENT_OFFSET, 13865 },
+  { 0xfd71, G_UNICODE_NOT_PRESENT_OFFSET, 13872 },
+  { 0xfd72, G_UNICODE_NOT_PRESENT_OFFSET, 13872 },
+  { 0xfd73, G_UNICODE_NOT_PRESENT_OFFSET, 13879 },
+  { 0xfd74, G_UNICODE_NOT_PRESENT_OFFSET, 13886 },
+  { 0xfd75, G_UNICODE_NOT_PRESENT_OFFSET, 13893 },
+  { 0xfd76, G_UNICODE_NOT_PRESENT_OFFSET, 13900 },
+  { 0xfd77, G_UNICODE_NOT_PRESENT_OFFSET, 13900 },
+  { 0xfd78, G_UNICODE_NOT_PRESENT_OFFSET, 13907 },
+  { 0xfd79, G_UNICODE_NOT_PRESENT_OFFSET, 13914 },
+  { 0xfd7a, G_UNICODE_NOT_PRESENT_OFFSET, 13921 },
+  { 0xfd7b, G_UNICODE_NOT_PRESENT_OFFSET, 13928 },
+  { 0xfd7c, G_UNICODE_NOT_PRESENT_OFFSET, 13935 },
+  { 0xfd7d, G_UNICODE_NOT_PRESENT_OFFSET, 13935 },
+  { 0xfd7e, G_UNICODE_NOT_PRESENT_OFFSET, 13942 },
+  { 0xfd7f, G_UNICODE_NOT_PRESENT_OFFSET, 13949 },
+  { 0xfd80, G_UNICODE_NOT_PRESENT_OFFSET, 13956 },
+  { 0xfd81, G_UNICODE_NOT_PRESENT_OFFSET, 13963 },
+  { 0xfd82, G_UNICODE_NOT_PRESENT_OFFSET, 13970 },
+  { 0xfd83, G_UNICODE_NOT_PRESENT_OFFSET, 13977 },
+  { 0xfd84, G_UNICODE_NOT_PRESENT_OFFSET, 13977 },
+  { 0xfd85, G_UNICODE_NOT_PRESENT_OFFSET, 13984 },
+  { 0xfd86, G_UNICODE_NOT_PRESENT_OFFSET, 13984 },
+  { 0xfd87, G_UNICODE_NOT_PRESENT_OFFSET, 13991 },
+  { 0xfd88, G_UNICODE_NOT_PRESENT_OFFSET, 13991 },
+  { 0xfd89, G_UNICODE_NOT_PRESENT_OFFSET, 13998 },
+  { 0xfd8a, G_UNICODE_NOT_PRESENT_OFFSET, 14005 },
+  { 0xfd8b, G_UNICODE_NOT_PRESENT_OFFSET, 14012 },
+  { 0xfd8c, G_UNICODE_NOT_PRESENT_OFFSET, 14019 },
+  { 0xfd8d, G_UNICODE_NOT_PRESENT_OFFSET, 14026 },
+  { 0xfd8e, G_UNICODE_NOT_PRESENT_OFFSET, 14033 },
+  { 0xfd8f, G_UNICODE_NOT_PRESENT_OFFSET, 14040 },
+  { 0xfd92, G_UNICODE_NOT_PRESENT_OFFSET, 14047 },
+  { 0xfd93, G_UNICODE_NOT_PRESENT_OFFSET, 14054 },
+  { 0xfd94, G_UNICODE_NOT_PRESENT_OFFSET, 14061 },
+  { 0xfd95, G_UNICODE_NOT_PRESENT_OFFSET, 14068 },
+  { 0xfd96, G_UNICODE_NOT_PRESENT_OFFSET, 14075 },
+  { 0xfd97, G_UNICODE_NOT_PRESENT_OFFSET, 14082 },
+  { 0xfd98, G_UNICODE_NOT_PRESENT_OFFSET, 14082 },
+  { 0xfd99, G_UNICODE_NOT_PRESENT_OFFSET, 14089 },
+  { 0xfd9a, G_UNICODE_NOT_PRESENT_OFFSET, 14096 },
+  { 0xfd9b, G_UNICODE_NOT_PRESENT_OFFSET, 14103 },
+  { 0xfd9c, G_UNICODE_NOT_PRESENT_OFFSET, 14110 },
+  { 0xfd9d, G_UNICODE_NOT_PRESENT_OFFSET, 14110 },
+  { 0xfd9e, G_UNICODE_NOT_PRESENT_OFFSET, 14117 },
+  { 0xfd9f, G_UNICODE_NOT_PRESENT_OFFSET, 14124 },
+  { 0xfda0, G_UNICODE_NOT_PRESENT_OFFSET, 14131 },
+  { 0xfda1, G_UNICODE_NOT_PRESENT_OFFSET, 14138 },
+  { 0xfda2, G_UNICODE_NOT_PRESENT_OFFSET, 14145 },
+  { 0xfda3, G_UNICODE_NOT_PRESENT_OFFSET, 14152 },
+  { 0xfda4, G_UNICODE_NOT_PRESENT_OFFSET, 14159 },
+  { 0xfda5, G_UNICODE_NOT_PRESENT_OFFSET, 14166 },
+  { 0xfda6, G_UNICODE_NOT_PRESENT_OFFSET, 14173 },
+  { 0xfda7, G_UNICODE_NOT_PRESENT_OFFSET, 14180 },
+  { 0xfda8, G_UNICODE_NOT_PRESENT_OFFSET, 14187 },
+  { 0xfda9, G_UNICODE_NOT_PRESENT_OFFSET, 14194 },
+  { 0xfdaa, G_UNICODE_NOT_PRESENT_OFFSET, 14201 },
+  { 0xfdab, G_UNICODE_NOT_PRESENT_OFFSET, 14208 },
+  { 0xfdac, G_UNICODE_NOT_PRESENT_OFFSET, 14215 },
+  { 0xfdad, G_UNICODE_NOT_PRESENT_OFFSET, 14222 },
+  { 0xfdae, G_UNICODE_NOT_PRESENT_OFFSET, 14229 },
+  { 0xfdaf, G_UNICODE_NOT_PRESENT_OFFSET, 14236 },
+  { 0xfdb0, G_UNICODE_NOT_PRESENT_OFFSET, 14243 },
+  { 0xfdb1, G_UNICODE_NOT_PRESENT_OFFSET, 14250 },
+  { 0xfdb2, G_UNICODE_NOT_PRESENT_OFFSET, 14257 },
+  { 0xfdb3, G_UNICODE_NOT_PRESENT_OFFSET, 14264 },
+  { 0xfdb4, G_UNICODE_NOT_PRESENT_OFFSET, 13942 },
+  { 0xfdb5, G_UNICODE_NOT_PRESENT_OFFSET, 13956 },
+  { 0xfdb6, G_UNICODE_NOT_PRESENT_OFFSET, 14271 },
+  { 0xfdb7, G_UNICODE_NOT_PRESENT_OFFSET, 14278 },
+  { 0xfdb8, G_UNICODE_NOT_PRESENT_OFFSET, 14285 },
+  { 0xfdb9, G_UNICODE_NOT_PRESENT_OFFSET, 14292 },
+  { 0xfdba, G_UNICODE_NOT_PRESENT_OFFSET, 14299 },
+  { 0xfdbb, G_UNICODE_NOT_PRESENT_OFFSET, 14306 },
+  { 0xfdbc, G_UNICODE_NOT_PRESENT_OFFSET, 14299 },
+  { 0xfdbd, G_UNICODE_NOT_PRESENT_OFFSET, 14285 },
+  { 0xfdbe, G_UNICODE_NOT_PRESENT_OFFSET, 14313 },
+  { 0xfdbf, G_UNICODE_NOT_PRESENT_OFFSET, 14320 },
+  { 0xfdc0, G_UNICODE_NOT_PRESENT_OFFSET, 14327 },
+  { 0xfdc1, G_UNICODE_NOT_PRESENT_OFFSET, 14334 },
+  { 0xfdc2, G_UNICODE_NOT_PRESENT_OFFSET, 14341 },
+  { 0xfdc3, G_UNICODE_NOT_PRESENT_OFFSET, 14306 },
+  { 0xfdc4, G_UNICODE_NOT_PRESENT_OFFSET, 13893 },
+  { 0xfdc5, G_UNICODE_NOT_PRESENT_OFFSET, 13823 },
+  { 0xfdc6, G_UNICODE_NOT_PRESENT_OFFSET, 14348 },
+  { 0xfdc7, G_UNICODE_NOT_PRESENT_OFFSET, 14355 },
+  { 0xfdf0, G_UNICODE_NOT_PRESENT_OFFSET, 14362 },
+  { 0xfdf1, G_UNICODE_NOT_PRESENT_OFFSET, 14369 },
+  { 0xfdf2, G_UNICODE_NOT_PRESENT_OFFSET, 14376 },
+  { 0xfdf3, G_UNICODE_NOT_PRESENT_OFFSET, 14385 },
+  { 0xfdf4, G_UNICODE_NOT_PRESENT_OFFSET, 14394 },
+  { 0xfdf5, G_UNICODE_NOT_PRESENT_OFFSET, 14403 },
+  { 0xfdf6, G_UNICODE_NOT_PRESENT_OFFSET, 14412 },
+  { 0xfdf7, G_UNICODE_NOT_PRESENT_OFFSET, 14421 },
+  { 0xfdf8, G_UNICODE_NOT_PRESENT_OFFSET, 14430 },
+  { 0xfdf9, G_UNICODE_NOT_PRESENT_OFFSET, 14439 },
+  { 0xfdfa, G_UNICODE_NOT_PRESENT_OFFSET, 14446 },
+  { 0xfdfb, G_UNICODE_NOT_PRESENT_OFFSET, 14480 },
+  { 0xfdfc, G_UNICODE_NOT_PRESENT_OFFSET, 14496 },
+  { 0xfe10, G_UNICODE_NOT_PRESENT_OFFSET, 14505 },
+  { 0xfe11, G_UNICODE_NOT_PRESENT_OFFSET, 14507 },
+  { 0xfe12, G_UNICODE_NOT_PRESENT_OFFSET, 14511 },
+  { 0xfe13, G_UNICODE_NOT_PRESENT_OFFSET, 14515 },
+  { 0xfe14, G_UNICODE_NOT_PRESENT_OFFSET, 1248 },
+  { 0xfe15, G_UNICODE_NOT_PRESENT_OFFSET, 14517 },
+  { 0xfe16, G_UNICODE_NOT_PRESENT_OFFSET, 14519 },
+  { 0xfe17, G_UNICODE_NOT_PRESENT_OFFSET, 14521 },
+  { 0xfe18, G_UNICODE_NOT_PRESENT_OFFSET, 14525 },
+  { 0xfe19, G_UNICODE_NOT_PRESENT_OFFSET, 5186 },
+  { 0xfe30, G_UNICODE_NOT_PRESENT_OFFSET, 5183 },
+  { 0xfe31, G_UNICODE_NOT_PRESENT_OFFSET, 14529 },
+  { 0xfe32, G_UNICODE_NOT_PRESENT_OFFSET, 14533 },
+  { 0xfe33, G_UNICODE_NOT_PRESENT_OFFSET, 14537 },
+  { 0xfe34, G_UNICODE_NOT_PRESENT_OFFSET, 14537 },
+  { 0xfe35, G_UNICODE_NOT_PRESENT_OFFSET, 5275 },
+  { 0xfe36, G_UNICODE_NOT_PRESENT_OFFSET, 5277 },
+  { 0xfe37, G_UNICODE_NOT_PRESENT_OFFSET, 14539 },
+  { 0xfe38, G_UNICODE_NOT_PRESENT_OFFSET, 14541 },
+  { 0xfe39, G_UNICODE_NOT_PRESENT_OFFSET, 14543 },
+  { 0xfe3a, G_UNICODE_NOT_PRESENT_OFFSET, 14547 },
+  { 0xfe3b, G_UNICODE_NOT_PRESENT_OFFSET, 14551 },
+  { 0xfe3c, G_UNICODE_NOT_PRESENT_OFFSET, 14555 },
+  { 0xfe3d, G_UNICODE_NOT_PRESENT_OFFSET, 14559 },
+  { 0xfe3e, G_UNICODE_NOT_PRESENT_OFFSET, 14563 },
+  { 0xfe3f, G_UNICODE_NOT_PRESENT_OFFSET, 5801 },
+  { 0xfe40, G_UNICODE_NOT_PRESENT_OFFSET, 5805 },
+  { 0xfe41, G_UNICODE_NOT_PRESENT_OFFSET, 14567 },
+  { 0xfe42, G_UNICODE_NOT_PRESENT_OFFSET, 14571 },
+  { 0xfe43, G_UNICODE_NOT_PRESENT_OFFSET, 14575 },
+  { 0xfe44, G_UNICODE_NOT_PRESENT_OFFSET, 14579 },
+  { 0xfe47, G_UNICODE_NOT_PRESENT_OFFSET, 14583 },
+  { 0xfe48, G_UNICODE_NOT_PRESENT_OFFSET, 14585 },
+  { 0xfe49, G_UNICODE_NOT_PRESENT_OFFSET, 5227 },
+  { 0xfe4a, G_UNICODE_NOT_PRESENT_OFFSET, 5227 },
+  { 0xfe4b, G_UNICODE_NOT_PRESENT_OFFSET, 5227 },
+  { 0xfe4c, G_UNICODE_NOT_PRESENT_OFFSET, 5227 },
+  { 0xfe4d, G_UNICODE_NOT_PRESENT_OFFSET, 14537 },
+  { 0xfe4e, G_UNICODE_NOT_PRESENT_OFFSET, 14537 },
+  { 0xfe4f, G_UNICODE_NOT_PRESENT_OFFSET, 14537 },
+  { 0xfe50, G_UNICODE_NOT_PRESENT_OFFSET, 14505 },
+  { 0xfe51, G_UNICODE_NOT_PRESENT_OFFSET, 14507 },
+  { 0xfe52, G_UNICODE_NOT_PRESENT_OFFSET, 5181 },
+  { 0xfe54, G_UNICODE_NOT_PRESENT_OFFSET, 1248 },
+  { 0xfe55, G_UNICODE_NOT_PRESENT_OFFSET, 14515 },
+  { 0xfe56, G_UNICODE_NOT_PRESENT_OFFSET, 14519 },
+  { 0xfe57, G_UNICODE_NOT_PRESENT_OFFSET, 14517 },
+  { 0xfe58, G_UNICODE_NOT_PRESENT_OFFSET, 14529 },
+  { 0xfe59, G_UNICODE_NOT_PRESENT_OFFSET, 5275 },
+  { 0xfe5a, G_UNICODE_NOT_PRESENT_OFFSET, 5277 },
+  { 0xfe5b, G_UNICODE_NOT_PRESENT_OFFSET, 14539 },
+  { 0xfe5c, G_UNICODE_NOT_PRESENT_OFFSET, 14541 },
+  { 0xfe5d, G_UNICODE_NOT_PRESENT_OFFSET, 14543 },
+  { 0xfe5e, G_UNICODE_NOT_PRESENT_OFFSET, 14547 },
+  { 0xfe5f, G_UNICODE_NOT_PRESENT_OFFSET, 14587 },
+  { 0xfe60, G_UNICODE_NOT_PRESENT_OFFSET, 14589 },
+  { 0xfe61, G_UNICODE_NOT_PRESENT_OFFSET, 14591 },
+  { 0xfe62, G_UNICODE_NOT_PRESENT_OFFSET, 5267 },
+  { 0xfe63, G_UNICODE_NOT_PRESENT_OFFSET, 14593 },
+  { 0xfe64, G_UNICODE_NOT_PRESENT_OFFSET, 14595 },
+  { 0xfe65, G_UNICODE_NOT_PRESENT_OFFSET, 14597 },
+  { 0xfe66, G_UNICODE_NOT_PRESENT_OFFSET, 5273 },
+  { 0xfe68, G_UNICODE_NOT_PRESENT_OFFSET, 14599 },
+  { 0xfe69, G_UNICODE_NOT_PRESENT_OFFSET, 14601 },
+  { 0xfe6a, G_UNICODE_NOT_PRESENT_OFFSET, 14603 },
+  { 0xfe6b, G_UNICODE_NOT_PRESENT_OFFSET, 14605 },
+  { 0xfe70, G_UNICODE_NOT_PRESENT_OFFSET, 14607 },
+  { 0xfe71, G_UNICODE_NOT_PRESENT_OFFSET, 14611 },
+  { 0xfe72, G_UNICODE_NOT_PRESENT_OFFSET, 14616 },
+  { 0xfe74, G_UNICODE_NOT_PRESENT_OFFSET, 14620 },
+  { 0xfe76, G_UNICODE_NOT_PRESENT_OFFSET, 14624 },
+  { 0xfe77, G_UNICODE_NOT_PRESENT_OFFSET, 14628 },
+  { 0xfe78, G_UNICODE_NOT_PRESENT_OFFSET, 14633 },
+  { 0xfe79, G_UNICODE_NOT_PRESENT_OFFSET, 14637 },
+  { 0xfe7a, G_UNICODE_NOT_PRESENT_OFFSET, 14642 },
+  { 0xfe7b, G_UNICODE_NOT_PRESENT_OFFSET, 14646 },
+  { 0xfe7c, G_UNICODE_NOT_PRESENT_OFFSET, 14651 },
+  { 0xfe7d, G_UNICODE_NOT_PRESENT_OFFSET, 14655 },
+  { 0xfe7e, G_UNICODE_NOT_PRESENT_OFFSET, 14660 },
+  { 0xfe7f, G_UNICODE_NOT_PRESENT_OFFSET, 14664 },
+  { 0xfe80, G_UNICODE_NOT_PRESENT_OFFSET, 14669 },
+  { 0xfe81, G_UNICODE_NOT_PRESENT_OFFSET, 1676 },
+  { 0xfe82, G_UNICODE_NOT_PRESENT_OFFSET, 1676 },
+  { 0xfe83, G_UNICODE_NOT_PRESENT_OFFSET, 1681 },
+  { 0xfe84, G_UNICODE_NOT_PRESENT_OFFSET, 1681 },
+  { 0xfe85, G_UNICODE_NOT_PRESENT_OFFSET, 1686 },
+  { 0xfe86, G_UNICODE_NOT_PRESENT_OFFSET, 1686 },
+  { 0xfe87, G_UNICODE_NOT_PRESENT_OFFSET, 1691 },
+  { 0xfe88, G_UNICODE_NOT_PRESENT_OFFSET, 1691 },
+  { 0xfe89, G_UNICODE_NOT_PRESENT_OFFSET, 1696 },
+  { 0xfe8a, G_UNICODE_NOT_PRESENT_OFFSET, 1696 },
+  { 0xfe8b, G_UNICODE_NOT_PRESENT_OFFSET, 1696 },
+  { 0xfe8c, G_UNICODE_NOT_PRESENT_OFFSET, 1696 },
+  { 0xfe8d, G_UNICODE_NOT_PRESENT_OFFSET, 14672 },
+  { 0xfe8e, G_UNICODE_NOT_PRESENT_OFFSET, 14672 },
+  { 0xfe8f, G_UNICODE_NOT_PRESENT_OFFSET, 14675 },
+  { 0xfe90, G_UNICODE_NOT_PRESENT_OFFSET, 14675 },
+  { 0xfe91, G_UNICODE_NOT_PRESENT_OFFSET, 14675 },
+  { 0xfe92, G_UNICODE_NOT_PRESENT_OFFSET, 14675 },
+  { 0xfe93, G_UNICODE_NOT_PRESENT_OFFSET, 14678 },
+  { 0xfe94, G_UNICODE_NOT_PRESENT_OFFSET, 14678 },
+  { 0xfe95, G_UNICODE_NOT_PRESENT_OFFSET, 14681 },
+  { 0xfe96, G_UNICODE_NOT_PRESENT_OFFSET, 14681 },
+  { 0xfe97, G_UNICODE_NOT_PRESENT_OFFSET, 14681 },
+  { 0xfe98, G_UNICODE_NOT_PRESENT_OFFSET, 14681 },
+  { 0xfe99, G_UNICODE_NOT_PRESENT_OFFSET, 14684 },
+  { 0xfe9a, G_UNICODE_NOT_PRESENT_OFFSET, 14684 },
+  { 0xfe9b, G_UNICODE_NOT_PRESENT_OFFSET, 14684 },
+  { 0xfe9c, G_UNICODE_NOT_PRESENT_OFFSET, 14684 },
+  { 0xfe9d, G_UNICODE_NOT_PRESENT_OFFSET, 14687 },
+  { 0xfe9e, G_UNICODE_NOT_PRESENT_OFFSET, 14687 },
+  { 0xfe9f, G_UNICODE_NOT_PRESENT_OFFSET, 14687 },
+  { 0xfea0, G_UNICODE_NOT_PRESENT_OFFSET, 14687 },
+  { 0xfea1, G_UNICODE_NOT_PRESENT_OFFSET, 14690 },
+  { 0xfea2, G_UNICODE_NOT_PRESENT_OFFSET, 14690 },
+  { 0xfea3, G_UNICODE_NOT_PRESENT_OFFSET, 14690 },
+  { 0xfea4, G_UNICODE_NOT_PRESENT_OFFSET, 14690 },
+  { 0xfea5, G_UNICODE_NOT_PRESENT_OFFSET, 14693 },
+  { 0xfea6, G_UNICODE_NOT_PRESENT_OFFSET, 14693 },
+  { 0xfea7, G_UNICODE_NOT_PRESENT_OFFSET, 14693 },
+  { 0xfea8, G_UNICODE_NOT_PRESENT_OFFSET, 14693 },
+  { 0xfea9, G_UNICODE_NOT_PRESENT_OFFSET, 14696 },
+  { 0xfeaa, G_UNICODE_NOT_PRESENT_OFFSET, 14696 },
+  { 0xfeab, G_UNICODE_NOT_PRESENT_OFFSET, 14699 },
+  { 0xfeac, G_UNICODE_NOT_PRESENT_OFFSET, 14699 },
+  { 0xfead, G_UNICODE_NOT_PRESENT_OFFSET, 14702 },
+  { 0xfeae, G_UNICODE_NOT_PRESENT_OFFSET, 14702 },
+  { 0xfeaf, G_UNICODE_NOT_PRESENT_OFFSET, 14705 },
+  { 0xfeb0, G_UNICODE_NOT_PRESENT_OFFSET, 14705 },
+  { 0xfeb1, G_UNICODE_NOT_PRESENT_OFFSET, 14708 },
+  { 0xfeb2, G_UNICODE_NOT_PRESENT_OFFSET, 14708 },
+  { 0xfeb3, G_UNICODE_NOT_PRESENT_OFFSET, 14708 },
+  { 0xfeb4, G_UNICODE_NOT_PRESENT_OFFSET, 14708 },
+  { 0xfeb5, G_UNICODE_NOT_PRESENT_OFFSET, 14711 },
+  { 0xfeb6, G_UNICODE_NOT_PRESENT_OFFSET, 14711 },
+  { 0xfeb7, G_UNICODE_NOT_PRESENT_OFFSET, 14711 },
+  { 0xfeb8, G_UNICODE_NOT_PRESENT_OFFSET, 14711 },
+  { 0xfeb9, G_UNICODE_NOT_PRESENT_OFFSET, 14714 },
+  { 0xfeba, G_UNICODE_NOT_PRESENT_OFFSET, 14714 },
+  { 0xfebb, G_UNICODE_NOT_PRESENT_OFFSET, 14714 },
+  { 0xfebc, G_UNICODE_NOT_PRESENT_OFFSET, 14714 },
+  { 0xfebd, G_UNICODE_NOT_PRESENT_OFFSET, 14717 },
+  { 0xfebe, G_UNICODE_NOT_PRESENT_OFFSET, 14717 },
+  { 0xfebf, G_UNICODE_NOT_PRESENT_OFFSET, 14717 },
+  { 0xfec0, G_UNICODE_NOT_PRESENT_OFFSET, 14717 },
+  { 0xfec1, G_UNICODE_NOT_PRESENT_OFFSET, 14720 },
+  { 0xfec2, G_UNICODE_NOT_PRESENT_OFFSET, 14720 },
+  { 0xfec3, G_UNICODE_NOT_PRESENT_OFFSET, 14720 },
+  { 0xfec4, G_UNICODE_NOT_PRESENT_OFFSET, 14720 },
+  { 0xfec5, G_UNICODE_NOT_PRESENT_OFFSET, 14723 },
+  { 0xfec6, G_UNICODE_NOT_PRESENT_OFFSET, 14723 },
+  { 0xfec7, G_UNICODE_NOT_PRESENT_OFFSET, 14723 },
+  { 0xfec8, G_UNICODE_NOT_PRESENT_OFFSET, 14723 },
+  { 0xfec9, G_UNICODE_NOT_PRESENT_OFFSET, 14726 },
+  { 0xfeca, G_UNICODE_NOT_PRESENT_OFFSET, 14726 },
+  { 0xfecb, G_UNICODE_NOT_PRESENT_OFFSET, 14726 },
+  { 0xfecc, G_UNICODE_NOT_PRESENT_OFFSET, 14726 },
+  { 0xfecd, G_UNICODE_NOT_PRESENT_OFFSET, 14729 },
+  { 0xfece, G_UNICODE_NOT_PRESENT_OFFSET, 14729 },
+  { 0xfecf, G_UNICODE_NOT_PRESENT_OFFSET, 14729 },
+  { 0xfed0, G_UNICODE_NOT_PRESENT_OFFSET, 14729 },
+  { 0xfed1, G_UNICODE_NOT_PRESENT_OFFSET, 14732 },
+  { 0xfed2, G_UNICODE_NOT_PRESENT_OFFSET, 14732 },
+  { 0xfed3, G_UNICODE_NOT_PRESENT_OFFSET, 14732 },
+  { 0xfed4, G_UNICODE_NOT_PRESENT_OFFSET, 14732 },
+  { 0xfed5, G_UNICODE_NOT_PRESENT_OFFSET, 14735 },
+  { 0xfed6, G_UNICODE_NOT_PRESENT_OFFSET, 14735 },
+  { 0xfed7, G_UNICODE_NOT_PRESENT_OFFSET, 14735 },
+  { 0xfed8, G_UNICODE_NOT_PRESENT_OFFSET, 14735 },
+  { 0xfed9, G_UNICODE_NOT_PRESENT_OFFSET, 14738 },
+  { 0xfeda, G_UNICODE_NOT_PRESENT_OFFSET, 14738 },
+  { 0xfedb, G_UNICODE_NOT_PRESENT_OFFSET, 14738 },
+  { 0xfedc, G_UNICODE_NOT_PRESENT_OFFSET, 14738 },
+  { 0xfedd, G_UNICODE_NOT_PRESENT_OFFSET, 14741 },
+  { 0xfede, G_UNICODE_NOT_PRESENT_OFFSET, 14741 },
+  { 0xfedf, G_UNICODE_NOT_PRESENT_OFFSET, 14741 },
+  { 0xfee0, G_UNICODE_NOT_PRESENT_OFFSET, 14741 },
+  { 0xfee1, G_UNICODE_NOT_PRESENT_OFFSET, 14744 },
+  { 0xfee2, G_UNICODE_NOT_PRESENT_OFFSET, 14744 },
+  { 0xfee3, G_UNICODE_NOT_PRESENT_OFFSET, 14744 },
+  { 0xfee4, G_UNICODE_NOT_PRESENT_OFFSET, 14744 },
+  { 0xfee5, G_UNICODE_NOT_PRESENT_OFFSET, 14747 },
+  { 0xfee6, G_UNICODE_NOT_PRESENT_OFFSET, 14747 },
+  { 0xfee7, G_UNICODE_NOT_PRESENT_OFFSET, 14747 },
+  { 0xfee8, G_UNICODE_NOT_PRESENT_OFFSET, 14747 },
+  { 0xfee9, G_UNICODE_NOT_PRESENT_OFFSET, 14750 },
+  { 0xfeea, G_UNICODE_NOT_PRESENT_OFFSET, 14750 },
+  { 0xfeeb, G_UNICODE_NOT_PRESENT_OFFSET, 14750 },
+  { 0xfeec, G_UNICODE_NOT_PRESENT_OFFSET, 14750 },
+  { 0xfeed, G_UNICODE_NOT_PRESENT_OFFSET, 14753 },
+  { 0xfeee, G_UNICODE_NOT_PRESENT_OFFSET, 14753 },
+  { 0xfeef, G_UNICODE_NOT_PRESENT_OFFSET, 12802 },
+  { 0xfef0, G_UNICODE_NOT_PRESENT_OFFSET, 12802 },
+  { 0xfef1, G_UNICODE_NOT_PRESENT_OFFSET, 14756 },
+  { 0xfef2, G_UNICODE_NOT_PRESENT_OFFSET, 14756 },
+  { 0xfef3, G_UNICODE_NOT_PRESENT_OFFSET, 14756 },
+  { 0xfef4, G_UNICODE_NOT_PRESENT_OFFSET, 14756 },
+  { 0xfef5, G_UNICODE_NOT_PRESENT_OFFSET, 14759 },
+  { 0xfef6, G_UNICODE_NOT_PRESENT_OFFSET, 14759 },
+  { 0xfef7, G_UNICODE_NOT_PRESENT_OFFSET, 14766 },
+  { 0xfef8, G_UNICODE_NOT_PRESENT_OFFSET, 14766 },
+  { 0xfef9, G_UNICODE_NOT_PRESENT_OFFSET, 14773 },
+  { 0xfefa, G_UNICODE_NOT_PRESENT_OFFSET, 14773 },
+  { 0xfefb, G_UNICODE_NOT_PRESENT_OFFSET, 14780 },
+  { 0xfefc, G_UNICODE_NOT_PRESENT_OFFSET, 14780 },
+  { 0xff01, G_UNICODE_NOT_PRESENT_OFFSET, 14517 },
+  { 0xff02, G_UNICODE_NOT_PRESENT_OFFSET, 14785 },
+  { 0xff03, G_UNICODE_NOT_PRESENT_OFFSET, 14587 },
+  { 0xff04, G_UNICODE_NOT_PRESENT_OFFSET, 14601 },
+  { 0xff05, G_UNICODE_NOT_PRESENT_OFFSET, 14603 },
+  { 0xff06, G_UNICODE_NOT_PRESENT_OFFSET, 14589 },
+  { 0xff07, G_UNICODE_NOT_PRESENT_OFFSET, 14787 },
+  { 0xff08, G_UNICODE_NOT_PRESENT_OFFSET, 5275 },
+  { 0xff09, G_UNICODE_NOT_PRESENT_OFFSET, 5277 },
+  { 0xff0a, G_UNICODE_NOT_PRESENT_OFFSET, 14591 },
+  { 0xff0b, G_UNICODE_NOT_PRESENT_OFFSET, 5267 },
+  { 0xff0c, G_UNICODE_NOT_PRESENT_OFFSET, 14505 },
+  { 0xff0d, G_UNICODE_NOT_PRESENT_OFFSET, 14593 },
+  { 0xff0e, G_UNICODE_NOT_PRESENT_OFFSET, 5181 },
+  { 0xff0f, G_UNICODE_NOT_PRESENT_OFFSET, 14789 },
+  { 0xff10, G_UNICODE_NOT_PRESENT_OFFSET, 5253 },
+  { 0xff11, G_UNICODE_NOT_PRESENT_OFFSET, 27 },
+  { 0xff12, G_UNICODE_NOT_PRESENT_OFFSET, 12 },
+  { 0xff13, G_UNICODE_NOT_PRESENT_OFFSET, 14 },
+  { 0xff14, G_UNICODE_NOT_PRESENT_OFFSET, 5255 },
+  { 0xff15, G_UNICODE_NOT_PRESENT_OFFSET, 5257 },
+  { 0xff16, G_UNICODE_NOT_PRESENT_OFFSET, 5259 },
+  { 0xff17, G_UNICODE_NOT_PRESENT_OFFSET, 5261 },
+  { 0xff18, G_UNICODE_NOT_PRESENT_OFFSET, 5263 },
+  { 0xff19, G_UNICODE_NOT_PRESENT_OFFSET, 5265 },
+  { 0xff1a, G_UNICODE_NOT_PRESENT_OFFSET, 14515 },
+  { 0xff1b, G_UNICODE_NOT_PRESENT_OFFSET, 1248 },
+  { 0xff1c, G_UNICODE_NOT_PRESENT_OFFSET, 14595 },
+  { 0xff1d, G_UNICODE_NOT_PRESENT_OFFSET, 5273 },
+  { 0xff1e, G_UNICODE_NOT_PRESENT_OFFSET, 14597 },
+  { 0xff1f, G_UNICODE_NOT_PRESENT_OFFSET, 14519 },
+  { 0xff20, G_UNICODE_NOT_PRESENT_OFFSET, 14605 },
+  { 0xff21, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0xff22, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0xff23, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0xff24, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0xff25, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0xff26, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0xff27, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0xff28, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0xff29, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0xff2a, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0xff2b, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0xff2c, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0xff2d, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0xff2e, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0xff2f, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0xff30, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0xff31, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0xff32, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0xff33, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0xff34, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0xff35, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0xff36, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0xff37, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0xff38, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0xff39, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0xff3a, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0xff3b, G_UNICODE_NOT_PRESENT_OFFSET, 14583 },
+  { 0xff3c, G_UNICODE_NOT_PRESENT_OFFSET, 14599 },
+  { 0xff3d, G_UNICODE_NOT_PRESENT_OFFSET, 14585 },
+  { 0xff3e, G_UNICODE_NOT_PRESENT_OFFSET, 14791 },
+  { 0xff3f, G_UNICODE_NOT_PRESENT_OFFSET, 14537 },
+  { 0xff40, G_UNICODE_NOT_PRESENT_OFFSET, 5110 },
+  { 0xff41, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0xff42, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0xff43, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0xff44, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0xff45, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0xff46, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0xff47, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0xff48, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0xff49, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0xff4a, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0xff4b, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0xff4c, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0xff4d, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0xff4e, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0xff4f, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0xff50, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0xff51, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0xff52, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0xff53, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0xff54, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0xff55, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0xff56, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0xff57, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0xff58, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0xff59, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0xff5a, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0xff5b, G_UNICODE_NOT_PRESENT_OFFSET, 14539 },
+  { 0xff5c, G_UNICODE_NOT_PRESENT_OFFSET, 14793 },
+  { 0xff5d, G_UNICODE_NOT_PRESENT_OFFSET, 14541 },
+  { 0xff5e, G_UNICODE_NOT_PRESENT_OFFSET, 14795 },
+  { 0xff5f, G_UNICODE_NOT_PRESENT_OFFSET, 14797 },
+  { 0xff60, G_UNICODE_NOT_PRESENT_OFFSET, 14801 },
+  { 0xff61, G_UNICODE_NOT_PRESENT_OFFSET, 14511 },
+  { 0xff62, G_UNICODE_NOT_PRESENT_OFFSET, 14567 },
+  { 0xff63, G_UNICODE_NOT_PRESENT_OFFSET, 14571 },
+  { 0xff64, G_UNICODE_NOT_PRESENT_OFFSET, 14507 },
+  { 0xff65, G_UNICODE_NOT_PRESENT_OFFSET, 14805 },
+  { 0xff66, G_UNICODE_NOT_PRESENT_OFFSET, 8955 },
+  { 0xff67, G_UNICODE_NOT_PRESENT_OFFSET, 14809 },
+  { 0xff68, G_UNICODE_NOT_PRESENT_OFFSET, 14813 },
+  { 0xff69, G_UNICODE_NOT_PRESENT_OFFSET, 14817 },
+  { 0xff6a, G_UNICODE_NOT_PRESENT_OFFSET, 14821 },
+  { 0xff6b, G_UNICODE_NOT_PRESENT_OFFSET, 14825 },
+  { 0xff6c, G_UNICODE_NOT_PRESENT_OFFSET, 14829 },
+  { 0xff6d, G_UNICODE_NOT_PRESENT_OFFSET, 14833 },
+  { 0xff6e, G_UNICODE_NOT_PRESENT_OFFSET, 14837 },
+  { 0xff6f, G_UNICODE_NOT_PRESENT_OFFSET, 14841 },
+  { 0xff70, G_UNICODE_NOT_PRESENT_OFFSET, 14845 },
+  { 0xff71, G_UNICODE_NOT_PRESENT_OFFSET, 8771 },
+  { 0xff72, G_UNICODE_NOT_PRESENT_OFFSET, 8775 },
+  { 0xff73, G_UNICODE_NOT_PRESENT_OFFSET, 8779 },
+  { 0xff74, G_UNICODE_NOT_PRESENT_OFFSET, 8783 },
+  { 0xff75, G_UNICODE_NOT_PRESENT_OFFSET, 8787 },
+  { 0xff76, G_UNICODE_NOT_PRESENT_OFFSET, 8791 },
+  { 0xff77, G_UNICODE_NOT_PRESENT_OFFSET, 8795 },
+  { 0xff78, G_UNICODE_NOT_PRESENT_OFFSET, 8799 },
+  { 0xff79, G_UNICODE_NOT_PRESENT_OFFSET, 8803 },
+  { 0xff7a, G_UNICODE_NOT_PRESENT_OFFSET, 8807 },
+  { 0xff7b, G_UNICODE_NOT_PRESENT_OFFSET, 8811 },
+  { 0xff7c, G_UNICODE_NOT_PRESENT_OFFSET, 8815 },
+  { 0xff7d, G_UNICODE_NOT_PRESENT_OFFSET, 8819 },
+  { 0xff7e, G_UNICODE_NOT_PRESENT_OFFSET, 8823 },
+  { 0xff7f, G_UNICODE_NOT_PRESENT_OFFSET, 8827 },
+  { 0xff80, G_UNICODE_NOT_PRESENT_OFFSET, 8831 },
+  { 0xff81, G_UNICODE_NOT_PRESENT_OFFSET, 8835 },
+  { 0xff82, G_UNICODE_NOT_PRESENT_OFFSET, 8839 },
+  { 0xff83, G_UNICODE_NOT_PRESENT_OFFSET, 8843 },
+  { 0xff84, G_UNICODE_NOT_PRESENT_OFFSET, 8847 },
+  { 0xff85, G_UNICODE_NOT_PRESENT_OFFSET, 8851 },
+  { 0xff86, G_UNICODE_NOT_PRESENT_OFFSET, 8855 },
+  { 0xff87, G_UNICODE_NOT_PRESENT_OFFSET, 8859 },
+  { 0xff88, G_UNICODE_NOT_PRESENT_OFFSET, 8863 },
+  { 0xff89, G_UNICODE_NOT_PRESENT_OFFSET, 8867 },
+  { 0xff8a, G_UNICODE_NOT_PRESENT_OFFSET, 8871 },
+  { 0xff8b, G_UNICODE_NOT_PRESENT_OFFSET, 8875 },
+  { 0xff8c, G_UNICODE_NOT_PRESENT_OFFSET, 8879 },
+  { 0xff8d, G_UNICODE_NOT_PRESENT_OFFSET, 8883 },
+  { 0xff8e, G_UNICODE_NOT_PRESENT_OFFSET, 8887 },
+  { 0xff8f, G_UNICODE_NOT_PRESENT_OFFSET, 8891 },
+  { 0xff90, G_UNICODE_NOT_PRESENT_OFFSET, 8895 },
+  { 0xff91, G_UNICODE_NOT_PRESENT_OFFSET, 8899 },
+  { 0xff92, G_UNICODE_NOT_PRESENT_OFFSET, 8903 },
+  { 0xff93, G_UNICODE_NOT_PRESENT_OFFSET, 8907 },
+  { 0xff94, G_UNICODE_NOT_PRESENT_OFFSET, 8911 },
+  { 0xff95, G_UNICODE_NOT_PRESENT_OFFSET, 8915 },
+  { 0xff96, G_UNICODE_NOT_PRESENT_OFFSET, 8919 },
+  { 0xff97, G_UNICODE_NOT_PRESENT_OFFSET, 8923 },
+  { 0xff98, G_UNICODE_NOT_PRESENT_OFFSET, 8927 },
+  { 0xff99, G_UNICODE_NOT_PRESENT_OFFSET, 8931 },
+  { 0xff9a, G_UNICODE_NOT_PRESENT_OFFSET, 8935 },
+  { 0xff9b, G_UNICODE_NOT_PRESENT_OFFSET, 8939 },
+  { 0xff9c, G_UNICODE_NOT_PRESENT_OFFSET, 8943 },
+  { 0xff9d, G_UNICODE_NOT_PRESENT_OFFSET, 14849 },
+  { 0xff9e, G_UNICODE_NOT_PRESENT_OFFSET, 14853 },
+  { 0xff9f, G_UNICODE_NOT_PRESENT_OFFSET, 14857 },
+  { 0xffa0, G_UNICODE_NOT_PRESENT_OFFSET, 7658 },
+  { 0xffa1, G_UNICODE_NOT_PRESENT_OFFSET, 7454 },
+  { 0xffa2, G_UNICODE_NOT_PRESENT_OFFSET, 7458 },
+  { 0xffa3, G_UNICODE_NOT_PRESENT_OFFSET, 7462 },
+  { 0xffa4, G_UNICODE_NOT_PRESENT_OFFSET, 7466 },
+  { 0xffa5, G_UNICODE_NOT_PRESENT_OFFSET, 7470 },
+  { 0xffa6, G_UNICODE_NOT_PRESENT_OFFSET, 7474 },
+  { 0xffa7, G_UNICODE_NOT_PRESENT_OFFSET, 7478 },
+  { 0xffa8, G_UNICODE_NOT_PRESENT_OFFSET, 7482 },
+  { 0xffa9, G_UNICODE_NOT_PRESENT_OFFSET, 7486 },
+  { 0xffaa, G_UNICODE_NOT_PRESENT_OFFSET, 7490 },
+  { 0xffab, G_UNICODE_NOT_PRESENT_OFFSET, 7494 },
+  { 0xffac, G_UNICODE_NOT_PRESENT_OFFSET, 7498 },
+  { 0xffad, G_UNICODE_NOT_PRESENT_OFFSET, 7502 },
+  { 0xffae, G_UNICODE_NOT_PRESENT_OFFSET, 7506 },
+  { 0xffaf, G_UNICODE_NOT_PRESENT_OFFSET, 7510 },
+  { 0xffb0, G_UNICODE_NOT_PRESENT_OFFSET, 7514 },
+  { 0xffb1, G_UNICODE_NOT_PRESENT_OFFSET, 7518 },
+  { 0xffb2, G_UNICODE_NOT_PRESENT_OFFSET, 7522 },
+  { 0xffb3, G_UNICODE_NOT_PRESENT_OFFSET, 7526 },
+  { 0xffb4, G_UNICODE_NOT_PRESENT_OFFSET, 7530 },
+  { 0xffb5, G_UNICODE_NOT_PRESENT_OFFSET, 7534 },
+  { 0xffb6, G_UNICODE_NOT_PRESENT_OFFSET, 7538 },
+  { 0xffb7, G_UNICODE_NOT_PRESENT_OFFSET, 7542 },
+  { 0xffb8, G_UNICODE_NOT_PRESENT_OFFSET, 7546 },
+  { 0xffb9, G_UNICODE_NOT_PRESENT_OFFSET, 7550 },
+  { 0xffba, G_UNICODE_NOT_PRESENT_OFFSET, 7554 },
+  { 0xffbb, G_UNICODE_NOT_PRESENT_OFFSET, 7558 },
+  { 0xffbc, G_UNICODE_NOT_PRESENT_OFFSET, 7562 },
+  { 0xffbd, G_UNICODE_NOT_PRESENT_OFFSET, 7566 },
+  { 0xffbe, G_UNICODE_NOT_PRESENT_OFFSET, 7570 },
+  { 0xffc2, G_UNICODE_NOT_PRESENT_OFFSET, 7574 },
+  { 0xffc3, G_UNICODE_NOT_PRESENT_OFFSET, 7578 },
+  { 0xffc4, G_UNICODE_NOT_PRESENT_OFFSET, 7582 },
+  { 0xffc5, G_UNICODE_NOT_PRESENT_OFFSET, 7586 },
+  { 0xffc6, G_UNICODE_NOT_PRESENT_OFFSET, 7590 },
+  { 0xffc7, G_UNICODE_NOT_PRESENT_OFFSET, 7594 },
+  { 0xffca, G_UNICODE_NOT_PRESENT_OFFSET, 7598 },
+  { 0xffcb, G_UNICODE_NOT_PRESENT_OFFSET, 7602 },
+  { 0xffcc, G_UNICODE_NOT_PRESENT_OFFSET, 7606 },
+  { 0xffcd, G_UNICODE_NOT_PRESENT_OFFSET, 7610 },
+  { 0xffce, G_UNICODE_NOT_PRESENT_OFFSET, 7614 },
+  { 0xffcf, G_UNICODE_NOT_PRESENT_OFFSET, 7618 },
+  { 0xffd2, G_UNICODE_NOT_PRESENT_OFFSET, 7622 },
+  { 0xffd3, G_UNICODE_NOT_PRESENT_OFFSET, 7626 },
+  { 0xffd4, G_UNICODE_NOT_PRESENT_OFFSET, 7630 },
+  { 0xffd5, G_UNICODE_NOT_PRESENT_OFFSET, 7634 },
+  { 0xffd6, G_UNICODE_NOT_PRESENT_OFFSET, 7638 },
+  { 0xffd7, G_UNICODE_NOT_PRESENT_OFFSET, 7642 },
+  { 0xffda, G_UNICODE_NOT_PRESENT_OFFSET, 7646 },
+  { 0xffdb, G_UNICODE_NOT_PRESENT_OFFSET, 7650 },
+  { 0xffdc, G_UNICODE_NOT_PRESENT_OFFSET, 7654 },
+  { 0xffe0, G_UNICODE_NOT_PRESENT_OFFSET, 14861 },
+  { 0xffe1, G_UNICODE_NOT_PRESENT_OFFSET, 14864 },
+  { 0xffe2, G_UNICODE_NOT_PRESENT_OFFSET, 14867 },
+  { 0xffe3, G_UNICODE_NOT_PRESENT_OFFSET, 8 },
+  { 0xffe4, G_UNICODE_NOT_PRESENT_OFFSET, 14870 },
+  { 0xffe5, G_UNICODE_NOT_PRESENT_OFFSET, 14873 },
+  { 0xffe6, G_UNICODE_NOT_PRESENT_OFFSET, 14876 },
+  { 0xffe8, G_UNICODE_NOT_PRESENT_OFFSET, 14880 },
+  { 0xffe9, G_UNICODE_NOT_PRESENT_OFFSET, 14884 },
+  { 0xffea, G_UNICODE_NOT_PRESENT_OFFSET, 14888 },
+  { 0xffeb, G_UNICODE_NOT_PRESENT_OFFSET, 14892 },
+  { 0xffec, G_UNICODE_NOT_PRESENT_OFFSET, 14896 },
+  { 0xffed, G_UNICODE_NOT_PRESENT_OFFSET, 14900 },
+  { 0xffee, G_UNICODE_NOT_PRESENT_OFFSET, 14904 },
+  { 0x1d15e, 14908, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d15f, 14917, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d160, 14926, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d161, 14939, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d162, 14952, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d163, 14965, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d164, 14978, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d1bb, 14991, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d1bc, 15000, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d1bd, 15009, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d1be, 15022, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d1bf, 15035, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d1c0, 15048, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x1d400, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d401, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x1d402, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x1d403, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d404, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x1d405, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x1d406, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d407, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x1d408, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x1d409, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d40a, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d40b, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x1d40c, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x1d40d, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x1d40e, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d40f, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x1d410, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x1d411, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x1d412, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x1d413, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d414, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d415, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x1d416, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d417, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x1d418, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x1d419, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x1d41a, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d41b, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d41c, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d41d, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d41e, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x1d41f, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1d420, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x1d421, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x1d422, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d423, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x1d424, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d425, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x1d426, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d427, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x1d428, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x1d429, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d42a, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x1d42b, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d42c, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x1d42d, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d42e, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d42f, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d430, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x1d431, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x1d432, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x1d433, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1d434, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d435, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x1d436, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x1d437, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d438, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x1d439, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x1d43a, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d43b, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x1d43c, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x1d43d, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d43e, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d43f, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x1d440, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x1d441, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x1d442, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d443, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x1d444, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x1d445, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x1d446, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x1d447, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d448, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d449, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x1d44a, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d44b, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x1d44c, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x1d44d, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x1d44e, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d44f, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d450, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d451, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d452, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x1d453, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1d454, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x1d456, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d457, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x1d458, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d459, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x1d45a, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d45b, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x1d45c, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x1d45d, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d45e, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x1d45f, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d460, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x1d461, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d462, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d463, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d464, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x1d465, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x1d466, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x1d467, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1d468, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d469, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x1d46a, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x1d46b, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d46c, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x1d46d, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x1d46e, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d46f, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x1d470, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x1d471, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d472, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d473, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x1d474, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x1d475, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x1d476, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d477, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x1d478, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x1d479, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x1d47a, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x1d47b, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d47c, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d47d, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x1d47e, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d47f, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x1d480, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x1d481, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x1d482, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d483, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d484, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d485, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d486, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x1d487, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1d488, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x1d489, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x1d48a, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d48b, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x1d48c, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d48d, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x1d48e, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d48f, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x1d490, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x1d491, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d492, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x1d493, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d494, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x1d495, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d496, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d497, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d498, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x1d499, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x1d49a, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x1d49b, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1d49c, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d49e, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x1d49f, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d4a2, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d4a5, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d4a6, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d4a9, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x1d4aa, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d4ab, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x1d4ac, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x1d4ae, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x1d4af, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d4b0, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d4b1, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x1d4b2, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d4b3, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x1d4b4, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x1d4b5, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x1d4b6, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d4b7, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d4b8, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d4b9, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d4bb, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1d4bd, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x1d4be, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d4bf, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x1d4c0, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d4c1, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x1d4c2, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d4c3, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x1d4c5, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d4c6, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x1d4c7, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d4c8, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x1d4c9, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d4ca, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d4cb, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d4cc, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x1d4cd, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x1d4ce, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x1d4cf, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1d4d0, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d4d1, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x1d4d2, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x1d4d3, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d4d4, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x1d4d5, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x1d4d6, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d4d7, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x1d4d8, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x1d4d9, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d4da, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d4db, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x1d4dc, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x1d4dd, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x1d4de, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d4df, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x1d4e0, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x1d4e1, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x1d4e2, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x1d4e3, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d4e4, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d4e5, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x1d4e6, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d4e7, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x1d4e8, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x1d4e9, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x1d4ea, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d4eb, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d4ec, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d4ed, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d4ee, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x1d4ef, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1d4f0, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x1d4f1, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x1d4f2, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d4f3, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x1d4f4, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d4f5, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x1d4f6, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d4f7, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x1d4f8, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x1d4f9, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d4fa, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x1d4fb, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d4fc, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x1d4fd, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d4fe, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d4ff, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d500, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x1d501, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x1d502, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x1d503, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1d504, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d505, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x1d507, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d508, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x1d509, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x1d50a, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d50d, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d50e, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d50f, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x1d510, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x1d511, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x1d512, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d513, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x1d514, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x1d516, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x1d517, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d518, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d519, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x1d51a, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d51b, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x1d51c, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x1d51e, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d51f, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d520, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d521, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d522, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x1d523, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1d524, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x1d525, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x1d526, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d527, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x1d528, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d529, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x1d52a, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d52b, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x1d52c, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x1d52d, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d52e, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x1d52f, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d530, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x1d531, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d532, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d533, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d534, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x1d535, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x1d536, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x1d537, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1d538, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d539, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x1d53b, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d53c, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x1d53d, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x1d53e, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d540, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x1d541, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d542, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d543, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x1d544, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x1d546, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d54a, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x1d54b, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d54c, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d54d, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x1d54e, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d54f, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x1d550, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x1d552, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d553, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d554, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d555, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d556, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x1d557, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1d558, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x1d559, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x1d55a, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d55b, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x1d55c, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d55d, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x1d55e, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d55f, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x1d560, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x1d561, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d562, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x1d563, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d564, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x1d565, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d566, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d567, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d568, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x1d569, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x1d56a, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x1d56b, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1d56c, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d56d, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x1d56e, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x1d56f, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d570, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x1d571, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x1d572, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d573, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x1d574, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x1d575, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d576, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d577, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x1d578, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x1d579, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x1d57a, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d57b, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x1d57c, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x1d57d, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x1d57e, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x1d57f, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d580, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d581, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x1d582, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d583, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x1d584, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x1d585, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x1d586, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d587, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d588, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d589, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d58a, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x1d58b, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1d58c, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x1d58d, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x1d58e, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d58f, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x1d590, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d591, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x1d592, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d593, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x1d594, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x1d595, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d596, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x1d597, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d598, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x1d599, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d59a, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d59b, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d59c, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x1d59d, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x1d59e, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x1d59f, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1d5a0, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d5a1, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x1d5a2, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x1d5a3, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d5a4, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x1d5a5, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x1d5a6, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d5a7, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x1d5a8, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x1d5a9, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d5aa, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d5ab, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x1d5ac, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x1d5ad, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x1d5ae, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d5af, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x1d5b0, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x1d5b1, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x1d5b2, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x1d5b3, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d5b4, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d5b5, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x1d5b6, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d5b7, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x1d5b8, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x1d5b9, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x1d5ba, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d5bb, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d5bc, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d5bd, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d5be, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x1d5bf, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1d5c0, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x1d5c1, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x1d5c2, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d5c3, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x1d5c4, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d5c5, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x1d5c6, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d5c7, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x1d5c8, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x1d5c9, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d5ca, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x1d5cb, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d5cc, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x1d5cd, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d5ce, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d5cf, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d5d0, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x1d5d1, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x1d5d2, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x1d5d3, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1d5d4, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d5d5, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x1d5d6, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x1d5d7, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d5d8, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x1d5d9, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x1d5da, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d5db, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x1d5dc, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x1d5dd, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d5de, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d5df, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x1d5e0, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x1d5e1, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x1d5e2, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d5e3, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x1d5e4, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x1d5e5, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x1d5e6, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x1d5e7, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d5e8, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d5e9, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x1d5ea, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d5eb, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x1d5ec, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x1d5ed, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x1d5ee, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d5ef, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d5f0, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d5f1, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d5f2, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x1d5f3, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1d5f4, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x1d5f5, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x1d5f6, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d5f7, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x1d5f8, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d5f9, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x1d5fa, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d5fb, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x1d5fc, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x1d5fd, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d5fe, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x1d5ff, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d600, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x1d601, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d602, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d603, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d604, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x1d605, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x1d606, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x1d607, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1d608, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d609, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x1d60a, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x1d60b, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d60c, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x1d60d, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x1d60e, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d60f, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x1d610, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x1d611, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d612, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d613, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x1d614, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x1d615, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x1d616, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d617, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x1d618, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x1d619, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x1d61a, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x1d61b, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d61c, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d61d, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x1d61e, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d61f, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x1d620, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x1d621, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x1d622, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d623, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d624, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d625, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d626, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x1d627, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1d628, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x1d629, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x1d62a, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d62b, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x1d62c, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d62d, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x1d62e, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d62f, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x1d630, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x1d631, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d632, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x1d633, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d634, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x1d635, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d636, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d637, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d638, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x1d639, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x1d63a, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x1d63b, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1d63c, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d63d, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x1d63e, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x1d63f, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d640, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x1d641, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x1d642, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d643, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x1d644, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x1d645, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d646, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d647, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x1d648, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x1d649, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x1d64a, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d64b, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x1d64c, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x1d64d, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x1d64e, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x1d64f, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d650, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d651, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x1d652, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d653, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x1d654, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x1d655, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x1d656, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d657, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d658, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d659, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d65a, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x1d65b, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1d65c, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x1d65d, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x1d65e, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d65f, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x1d660, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d661, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x1d662, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d663, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x1d664, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x1d665, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d666, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x1d667, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d668, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x1d669, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d66a, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d66b, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d66c, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x1d66d, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x1d66e, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x1d66f, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1d670, G_UNICODE_NOT_PRESENT_OFFSET, 2309 },
+  { 0x1d671, G_UNICODE_NOT_PRESENT_OFFSET, 2314 },
+  { 0x1d672, G_UNICODE_NOT_PRESENT_OFFSET, 5292 },
+  { 0x1d673, G_UNICODE_NOT_PRESENT_OFFSET, 2316 },
+  { 0x1d674, G_UNICODE_NOT_PRESENT_OFFSET, 2318 },
+  { 0x1d675, G_UNICODE_NOT_PRESENT_OFFSET, 5336 },
+  { 0x1d676, G_UNICODE_NOT_PRESENT_OFFSET, 2323 },
+  { 0x1d677, G_UNICODE_NOT_PRESENT_OFFSET, 2325 },
+  { 0x1d678, G_UNICODE_NOT_PRESENT_OFFSET, 2327 },
+  { 0x1d679, G_UNICODE_NOT_PRESENT_OFFSET, 2329 },
+  { 0x1d67a, G_UNICODE_NOT_PRESENT_OFFSET, 2331 },
+  { 0x1d67b, G_UNICODE_NOT_PRESENT_OFFSET, 2333 },
+  { 0x1d67c, G_UNICODE_NOT_PRESENT_OFFSET, 2335 },
+  { 0x1d67d, G_UNICODE_NOT_PRESENT_OFFSET, 2337 },
+  { 0x1d67e, G_UNICODE_NOT_PRESENT_OFFSET, 2339 },
+  { 0x1d67f, G_UNICODE_NOT_PRESENT_OFFSET, 2344 },
+  { 0x1d680, G_UNICODE_NOT_PRESENT_OFFSET, 5319 },
+  { 0x1d681, G_UNICODE_NOT_PRESENT_OFFSET, 2346 },
+  { 0x1d682, G_UNICODE_NOT_PRESENT_OFFSET, 6108 },
+  { 0x1d683, G_UNICODE_NOT_PRESENT_OFFSET, 2348 },
+  { 0x1d684, G_UNICODE_NOT_PRESENT_OFFSET, 2350 },
+  { 0x1d685, G_UNICODE_NOT_PRESENT_OFFSET, 5451 },
+  { 0x1d686, G_UNICODE_NOT_PRESENT_OFFSET, 2352 },
+  { 0x1d687, G_UNICODE_NOT_PRESENT_OFFSET, 5468 },
+  { 0x1d688, G_UNICODE_NOT_PRESENT_OFFSET, 6110 },
+  { 0x1d689, G_UNICODE_NOT_PRESENT_OFFSET, 5331 },
+  { 0x1d68a, G_UNICODE_NOT_PRESENT_OFFSET, 6 },
+  { 0x1d68b, G_UNICODE_NOT_PRESENT_OFFSET, 2364 },
+  { 0x1d68c, G_UNICODE_NOT_PRESENT_OFFSET, 2435 },
+  { 0x1d68d, G_UNICODE_NOT_PRESENT_OFFSET, 2366 },
+  { 0x1d68e, G_UNICODE_NOT_PRESENT_OFFSET, 2368 },
+  { 0x1d68f, G_UNICODE_NOT_PRESENT_OFFSET, 2443 },
+  { 0x1d690, G_UNICODE_NOT_PRESENT_OFFSET, 2379 },
+  { 0x1d691, G_UNICODE_NOT_PRESENT_OFFSET, 1171 },
+  { 0x1d692, G_UNICODE_NOT_PRESENT_OFFSET, 2427 },
+  { 0x1d693, G_UNICODE_NOT_PRESENT_OFFSET, 1176 },
+  { 0x1d694, G_UNICODE_NOT_PRESENT_OFFSET, 2381 },
+  { 0x1d695, G_UNICODE_NOT_PRESENT_OFFSET, 1220 },
+  { 0x1d696, G_UNICODE_NOT_PRESENT_OFFSET, 2383 },
+  { 0x1d697, G_UNICODE_NOT_PRESENT_OFFSET, 5279 },
+  { 0x1d698, G_UNICODE_NOT_PRESENT_OFFSET, 29 },
+  { 0x1d699, G_UNICODE_NOT_PRESENT_OFFSET, 2399 },
+  { 0x1d69a, G_UNICODE_NOT_PRESENT_OFFSET, 6112 },
+  { 0x1d69b, G_UNICODE_NOT_PRESENT_OFFSET, 1178 },
+  { 0x1d69c, G_UNICODE_NOT_PRESENT_OFFSET, 711 },
+  { 0x1d69d, G_UNICODE_NOT_PRESENT_OFFSET, 2401 },
+  { 0x1d69e, G_UNICODE_NOT_PRESENT_OFFSET, 2403 },
+  { 0x1d69f, G_UNICODE_NOT_PRESENT_OFFSET, 2412 },
+  { 0x1d6a0, G_UNICODE_NOT_PRESENT_OFFSET, 1189 },
+  { 0x1d6a1, G_UNICODE_NOT_PRESENT_OFFSET, 1222 },
+  { 0x1d6a2, G_UNICODE_NOT_PRESENT_OFFSET, 1191 },
+  { 0x1d6a3, G_UNICODE_NOT_PRESENT_OFFSET, 2526 },
+  { 0x1d6a4, G_UNICODE_NOT_PRESENT_OFFSET, 15061 },
+  { 0x1d6a5, G_UNICODE_NOT_PRESENT_OFFSET, 15064 },
+  { 0x1d6a8, G_UNICODE_NOT_PRESENT_OFFSET, 15067 },
+  { 0x1d6a9, G_UNICODE_NOT_PRESENT_OFFSET, 15070 },
+  { 0x1d6aa, G_UNICODE_NOT_PRESENT_OFFSET, 5354 },
+  { 0x1d6ab, G_UNICODE_NOT_PRESENT_OFFSET, 15073 },
+  { 0x1d6ac, G_UNICODE_NOT_PRESENT_OFFSET, 15076 },
+  { 0x1d6ad, G_UNICODE_NOT_PRESENT_OFFSET, 15079 },
+  { 0x1d6ae, G_UNICODE_NOT_PRESENT_OFFSET, 15082 },
+  { 0x1d6af, G_UNICODE_NOT_PRESENT_OFFSET, 1402 },
+  { 0x1d6b0, G_UNICODE_NOT_PRESENT_OFFSET, 15085 },
+  { 0x1d6b1, G_UNICODE_NOT_PRESENT_OFFSET, 15088 },
+  { 0x1d6b2, G_UNICODE_NOT_PRESENT_OFFSET, 15091 },
+  { 0x1d6b3, G_UNICODE_NOT_PRESENT_OFFSET, 15094 },
+  { 0x1d6b4, G_UNICODE_NOT_PRESENT_OFFSET, 15097 },
+  { 0x1d6b5, G_UNICODE_NOT_PRESENT_OFFSET, 15100 },
+  { 0x1d6b6, G_UNICODE_NOT_PRESENT_OFFSET, 15103 },
+  { 0x1d6b7, G_UNICODE_NOT_PRESENT_OFFSET, 5357 },
+  { 0x1d6b8, G_UNICODE_NOT_PRESENT_OFFSET, 15106 },
+  { 0x1d6b9, G_UNICODE_NOT_PRESENT_OFFSET, 1402 },
+  { 0x1d6ba, G_UNICODE_NOT_PRESENT_OFFSET, 1408 },
+  { 0x1d6bb, G_UNICODE_NOT_PRESENT_OFFSET, 15109 },
+  { 0x1d6bc, G_UNICODE_NOT_PRESENT_OFFSET, 1374 },
+  { 0x1d6bd, G_UNICODE_NOT_PRESENT_OFFSET, 15112 },
+  { 0x1d6be, G_UNICODE_NOT_PRESENT_OFFSET, 15115 },
+  { 0x1d6bf, G_UNICODE_NOT_PRESENT_OFFSET, 15118 },
+  { 0x1d6c0, G_UNICODE_NOT_PRESENT_OFFSET, 5333 },
+  { 0x1d6c1, G_UNICODE_NOT_PRESENT_OFFSET, 15121 },
+  { 0x1d6c2, G_UNICODE_NOT_PRESENT_OFFSET, 15125 },
+  { 0x1d6c3, G_UNICODE_NOT_PRESENT_OFFSET, 1368 },
+  { 0x1d6c4, G_UNICODE_NOT_PRESENT_OFFSET, 2418 },
+  { 0x1d6c5, G_UNICODE_NOT_PRESENT_OFFSET, 2421 },
+  { 0x1d6c6, G_UNICODE_NOT_PRESENT_OFFSET, 1405 },
+  { 0x1d6c7, G_UNICODE_NOT_PRESENT_OFFSET, 15128 },
+  { 0x1d6c8, G_UNICODE_NOT_PRESENT_OFFSET, 15131 },
+  { 0x1d6c9, G_UNICODE_NOT_PRESENT_OFFSET, 1371 },
+  { 0x1d6ca, G_UNICODE_NOT_PRESENT_OFFSET, 4860 },
+  { 0x1d6cb, G_UNICODE_NOT_PRESENT_OFFSET, 1393 },
+  { 0x1d6cc, G_UNICODE_NOT_PRESENT_OFFSET, 15134 },
+  { 0x1d6cd, G_UNICODE_NOT_PRESENT_OFFSET, 20 },
+  { 0x1d6ce, G_UNICODE_NOT_PRESENT_OFFSET, 15137 },
+  { 0x1d6cf, G_UNICODE_NOT_PRESENT_OFFSET, 15140 },
+  { 0x1d6d0, G_UNICODE_NOT_PRESENT_OFFSET, 15143 },
+  { 0x1d6d1, G_UNICODE_NOT_PRESENT_OFFSET, 1390 },
+  { 0x1d6d2, G_UNICODE_NOT_PRESENT_OFFSET, 1396 },
+  { 0x1d6d3, G_UNICODE_NOT_PRESENT_OFFSET, 1399 },
+  { 0x1d6d4, G_UNICODE_NOT_PRESENT_OFFSET, 15146 },
+  { 0x1d6d5, G_UNICODE_NOT_PRESENT_OFFSET, 15149 },
+  { 0x1d6d6, G_UNICODE_NOT_PRESENT_OFFSET, 15152 },
+  { 0x1d6d7, G_UNICODE_NOT_PRESENT_OFFSET, 1387 },
+  { 0x1d6d8, G_UNICODE_NOT_PRESENT_OFFSET, 2424 },
+  { 0x1d6d9, G_UNICODE_NOT_PRESENT_OFFSET, 15155 },
+  { 0x1d6da, G_UNICODE_NOT_PRESENT_OFFSET, 15158 },
+  { 0x1d6db, G_UNICODE_NOT_PRESENT_OFFSET, 15161 },
+  { 0x1d6dc, G_UNICODE_NOT_PRESENT_OFFSET, 1405 },
+  { 0x1d6dd, G_UNICODE_NOT_PRESENT_OFFSET, 1371 },
+  { 0x1d6de, G_UNICODE_NOT_PRESENT_OFFSET, 1393 },
+  { 0x1d6df, G_UNICODE_NOT_PRESENT_OFFSET, 1387 },
+  { 0x1d6e0, G_UNICODE_NOT_PRESENT_OFFSET, 1396 },
+  { 0x1d6e1, G_UNICODE_NOT_PRESENT_OFFSET, 1390 },
+  { 0x1d6e2, G_UNICODE_NOT_PRESENT_OFFSET, 15067 },
+  { 0x1d6e3, G_UNICODE_NOT_PRESENT_OFFSET, 15070 },
+  { 0x1d6e4, G_UNICODE_NOT_PRESENT_OFFSET, 5354 },
+  { 0x1d6e5, G_UNICODE_NOT_PRESENT_OFFSET, 15073 },
+  { 0x1d6e6, G_UNICODE_NOT_PRESENT_OFFSET, 15076 },
+  { 0x1d6e7, G_UNICODE_NOT_PRESENT_OFFSET, 15079 },
+  { 0x1d6e8, G_UNICODE_NOT_PRESENT_OFFSET, 15082 },
+  { 0x1d6e9, G_UNICODE_NOT_PRESENT_OFFSET, 1402 },
+  { 0x1d6ea, G_UNICODE_NOT_PRESENT_OFFSET, 15085 },
+  { 0x1d6eb, G_UNICODE_NOT_PRESENT_OFFSET, 15088 },
+  { 0x1d6ec, G_UNICODE_NOT_PRESENT_OFFSET, 15091 },
+  { 0x1d6ed, G_UNICODE_NOT_PRESENT_OFFSET, 15094 },
+  { 0x1d6ee, G_UNICODE_NOT_PRESENT_OFFSET, 15097 },
+  { 0x1d6ef, G_UNICODE_NOT_PRESENT_OFFSET, 15100 },
+  { 0x1d6f0, G_UNICODE_NOT_PRESENT_OFFSET, 15103 },
+  { 0x1d6f1, G_UNICODE_NOT_PRESENT_OFFSET, 5357 },
+  { 0x1d6f2, G_UNICODE_NOT_PRESENT_OFFSET, 15106 },
+  { 0x1d6f3, G_UNICODE_NOT_PRESENT_OFFSET, 1402 },
+  { 0x1d6f4, G_UNICODE_NOT_PRESENT_OFFSET, 1408 },
+  { 0x1d6f5, G_UNICODE_NOT_PRESENT_OFFSET, 15109 },
+  { 0x1d6f6, G_UNICODE_NOT_PRESENT_OFFSET, 1374 },
+  { 0x1d6f7, G_UNICODE_NOT_PRESENT_OFFSET, 15112 },
+  { 0x1d6f8, G_UNICODE_NOT_PRESENT_OFFSET, 15115 },
+  { 0x1d6f9, G_UNICODE_NOT_PRESENT_OFFSET, 15118 },
+  { 0x1d6fa, G_UNICODE_NOT_PRESENT_OFFSET, 5333 },
+  { 0x1d6fb, G_UNICODE_NOT_PRESENT_OFFSET, 15121 },
+  { 0x1d6fc, G_UNICODE_NOT_PRESENT_OFFSET, 15125 },
+  { 0x1d6fd, G_UNICODE_NOT_PRESENT_OFFSET, 1368 },
+  { 0x1d6fe, G_UNICODE_NOT_PRESENT_OFFSET, 2418 },
+  { 0x1d6ff, G_UNICODE_NOT_PRESENT_OFFSET, 2421 },
+  { 0x1d700, G_UNICODE_NOT_PRESENT_OFFSET, 1405 },
+  { 0x1d701, G_UNICODE_NOT_PRESENT_OFFSET, 15128 },
+  { 0x1d702, G_UNICODE_NOT_PRESENT_OFFSET, 15131 },
+  { 0x1d703, G_UNICODE_NOT_PRESENT_OFFSET, 1371 },
+  { 0x1d704, G_UNICODE_NOT_PRESENT_OFFSET, 4860 },
+  { 0x1d705, G_UNICODE_NOT_PRESENT_OFFSET, 1393 },
+  { 0x1d706, G_UNICODE_NOT_PRESENT_OFFSET, 15134 },
+  { 0x1d707, G_UNICODE_NOT_PRESENT_OFFSET, 20 },
+  { 0x1d708, G_UNICODE_NOT_PRESENT_OFFSET, 15137 },
+  { 0x1d709, G_UNICODE_NOT_PRESENT_OFFSET, 15140 },
+  { 0x1d70a, G_UNICODE_NOT_PRESENT_OFFSET, 15143 },
+  { 0x1d70b, G_UNICODE_NOT_PRESENT_OFFSET, 1390 },
+  { 0x1d70c, G_UNICODE_NOT_PRESENT_OFFSET, 1396 },
+  { 0x1d70d, G_UNICODE_NOT_PRESENT_OFFSET, 1399 },
+  { 0x1d70e, G_UNICODE_NOT_PRESENT_OFFSET, 15146 },
+  { 0x1d70f, G_UNICODE_NOT_PRESENT_OFFSET, 15149 },
+  { 0x1d710, G_UNICODE_NOT_PRESENT_OFFSET, 15152 },
+  { 0x1d711, G_UNICODE_NOT_PRESENT_OFFSET, 1387 },
+  { 0x1d712, G_UNICODE_NOT_PRESENT_OFFSET, 2424 },
+  { 0x1d713, G_UNICODE_NOT_PRESENT_OFFSET, 15155 },
+  { 0x1d714, G_UNICODE_NOT_PRESENT_OFFSET, 15158 },
+  { 0x1d715, G_UNICODE_NOT_PRESENT_OFFSET, 15161 },
+  { 0x1d716, G_UNICODE_NOT_PRESENT_OFFSET, 1405 },
+  { 0x1d717, G_UNICODE_NOT_PRESENT_OFFSET, 1371 },
+  { 0x1d718, G_UNICODE_NOT_PRESENT_OFFSET, 1393 },
+  { 0x1d719, G_UNICODE_NOT_PRESENT_OFFSET, 1387 },
+  { 0x1d71a, G_UNICODE_NOT_PRESENT_OFFSET, 1396 },
+  { 0x1d71b, G_UNICODE_NOT_PRESENT_OFFSET, 1390 },
+  { 0x1d71c, G_UNICODE_NOT_PRESENT_OFFSET, 15067 },
+  { 0x1d71d, G_UNICODE_NOT_PRESENT_OFFSET, 15070 },
+  { 0x1d71e, G_UNICODE_NOT_PRESENT_OFFSET, 5354 },
+  { 0x1d71f, G_UNICODE_NOT_PRESENT_OFFSET, 15073 },
+  { 0x1d720, G_UNICODE_NOT_PRESENT_OFFSET, 15076 },
+  { 0x1d721, G_UNICODE_NOT_PRESENT_OFFSET, 15079 },
+  { 0x1d722, G_UNICODE_NOT_PRESENT_OFFSET, 15082 },
+  { 0x1d723, G_UNICODE_NOT_PRESENT_OFFSET, 1402 },
+  { 0x1d724, G_UNICODE_NOT_PRESENT_OFFSET, 15085 },
+  { 0x1d725, G_UNICODE_NOT_PRESENT_OFFSET, 15088 },
+  { 0x1d726, G_UNICODE_NOT_PRESENT_OFFSET, 15091 },
+  { 0x1d727, G_UNICODE_NOT_PRESENT_OFFSET, 15094 },
+  { 0x1d728, G_UNICODE_NOT_PRESENT_OFFSET, 15097 },
+  { 0x1d729, G_UNICODE_NOT_PRESENT_OFFSET, 15100 },
+  { 0x1d72a, G_UNICODE_NOT_PRESENT_OFFSET, 15103 },
+  { 0x1d72b, G_UNICODE_NOT_PRESENT_OFFSET, 5357 },
+  { 0x1d72c, G_UNICODE_NOT_PRESENT_OFFSET, 15106 },
+  { 0x1d72d, G_UNICODE_NOT_PRESENT_OFFSET, 1402 },
+  { 0x1d72e, G_UNICODE_NOT_PRESENT_OFFSET, 1408 },
+  { 0x1d72f, G_UNICODE_NOT_PRESENT_OFFSET, 15109 },
+  { 0x1d730, G_UNICODE_NOT_PRESENT_OFFSET, 1374 },
+  { 0x1d731, G_UNICODE_NOT_PRESENT_OFFSET, 15112 },
+  { 0x1d732, G_UNICODE_NOT_PRESENT_OFFSET, 15115 },
+  { 0x1d733, G_UNICODE_NOT_PRESENT_OFFSET, 15118 },
+  { 0x1d734, G_UNICODE_NOT_PRESENT_OFFSET, 5333 },
+  { 0x1d735, G_UNICODE_NOT_PRESENT_OFFSET, 15121 },
+  { 0x1d736, G_UNICODE_NOT_PRESENT_OFFSET, 15125 },
+  { 0x1d737, G_UNICODE_NOT_PRESENT_OFFSET, 1368 },
+  { 0x1d738, G_UNICODE_NOT_PRESENT_OFFSET, 2418 },
+  { 0x1d739, G_UNICODE_NOT_PRESENT_OFFSET, 2421 },
+  { 0x1d73a, G_UNICODE_NOT_PRESENT_OFFSET, 1405 },
+  { 0x1d73b, G_UNICODE_NOT_PRESENT_OFFSET, 15128 },
+  { 0x1d73c, G_UNICODE_NOT_PRESENT_OFFSET, 15131 },
+  { 0x1d73d, G_UNICODE_NOT_PRESENT_OFFSET, 1371 },
+  { 0x1d73e, G_UNICODE_NOT_PRESENT_OFFSET, 4860 },
+  { 0x1d73f, G_UNICODE_NOT_PRESENT_OFFSET, 1393 },
+  { 0x1d740, G_UNICODE_NOT_PRESENT_OFFSET, 15134 },
+  { 0x1d741, G_UNICODE_NOT_PRESENT_OFFSET, 20 },
+  { 0x1d742, G_UNICODE_NOT_PRESENT_OFFSET, 15137 },
+  { 0x1d743, G_UNICODE_NOT_PRESENT_OFFSET, 15140 },
+  { 0x1d744, G_UNICODE_NOT_PRESENT_OFFSET, 15143 },
+  { 0x1d745, G_UNICODE_NOT_PRESENT_OFFSET, 1390 },
+  { 0x1d746, G_UNICODE_NOT_PRESENT_OFFSET, 1396 },
+  { 0x1d747, G_UNICODE_NOT_PRESENT_OFFSET, 1399 },
+  { 0x1d748, G_UNICODE_NOT_PRESENT_OFFSET, 15146 },
+  { 0x1d749, G_UNICODE_NOT_PRESENT_OFFSET, 15149 },
+  { 0x1d74a, G_UNICODE_NOT_PRESENT_OFFSET, 15152 },
+  { 0x1d74b, G_UNICODE_NOT_PRESENT_OFFSET, 1387 },
+  { 0x1d74c, G_UNICODE_NOT_PRESENT_OFFSET, 2424 },
+  { 0x1d74d, G_UNICODE_NOT_PRESENT_OFFSET, 15155 },
+  { 0x1d74e, G_UNICODE_NOT_PRESENT_OFFSET, 15158 },
+  { 0x1d74f, G_UNICODE_NOT_PRESENT_OFFSET, 15161 },
+  { 0x1d750, G_UNICODE_NOT_PRESENT_OFFSET, 1405 },
+  { 0x1d751, G_UNICODE_NOT_PRESENT_OFFSET, 1371 },
+  { 0x1d752, G_UNICODE_NOT_PRESENT_OFFSET, 1393 },
+  { 0x1d753, G_UNICODE_NOT_PRESENT_OFFSET, 1387 },
+  { 0x1d754, G_UNICODE_NOT_PRESENT_OFFSET, 1396 },
+  { 0x1d755, G_UNICODE_NOT_PRESENT_OFFSET, 1390 },
+  { 0x1d756, G_UNICODE_NOT_PRESENT_OFFSET, 15067 },
+  { 0x1d757, G_UNICODE_NOT_PRESENT_OFFSET, 15070 },
+  { 0x1d758, G_UNICODE_NOT_PRESENT_OFFSET, 5354 },
+  { 0x1d759, G_UNICODE_NOT_PRESENT_OFFSET, 15073 },
+  { 0x1d75a, G_UNICODE_NOT_PRESENT_OFFSET, 15076 },
+  { 0x1d75b, G_UNICODE_NOT_PRESENT_OFFSET, 15079 },
+  { 0x1d75c, G_UNICODE_NOT_PRESENT_OFFSET, 15082 },
+  { 0x1d75d, G_UNICODE_NOT_PRESENT_OFFSET, 1402 },
+  { 0x1d75e, G_UNICODE_NOT_PRESENT_OFFSET, 15085 },
+  { 0x1d75f, G_UNICODE_NOT_PRESENT_OFFSET, 15088 },
+  { 0x1d760, G_UNICODE_NOT_PRESENT_OFFSET, 15091 },
+  { 0x1d761, G_UNICODE_NOT_PRESENT_OFFSET, 15094 },
+  { 0x1d762, G_UNICODE_NOT_PRESENT_OFFSET, 15097 },
+  { 0x1d763, G_UNICODE_NOT_PRESENT_OFFSET, 15100 },
+  { 0x1d764, G_UNICODE_NOT_PRESENT_OFFSET, 15103 },
+  { 0x1d765, G_UNICODE_NOT_PRESENT_OFFSET, 5357 },
+  { 0x1d766, G_UNICODE_NOT_PRESENT_OFFSET, 15106 },
+  { 0x1d767, G_UNICODE_NOT_PRESENT_OFFSET, 1402 },
+  { 0x1d768, G_UNICODE_NOT_PRESENT_OFFSET, 1408 },
+  { 0x1d769, G_UNICODE_NOT_PRESENT_OFFSET, 15109 },
+  { 0x1d76a, G_UNICODE_NOT_PRESENT_OFFSET, 1374 },
+  { 0x1d76b, G_UNICODE_NOT_PRESENT_OFFSET, 15112 },
+  { 0x1d76c, G_UNICODE_NOT_PRESENT_OFFSET, 15115 },
+  { 0x1d76d, G_UNICODE_NOT_PRESENT_OFFSET, 15118 },
+  { 0x1d76e, G_UNICODE_NOT_PRESENT_OFFSET, 5333 },
+  { 0x1d76f, G_UNICODE_NOT_PRESENT_OFFSET, 15121 },
+  { 0x1d770, G_UNICODE_NOT_PRESENT_OFFSET, 15125 },
+  { 0x1d771, G_UNICODE_NOT_PRESENT_OFFSET, 1368 },
+  { 0x1d772, G_UNICODE_NOT_PRESENT_OFFSET, 2418 },
+  { 0x1d773, G_UNICODE_NOT_PRESENT_OFFSET, 2421 },
+  { 0x1d774, G_UNICODE_NOT_PRESENT_OFFSET, 1405 },
+  { 0x1d775, G_UNICODE_NOT_PRESENT_OFFSET, 15128 },
+  { 0x1d776, G_UNICODE_NOT_PRESENT_OFFSET, 15131 },
+  { 0x1d777, G_UNICODE_NOT_PRESENT_OFFSET, 1371 },
+  { 0x1d778, G_UNICODE_NOT_PRESENT_OFFSET, 4860 },
+  { 0x1d779, G_UNICODE_NOT_PRESENT_OFFSET, 1393 },
+  { 0x1d77a, G_UNICODE_NOT_PRESENT_OFFSET, 15134 },
+  { 0x1d77b, G_UNICODE_NOT_PRESENT_OFFSET, 20 },
+  { 0x1d77c, G_UNICODE_NOT_PRESENT_OFFSET, 15137 },
+  { 0x1d77d, G_UNICODE_NOT_PRESENT_OFFSET, 15140 },
+  { 0x1d77e, G_UNICODE_NOT_PRESENT_OFFSET, 15143 },
+  { 0x1d77f, G_UNICODE_NOT_PRESENT_OFFSET, 1390 },
+  { 0x1d780, G_UNICODE_NOT_PRESENT_OFFSET, 1396 },
+  { 0x1d781, G_UNICODE_NOT_PRESENT_OFFSET, 1399 },
+  { 0x1d782, G_UNICODE_NOT_PRESENT_OFFSET, 15146 },
+  { 0x1d783, G_UNICODE_NOT_PRESENT_OFFSET, 15149 },
+  { 0x1d784, G_UNICODE_NOT_PRESENT_OFFSET, 15152 },
+  { 0x1d785, G_UNICODE_NOT_PRESENT_OFFSET, 1387 },
+  { 0x1d786, G_UNICODE_NOT_PRESENT_OFFSET, 2424 },
+  { 0x1d787, G_UNICODE_NOT_PRESENT_OFFSET, 15155 },
+  { 0x1d788, G_UNICODE_NOT_PRESENT_OFFSET, 15158 },
+  { 0x1d789, G_UNICODE_NOT_PRESENT_OFFSET, 15161 },
+  { 0x1d78a, G_UNICODE_NOT_PRESENT_OFFSET, 1405 },
+  { 0x1d78b, G_UNICODE_NOT_PRESENT_OFFSET, 1371 },
+  { 0x1d78c, G_UNICODE_NOT_PRESENT_OFFSET, 1393 },
+  { 0x1d78d, G_UNICODE_NOT_PRESENT_OFFSET, 1387 },
+  { 0x1d78e, G_UNICODE_NOT_PRESENT_OFFSET, 1396 },
+  { 0x1d78f, G_UNICODE_NOT_PRESENT_OFFSET, 1390 },
+  { 0x1d790, G_UNICODE_NOT_PRESENT_OFFSET, 15067 },
+  { 0x1d791, G_UNICODE_NOT_PRESENT_OFFSET, 15070 },
+  { 0x1d792, G_UNICODE_NOT_PRESENT_OFFSET, 5354 },
+  { 0x1d793, G_UNICODE_NOT_PRESENT_OFFSET, 15073 },
+  { 0x1d794, G_UNICODE_NOT_PRESENT_OFFSET, 15076 },
+  { 0x1d795, G_UNICODE_NOT_PRESENT_OFFSET, 15079 },
+  { 0x1d796, G_UNICODE_NOT_PRESENT_OFFSET, 15082 },
+  { 0x1d797, G_UNICODE_NOT_PRESENT_OFFSET, 1402 },
+  { 0x1d798, G_UNICODE_NOT_PRESENT_OFFSET, 15085 },
+  { 0x1d799, G_UNICODE_NOT_PRESENT_OFFSET, 15088 },
+  { 0x1d79a, G_UNICODE_NOT_PRESENT_OFFSET, 15091 },
+  { 0x1d79b, G_UNICODE_NOT_PRESENT_OFFSET, 15094 },
+  { 0x1d79c, G_UNICODE_NOT_PRESENT_OFFSET, 15097 },
+  { 0x1d79d, G_UNICODE_NOT_PRESENT_OFFSET, 15100 },
+  { 0x1d79e, G_UNICODE_NOT_PRESENT_OFFSET, 15103 },
+  { 0x1d79f, G_UNICODE_NOT_PRESENT_OFFSET, 5357 },
+  { 0x1d7a0, G_UNICODE_NOT_PRESENT_OFFSET, 15106 },
+  { 0x1d7a1, G_UNICODE_NOT_PRESENT_OFFSET, 1402 },
+  { 0x1d7a2, G_UNICODE_NOT_PRESENT_OFFSET, 1408 },
+  { 0x1d7a3, G_UNICODE_NOT_PRESENT_OFFSET, 15109 },
+  { 0x1d7a4, G_UNICODE_NOT_PRESENT_OFFSET, 1374 },
+  { 0x1d7a5, G_UNICODE_NOT_PRESENT_OFFSET, 15112 },
+  { 0x1d7a6, G_UNICODE_NOT_PRESENT_OFFSET, 15115 },
+  { 0x1d7a7, G_UNICODE_NOT_PRESENT_OFFSET, 15118 },
+  { 0x1d7a8, G_UNICODE_NOT_PRESENT_OFFSET, 5333 },
+  { 0x1d7a9, G_UNICODE_NOT_PRESENT_OFFSET, 15121 },
+  { 0x1d7aa, G_UNICODE_NOT_PRESENT_OFFSET, 15125 },
+  { 0x1d7ab, G_UNICODE_NOT_PRESENT_OFFSET, 1368 },
+  { 0x1d7ac, G_UNICODE_NOT_PRESENT_OFFSET, 2418 },
+  { 0x1d7ad, G_UNICODE_NOT_PRESENT_OFFSET, 2421 },
+  { 0x1d7ae, G_UNICODE_NOT_PRESENT_OFFSET, 1405 },
+  { 0x1d7af, G_UNICODE_NOT_PRESENT_OFFSET, 15128 },
+  { 0x1d7b0, G_UNICODE_NOT_PRESENT_OFFSET, 15131 },
+  { 0x1d7b1, G_UNICODE_NOT_PRESENT_OFFSET, 1371 },
+  { 0x1d7b2, G_UNICODE_NOT_PRESENT_OFFSET, 4860 },
+  { 0x1d7b3, G_UNICODE_NOT_PRESENT_OFFSET, 1393 },
+  { 0x1d7b4, G_UNICODE_NOT_PRESENT_OFFSET, 15134 },
+  { 0x1d7b5, G_UNICODE_NOT_PRESENT_OFFSET, 20 },
+  { 0x1d7b6, G_UNICODE_NOT_PRESENT_OFFSET, 15137 },
+  { 0x1d7b7, G_UNICODE_NOT_PRESENT_OFFSET, 15140 },
+  { 0x1d7b8, G_UNICODE_NOT_PRESENT_OFFSET, 15143 },
+  { 0x1d7b9, G_UNICODE_NOT_PRESENT_OFFSET, 1390 },
+  { 0x1d7ba, G_UNICODE_NOT_PRESENT_OFFSET, 1396 },
+  { 0x1d7bb, G_UNICODE_NOT_PRESENT_OFFSET, 1399 },
+  { 0x1d7bc, G_UNICODE_NOT_PRESENT_OFFSET, 15146 },
+  { 0x1d7bd, G_UNICODE_NOT_PRESENT_OFFSET, 15149 },
+  { 0x1d7be, G_UNICODE_NOT_PRESENT_OFFSET, 15152 },
+  { 0x1d7bf, G_UNICODE_NOT_PRESENT_OFFSET, 1387 },
+  { 0x1d7c0, G_UNICODE_NOT_PRESENT_OFFSET, 2424 },
+  { 0x1d7c1, G_UNICODE_NOT_PRESENT_OFFSET, 15155 },
+  { 0x1d7c2, G_UNICODE_NOT_PRESENT_OFFSET, 15158 },
+  { 0x1d7c3, G_UNICODE_NOT_PRESENT_OFFSET, 15161 },
+  { 0x1d7c4, G_UNICODE_NOT_PRESENT_OFFSET, 1405 },
+  { 0x1d7c5, G_UNICODE_NOT_PRESENT_OFFSET, 1371 },
+  { 0x1d7c6, G_UNICODE_NOT_PRESENT_OFFSET, 1393 },
+  { 0x1d7c7, G_UNICODE_NOT_PRESENT_OFFSET, 1387 },
+  { 0x1d7c8, G_UNICODE_NOT_PRESENT_OFFSET, 1396 },
+  { 0x1d7c9, G_UNICODE_NOT_PRESENT_OFFSET, 1390 },
+  { 0x1d7ca, G_UNICODE_NOT_PRESENT_OFFSET, 15165 },
+  { 0x1d7cb, G_UNICODE_NOT_PRESENT_OFFSET, 15168 },
+  { 0x1d7ce, G_UNICODE_NOT_PRESENT_OFFSET, 5253 },
+  { 0x1d7cf, G_UNICODE_NOT_PRESENT_OFFSET, 27 },
+  { 0x1d7d0, G_UNICODE_NOT_PRESENT_OFFSET, 12 },
+  { 0x1d7d1, G_UNICODE_NOT_PRESENT_OFFSET, 14 },
+  { 0x1d7d2, G_UNICODE_NOT_PRESENT_OFFSET, 5255 },
+  { 0x1d7d3, G_UNICODE_NOT_PRESENT_OFFSET, 5257 },
+  { 0x1d7d4, G_UNICODE_NOT_PRESENT_OFFSET, 5259 },
+  { 0x1d7d5, G_UNICODE_NOT_PRESENT_OFFSET, 5261 },
+  { 0x1d7d6, G_UNICODE_NOT_PRESENT_OFFSET, 5263 },
+  { 0x1d7d7, G_UNICODE_NOT_PRESENT_OFFSET, 5265 },
+  { 0x1d7d8, G_UNICODE_NOT_PRESENT_OFFSET, 5253 },
+  { 0x1d7d9, G_UNICODE_NOT_PRESENT_OFFSET, 27 },
+  { 0x1d7da, G_UNICODE_NOT_PRESENT_OFFSET, 12 },
+  { 0x1d7db, G_UNICODE_NOT_PRESENT_OFFSET, 14 },
+  { 0x1d7dc, G_UNICODE_NOT_PRESENT_OFFSET, 5255 },
+  { 0x1d7dd, G_UNICODE_NOT_PRESENT_OFFSET, 5257 },
+  { 0x1d7de, G_UNICODE_NOT_PRESENT_OFFSET, 5259 },
+  { 0x1d7df, G_UNICODE_NOT_PRESENT_OFFSET, 5261 },
+  { 0x1d7e0, G_UNICODE_NOT_PRESENT_OFFSET, 5263 },
+  { 0x1d7e1, G_UNICODE_NOT_PRESENT_OFFSET, 5265 },
+  { 0x1d7e2, G_UNICODE_NOT_PRESENT_OFFSET, 5253 },
+  { 0x1d7e3, G_UNICODE_NOT_PRESENT_OFFSET, 27 },
+  { 0x1d7e4, G_UNICODE_NOT_PRESENT_OFFSET, 12 },
+  { 0x1d7e5, G_UNICODE_NOT_PRESENT_OFFSET, 14 },
+  { 0x1d7e6, G_UNICODE_NOT_PRESENT_OFFSET, 5255 },
+  { 0x1d7e7, G_UNICODE_NOT_PRESENT_OFFSET, 5257 },
+  { 0x1d7e8, G_UNICODE_NOT_PRESENT_OFFSET, 5259 },
+  { 0x1d7e9, G_UNICODE_NOT_PRESENT_OFFSET, 5261 },
+  { 0x1d7ea, G_UNICODE_NOT_PRESENT_OFFSET, 5263 },
+  { 0x1d7eb, G_UNICODE_NOT_PRESENT_OFFSET, 5265 },
+  { 0x1d7ec, G_UNICODE_NOT_PRESENT_OFFSET, 5253 },
+  { 0x1d7ed, G_UNICODE_NOT_PRESENT_OFFSET, 27 },
+  { 0x1d7ee, G_UNICODE_NOT_PRESENT_OFFSET, 12 },
+  { 0x1d7ef, G_UNICODE_NOT_PRESENT_OFFSET, 14 },
+  { 0x1d7f0, G_UNICODE_NOT_PRESENT_OFFSET, 5255 },
+  { 0x1d7f1, G_UNICODE_NOT_PRESENT_OFFSET, 5257 },
+  { 0x1d7f2, G_UNICODE_NOT_PRESENT_OFFSET, 5259 },
+  { 0x1d7f3, G_UNICODE_NOT_PRESENT_OFFSET, 5261 },
+  { 0x1d7f4, G_UNICODE_NOT_PRESENT_OFFSET, 5263 },
+  { 0x1d7f5, G_UNICODE_NOT_PRESENT_OFFSET, 5265 },
+  { 0x1d7f6, G_UNICODE_NOT_PRESENT_OFFSET, 5253 },
+  { 0x1d7f7, G_UNICODE_NOT_PRESENT_OFFSET, 27 },
+  { 0x1d7f8, G_UNICODE_NOT_PRESENT_OFFSET, 12 },
+  { 0x1d7f9, G_UNICODE_NOT_PRESENT_OFFSET, 14 },
+  { 0x1d7fa, G_UNICODE_NOT_PRESENT_OFFSET, 5255 },
+  { 0x1d7fb, G_UNICODE_NOT_PRESENT_OFFSET, 5257 },
+  { 0x1d7fc, G_UNICODE_NOT_PRESENT_OFFSET, 5259 },
+  { 0x1d7fd, G_UNICODE_NOT_PRESENT_OFFSET, 5261 },
+  { 0x1d7fe, G_UNICODE_NOT_PRESENT_OFFSET, 5263 },
+  { 0x1d7ff, G_UNICODE_NOT_PRESENT_OFFSET, 5265 },
+  { 0x2f800, 15171, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f801, 15175, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f802, 15179, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f803, 15183, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f804, 15188, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f805, 11915, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f806, 15192, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f807, 15196, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f808, 15200, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f809, 15204, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f80a, 11919, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f80b, 15208, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f80c, 15212, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f80d, 15216, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f80e, 11923, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f80f, 15221, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f810, 15225, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f811, 15229, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f812, 15233, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f813, 15238, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f814, 15242, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f815, 15246, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f816, 15250, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f817, 15255, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f818, 15259, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f819, 15263, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f81a, 15267, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f81b, 12131, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f81c, 15271, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f81d, 6220, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f81e, 15276, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f81f, 15280, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f820, 15284, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f821, 15288, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f822, 15292, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f823, 15296, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f824, 15300, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f825, 12151, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f826, 11927, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f827, 11931, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f828, 12155, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f829, 15304, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f82a, 15308, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f82b, 11207, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f82c, 15312, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f82d, 11935, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f82e, 15316, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f82f, 15320, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f830, 15324, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f831, 15328, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f832, 15328, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f833, 15328, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f834, 15332, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f835, 15337, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f836, 15341, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f837, 15345, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f838, 15349, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f839, 15354, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f83a, 15358, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f83b, 15362, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f83c, 15366, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f83d, 15370, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f83e, 15374, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f83f, 15378, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f840, 15382, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f841, 15386, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f842, 15390, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f843, 15394, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f844, 15398, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f845, 15402, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f846, 15402, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f847, 12163, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f848, 15406, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f849, 15410, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f84a, 15414, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f84b, 15418, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f84c, 11943, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f84d, 15422, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f84e, 15426, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f84f, 15430, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f850, 11791, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f851, 15434, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f852, 15438, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f853, 15442, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f854, 15446, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f855, 15450, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f856, 15454, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f857, 15458, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f858, 15462, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f859, 15466, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f85a, 15471, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f85b, 15475, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f85c, 15479, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f85d, 15483, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f85e, 15487, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f85f, 15491, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f860, 15495, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f861, 15500, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f862, 15505, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f863, 15509, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f864, 15513, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f865, 15517, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f866, 15521, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f867, 15525, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f868, 15529, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f869, 15533, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f86a, 15537, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f86b, 15537, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f86c, 15541, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f86d, 15546, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f86e, 15550, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f86f, 11191, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f870, 15554, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f871, 15558, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f872, 15563, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f873, 15567, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f874, 15571, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f875, 6324, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f876, 15575, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f877, 15579, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f878, 6332, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f879, 15583, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f87a, 15587, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f87b, 15591, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f87c, 15596, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f87d, 15600, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f87e, 15605, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f87f, 15609, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f880, 15613, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f881, 15617, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f882, 15621, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f883, 15625, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f884, 15629, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f885, 15633, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f886, 15637, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f887, 15641, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f888, 15645, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f889, 15649, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f88a, 15654, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f88b, 15658, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f88c, 15662, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f88d, 15666, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f88e, 10983, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f88f, 15670, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f890, 6372, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f891, 15675, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f892, 15675, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f893, 15680, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f894, 15684, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f895, 15684, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f896, 15688, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f897, 15692, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f898, 15697, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f899, 15702, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f89a, 15706, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f89b, 15710, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f89c, 15714, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f89d, 15718, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f89e, 15722, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f89f, 15726, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8a0, 15730, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8a1, 15734, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8a2, 15738, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8a3, 11963, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8a4, 15742, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8a5, 15747, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8a6, 15751, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8a7, 15755, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8a8, 12211, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8a9, 15755, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8aa, 15759, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8ab, 11971, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8ac, 15763, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8ad, 15767, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8ae, 15771, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8af, 15775, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8b0, 11975, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8b1, 10875, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8b2, 15779, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8b3, 15783, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8b4, 15787, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8b5, 15791, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8b6, 15795, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8b7, 15799, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8b8, 15803, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8b9, 15808, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8ba, 15812, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8bb, 15816, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8bc, 15820, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8bd, 15824, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8be, 15828, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8bf, 15833, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8c0, 15837, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8c1, 15841, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8c2, 15845, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8c3, 15849, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8c4, 15853, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8c5, 15857, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8c6, 15861, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8c7, 15865, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8c8, 11979, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8c9, 15869, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8ca, 15873, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8cb, 15878, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8cc, 15882, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8cd, 15886, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8ce, 15890, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8cf, 11987, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8d0, 15894, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8d1, 15898, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8d2, 15902, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8d3, 15906, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8d4, 15910, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8d5, 15914, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8d6, 15918, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8d7, 15922, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8d8, 10987, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8d9, 12243, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8da, 15926, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8db, 15930, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8dc, 15934, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8dd, 15938, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8de, 15943, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8df, 15947, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8e0, 15951, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8e1, 15955, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8e2, 11991, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8e3, 15959, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8e4, 15964, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8e5, 15968, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8e6, 15972, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8e7, 12414, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8e8, 15976, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8e9, 15980, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8ea, 15984, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8eb, 15988, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8ec, 15992, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8ed, 15997, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8ee, 16001, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8ef, 16005, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8f0, 16009, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8f1, 16014, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8f2, 16018, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8f3, 16022, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8f4, 16026, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8f5, 11259, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8f6, 16030, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8f7, 16034, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8f8, 16039, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8f9, 16044, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8fa, 16049, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8fb, 16053, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8fc, 16058, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8fd, 16062, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8fe, 16066, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f8ff, 16070, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f900, 16074, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f901, 11995, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f902, 11591, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f903, 16078, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f904, 16082, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f905, 16086, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f906, 16090, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f907, 16095, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f908, 16099, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f909, 16103, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f90a, 16107, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f90b, 12255, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f90c, 16111, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f90d, 16115, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f90e, 16120, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f90f, 16124, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f910, 16128, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f911, 16133, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f912, 16138, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f913, 16142, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f914, 12259, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f915, 16146, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f916, 16150, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f917, 16154, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f918, 16158, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f919, 16162, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f91a, 16166, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f91b, 16170, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f91c, 16175, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f91d, 16179, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f91e, 16184, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f91f, 16188, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f920, 16193, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f921, 12267, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f922, 16197, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f923, 16201, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f924, 16206, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f925, 16210, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f926, 16214, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f927, 16219, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f928, 16224, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f929, 16228, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f92a, 16232, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f92b, 16236, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f92c, 16240, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f92d, 16240, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f92e, 16244, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f92f, 16248, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f930, 12275, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f931, 16252, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f932, 16256, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f933, 16260, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f934, 16264, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f935, 16268, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f936, 16273, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f937, 16277, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f938, 11203, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f939, 16282, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f93a, 16287, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f93b, 16291, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f93c, 16296, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f93d, 16301, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f93e, 16306, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f93f, 16310, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f940, 12299, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f941, 16314, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f942, 16319, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f943, 16324, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f944, 16329, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f945, 16334, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f946, 16338, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f947, 16338, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f948, 12303, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f949, 12422, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f94a, 16342, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f94b, 16346, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f94c, 16350, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f94d, 16354, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f94e, 16359, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f94f, 11055, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f950, 12311, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f951, 16363, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f952, 16367, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f953, 12035, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f954, 16372, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f955, 16377, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f956, 11871, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f957, 16382, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f958, 16386, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f959, 12047, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f95a, 16390, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f95b, 16394, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f95c, 16398, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f95d, 16403, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f95e, 16403, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f95f, 16408, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f960, 16412, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f961, 16416, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f962, 16421, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f963, 16425, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f964, 16429, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f965, 16433, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f966, 16438, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f967, 16442, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f968, 16446, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f969, 16450, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f96a, 16454, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f96b, 16458, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f96c, 16463, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f96d, 16467, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f96e, 16471, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f96f, 16475, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f970, 16479, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f971, 16483, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f972, 16487, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f973, 16492, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f974, 16497, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f975, 16501, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f976, 16506, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f977, 16510, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f978, 16515, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f979, 16519, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f97a, 12071, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f97b, 16523, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f97c, 16528, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f97d, 16533, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f97e, 16537, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f97f, 16542, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f980, 16546, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f981, 16551, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f982, 16555, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f983, 16559, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f984, 16563, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f985, 16567, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f986, 16571, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f987, 16575, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f988, 16580, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f989, 16585, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f98a, 16590, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f98b, 15680, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f98c, 16595, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f98d, 16599, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f98e, 16603, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f98f, 16607, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f990, 16611, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f991, 16615, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f992, 16619, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f993, 16623, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f994, 16627, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f995, 16631, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f996, 16635, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f997, 16639, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f998, 11271, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f999, 16644, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f99a, 16648, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f99b, 16652, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f99c, 16656, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f99d, 16660, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f99e, 16664, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f99f, 12083, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9a0, 16668, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9a1, 16672, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9a2, 16676, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9a3, 16680, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9a4, 16684, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9a5, 16689, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9a6, 16694, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9a7, 16699, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9a8, 16703, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9a9, 16707, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9aa, 16711, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9ab, 16715, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9ac, 16720, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9ad, 16724, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9ae, 16729, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9af, 16733, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9b0, 16737, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9b1, 16742, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9b2, 16747, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9b3, 16751, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9b4, 11035, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9b5, 16755, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9b6, 16759, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9b7, 16763, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9b8, 16767, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9b9, 16771, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9ba, 16775, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9bb, 12339, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9bc, 16779, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9bd, 16783, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9be, 16787, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9bf, 16791, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9c0, 16795, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9c1, 16799, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9c2, 16803, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9c3, 16807, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9c4, 6732, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9c5, 16811, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9c6, 16816, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9c7, 16820, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9c8, 16824, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9c9, 16828, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9ca, 16832, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9cb, 16836, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9cc, 16841, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9cd, 16846, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9ce, 16850, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9cf, 16854, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9d0, 12359, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9d1, 12363, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9d2, 6760, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9d3, 16858, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9d4, 16863, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9d5, 16867, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9d6, 16871, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9d7, 16875, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9d8, 16879, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9d9, 16884, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9da, 16889, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9db, 16893, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9dc, 16897, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9dd, 16901, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9de, 16906, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9df, 12367, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9e0, 16910, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9e1, 16915, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9e2, 16920, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9e3, 16924, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9e4, 16928, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9e5, 16932, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9e6, 16937, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9e7, 16941, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9e8, 16945, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9e9, 16949, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9ea, 16953, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9eb, 16957, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9ec, 16961, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9ed, 16965, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9ee, 16970, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9ef, 16974, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9f0, 16978, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9f1, 16982, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9f2, 16987, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9f3, 16991, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9f4, 16995, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9f5, 16999, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9f6, 17003, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9f7, 17008, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9f8, 17013, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9f9, 17017, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9fa, 17021, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9fb, 17025, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9fc, 17030, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9fd, 17034, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9fe, 12391, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2f9ff, 12391, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa00, 17039, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa01, 17043, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa02, 17048, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa03, 17052, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa04, 17056, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa05, 17060, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa06, 17064, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa07, 17068, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa08, 17072, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa09, 17076, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa0a, 12395, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa0b, 17081, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa0c, 17085, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa0d, 17089, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa0e, 17093, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa0f, 17097, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa10, 17101, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa11, 17106, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa12, 17110, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa13, 17115, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa14, 17120, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa15, 6952, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa16, 17125, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa17, 6968, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa18, 17129, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa19, 17133, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa1a, 17137, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa1b, 17141, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa1c, 6988, G_UNICODE_NOT_PRESENT_OFFSET },
+  { 0x2fa1d, 17145, G_UNICODE_NOT_PRESENT_OFFSET }
+};
+
+static const gchar decomp_expansion_string[] = 
+  "\x20\0" /* offset 0 */
+  "\x20\xcc\x88\0" /* offset 2 */
+  "\x61\0" /* offset 6 */
+  "\x20\xcc\x84\0" /* offset 8 */
+  "\x32\0" /* offset 12 */
+  "\x33\0" /* offset 14 */
+  "\x20\xcc\x81\0" /* offset 16 */
+  "\xce\xbc\0" /* offset 20 */
+  "\x20\xcc\xa7\0" /* offset 23 */
+  "\x31\0" /* offset 27 */
+  "\x6f\0" /* offset 29 */
+  "\x31\xe2\x81\x84\x34\0" /* offset 31 */
+  "\x31\xe2\x81\x84\x32\0" /* offset 37 */
+  "\x33\xe2\x81\x84\x34\0" /* offset 43 */
+  "\x41\xcc\x80\0" /* offset 49 */
+  "\x41\xcc\x81\0" /* offset 53 */
+  "\x41\xcc\x82\0" /* offset 57 */
+  "\x41\xcc\x83\0" /* offset 61 */
+  "\x41\xcc\x88\0" /* offset 65 */
+  "\x41\xcc\x8a\0" /* offset 69 */
+  "\x43\xcc\xa7\0" /* offset 73 */
+  "\x45\xcc\x80\0" /* offset 77 */
+  "\x45\xcc\x81\0" /* offset 81 */
+  "\x45\xcc\x82\0" /* offset 85 */
+  "\x45\xcc\x88\0" /* offset 89 */
+  "\x49\xcc\x80\0" /* offset 93 */
+  "\x49\xcc\x81\0" /* offset 97 */
+  "\x49\xcc\x82\0" /* offset 101 */
+  "\x49\xcc\x88\0" /* offset 105 */
+  "\x4e\xcc\x83\0" /* offset 109 */
+  "\x4f\xcc\x80\0" /* offset 113 */
+  "\x4f\xcc\x81\0" /* offset 117 */
+  "\x4f\xcc\x82\0" /* offset 121 */
+  "\x4f\xcc\x83\0" /* offset 125 */
+  "\x4f\xcc\x88\0" /* offset 129 */
+  "\x55\xcc\x80\0" /* offset 133 */
+  "\x55\xcc\x81\0" /* offset 137 */
+  "\x55\xcc\x82\0" /* offset 141 */
+  "\x55\xcc\x88\0" /* offset 145 */
+  "\x59\xcc\x81\0" /* offset 149 */
+  "\x61\xcc\x80\0" /* offset 153 */
+  "\x61\xcc\x81\0" /* offset 157 */
+  "\x61\xcc\x82\0" /* offset 161 */
+  "\x61\xcc\x83\0" /* offset 165 */
+  "\x61\xcc\x88\0" /* offset 169 */
+  "\x61\xcc\x8a\0" /* offset 173 */
+  "\x63\xcc\xa7\0" /* offset 177 */
+  "\x65\xcc\x80\0" /* offset 181 */
+  "\x65\xcc\x81\0" /* offset 185 */
+  "\x65\xcc\x82\0" /* offset 189 */
+  "\x65\xcc\x88\0" /* offset 193 */
+  "\x69\xcc\x80\0" /* offset 197 */
+  "\x69\xcc\x81\0" /* offset 201 */
+  "\x69\xcc\x82\0" /* offset 205 */
+  "\x69\xcc\x88\0" /* offset 209 */
+  "\x6e\xcc\x83\0" /* offset 213 */
+  "\x6f\xcc\x80\0" /* offset 217 */
+  "\x6f\xcc\x81\0" /* offset 221 */
+  "\x6f\xcc\x82\0" /* offset 225 */
+  "\x6f\xcc\x83\0" /* offset 229 */
+  "\x6f\xcc\x88\0" /* offset 233 */
+  "\x75\xcc\x80\0" /* offset 237 */
+  "\x75\xcc\x81\0" /* offset 241 */
+  "\x75\xcc\x82\0" /* offset 245 */
+  "\x75\xcc\x88\0" /* offset 249 */
+  "\x79\xcc\x81\0" /* offset 253 */
+  "\x79\xcc\x88\0" /* offset 257 */
+  "\x41\xcc\x84\0" /* offset 261 */
+  "\x61\xcc\x84\0" /* offset 265 */
+  "\x41\xcc\x86\0" /* offset 269 */
+  "\x61\xcc\x86\0" /* offset 273 */
+  "\x41\xcc\xa8\0" /* offset 277 */
+  "\x61\xcc\xa8\0" /* offset 281 */
+  "\x43\xcc\x81\0" /* offset 285 */
+  "\x63\xcc\x81\0" /* offset 289 */
+  "\x43\xcc\x82\0" /* offset 293 */
+  "\x63\xcc\x82\0" /* offset 297 */
+  "\x43\xcc\x87\0" /* offset 301 */
+  "\x63\xcc\x87\0" /* offset 305 */
+  "\x43\xcc\x8c\0" /* offset 309 */
+  "\x63\xcc\x8c\0" /* offset 313 */
+  "\x44\xcc\x8c\0" /* offset 317 */
+  "\x64\xcc\x8c\0" /* offset 321 */
+  "\x45\xcc\x84\0" /* offset 325 */
+  "\x65\xcc\x84\0" /* offset 329 */
+  "\x45\xcc\x86\0" /* offset 333 */
+  "\x65\xcc\x86\0" /* offset 337 */
+  "\x45\xcc\x87\0" /* offset 341 */
+  "\x65\xcc\x87\0" /* offset 345 */
+  "\x45\xcc\xa8\0" /* offset 349 */
+  "\x65\xcc\xa8\0" /* offset 353 */
+  "\x45\xcc\x8c\0" /* offset 357 */
+  "\x65\xcc\x8c\0" /* offset 361 */
+  "\x47\xcc\x82\0" /* offset 365 */
+  "\x67\xcc\x82\0" /* offset 369 */
+  "\x47\xcc\x86\0" /* offset 373 */
+  "\x67\xcc\x86\0" /* offset 377 */
+  "\x47\xcc\x87\0" /* offset 381 */
+  "\x67\xcc\x87\0" /* offset 385 */
+  "\x47\xcc\xa7\0" /* offset 389 */
+  "\x67\xcc\xa7\0" /* offset 393 */
+  "\x48\xcc\x82\0" /* offset 397 */
+  "\x68\xcc\x82\0" /* offset 401 */
+  "\x49\xcc\x83\0" /* offset 405 */
+  "\x69\xcc\x83\0" /* offset 409 */
+  "\x49\xcc\x84\0" /* offset 413 */
+  "\x69\xcc\x84\0" /* offset 417 */
+  "\x49\xcc\x86\0" /* offset 421 */
+  "\x69\xcc\x86\0" /* offset 425 */
+  "\x49\xcc\xa8\0" /* offset 429 */
+  "\x69\xcc\xa8\0" /* offset 433 */
+  "\x49\xcc\x87\0" /* offset 437 */
+  "\x49\x4a\0" /* offset 441 */
+  "\x69\x6a\0" /* offset 444 */
+  "\x4a\xcc\x82\0" /* offset 447 */
+  "\x6a\xcc\x82\0" /* offset 451 */
+  "\x4b\xcc\xa7\0" /* offset 455 */
+  "\x6b\xcc\xa7\0" /* offset 459 */
+  "\x4c\xcc\x81\0" /* offset 463 */
+  "\x6c\xcc\x81\0" /* offset 467 */
+  "\x4c\xcc\xa7\0" /* offset 471 */
+  "\x6c\xcc\xa7\0" /* offset 475 */
+  "\x4c\xcc\x8c\0" /* offset 479 */
+  "\x6c\xcc\x8c\0" /* offset 483 */
+  "\x4c\xc2\xb7\0" /* offset 487 */
+  "\x6c\xc2\xb7\0" /* offset 491 */
+  "\x4e\xcc\x81\0" /* offset 495 */
+  "\x6e\xcc\x81\0" /* offset 499 */
+  "\x4e\xcc\xa7\0" /* offset 503 */
+  "\x6e\xcc\xa7\0" /* offset 507 */
+  "\x4e\xcc\x8c\0" /* offset 511 */
+  "\x6e\xcc\x8c\0" /* offset 515 */
+  "\xca\xbc\x6e\0" /* offset 519 */
+  "\x4f\xcc\x84\0" /* offset 523 */
+  "\x6f\xcc\x84\0" /* offset 527 */
+  "\x4f\xcc\x86\0" /* offset 531 */
+  "\x6f\xcc\x86\0" /* offset 535 */
+  "\x4f\xcc\x8b\0" /* offset 539 */
+  "\x6f\xcc\x8b\0" /* offset 543 */
+  "\x52\xcc\x81\0" /* offset 547 */
+  "\x72\xcc\x81\0" /* offset 551 */
+  "\x52\xcc\xa7\0" /* offset 555 */
+  "\x72\xcc\xa7\0" /* offset 559 */
+  "\x52\xcc\x8c\0" /* offset 563 */
+  "\x72\xcc\x8c\0" /* offset 567 */
+  "\x53\xcc\x81\0" /* offset 571 */
+  "\x73\xcc\x81\0" /* offset 575 */
+  "\x53\xcc\x82\0" /* offset 579 */
+  "\x73\xcc\x82\0" /* offset 583 */
+  "\x53\xcc\xa7\0" /* offset 587 */
+  "\x73\xcc\xa7\0" /* offset 591 */
+  "\x53\xcc\x8c\0" /* offset 595 */
+  "\x73\xcc\x8c\0" /* offset 599 */
+  "\x54\xcc\xa7\0" /* offset 603 */
+  "\x74\xcc\xa7\0" /* offset 607 */
+  "\x54\xcc\x8c\0" /* offset 611 */
+  "\x74\xcc\x8c\0" /* offset 615 */
+  "\x55\xcc\x83\0" /* offset 619 */
+  "\x75\xcc\x83\0" /* offset 623 */
+  "\x55\xcc\x84\0" /* offset 627 */
+  "\x75\xcc\x84\0" /* offset 631 */
+  "\x55\xcc\x86\0" /* offset 635 */
+  "\x75\xcc\x86\0" /* offset 639 */
+  "\x55\xcc\x8a\0" /* offset 643 */
+  "\x75\xcc\x8a\0" /* offset 647 */
+  "\x55\xcc\x8b\0" /* offset 651 */
+  "\x75\xcc\x8b\0" /* offset 655 */
+  "\x55\xcc\xa8\0" /* offset 659 */
+  "\x75\xcc\xa8\0" /* offset 663 */
+  "\x57\xcc\x82\0" /* offset 667 */
+  "\x77\xcc\x82\0" /* offset 671 */
+  "\x59\xcc\x82\0" /* offset 675 */
+  "\x79\xcc\x82\0" /* offset 679 */
+  "\x59\xcc\x88\0" /* offset 683 */
+  "\x5a\xcc\x81\0" /* offset 687 */
+  "\x7a\xcc\x81\0" /* offset 691 */
+  "\x5a\xcc\x87\0" /* offset 695 */
+  "\x7a\xcc\x87\0" /* offset 699 */
+  "\x5a\xcc\x8c\0" /* offset 703 */
+  "\x7a\xcc\x8c\0" /* offset 707 */
+  "\x73\0" /* offset 711 */
+  "\x4f\xcc\x9b\0" /* offset 713 */
+  "\x6f\xcc\x9b\0" /* offset 717 */
+  "\x55\xcc\x9b\0" /* offset 721 */
+  "\x75\xcc\x9b\0" /* offset 725 */
+  "\x44\x5a\xcc\x8c\0" /* offset 729 */
+  "\x44\x7a\xcc\x8c\0" /* offset 734 */
+  "\x64\x7a\xcc\x8c\0" /* offset 739 */
+  "\x4c\x4a\0" /* offset 744 */
+  "\x4c\x6a\0" /* offset 747 */
+  "\x6c\x6a\0" /* offset 750 */
+  "\x4e\x4a\0" /* offset 753 */
+  "\x4e\x6a\0" /* offset 756 */
+  "\x6e\x6a\0" /* offset 759 */
+  "\x41\xcc\x8c\0" /* offset 762 */
+  "\x61\xcc\x8c\0" /* offset 766 */
+  "\x49\xcc\x8c\0" /* offset 770 */
+  "\x69\xcc\x8c\0" /* offset 774 */
+  "\x4f\xcc\x8c\0" /* offset 778 */
+  "\x6f\xcc\x8c\0" /* offset 782 */
+  "\x55\xcc\x8c\0" /* offset 786 */
+  "\x75\xcc\x8c\0" /* offset 790 */
+  "\x55\xcc\x88\xcc\x84\0" /* offset 794 */
+  "\x75\xcc\x88\xcc\x84\0" /* offset 800 */
+  "\x55\xcc\x88\xcc\x81\0" /* offset 806 */
+  "\x75\xcc\x88\xcc\x81\0" /* offset 812 */
+  "\x55\xcc\x88\xcc\x8c\0" /* offset 818 */
+  "\x75\xcc\x88\xcc\x8c\0" /* offset 824 */
+  "\x55\xcc\x88\xcc\x80\0" /* offset 830 */
+  "\x75\xcc\x88\xcc\x80\0" /* offset 836 */
+  "\x41\xcc\x88\xcc\x84\0" /* offset 842 */
+  "\x61\xcc\x88\xcc\x84\0" /* offset 848 */
+  "\x41\xcc\x87\xcc\x84\0" /* offset 854 */
+  "\x61\xcc\x87\xcc\x84\0" /* offset 860 */
+  "\xc3\x86\xcc\x84\0" /* offset 866 */
+  "\xc3\xa6\xcc\x84\0" /* offset 871 */
+  "\x47\xcc\x8c\0" /* offset 876 */
+  "\x67\xcc\x8c\0" /* offset 880 */
+  "\x4b\xcc\x8c\0" /* offset 884 */
+  "\x6b\xcc\x8c\0" /* offset 888 */
+  "\x4f\xcc\xa8\0" /* offset 892 */
+  "\x6f\xcc\xa8\0" /* offset 896 */
+  "\x4f\xcc\xa8\xcc\x84\0" /* offset 900 */
+  "\x6f\xcc\xa8\xcc\x84\0" /* offset 906 */
+  "\xc6\xb7\xcc\x8c\0" /* offset 912 */
+  "\xca\x92\xcc\x8c\0" /* offset 917 */
+  "\x6a\xcc\x8c\0" /* offset 922 */
+  "\x44\x5a\0" /* offset 926 */
+  "\x44\x7a\0" /* offset 929 */
+  "\x64\x7a\0" /* offset 932 */
+  "\x47\xcc\x81\0" /* offset 935 */
+  "\x67\xcc\x81\0" /* offset 939 */
+  "\x4e\xcc\x80\0" /* offset 943 */
+  "\x6e\xcc\x80\0" /* offset 947 */
+  "\x41\xcc\x8a\xcc\x81\0" /* offset 951 */
+  "\x61\xcc\x8a\xcc\x81\0" /* offset 957 */
+  "\xc3\x86\xcc\x81\0" /* offset 963 */
+  "\xc3\xa6\xcc\x81\0" /* offset 968 */
+  "\xc3\x98\xcc\x81\0" /* offset 973 */
+  "\xc3\xb8\xcc\x81\0" /* offset 978 */
+  "\x41\xcc\x8f\0" /* offset 983 */
+  "\x61\xcc\x8f\0" /* offset 987 */
+  "\x41\xcc\x91\0" /* offset 991 */
+  "\x61\xcc\x91\0" /* offset 995 */
+  "\x45\xcc\x8f\0" /* offset 999 */
+  "\x65\xcc\x8f\0" /* offset 1003 */
+  "\x45\xcc\x91\0" /* offset 1007 */
+  "\x65\xcc\x91\0" /* offset 1011 */
+  "\x49\xcc\x8f\0" /* offset 1015 */
+  "\x69\xcc\x8f\0" /* offset 1019 */
+  "\x49\xcc\x91\0" /* offset 1023 */
+  "\x69\xcc\x91\0" /* offset 1027 */
+  "\x4f\xcc\x8f\0" /* offset 1031 */
+  "\x6f\xcc\x8f\0" /* offset 1035 */
+  "\x4f\xcc\x91\0" /* offset 1039 */
+  "\x6f\xcc\x91\0" /* offset 1043 */
+  "\x52\xcc\x8f\0" /* offset 1047 */
+  "\x72\xcc\x8f\0" /* offset 1051 */
+  "\x52\xcc\x91\0" /* offset 1055 */
+  "\x72\xcc\x91\0" /* offset 1059 */
+  "\x55\xcc\x8f\0" /* offset 1063 */
+  "\x75\xcc\x8f\0" /* offset 1067 */
+  "\x55\xcc\x91\0" /* offset 1071 */
+  "\x75\xcc\x91\0" /* offset 1075 */
+  "\x53\xcc\xa6\0" /* offset 1079 */
+  "\x73\xcc\xa6\0" /* offset 1083 */
+  "\x54\xcc\xa6\0" /* offset 1087 */
+  "\x74\xcc\xa6\0" /* offset 1091 */
+  "\x48\xcc\x8c\0" /* offset 1095 */
+  "\x68\xcc\x8c\0" /* offset 1099 */
+  "\x41\xcc\x87\0" /* offset 1103 */
+  "\x61\xcc\x87\0" /* offset 1107 */
+  "\x45\xcc\xa7\0" /* offset 1111 */
+  "\x65\xcc\xa7\0" /* offset 1115 */
+  "\x4f\xcc\x88\xcc\x84\0" /* offset 1119 */
+  "\x6f\xcc\x88\xcc\x84\0" /* offset 1125 */
+  "\x4f\xcc\x83\xcc\x84\0" /* offset 1131 */
+  "\x6f\xcc\x83\xcc\x84\0" /* offset 1137 */
+  "\x4f\xcc\x87\0" /* offset 1143 */
+  "\x6f\xcc\x87\0" /* offset 1147 */
+  "\x4f\xcc\x87\xcc\x84\0" /* offset 1151 */
+  "\x6f\xcc\x87\xcc\x84\0" /* offset 1157 */
+  "\x59\xcc\x84\0" /* offset 1163 */
+  "\x79\xcc\x84\0" /* offset 1167 */
+  "\x68\0" /* offset 1171 */
+  "\xc9\xa6\0" /* offset 1173 */
+  "\x6a\0" /* offset 1176 */
+  "\x72\0" /* offset 1178 */
+  "\xc9\xb9\0" /* offset 1180 */
+  "\xc9\xbb\0" /* offset 1183 */
+  "\xca\x81\0" /* offset 1186 */
+  "\x77\0" /* offset 1189 */
+  "\x79\0" /* offset 1191 */
+  "\x20\xcc\x86\0" /* offset 1193 */
+  "\x20\xcc\x87\0" /* offset 1197 */
+  "\x20\xcc\x8a\0" /* offset 1201 */
+  "\x20\xcc\xa8\0" /* offset 1205 */
+  "\x20\xcc\x83\0" /* offset 1209 */
+  "\x20\xcc\x8b\0" /* offset 1213 */
+  "\xc9\xa3\0" /* offset 1217 */
+  "\x6c\0" /* offset 1220 */
+  "\x78\0" /* offset 1222 */
+  "\xca\x95\0" /* offset 1224 */
+  "\xcc\x80\0" /* offset 1227 */
+  "\xcc\x81\0" /* offset 1230 */
+  "\xcc\x93\0" /* offset 1233 */
+  "\xcc\x88\xcc\x81\0" /* offset 1236 */
+  "\xca\xb9\0" /* offset 1241 */
+  "\x20\xcd\x85\0" /* offset 1244 */
+  "\x3b\0" /* offset 1248 */
+  "\xc2\xa8\xcc\x81\0" /* offset 1250 */
+  "\x20\xcc\x88\xcc\x81\0" /* offset 1255 */
+  "\xce\x91\xcc\x81\0" /* offset 1261 */
+  "\xc2\xb7\0" /* offset 1266 */
+  "\xce\x95\xcc\x81\0" /* offset 1269 */
+  "\xce\x97\xcc\x81\0" /* offset 1274 */
+  "\xce\x99\xcc\x81\0" /* offset 1279 */
+  "\xce\x9f\xcc\x81\0" /* offset 1284 */
+  "\xce\xa5\xcc\x81\0" /* offset 1289 */
+  "\xce\xa9\xcc\x81\0" /* offset 1294 */
+  "\xce\xb9\xcc\x88\xcc\x81\0" /* offset 1299 */
+  "\xce\x99\xcc\x88\0" /* offset 1306 */
+  "\xce\xa5\xcc\x88\0" /* offset 1311 */
+  "\xce\xb1\xcc\x81\0" /* offset 1316 */
+  "\xce\xb5\xcc\x81\0" /* offset 1321 */
+  "\xce\xb7\xcc\x81\0" /* offset 1326 */
+  "\xce\xb9\xcc\x81\0" /* offset 1331 */
+  "\xcf\x85\xcc\x88\xcc\x81\0" /* offset 1336 */
+  "\xce\xb9\xcc\x88\0" /* offset 1343 */
+  "\xcf\x85\xcc\x88\0" /* offset 1348 */
+  "\xce\xbf\xcc\x81\0" /* offset 1353 */
+  "\xcf\x85\xcc\x81\0" /* offset 1358 */
+  "\xcf\x89\xcc\x81\0" /* offset 1363 */
+  "\xce\xb2\0" /* offset 1368 */
+  "\xce\xb8\0" /* offset 1371 */
+  "\xce\xa5\0" /* offset 1374 */
+  "\xcf\x92\xcc\x81\0" /* offset 1377 */
+  "\xcf\x92\xcc\x88\0" /* offset 1382 */
+  "\xcf\x86\0" /* offset 1387 */
+  "\xcf\x80\0" /* offset 1390 */
+  "\xce\xba\0" /* offset 1393 */
+  "\xcf\x81\0" /* offset 1396 */
+  "\xcf\x82\0" /* offset 1399 */
+  "\xce\x98\0" /* offset 1402 */
+  "\xce\xb5\0" /* offset 1405 */
+  "\xce\xa3\0" /* offset 1408 */
+  "\xd0\x95\xcc\x80\0" /* offset 1411 */
+  "\xd0\x95\xcc\x88\0" /* offset 1416 */
+  "\xd0\x93\xcc\x81\0" /* offset 1421 */
+  "\xd0\x86\xcc\x88\0" /* offset 1426 */
+  "\xd0\x9a\xcc\x81\0" /* offset 1431 */
+  "\xd0\x98\xcc\x80\0" /* offset 1436 */
+  "\xd0\xa3\xcc\x86\0" /* offset 1441 */
+  "\xd0\x98\xcc\x86\0" /* offset 1446 */
+  "\xd0\xb8\xcc\x86\0" /* offset 1451 */
+  "\xd0\xb5\xcc\x80\0" /* offset 1456 */
+  "\xd0\xb5\xcc\x88\0" /* offset 1461 */
+  "\xd0\xb3\xcc\x81\0" /* offset 1466 */
+  "\xd1\x96\xcc\x88\0" /* offset 1471 */
+  "\xd0\xba\xcc\x81\0" /* offset 1476 */
+  "\xd0\xb8\xcc\x80\0" /* offset 1481 */
+  "\xd1\x83\xcc\x86\0" /* offset 1486 */
+  "\xd1\xb4\xcc\x8f\0" /* offset 1491 */
+  "\xd1\xb5\xcc\x8f\0" /* offset 1496 */
+  "\xd0\x96\xcc\x86\0" /* offset 1501 */
+  "\xd0\xb6\xcc\x86\0" /* offset 1506 */
+  "\xd0\x90\xcc\x86\0" /* offset 1511 */
+  "\xd0\xb0\xcc\x86\0" /* offset 1516 */
+  "\xd0\x90\xcc\x88\0" /* offset 1521 */
+  "\xd0\xb0\xcc\x88\0" /* offset 1526 */
+  "\xd0\x95\xcc\x86\0" /* offset 1531 */
+  "\xd0\xb5\xcc\x86\0" /* offset 1536 */
+  "\xd3\x98\xcc\x88\0" /* offset 1541 */
+  "\xd3\x99\xcc\x88\0" /* offset 1546 */
+  "\xd0\x96\xcc\x88\0" /* offset 1551 */
+  "\xd0\xb6\xcc\x88\0" /* offset 1556 */
+  "\xd0\x97\xcc\x88\0" /* offset 1561 */
+  "\xd0\xb7\xcc\x88\0" /* offset 1566 */
+  "\xd0\x98\xcc\x84\0" /* offset 1571 */
+  "\xd0\xb8\xcc\x84\0" /* offset 1576 */
+  "\xd0\x98\xcc\x88\0" /* offset 1581 */
+  "\xd0\xb8\xcc\x88\0" /* offset 1586 */
+  "\xd0\x9e\xcc\x88\0" /* offset 1591 */
+  "\xd0\xbe\xcc\x88\0" /* offset 1596 */
+  "\xd3\xa8\xcc\x88\0" /* offset 1601 */
+  "\xd3\xa9\xcc\x88\0" /* offset 1606 */
+  "\xd0\xad\xcc\x88\0" /* offset 1611 */
+  "\xd1\x8d\xcc\x88\0" /* offset 1616 */
+  "\xd0\xa3\xcc\x84\0" /* offset 1621 */
+  "\xd1\x83\xcc\x84\0" /* offset 1626 */
+  "\xd0\xa3\xcc\x88\0" /* offset 1631 */
+  "\xd1\x83\xcc\x88\0" /* offset 1636 */
+  "\xd0\xa3\xcc\x8b\0" /* offset 1641 */
+  "\xd1\x83\xcc\x8b\0" /* offset 1646 */
+  "\xd0\xa7\xcc\x88\0" /* offset 1651 */
+  "\xd1\x87\xcc\x88\0" /* offset 1656 */
+  "\xd0\xab\xcc\x88\0" /* offset 1661 */
+  "\xd1\x8b\xcc\x88\0" /* offset 1666 */
+  "\xd5\xa5\xd6\x82\0" /* offset 1671 */
+  "\xd8\xa7\xd9\x93\0" /* offset 1676 */
+  "\xd8\xa7\xd9\x94\0" /* offset 1681 */
+  "\xd9\x88\xd9\x94\0" /* offset 1686 */
+  "\xd8\xa7\xd9\x95\0" /* offset 1691 */
+  "\xd9\x8a\xd9\x94\0" /* offset 1696 */
+  "\xd8\xa7\xd9\xb4\0" /* offset 1701 */
+  "\xd9\x88\xd9\xb4\0" /* offset 1706 */
+  "\xdb\x87\xd9\xb4\0" /* offset 1711 */
+  "\xd9\x8a\xd9\xb4\0" /* offset 1716 */
+  "\xdb\x95\xd9\x94\0" /* offset 1721 */
+  "\xdb\x81\xd9\x94\0" /* offset 1726 */
+  "\xdb\x92\xd9\x94\0" /* offset 1731 */
+  "\xe0\xa4\xa8\xe0\xa4\xbc\0" /* offset 1736 */
+  "\xe0\xa4\xb0\xe0\xa4\xbc\0" /* offset 1743 */
+  "\xe0\xa4\xb3\xe0\xa4\xbc\0" /* offset 1750 */
+  "\xe0\xa4\x95\xe0\xa4\xbc\0" /* offset 1757 */
+  "\xe0\xa4\x96\xe0\xa4\xbc\0" /* offset 1764 */
+  "\xe0\xa4\x97\xe0\xa4\xbc\0" /* offset 1771 */
+  "\xe0\xa4\x9c\xe0\xa4\xbc\0" /* offset 1778 */
+  "\xe0\xa4\xa1\xe0\xa4\xbc\0" /* offset 1785 */
+  "\xe0\xa4\xa2\xe0\xa4\xbc\0" /* offset 1792 */
+  "\xe0\xa4\xab\xe0\xa4\xbc\0" /* offset 1799 */
+  "\xe0\xa4\xaf\xe0\xa4\xbc\0" /* offset 1806 */
+  "\xe0\xa7\x87\xe0\xa6\xbe\0" /* offset 1813 */
+  "\xe0\xa7\x87\xe0\xa7\x97\0" /* offset 1820 */
+  "\xe0\xa6\xa1\xe0\xa6\xbc\0" /* offset 1827 */
+  "\xe0\xa6\xa2\xe0\xa6\xbc\0" /* offset 1834 */
+  "\xe0\xa6\xaf\xe0\xa6\xbc\0" /* offset 1841 */
+  "\xe0\xa8\xb2\xe0\xa8\xbc\0" /* offset 1848 */
+  "\xe0\xa8\xb8\xe0\xa8\xbc\0" /* offset 1855 */
+  "\xe0\xa8\x96\xe0\xa8\xbc\0" /* offset 1862 */
+  "\xe0\xa8\x97\xe0\xa8\xbc\0" /* offset 1869 */
+  "\xe0\xa8\x9c\xe0\xa8\xbc\0" /* offset 1876 */
+  "\xe0\xa8\xab\xe0\xa8\xbc\0" /* offset 1883 */
+  "\xe0\xad\x87\xe0\xad\x96\0" /* offset 1890 */
+  "\xe0\xad\x87\xe0\xac\xbe\0" /* offset 1897 */
+  "\xe0\xad\x87\xe0\xad\x97\0" /* offset 1904 */
+  "\xe0\xac\xa1\xe0\xac\xbc\0" /* offset 1911 */
+  "\xe0\xac\xa2\xe0\xac\xbc\0" /* offset 1918 */
+  "\xe0\xae\x92\xe0\xaf\x97\0" /* offset 1925 */
+  "\xe0\xaf\x86\xe0\xae\xbe\0" /* offset 1932 */
+  "\xe0\xaf\x87\xe0\xae\xbe\0" /* offset 1939 */
+  "\xe0\xaf\x86\xe0\xaf\x97\0" /* offset 1946 */
+  "\xe0\xb1\x86\xe0\xb1\x96\0" /* offset 1953 */
+  "\xe0\xb2\xbf\xe0\xb3\x95\0" /* offset 1960 */
+  "\xe0\xb3\x86\xe0\xb3\x95\0" /* offset 1967 */
+  "\xe0\xb3\x86\xe0\xb3\x96\0" /* offset 1974 */
+  "\xe0\xb3\x86\xe0\xb3\x82\0" /* offset 1981 */
+  "\xe0\xb3\x86\xe0\xb3\x82\xe0\xb3\x95\0" /* offset 1988 */
+  "\xe0\xb5\x86\xe0\xb4\xbe\0" /* offset 1998 */
+  "\xe0\xb5\x87\xe0\xb4\xbe\0" /* offset 2005 */
+  "\xe0\xb5\x86\xe0\xb5\x97\0" /* offset 2012 */
+  "\xe0\xb7\x99\xe0\xb7\x8a\0" /* offset 2019 */
+  "\xe0\xb7\x99\xe0\xb7\x8f\0" /* offset 2026 */
+  "\xe0\xb7\x99\xe0\xb7\x8f\xe0\xb7\x8a\0" /* offset 2033 */
+  "\xe0\xb7\x99\xe0\xb7\x9f\0" /* offset 2043 */
+  "\xe0\xb9\x8d\xe0\xb8\xb2\0" /* offset 2050 */
+  "\xe0\xbb\x8d\xe0\xba\xb2\0" /* offset 2057 */
+  "\xe0\xba\xab\xe0\xba\x99\0" /* offset 2064 */
+  "\xe0\xba\xab\xe0\xba\xa1\0" /* offset 2071 */
+  "\xe0\xbc\x8b\0" /* offset 2078 */
+  "\xe0\xbd\x82\xe0\xbe\xb7\0" /* offset 2082 */
+  "\xe0\xbd\x8c\xe0\xbe\xb7\0" /* offset 2089 */
+  "\xe0\xbd\x91\xe0\xbe\xb7\0" /* offset 2096 */
+  "\xe0\xbd\x96\xe0\xbe\xb7\0" /* offset 2103 */
+  "\xe0\xbd\x9b\xe0\xbe\xb7\0" /* offset 2110 */
+  "\xe0\xbd\x80\xe0\xbe\xb5\0" /* offset 2117 */
+  "\xe0\xbd\xb1\xe0\xbd\xb2\0" /* offset 2124 */
+  "\xe0\xbd\xb1\xe0\xbd\xb4\0" /* offset 2131 */
+  "\xe0\xbe\xb2\xe0\xbe\x80\0" /* offset 2138 */
+  "\xe0\xbe\xb2\xe0\xbd\xb1\xe0\xbe\x80\0" /* offset 2145 */
+  "\xe0\xbe\xb3\xe0\xbe\x80\0" /* offset 2155 */
+  "\xe0\xbe\xb3\xe0\xbd\xb1\xe0\xbe\x80\0" /* offset 2162 */
+  "\xe0\xbd\xb1\xe0\xbe\x80\0" /* offset 2172 */
+  "\xe0\xbe\x92\xe0\xbe\xb7\0" /* offset 2179 */
+  "\xe0\xbe\x9c\xe0\xbe\xb7\0" /* offset 2186 */
+  "\xe0\xbe\xa1\xe0\xbe\xb7\0" /* offset 2193 */
+  "\xe0\xbe\xa6\xe0\xbe\xb7\0" /* offset 2200 */
+  "\xe0\xbe\xab\xe0\xbe\xb7\0" /* offset 2207 */
+  "\xe0\xbe\x90\xe0\xbe\xb5\0" /* offset 2214 */
+  "\xe1\x80\xa5\xe1\x80\xae\0" /* offset 2221 */
+  "\xe1\x83\x9c\0" /* offset 2228 */
+  "\xe1\xac\x85\xe1\xac\xb5\0" /* offset 2232 */
+  "\xe1\xac\x87\xe1\xac\xb5\0" /* offset 2239 */
+  "\xe1\xac\x89\xe1\xac\xb5\0" /* offset 2246 */
+  "\xe1\xac\x8b\xe1\xac\xb5\0" /* offset 2253 */
+  "\xe1\xac\x8d\xe1\xac\xb5\0" /* offset 2260 */
+  "\xe1\xac\x91\xe1\xac\xb5\0" /* offset 2267 */
+  "\xe1\xac\xba\xe1\xac\xb5\0" /* offset 2274 */
+  "\xe1\xac\xbc\xe1\xac\xb5\0" /* offset 2281 */
+  "\xe1\xac\xbe\xe1\xac\xb5\0" /* offset 2288 */
+  "\xe1\xac\xbf\xe1\xac\xb5\0" /* offset 2295 */
+  "\xe1\xad\x82\xe1\xac\xb5\0" /* offset 2302 */
+  "\x41\0" /* offset 2309 */
+  "\xc3\x86\0" /* offset 2311 */
+  "\x42\0" /* offset 2314 */
+  "\x44\0" /* offset 2316 */
+  "\x45\0" /* offset 2318 */
+  "\xc6\x8e\0" /* offset 2320 */
+  "\x47\0" /* offset 2323 */
+  "\x48\0" /* offset 2325 */
+  "\x49\0" /* offset 2327 */
+  "\x4a\0" /* offset 2329 */
+  "\x4b\0" /* offset 2331 */
+  "\x4c\0" /* offset 2333 */
+  "\x4d\0" /* offset 2335 */
+  "\x4e\0" /* offset 2337 */
+  "\x4f\0" /* offset 2339 */
+  "\xc8\xa2\0" /* offset 2341 */
+  "\x50\0" /* offset 2344 */
+  "\x52\0" /* offset 2346 */
+  "\x54\0" /* offset 2348 */
+  "\x55\0" /* offset 2350 */
+  "\x57\0" /* offset 2352 */
+  "\xc9\x90\0" /* offset 2354 */
+  "\xc9\x91\0" /* offset 2357 */
+  "\xe1\xb4\x82\0" /* offset 2360 */
+  "\x62\0" /* offset 2364 */
+  "\x64\0" /* offset 2366 */
+  "\x65\0" /* offset 2368 */
+  "\xc9\x99\0" /* offset 2370 */
+  "\xc9\x9b\0" /* offset 2373 */
+  "\xc9\x9c\0" /* offset 2376 */
+  "\x67\0" /* offset 2379 */
+  "\x6b\0" /* offset 2381 */
+  "\x6d\0" /* offset 2383 */
+  "\xc5\x8b\0" /* offset 2385 */
+  "\xc9\x94\0" /* offset 2388 */
+  "\xe1\xb4\x96\0" /* offset 2391 */
+  "\xe1\xb4\x97\0" /* offset 2395 */
+  "\x70\0" /* offset 2399 */
+  "\x74\0" /* offset 2401 */
+  "\x75\0" /* offset 2403 */
+  "\xe1\xb4\x9d\0" /* offset 2405 */
+  "\xc9\xaf\0" /* offset 2409 */
+  "\x76\0" /* offset 2412 */
+  "\xe1\xb4\xa5\0" /* offset 2414 */
+  "\xce\xb3\0" /* offset 2418 */
+  "\xce\xb4\0" /* offset 2421 */
+  "\xcf\x87\0" /* offset 2424 */
+  "\x69\0" /* offset 2427 */
+  "\xd0\xbd\0" /* offset 2429 */
+  "\xc9\x92\0" /* offset 2432 */
+  "\x63\0" /* offset 2435 */
+  "\xc9\x95\0" /* offset 2437 */
+  "\xc3\xb0\0" /* offset 2440 */
+  "\x66\0" /* offset 2443 */
+  "\xc9\x9f\0" /* offset 2445 */
+  "\xc9\xa1\0" /* offset 2448 */
+  "\xc9\xa5\0" /* offset 2451 */
+  "\xc9\xa8\0" /* offset 2454 */
+  "\xc9\xa9\0" /* offset 2457 */
+  "\xc9\xaa\0" /* offset 2460 */
+  "\xe1\xb5\xbb\0" /* offset 2463 */
+  "\xca\x9d\0" /* offset 2467 */
+  "\xc9\xad\0" /* offset 2470 */
+  "\xe1\xb6\x85\0" /* offset 2473 */
+  "\xca\x9f\0" /* offset 2477 */
+  "\xc9\xb1\0" /* offset 2480 */
+  "\xc9\xb0\0" /* offset 2483 */
+  "\xc9\xb2\0" /* offset 2486 */
+  "\xc9\xb3\0" /* offset 2489 */
+  "\xc9\xb4\0" /* offset 2492 */
+  "\xc9\xb5\0" /* offset 2495 */
+  "\xc9\xb8\0" /* offset 2498 */
+  "\xca\x82\0" /* offset 2501 */
+  "\xca\x83\0" /* offset 2504 */
+  "\xc6\xab\0" /* offset 2507 */
+  "\xca\x89\0" /* offset 2510 */
+  "\xca\x8a\0" /* offset 2513 */
+  "\xe1\xb4\x9c\0" /* offset 2516 */
+  "\xca\x8b\0" /* offset 2520 */
+  "\xca\x8c\0" /* offset 2523 */
+  "\x7a\0" /* offset 2526 */
+  "\xca\x90\0" /* offset 2528 */
+  "\xca\x91\0" /* offset 2531 */
+  "\xca\x92\0" /* offset 2534 */
+  "\x41\xcc\xa5\0" /* offset 2537 */
+  "\x61\xcc\xa5\0" /* offset 2541 */
+  "\x42\xcc\x87\0" /* offset 2545 */
+  "\x62\xcc\x87\0" /* offset 2549 */
+  "\x42\xcc\xa3\0" /* offset 2553 */
+  "\x62\xcc\xa3\0" /* offset 2557 */
+  "\x42\xcc\xb1\0" /* offset 2561 */
+  "\x62\xcc\xb1\0" /* offset 2565 */
+  "\x43\xcc\xa7\xcc\x81\0" /* offset 2569 */
+  "\x63\xcc\xa7\xcc\x81\0" /* offset 2575 */
+  "\x44\xcc\x87\0" /* offset 2581 */
+  "\x64\xcc\x87\0" /* offset 2585 */
+  "\x44\xcc\xa3\0" /* offset 2589 */
+  "\x64\xcc\xa3\0" /* offset 2593 */
+  "\x44\xcc\xb1\0" /* offset 2597 */
+  "\x64\xcc\xb1\0" /* offset 2601 */
+  "\x44\xcc\xa7\0" /* offset 2605 */
+  "\x64\xcc\xa7\0" /* offset 2609 */
+  "\x44\xcc\xad\0" /* offset 2613 */
+  "\x64\xcc\xad\0" /* offset 2617 */
+  "\x45\xcc\x84\xcc\x80\0" /* offset 2621 */
+  "\x65\xcc\x84\xcc\x80\0" /* offset 2627 */
+  "\x45\xcc\x84\xcc\x81\0" /* offset 2633 */
+  "\x65\xcc\x84\xcc\x81\0" /* offset 2639 */
+  "\x45\xcc\xad\0" /* offset 2645 */
+  "\x65\xcc\xad\0" /* offset 2649 */
+  "\x45\xcc\xb0\0" /* offset 2653 */
+  "\x65\xcc\xb0\0" /* offset 2657 */
+  "\x45\xcc\xa7\xcc\x86\0" /* offset 2661 */
+  "\x65\xcc\xa7\xcc\x86\0" /* offset 2667 */
+  "\x46\xcc\x87\0" /* offset 2673 */
+  "\x66\xcc\x87\0" /* offset 2677 */
+  "\x47\xcc\x84\0" /* offset 2681 */
+  "\x67\xcc\x84\0" /* offset 2685 */
+  "\x48\xcc\x87\0" /* offset 2689 */
+  "\x68\xcc\x87\0" /* offset 2693 */
+  "\x48\xcc\xa3\0" /* offset 2697 */
+  "\x68\xcc\xa3\0" /* offset 2701 */
+  "\x48\xcc\x88\0" /* offset 2705 */
+  "\x68\xcc\x88\0" /* offset 2709 */
+  "\x48\xcc\xa7\0" /* offset 2713 */
+  "\x68\xcc\xa7\0" /* offset 2717 */
+  "\x48\xcc\xae\0" /* offset 2721 */
+  "\x68\xcc\xae\0" /* offset 2725 */
+  "\x49\xcc\xb0\0" /* offset 2729 */
+  "\x69\xcc\xb0\0" /* offset 2733 */
+  "\x49\xcc\x88\xcc\x81\0" /* offset 2737 */
+  "\x69\xcc\x88\xcc\x81\0" /* offset 2743 */
+  "\x4b\xcc\x81\0" /* offset 2749 */
+  "\x6b\xcc\x81\0" /* offset 2753 */
+  "\x4b\xcc\xa3\0" /* offset 2757 */
+  "\x6b\xcc\xa3\0" /* offset 2761 */
+  "\x4b\xcc\xb1\0" /* offset 2765 */
+  "\x6b\xcc\xb1\0" /* offset 2769 */
+  "\x4c\xcc\xa3\0" /* offset 2773 */
+  "\x6c\xcc\xa3\0" /* offset 2777 */
+  "\x4c\xcc\xa3\xcc\x84\0" /* offset 2781 */
+  "\x6c\xcc\xa3\xcc\x84\0" /* offset 2787 */
+  "\x4c\xcc\xb1\0" /* offset 2793 */
+  "\x6c\xcc\xb1\0" /* offset 2797 */
+  "\x4c\xcc\xad\0" /* offset 2801 */
+  "\x6c\xcc\xad\0" /* offset 2805 */
+  "\x4d\xcc\x81\0" /* offset 2809 */
+  "\x6d\xcc\x81\0" /* offset 2813 */
+  "\x4d\xcc\x87\0" /* offset 2817 */
+  "\x6d\xcc\x87\0" /* offset 2821 */
+  "\x4d\xcc\xa3\0" /* offset 2825 */
+  "\x6d\xcc\xa3\0" /* offset 2829 */
+  "\x4e\xcc\x87\0" /* offset 2833 */
+  "\x6e\xcc\x87\0" /* offset 2837 */
+  "\x4e\xcc\xa3\0" /* offset 2841 */
+  "\x6e\xcc\xa3\0" /* offset 2845 */
+  "\x4e\xcc\xb1\0" /* offset 2849 */
+  "\x6e\xcc\xb1\0" /* offset 2853 */
+  "\x4e\xcc\xad\0" /* offset 2857 */
+  "\x6e\xcc\xad\0" /* offset 2861 */
+  "\x4f\xcc\x83\xcc\x81\0" /* offset 2865 */
+  "\x6f\xcc\x83\xcc\x81\0" /* offset 2871 */
+  "\x4f\xcc\x83\xcc\x88\0" /* offset 2877 */
+  "\x6f\xcc\x83\xcc\x88\0" /* offset 2883 */
+  "\x4f\xcc\x84\xcc\x80\0" /* offset 2889 */
+  "\x6f\xcc\x84\xcc\x80\0" /* offset 2895 */
+  "\x4f\xcc\x84\xcc\x81\0" /* offset 2901 */
+  "\x6f\xcc\x84\xcc\x81\0" /* offset 2907 */
+  "\x50\xcc\x81\0" /* offset 2913 */
+  "\x70\xcc\x81\0" /* offset 2917 */
+  "\x50\xcc\x87\0" /* offset 2921 */
+  "\x70\xcc\x87\0" /* offset 2925 */
+  "\x52\xcc\x87\0" /* offset 2929 */
+  "\x72\xcc\x87\0" /* offset 2933 */
+  "\x52\xcc\xa3\0" /* offset 2937 */
+  "\x72\xcc\xa3\0" /* offset 2941 */
+  "\x52\xcc\xa3\xcc\x84\0" /* offset 2945 */
+  "\x72\xcc\xa3\xcc\x84\0" /* offset 2951 */
+  "\x52\xcc\xb1\0" /* offset 2957 */
+  "\x72\xcc\xb1\0" /* offset 2961 */
+  "\x53\xcc\x87\0" /* offset 2965 */
+  "\x73\xcc\x87\0" /* offset 2969 */
+  "\x53\xcc\xa3\0" /* offset 2973 */
+  "\x73\xcc\xa3\0" /* offset 2977 */
+  "\x53\xcc\x81\xcc\x87\0" /* offset 2981 */
+  "\x73\xcc\x81\xcc\x87\0" /* offset 2987 */
+  "\x53\xcc\x8c\xcc\x87\0" /* offset 2993 */
+  "\x73\xcc\x8c\xcc\x87\0" /* offset 2999 */
+  "\x53\xcc\xa3\xcc\x87\0" /* offset 3005 */
+  "\x73\xcc\xa3\xcc\x87\0" /* offset 3011 */
+  "\x54\xcc\x87\0" /* offset 3017 */
+  "\x74\xcc\x87\0" /* offset 3021 */
+  "\x54\xcc\xa3\0" /* offset 3025 */
+  "\x74\xcc\xa3\0" /* offset 3029 */
+  "\x54\xcc\xb1\0" /* offset 3033 */
+  "\x74\xcc\xb1\0" /* offset 3037 */
+  "\x54\xcc\xad\0" /* offset 3041 */
+  "\x74\xcc\xad\0" /* offset 3045 */
+  "\x55\xcc\xa4\0" /* offset 3049 */
+  "\x75\xcc\xa4\0" /* offset 3053 */
+  "\x55\xcc\xb0\0" /* offset 3057 */
+  "\x75\xcc\xb0\0" /* offset 3061 */
+  "\x55\xcc\xad\0" /* offset 3065 */
+  "\x75\xcc\xad\0" /* offset 3069 */
+  "\x55\xcc\x83\xcc\x81\0" /* offset 3073 */
+  "\x75\xcc\x83\xcc\x81\0" /* offset 3079 */
+  "\x55\xcc\x84\xcc\x88\0" /* offset 3085 */
+  "\x75\xcc\x84\xcc\x88\0" /* offset 3091 */
+  "\x56\xcc\x83\0" /* offset 3097 */
+  "\x76\xcc\x83\0" /* offset 3101 */
+  "\x56\xcc\xa3\0" /* offset 3105 */
+  "\x76\xcc\xa3\0" /* offset 3109 */
+  "\x57\xcc\x80\0" /* offset 3113 */
+  "\x77\xcc\x80\0" /* offset 3117 */
+  "\x57\xcc\x81\0" /* offset 3121 */
+  "\x77\xcc\x81\0" /* offset 3125 */
+  "\x57\xcc\x88\0" /* offset 3129 */
+  "\x77\xcc\x88\0" /* offset 3133 */
+  "\x57\xcc\x87\0" /* offset 3137 */
+  "\x77\xcc\x87\0" /* offset 3141 */
+  "\x57\xcc\xa3\0" /* offset 3145 */
+  "\x77\xcc\xa3\0" /* offset 3149 */
+  "\x58\xcc\x87\0" /* offset 3153 */
+  "\x78\xcc\x87\0" /* offset 3157 */
+  "\x58\xcc\x88\0" /* offset 3161 */
+  "\x78\xcc\x88\0" /* offset 3165 */
+  "\x59\xcc\x87\0" /* offset 3169 */
+  "\x79\xcc\x87\0" /* offset 3173 */
+  "\x5a\xcc\x82\0" /* offset 3177 */
+  "\x7a\xcc\x82\0" /* offset 3181 */
+  "\x5a\xcc\xa3\0" /* offset 3185 */
+  "\x7a\xcc\xa3\0" /* offset 3189 */
+  "\x5a\xcc\xb1\0" /* offset 3193 */
+  "\x7a\xcc\xb1\0" /* offset 3197 */
+  "\x68\xcc\xb1\0" /* offset 3201 */
+  "\x74\xcc\x88\0" /* offset 3205 */
+  "\x77\xcc\x8a\0" /* offset 3209 */
+  "\x79\xcc\x8a\0" /* offset 3213 */
+  "\x61\xca\xbe\0" /* offset 3217 */
+  "\xc5\xbf\xcc\x87\0" /* offset 3221 */
+  "\x41\xcc\xa3\0" /* offset 3226 */
+  "\x61\xcc\xa3\0" /* offset 3230 */
+  "\x41\xcc\x89\0" /* offset 3234 */
+  "\x61\xcc\x89\0" /* offset 3238 */
+  "\x41\xcc\x82\xcc\x81\0" /* offset 3242 */
+  "\x61\xcc\x82\xcc\x81\0" /* offset 3248 */
+  "\x41\xcc\x82\xcc\x80\0" /* offset 3254 */
+  "\x61\xcc\x82\xcc\x80\0" /* offset 3260 */
+  "\x41\xcc\x82\xcc\x89\0" /* offset 3266 */
+  "\x61\xcc\x82\xcc\x89\0" /* offset 3272 */
+  "\x41\xcc\x82\xcc\x83\0" /* offset 3278 */
+  "\x61\xcc\x82\xcc\x83\0" /* offset 3284 */
+  "\x41\xcc\xa3\xcc\x82\0" /* offset 3290 */
+  "\x61\xcc\xa3\xcc\x82\0" /* offset 3296 */
+  "\x41\xcc\x86\xcc\x81\0" /* offset 3302 */
+  "\x61\xcc\x86\xcc\x81\0" /* offset 3308 */
+  "\x41\xcc\x86\xcc\x80\0" /* offset 3314 */
+  "\x61\xcc\x86\xcc\x80\0" /* offset 3320 */
+  "\x41\xcc\x86\xcc\x89\0" /* offset 3326 */
+  "\x61\xcc\x86\xcc\x89\0" /* offset 3332 */
+  "\x41\xcc\x86\xcc\x83\0" /* offset 3338 */
+  "\x61\xcc\x86\xcc\x83\0" /* offset 3344 */
+  "\x41\xcc\xa3\xcc\x86\0" /* offset 3350 */
+  "\x61\xcc\xa3\xcc\x86\0" /* offset 3356 */
+  "\x45\xcc\xa3\0" /* offset 3362 */
+  "\x65\xcc\xa3\0" /* offset 3366 */
+  "\x45\xcc\x89\0" /* offset 3370 */
+  "\x65\xcc\x89\0" /* offset 3374 */
+  "\x45\xcc\x83\0" /* offset 3378 */
+  "\x65\xcc\x83\0" /* offset 3382 */
+  "\x45\xcc\x82\xcc\x81\0" /* offset 3386 */
+  "\x65\xcc\x82\xcc\x81\0" /* offset 3392 */
+  "\x45\xcc\x82\xcc\x80\0" /* offset 3398 */
+  "\x65\xcc\x82\xcc\x80\0" /* offset 3404 */
+  "\x45\xcc\x82\xcc\x89\0" /* offset 3410 */
+  "\x65\xcc\x82\xcc\x89\0" /* offset 3416 */
+  "\x45\xcc\x82\xcc\x83\0" /* offset 3422 */
+  "\x65\xcc\x82\xcc\x83\0" /* offset 3428 */
+  "\x45\xcc\xa3\xcc\x82\0" /* offset 3434 */
+  "\x65\xcc\xa3\xcc\x82\0" /* offset 3440 */
+  "\x49\xcc\x89\0" /* offset 3446 */
+  "\x69\xcc\x89\0" /* offset 3450 */
+  "\x49\xcc\xa3\0" /* offset 3454 */
+  "\x69\xcc\xa3\0" /* offset 3458 */
+  "\x4f\xcc\xa3\0" /* offset 3462 */
+  "\x6f\xcc\xa3\0" /* offset 3466 */
+  "\x4f\xcc\x89\0" /* offset 3470 */
+  "\x6f\xcc\x89\0" /* offset 3474 */
+  "\x4f\xcc\x82\xcc\x81\0" /* offset 3478 */
+  "\x6f\xcc\x82\xcc\x81\0" /* offset 3484 */
+  "\x4f\xcc\x82\xcc\x80\0" /* offset 3490 */
+  "\x6f\xcc\x82\xcc\x80\0" /* offset 3496 */
+  "\x4f\xcc\x82\xcc\x89\0" /* offset 3502 */
+  "\x6f\xcc\x82\xcc\x89\0" /* offset 3508 */
+  "\x4f\xcc\x82\xcc\x83\0" /* offset 3514 */
+  "\x6f\xcc\x82\xcc\x83\0" /* offset 3520 */
+  "\x4f\xcc\xa3\xcc\x82\0" /* offset 3526 */
+  "\x6f\xcc\xa3\xcc\x82\0" /* offset 3532 */
+  "\x4f\xcc\x9b\xcc\x81\0" /* offset 3538 */
+  "\x6f\xcc\x9b\xcc\x81\0" /* offset 3544 */
+  "\x4f\xcc\x9b\xcc\x80\0" /* offset 3550 */
+  "\x6f\xcc\x9b\xcc\x80\0" /* offset 3556 */
+  "\x4f\xcc\x9b\xcc\x89\0" /* offset 3562 */
+  "\x6f\xcc\x9b\xcc\x89\0" /* offset 3568 */
+  "\x4f\xcc\x9b\xcc\x83\0" /* offset 3574 */
+  "\x6f\xcc\x9b\xcc\x83\0" /* offset 3580 */
+  "\x4f\xcc\x9b\xcc\xa3\0" /* offset 3586 */
+  "\x6f\xcc\x9b\xcc\xa3\0" /* offset 3592 */
+  "\x55\xcc\xa3\0" /* offset 3598 */
+  "\x75\xcc\xa3\0" /* offset 3602 */
+  "\x55\xcc\x89\0" /* offset 3606 */
+  "\x75\xcc\x89\0" /* offset 3610 */
+  "\x55\xcc\x9b\xcc\x81\0" /* offset 3614 */
+  "\x75\xcc\x9b\xcc\x81\0" /* offset 3620 */
+  "\x55\xcc\x9b\xcc\x80\0" /* offset 3626 */
+  "\x75\xcc\x9b\xcc\x80\0" /* offset 3632 */
+  "\x55\xcc\x9b\xcc\x89\0" /* offset 3638 */
+  "\x75\xcc\x9b\xcc\x89\0" /* offset 3644 */
+  "\x55\xcc\x9b\xcc\x83\0" /* offset 3650 */
+  "\x75\xcc\x9b\xcc\x83\0" /* offset 3656 */
+  "\x55\xcc\x9b\xcc\xa3\0" /* offset 3662 */
+  "\x75\xcc\x9b\xcc\xa3\0" /* offset 3668 */
+  "\x59\xcc\x80\0" /* offset 3674 */
+  "\x79\xcc\x80\0" /* offset 3678 */
+  "\x59\xcc\xa3\0" /* offset 3682 */
+  "\x79\xcc\xa3\0" /* offset 3686 */
+  "\x59\xcc\x89\0" /* offset 3690 */
+  "\x79\xcc\x89\0" /* offset 3694 */
+  "\x59\xcc\x83\0" /* offset 3698 */
+  "\x79\xcc\x83\0" /* offset 3702 */
+  "\xce\xb1\xcc\x93\0" /* offset 3706 */
+  "\xce\xb1\xcc\x94\0" /* offset 3711 */
+  "\xce\xb1\xcc\x93\xcc\x80\0" /* offset 3716 */
+  "\xce\xb1\xcc\x94\xcc\x80\0" /* offset 3723 */
+  "\xce\xb1\xcc\x93\xcc\x81\0" /* offset 3730 */
+  "\xce\xb1\xcc\x94\xcc\x81\0" /* offset 3737 */
+  "\xce\xb1\xcc\x93\xcd\x82\0" /* offset 3744 */
+  "\xce\xb1\xcc\x94\xcd\x82\0" /* offset 3751 */
+  "\xce\x91\xcc\x93\0" /* offset 3758 */
+  "\xce\x91\xcc\x94\0" /* offset 3763 */
+  "\xce\x91\xcc\x93\xcc\x80\0" /* offset 3768 */
+  "\xce\x91\xcc\x94\xcc\x80\0" /* offset 3775 */
+  "\xce\x91\xcc\x93\xcc\x81\0" /* offset 3782 */
+  "\xce\x91\xcc\x94\xcc\x81\0" /* offset 3789 */
+  "\xce\x91\xcc\x93\xcd\x82\0" /* offset 3796 */
+  "\xce\x91\xcc\x94\xcd\x82\0" /* offset 3803 */
+  "\xce\xb5\xcc\x93\0" /* offset 3810 */
+  "\xce\xb5\xcc\x94\0" /* offset 3815 */
+  "\xce\xb5\xcc\x93\xcc\x80\0" /* offset 3820 */
+  "\xce\xb5\xcc\x94\xcc\x80\0" /* offset 3827 */
+  "\xce\xb5\xcc\x93\xcc\x81\0" /* offset 3834 */
+  "\xce\xb5\xcc\x94\xcc\x81\0" /* offset 3841 */
+  "\xce\x95\xcc\x93\0" /* offset 3848 */
+  "\xce\x95\xcc\x94\0" /* offset 3853 */
+  "\xce\x95\xcc\x93\xcc\x80\0" /* offset 3858 */
+  "\xce\x95\xcc\x94\xcc\x80\0" /* offset 3865 */
+  "\xce\x95\xcc\x93\xcc\x81\0" /* offset 3872 */
+  "\xce\x95\xcc\x94\xcc\x81\0" /* offset 3879 */
+  "\xce\xb7\xcc\x93\0" /* offset 3886 */
+  "\xce\xb7\xcc\x94\0" /* offset 3891 */
+  "\xce\xb7\xcc\x93\xcc\x80\0" /* offset 3896 */
+  "\xce\xb7\xcc\x94\xcc\x80\0" /* offset 3903 */
+  "\xce\xb7\xcc\x93\xcc\x81\0" /* offset 3910 */
+  "\xce\xb7\xcc\x94\xcc\x81\0" /* offset 3917 */
+  "\xce\xb7\xcc\x93\xcd\x82\0" /* offset 3924 */
+  "\xce\xb7\xcc\x94\xcd\x82\0" /* offset 3931 */
+  "\xce\x97\xcc\x93\0" /* offset 3938 */
+  "\xce\x97\xcc\x94\0" /* offset 3943 */
+  "\xce\x97\xcc\x93\xcc\x80\0" /* offset 3948 */
+  "\xce\x97\xcc\x94\xcc\x80\0" /* offset 3955 */
+  "\xce\x97\xcc\x93\xcc\x81\0" /* offset 3962 */
+  "\xce\x97\xcc\x94\xcc\x81\0" /* offset 3969 */
+  "\xce\x97\xcc\x93\xcd\x82\0" /* offset 3976 */
+  "\xce\x97\xcc\x94\xcd\x82\0" /* offset 3983 */
+  "\xce\xb9\xcc\x93\0" /* offset 3990 */
+  "\xce\xb9\xcc\x94\0" /* offset 3995 */
+  "\xce\xb9\xcc\x93\xcc\x80\0" /* offset 4000 */
+  "\xce\xb9\xcc\x94\xcc\x80\0" /* offset 4007 */
+  "\xce\xb9\xcc\x93\xcc\x81\0" /* offset 4014 */
+  "\xce\xb9\xcc\x94\xcc\x81\0" /* offset 4021 */
+  "\xce\xb9\xcc\x93\xcd\x82\0" /* offset 4028 */
+  "\xce\xb9\xcc\x94\xcd\x82\0" /* offset 4035 */
+  "\xce\x99\xcc\x93\0" /* offset 4042 */
+  "\xce\x99\xcc\x94\0" /* offset 4047 */
+  "\xce\x99\xcc\x93\xcc\x80\0" /* offset 4052 */
+  "\xce\x99\xcc\x94\xcc\x80\0" /* offset 4059 */
+  "\xce\x99\xcc\x93\xcc\x81\0" /* offset 4066 */
+  "\xce\x99\xcc\x94\xcc\x81\0" /* offset 4073 */
+  "\xce\x99\xcc\x93\xcd\x82\0" /* offset 4080 */
+  "\xce\x99\xcc\x94\xcd\x82\0" /* offset 4087 */
+  "\xce\xbf\xcc\x93\0" /* offset 4094 */
+  "\xce\xbf\xcc\x94\0" /* offset 4099 */
+  "\xce\xbf\xcc\x93\xcc\x80\0" /* offset 4104 */
+  "\xce\xbf\xcc\x94\xcc\x80\0" /* offset 4111 */
+  "\xce\xbf\xcc\x93\xcc\x81\0" /* offset 4118 */
+  "\xce\xbf\xcc\x94\xcc\x81\0" /* offset 4125 */
+  "\xce\x9f\xcc\x93\0" /* offset 4132 */
+  "\xce\x9f\xcc\x94\0" /* offset 4137 */
+  "\xce\x9f\xcc\x93\xcc\x80\0" /* offset 4142 */
+  "\xce\x9f\xcc\x94\xcc\x80\0" /* offset 4149 */
+  "\xce\x9f\xcc\x93\xcc\x81\0" /* offset 4156 */
+  "\xce\x9f\xcc\x94\xcc\x81\0" /* offset 4163 */
+  "\xcf\x85\xcc\x93\0" /* offset 4170 */
+  "\xcf\x85\xcc\x94\0" /* offset 4175 */
+  "\xcf\x85\xcc\x93\xcc\x80\0" /* offset 4180 */
+  "\xcf\x85\xcc\x94\xcc\x80\0" /* offset 4187 */
+  "\xcf\x85\xcc\x93\xcc\x81\0" /* offset 4194 */
+  "\xcf\x85\xcc\x94\xcc\x81\0" /* offset 4201 */
+  "\xcf\x85\xcc\x93\xcd\x82\0" /* offset 4208 */
+  "\xcf\x85\xcc\x94\xcd\x82\0" /* offset 4215 */
+  "\xce\xa5\xcc\x94\0" /* offset 4222 */
+  "\xce\xa5\xcc\x94\xcc\x80\0" /* offset 4227 */
+  "\xce\xa5\xcc\x94\xcc\x81\0" /* offset 4234 */
+  "\xce\xa5\xcc\x94\xcd\x82\0" /* offset 4241 */
+  "\xcf\x89\xcc\x93\0" /* offset 4248 */
+  "\xcf\x89\xcc\x94\0" /* offset 4253 */
+  "\xcf\x89\xcc\x93\xcc\x80\0" /* offset 4258 */
+  "\xcf\x89\xcc\x94\xcc\x80\0" /* offset 4265 */
+  "\xcf\x89\xcc\x93\xcc\x81\0" /* offset 4272 */
+  "\xcf\x89\xcc\x94\xcc\x81\0" /* offset 4279 */
+  "\xcf\x89\xcc\x93\xcd\x82\0" /* offset 4286 */
+  "\xcf\x89\xcc\x94\xcd\x82\0" /* offset 4293 */
+  "\xce\xa9\xcc\x93\0" /* offset 4300 */
+  "\xce\xa9\xcc\x94\0" /* offset 4305 */
+  "\xce\xa9\xcc\x93\xcc\x80\0" /* offset 4310 */
+  "\xce\xa9\xcc\x94\xcc\x80\0" /* offset 4317 */
+  "\xce\xa9\xcc\x93\xcc\x81\0" /* offset 4324 */
+  "\xce\xa9\xcc\x94\xcc\x81\0" /* offset 4331 */
+  "\xce\xa9\xcc\x93\xcd\x82\0" /* offset 4338 */
+  "\xce\xa9\xcc\x94\xcd\x82\0" /* offset 4345 */
+  "\xce\xb1\xcc\x80\0" /* offset 4352 */
+  "\xce\xb5\xcc\x80\0" /* offset 4357 */
+  "\xce\xb7\xcc\x80\0" /* offset 4362 */
+  "\xce\xb9\xcc\x80\0" /* offset 4367 */
+  "\xce\xbf\xcc\x80\0" /* offset 4372 */
+  "\xcf\x85\xcc\x80\0" /* offset 4377 */
+  "\xcf\x89\xcc\x80\0" /* offset 4382 */
+  "\xce\xb1\xcc\x93\xcd\x85\0" /* offset 4387 */
+  "\xce\xb1\xcc\x94\xcd\x85\0" /* offset 4394 */
+  "\xce\xb1\xcc\x93\xcc\x80\xcd\x85\0" /* offset 4401 */
+  "\xce\xb1\xcc\x94\xcc\x80\xcd\x85\0" /* offset 4410 */
+  "\xce\xb1\xcc\x93\xcc\x81\xcd\x85\0" /* offset 4419 */
+  "\xce\xb1\xcc\x94\xcc\x81\xcd\x85\0" /* offset 4428 */
+  "\xce\xb1\xcc\x93\xcd\x82\xcd\x85\0" /* offset 4437 */
+  "\xce\xb1\xcc\x94\xcd\x82\xcd\x85\0" /* offset 4446 */
+  "\xce\x91\xcc\x93\xcd\x85\0" /* offset 4455 */
+  "\xce\x91\xcc\x94\xcd\x85\0" /* offset 4462 */
+  "\xce\x91\xcc\x93\xcc\x80\xcd\x85\0" /* offset 4469 */
+  "\xce\x91\xcc\x94\xcc\x80\xcd\x85\0" /* offset 4478 */
+  "\xce\x91\xcc\x93\xcc\x81\xcd\x85\0" /* offset 4487 */
+  "\xce\x91\xcc\x94\xcc\x81\xcd\x85\0" /* offset 4496 */
+  "\xce\x91\xcc\x93\xcd\x82\xcd\x85\0" /* offset 4505 */
+  "\xce\x91\xcc\x94\xcd\x82\xcd\x85\0" /* offset 4514 */
+  "\xce\xb7\xcc\x93\xcd\x85\0" /* offset 4523 */
+  "\xce\xb7\xcc\x94\xcd\x85\0" /* offset 4530 */
+  "\xce\xb7\xcc\x93\xcc\x80\xcd\x85\0" /* offset 4537 */
+  "\xce\xb7\xcc\x94\xcc\x80\xcd\x85\0" /* offset 4546 */
+  "\xce\xb7\xcc\x93\xcc\x81\xcd\x85\0" /* offset 4555 */
+  "\xce\xb7\xcc\x94\xcc\x81\xcd\x85\0" /* offset 4564 */
+  "\xce\xb7\xcc\x93\xcd\x82\xcd\x85\0" /* offset 4573 */
+  "\xce\xb7\xcc\x94\xcd\x82\xcd\x85\0" /* offset 4582 */
+  "\xce\x97\xcc\x93\xcd\x85\0" /* offset 4591 */
+  "\xce\x97\xcc\x94\xcd\x85\0" /* offset 4598 */
+  "\xce\x97\xcc\x93\xcc\x80\xcd\x85\0" /* offset 4605 */
+  "\xce\x97\xcc\x94\xcc\x80\xcd\x85\0" /* offset 4614 */
+  "\xce\x97\xcc\x93\xcc\x81\xcd\x85\0" /* offset 4623 */
+  "\xce\x97\xcc\x94\xcc\x81\xcd\x85\0" /* offset 4632 */
+  "\xce\x97\xcc\x93\xcd\x82\xcd\x85\0" /* offset 4641 */
+  "\xce\x97\xcc\x94\xcd\x82\xcd\x85\0" /* offset 4650 */
+  "\xcf\x89\xcc\x93\xcd\x85\0" /* offset 4659 */
+  "\xcf\x89\xcc\x94\xcd\x85\0" /* offset 4666 */
+  "\xcf\x89\xcc\x93\xcc\x80\xcd\x85\0" /* offset 4673 */
+  "\xcf\x89\xcc\x94\xcc\x80\xcd\x85\0" /* offset 4682 */
+  "\xcf\x89\xcc\x93\xcc\x81\xcd\x85\0" /* offset 4691 */
+  "\xcf\x89\xcc\x94\xcc\x81\xcd\x85\0" /* offset 4700 */
+  "\xcf\x89\xcc\x93\xcd\x82\xcd\x85\0" /* offset 4709 */
+  "\xcf\x89\xcc\x94\xcd\x82\xcd\x85\0" /* offset 4718 */
+  "\xce\xa9\xcc\x93\xcd\x85\0" /* offset 4727 */
+  "\xce\xa9\xcc\x94\xcd\x85\0" /* offset 4734 */
+  "\xce\xa9\xcc\x93\xcc\x80\xcd\x85\0" /* offset 4741 */
+  "\xce\xa9\xcc\x94\xcc\x80\xcd\x85\0" /* offset 4750 */
+  "\xce\xa9\xcc\x93\xcc\x81\xcd\x85\0" /* offset 4759 */
+  "\xce\xa9\xcc\x94\xcc\x81\xcd\x85\0" /* offset 4768 */
+  "\xce\xa9\xcc\x93\xcd\x82\xcd\x85\0" /* offset 4777 */
+  "\xce\xa9\xcc\x94\xcd\x82\xcd\x85\0" /* offset 4786 */
+  "\xce\xb1\xcc\x86\0" /* offset 4795 */
+  "\xce\xb1\xcc\x84\0" /* offset 4800 */
+  "\xce\xb1\xcc\x80\xcd\x85\0" /* offset 4805 */
+  "\xce\xb1\xcd\x85\0" /* offset 4812 */
+  "\xce\xb1\xcc\x81\xcd\x85\0" /* offset 4817 */
+  "\xce\xb1\xcd\x82\0" /* offset 4824 */
+  "\xce\xb1\xcd\x82\xcd\x85\0" /* offset 4829 */
+  "\xce\x91\xcc\x86\0" /* offset 4836 */
+  "\xce\x91\xcc\x84\0" /* offset 4841 */
+  "\xce\x91\xcc\x80\0" /* offset 4846 */
+  "\xce\x91\xcd\x85\0" /* offset 4851 */
+  "\x20\xcc\x93\0" /* offset 4856 */
+  "\xce\xb9\0" /* offset 4860 */
+  "\x20\xcd\x82\0" /* offset 4863 */
+  "\xc2\xa8\xcd\x82\0" /* offset 4867 */
+  "\x20\xcc\x88\xcd\x82\0" /* offset 4872 */
+  "\xce\xb7\xcc\x80\xcd\x85\0" /* offset 4878 */
+  "\xce\xb7\xcd\x85\0" /* offset 4885 */
+  "\xce\xb7\xcc\x81\xcd\x85\0" /* offset 4890 */
+  "\xce\xb7\xcd\x82\0" /* offset 4897 */
+  "\xce\xb7\xcd\x82\xcd\x85\0" /* offset 4902 */
+  "\xce\x95\xcc\x80\0" /* offset 4909 */
+  "\xce\x97\xcc\x80\0" /* offset 4914 */
+  "\xce\x97\xcd\x85\0" /* offset 4919 */
+  "\xe1\xbe\xbf\xcc\x80\0" /* offset 4924 */
+  "\x20\xcc\x93\xcc\x80\0" /* offset 4930 */
+  "\xe1\xbe\xbf\xcc\x81\0" /* offset 4936 */
+  "\x20\xcc\x93\xcc\x81\0" /* offset 4942 */
+  "\xe1\xbe\xbf\xcd\x82\0" /* offset 4948 */
+  "\x20\xcc\x93\xcd\x82\0" /* offset 4954 */
+  "\xce\xb9\xcc\x86\0" /* offset 4960 */
+  "\xce\xb9\xcc\x84\0" /* offset 4965 */
+  "\xce\xb9\xcc\x88\xcc\x80\0" /* offset 4970 */
+  "\xce\xb9\xcd\x82\0" /* offset 4977 */
+  "\xce\xb9\xcc\x88\xcd\x82\0" /* offset 4982 */
+  "\xce\x99\xcc\x86\0" /* offset 4989 */
+  "\xce\x99\xcc\x84\0" /* offset 4994 */
+  "\xce\x99\xcc\x80\0" /* offset 4999 */
+  "\xe1\xbf\xbe\xcc\x80\0" /* offset 5004 */
+  "\x20\xcc\x94\xcc\x80\0" /* offset 5010 */
+  "\xe1\xbf\xbe\xcc\x81\0" /* offset 5016 */
+  "\x20\xcc\x94\xcc\x81\0" /* offset 5022 */
+  "\xe1\xbf\xbe\xcd\x82\0" /* offset 5028 */
+  "\x20\xcc\x94\xcd\x82\0" /* offset 5034 */
+  "\xcf\x85\xcc\x86\0" /* offset 5040 */
+  "\xcf\x85\xcc\x84\0" /* offset 5045 */
+  "\xcf\x85\xcc\x88\xcc\x80\0" /* offset 5050 */
+  "\xcf\x81\xcc\x93\0" /* offset 5057 */
+  "\xcf\x81\xcc\x94\0" /* offset 5062 */
+  "\xcf\x85\xcd\x82\0" /* offset 5067 */
+  "\xcf\x85\xcc\x88\xcd\x82\0" /* offset 5072 */
+  "\xce\xa5\xcc\x86\0" /* offset 5079 */
+  "\xce\xa5\xcc\x84\0" /* offset 5084 */
+  "\xce\xa5\xcc\x80\0" /* offset 5089 */
+  "\xce\xa1\xcc\x94\0" /* offset 5094 */
+  "\xc2\xa8\xcc\x80\0" /* offset 5099 */
+  "\x20\xcc\x88\xcc\x80\0" /* offset 5104 */
+  "\x60\0" /* offset 5110 */
+  "\xcf\x89\xcc\x80\xcd\x85\0" /* offset 5112 */
+  "\xcf\x89\xcd\x85\0" /* offset 5119 */
+  "\xcf\x89\xcc\x81\xcd\x85\0" /* offset 5124 */
+  "\xcf\x89\xcd\x82\0" /* offset 5131 */
+  "\xcf\x89\xcd\x82\xcd\x85\0" /* offset 5136 */
+  "\xce\x9f\xcc\x80\0" /* offset 5143 */
+  "\xce\xa9\xcc\x80\0" /* offset 5148 */
+  "\xce\xa9\xcd\x85\0" /* offset 5153 */
+  "\xc2\xb4\0" /* offset 5158 */
+  "\x20\xcc\x94\0" /* offset 5161 */
+  "\xe2\x80\x82\0" /* offset 5165 */
+  "\xe2\x80\x83\0" /* offset 5169 */
+  "\xe2\x80\x90\0" /* offset 5173 */
+  "\x20\xcc\xb3\0" /* offset 5177 */
+  "\x2e\0" /* offset 5181 */
+  "\x2e\x2e\0" /* offset 5183 */
+  "\x2e\x2e\x2e\0" /* offset 5186 */
+  "\xe2\x80\xb2\xe2\x80\xb2\0" /* offset 5190 */
+  "\xe2\x80\xb2\xe2\x80\xb2\xe2\x80\xb2\0" /* offset 5197 */
+  "\xe2\x80\xb5\xe2\x80\xb5\0" /* offset 5207 */
+  "\xe2\x80\xb5\xe2\x80\xb5\xe2\x80\xb5\0" /* offset 5214 */
+  "\x21\x21\0" /* offset 5224 */
+  "\x20\xcc\x85\0" /* offset 5227 */
+  "\x3f\x3f\0" /* offset 5231 */
+  "\x3f\x21\0" /* offset 5234 */
+  "\x21\x3f\0" /* offset 5237 */
+  "\xe2\x80\xb2\xe2\x80\xb2\xe2\x80\xb2\xe2\x80\xb2\0" /* offset 5240 */
+  "\x30\0" /* offset 5253 */
+  "\x34\0" /* offset 5255 */
+  "\x35\0" /* offset 5257 */
+  "\x36\0" /* offset 5259 */
+  "\x37\0" /* offset 5261 */
+  "\x38\0" /* offset 5263 */
+  "\x39\0" /* offset 5265 */
+  "\x2b\0" /* offset 5267 */
+  "\xe2\x88\x92\0" /* offset 5269 */
+  "\x3d\0" /* offset 5273 */
+  "\x28\0" /* offset 5275 */
+  "\x29\0" /* offset 5277 */
+  "\x6e\0" /* offset 5279 */
+  "\x52\x73\0" /* offset 5281 */
+  "\x61\x2f\x63\0" /* offset 5284 */
+  "\x61\x2f\x73\0" /* offset 5288 */
+  "\x43\0" /* offset 5292 */
+  "\xc2\xb0\x43\0" /* offset 5294 */
+  "\x63\x2f\x6f\0" /* offset 5298 */
+  "\x63\x2f\x75\0" /* offset 5302 */
+  "\xc6\x90\0" /* offset 5306 */
+  "\xc2\xb0\x46\0" /* offset 5309 */
+  "\xc4\xa7\0" /* offset 5313 */
+  "\x4e\x6f\0" /* offset 5316 */
+  "\x51\0" /* offset 5319 */
+  "\x53\x4d\0" /* offset 5321 */
+  "\x54\x45\x4c\0" /* offset 5324 */
+  "\x54\x4d\0" /* offset 5328 */
+  "\x5a\0" /* offset 5331 */
+  "\xce\xa9\0" /* offset 5333 */
+  "\x46\0" /* offset 5336 */
+  "\xd7\x90\0" /* offset 5338 */
+  "\xd7\x91\0" /* offset 5341 */
+  "\xd7\x92\0" /* offset 5344 */
+  "\xd7\x93\0" /* offset 5347 */
+  "\x46\x41\x58\0" /* offset 5350 */
+  "\xce\x93\0" /* offset 5354 */
+  "\xce\xa0\0" /* offset 5357 */
+  "\xe2\x88\x91\0" /* offset 5360 */
+  "\x31\xe2\x81\x84\x33\0" /* offset 5364 */
+  "\x32\xe2\x81\x84\x33\0" /* offset 5370 */
+  "\x31\xe2\x81\x84\x35\0" /* offset 5376 */
+  "\x32\xe2\x81\x84\x35\0" /* offset 5382 */
+  "\x33\xe2\x81\x84\x35\0" /* offset 5388 */
+  "\x34\xe2\x81\x84\x35\0" /* offset 5394 */
+  "\x31\xe2\x81\x84\x36\0" /* offset 5400 */
+  "\x35\xe2\x81\x84\x36\0" /* offset 5406 */
+  "\x31\xe2\x81\x84\x38\0" /* offset 5412 */
+  "\x33\xe2\x81\x84\x38\0" /* offset 5418 */
+  "\x35\xe2\x81\x84\x38\0" /* offset 5424 */
+  "\x37\xe2\x81\x84\x38\0" /* offset 5430 */
+  "\x31\xe2\x81\x84\0" /* offset 5436 */
+  "\x49\x49\0" /* offset 5441 */
+  "\x49\x49\x49\0" /* offset 5444 */
+  "\x49\x56\0" /* offset 5448 */
+  "\x56\0" /* offset 5451 */
+  "\x56\x49\0" /* offset 5453 */
+  "\x56\x49\x49\0" /* offset 5456 */
+  "\x56\x49\x49\x49\0" /* offset 5460 */
+  "\x49\x58\0" /* offset 5465 */
+  "\x58\0" /* offset 5468 */
+  "\x58\x49\0" /* offset 5470 */
+  "\x58\x49\x49\0" /* offset 5473 */
+  "\x69\x69\0" /* offset 5477 */
+  "\x69\x69\x69\0" /* offset 5480 */
+  "\x69\x76\0" /* offset 5484 */
+  "\x76\x69\0" /* offset 5487 */
+  "\x76\x69\x69\0" /* offset 5490 */
+  "\x76\x69\x69\x69\0" /* offset 5494 */
+  "\x69\x78\0" /* offset 5499 */
+  "\x78\x69\0" /* offset 5502 */
+  "\x78\x69\x69\0" /* offset 5505 */
+  "\xe2\x86\x90\xcc\xb8\0" /* offset 5509 */
+  "\xe2\x86\x92\xcc\xb8\0" /* offset 5515 */
+  "\xe2\x86\x94\xcc\xb8\0" /* offset 5521 */
+  "\xe2\x87\x90\xcc\xb8\0" /* offset 5527 */
+  "\xe2\x87\x94\xcc\xb8\0" /* offset 5533 */
+  "\xe2\x87\x92\xcc\xb8\0" /* offset 5539 */
+  "\xe2\x88\x83\xcc\xb8\0" /* offset 5545 */
+  "\xe2\x88\x88\xcc\xb8\0" /* offset 5551 */
+  "\xe2\x88\x8b\xcc\xb8\0" /* offset 5557 */
+  "\xe2\x88\xa3\xcc\xb8\0" /* offset 5563 */
+  "\xe2\x88\xa5\xcc\xb8\0" /* offset 5569 */
+  "\xe2\x88\xab\xe2\x88\xab\0" /* offset 5575 */
+  "\xe2\x88\xab\xe2\x88\xab\xe2\x88\xab\0" /* offset 5582 */
+  "\xe2\x88\xae\xe2\x88\xae\0" /* offset 5592 */
+  "\xe2\x88\xae\xe2\x88\xae\xe2\x88\xae\0" /* offset 5599 */
+  "\xe2\x88\xbc\xcc\xb8\0" /* offset 5609 */
+  "\xe2\x89\x83\xcc\xb8\0" /* offset 5615 */
+  "\xe2\x89\x85\xcc\xb8\0" /* offset 5621 */
+  "\xe2\x89\x88\xcc\xb8\0" /* offset 5627 */
+  "\x3d\xcc\xb8\0" /* offset 5633 */
+  "\xe2\x89\xa1\xcc\xb8\0" /* offset 5637 */
+  "\xe2\x89\x8d\xcc\xb8\0" /* offset 5643 */
+  "\x3c\xcc\xb8\0" /* offset 5649 */
+  "\x3e\xcc\xb8\0" /* offset 5653 */
+  "\xe2\x89\xa4\xcc\xb8\0" /* offset 5657 */
+  "\xe2\x89\xa5\xcc\xb8\0" /* offset 5663 */
+  "\xe2\x89\xb2\xcc\xb8\0" /* offset 5669 */
+  "\xe2\x89\xb3\xcc\xb8\0" /* offset 5675 */
+  "\xe2\x89\xb6\xcc\xb8\0" /* offset 5681 */
+  "\xe2\x89\xb7\xcc\xb8\0" /* offset 5687 */
+  "\xe2\x89\xba\xcc\xb8\0" /* offset 5693 */
+  "\xe2\x89\xbb\xcc\xb8\0" /* offset 5699 */
+  "\xe2\x8a\x82\xcc\xb8\0" /* offset 5705 */
+  "\xe2\x8a\x83\xcc\xb8\0" /* offset 5711 */
+  "\xe2\x8a\x86\xcc\xb8\0" /* offset 5717 */
+  "\xe2\x8a\x87\xcc\xb8\0" /* offset 5723 */
+  "\xe2\x8a\xa2\xcc\xb8\0" /* offset 5729 */
+  "\xe2\x8a\xa8\xcc\xb8\0" /* offset 5735 */
+  "\xe2\x8a\xa9\xcc\xb8\0" /* offset 5741 */
+  "\xe2\x8a\xab\xcc\xb8\0" /* offset 5747 */
+  "\xe2\x89\xbc\xcc\xb8\0" /* offset 5753 */
+  "\xe2\x89\xbd\xcc\xb8\0" /* offset 5759 */
+  "\xe2\x8a\x91\xcc\xb8\0" /* offset 5765 */
+  "\xe2\x8a\x92\xcc\xb8\0" /* offset 5771 */
+  "\xe2\x8a\xb2\xcc\xb8\0" /* offset 5777 */
+  "\xe2\x8a\xb3\xcc\xb8\0" /* offset 5783 */
+  "\xe2\x8a\xb4\xcc\xb8\0" /* offset 5789 */
+  "\xe2\x8a\xb5\xcc\xb8\0" /* offset 5795 */
+  "\xe3\x80\x88\0" /* offset 5801 */
+  "\xe3\x80\x89\0" /* offset 5805 */
+  "\x31\x30\0" /* offset 5809 */
+  "\x31\x31\0" /* offset 5812 */
+  "\x31\x32\0" /* offset 5815 */
+  "\x31\x33\0" /* offset 5818 */
+  "\x31\x34\0" /* offset 5821 */
+  "\x31\x35\0" /* offset 5824 */
+  "\x31\x36\0" /* offset 5827 */
+  "\x31\x37\0" /* offset 5830 */
+  "\x31\x38\0" /* offset 5833 */
+  "\x31\x39\0" /* offset 5836 */
+  "\x32\x30\0" /* offset 5839 */
+  "\x28\x31\x29\0" /* offset 5842 */
+  "\x28\x32\x29\0" /* offset 5846 */
+  "\x28\x33\x29\0" /* offset 5850 */
+  "\x28\x34\x29\0" /* offset 5854 */
+  "\x28\x35\x29\0" /* offset 5858 */
+  "\x28\x36\x29\0" /* offset 5862 */
+  "\x28\x37\x29\0" /* offset 5866 */
+  "\x28\x38\x29\0" /* offset 5870 */
+  "\x28\x39\x29\0" /* offset 5874 */
+  "\x28\x31\x30\x29\0" /* offset 5878 */
+  "\x28\x31\x31\x29\0" /* offset 5883 */
+  "\x28\x31\x32\x29\0" /* offset 5888 */
+  "\x28\x31\x33\x29\0" /* offset 5893 */
+  "\x28\x31\x34\x29\0" /* offset 5898 */
+  "\x28\x31\x35\x29\0" /* offset 5903 */
+  "\x28\x31\x36\x29\0" /* offset 5908 */
+  "\x28\x31\x37\x29\0" /* offset 5913 */
+  "\x28\x31\x38\x29\0" /* offset 5918 */
+  "\x28\x31\x39\x29\0" /* offset 5923 */
+  "\x28\x32\x30\x29\0" /* offset 5928 */
+  "\x31\x2e\0" /* offset 5933 */
+  "\x32\x2e\0" /* offset 5936 */
+  "\x33\x2e\0" /* offset 5939 */
+  "\x34\x2e\0" /* offset 5942 */
+  "\x35\x2e\0" /* offset 5945 */
+  "\x36\x2e\0" /* offset 5948 */
+  "\x37\x2e\0" /* offset 5951 */
+  "\x38\x2e\0" /* offset 5954 */
+  "\x39\x2e\0" /* offset 5957 */
+  "\x31\x30\x2e\0" /* offset 5960 */
+  "\x31\x31\x2e\0" /* offset 5964 */
+  "\x31\x32\x2e\0" /* offset 5968 */
+  "\x31\x33\x2e\0" /* offset 5972 */
+  "\x31\x34\x2e\0" /* offset 5976 */
+  "\x31\x35\x2e\0" /* offset 5980 */
+  "\x31\x36\x2e\0" /* offset 5984 */
+  "\x31\x37\x2e\0" /* offset 5988 */
+  "\x31\x38\x2e\0" /* offset 5992 */
+  "\x31\x39\x2e\0" /* offset 5996 */
+  "\x32\x30\x2e\0" /* offset 6000 */
+  "\x28\x61\x29\0" /* offset 6004 */
+  "\x28\x62\x29\0" /* offset 6008 */
+  "\x28\x63\x29\0" /* offset 6012 */
+  "\x28\x64\x29\0" /* offset 6016 */
+  "\x28\x65\x29\0" /* offset 6020 */
+  "\x28\x66\x29\0" /* offset 6024 */
+  "\x28\x67\x29\0" /* offset 6028 */
+  "\x28\x68\x29\0" /* offset 6032 */
+  "\x28\x69\x29\0" /* offset 6036 */
+  "\x28\x6a\x29\0" /* offset 6040 */
+  "\x28\x6b\x29\0" /* offset 6044 */
+  "\x28\x6c\x29\0" /* offset 6048 */
+  "\x28\x6d\x29\0" /* offset 6052 */
+  "\x28\x6e\x29\0" /* offset 6056 */
+  "\x28\x6f\x29\0" /* offset 6060 */
+  "\x28\x70\x29\0" /* offset 6064 */
+  "\x28\x71\x29\0" /* offset 6068 */
+  "\x28\x72\x29\0" /* offset 6072 */
+  "\x28\x73\x29\0" /* offset 6076 */
+  "\x28\x74\x29\0" /* offset 6080 */
+  "\x28\x75\x29\0" /* offset 6084 */
+  "\x28\x76\x29\0" /* offset 6088 */
+  "\x28\x77\x29\0" /* offset 6092 */
+  "\x28\x78\x29\0" /* offset 6096 */
+  "\x28\x79\x29\0" /* offset 6100 */
+  "\x28\x7a\x29\0" /* offset 6104 */
+  "\x53\0" /* offset 6108 */
+  "\x59\0" /* offset 6110 */
+  "\x71\0" /* offset 6112 */
+  "\xe2\x88\xab\xe2\x88\xab\xe2\x88\xab\xe2\x88\xab\0" /* offset 6114 */
+  "\x3a\x3a\x3d\0" /* offset 6127 */
+  "\x3d\x3d\0" /* offset 6131 */
+  "\x3d\x3d\x3d\0" /* offset 6134 */
+  "\xe2\xab\x9d\xcc\xb8\0" /* offset 6138 */
+  "\xe2\xb5\xa1\0" /* offset 6144 */
+  "\xe6\xaf\x8d\0" /* offset 6148 */
+  "\xe9\xbe\x9f\0" /* offset 6152 */
+  "\xe4\xb8\x80\0" /* offset 6156 */
+  "\xe4\xb8\xa8\0" /* offset 6160 */
+  "\xe4\xb8\xb6\0" /* offset 6164 */
+  "\xe4\xb8\xbf\0" /* offset 6168 */
+  "\xe4\xb9\x99\0" /* offset 6172 */
+  "\xe4\xba\x85\0" /* offset 6176 */
+  "\xe4\xba\x8c\0" /* offset 6180 */
+  "\xe4\xba\xa0\0" /* offset 6184 */
+  "\xe4\xba\xba\0" /* offset 6188 */
+  "\xe5\x84\xbf\0" /* offset 6192 */
+  "\xe5\x85\xa5\0" /* offset 6196 */
+  "\xe5\x85\xab\0" /* offset 6200 */
+  "\xe5\x86\x82\0" /* offset 6204 */
+  "\xe5\x86\x96\0" /* offset 6208 */
+  "\xe5\x86\xab\0" /* offset 6212 */
+  "\xe5\x87\xa0\0" /* offset 6216 */
+  "\xe5\x87\xb5\0" /* offset 6220 */
+  "\xe5\x88\x80\0" /* offset 6224 */
+  "\xe5\x8a\x9b\0" /* offset 6228 */
+  "\xe5\x8b\xb9\0" /* offset 6232 */
+  "\xe5\x8c\x95\0" /* offset 6236 */
+  "\xe5\x8c\x9a\0" /* offset 6240 */
+  "\xe5\x8c\xb8\0" /* offset 6244 */
+  "\xe5\x8d\x81\0" /* offset 6248 */
+  "\xe5\x8d\x9c\0" /* offset 6252 */
+  "\xe5\x8d\xa9\0" /* offset 6256 */
+  "\xe5\x8e\x82\0" /* offset 6260 */
+  "\xe5\x8e\xb6\0" /* offset 6264 */
+  "\xe5\x8f\x88\0" /* offset 6268 */
+  "\xe5\x8f\xa3\0" /* offset 6272 */
+  "\xe5\x9b\x97\0" /* offset 6276 */
+  "\xe5\x9c\x9f\0" /* offset 6280 */
+  "\xe5\xa3\xab\0" /* offset 6284 */
+  "\xe5\xa4\x82\0" /* offset 6288 */
+  "\xe5\xa4\x8a\0" /* offset 6292 */
+  "\xe5\xa4\x95\0" /* offset 6296 */
+  "\xe5\xa4\xa7\0" /* offset 6300 */
+  "\xe5\xa5\xb3\0" /* offset 6304 */
+  "\xe5\xad\x90\0" /* offset 6308 */
+  "\xe5\xae\x80\0" /* offset 6312 */
+  "\xe5\xaf\xb8\0" /* offset 6316 */
+  "\xe5\xb0\x8f\0" /* offset 6320 */
+  "\xe5\xb0\xa2\0" /* offset 6324 */
+  "\xe5\xb0\xb8\0" /* offset 6328 */
+  "\xe5\xb1\xae\0" /* offset 6332 */
+  "\xe5\xb1\xb1\0" /* offset 6336 */
+  "\xe5\xb7\x9b\0" /* offset 6340 */
+  "\xe5\xb7\xa5\0" /* offset 6344 */
+  "\xe5\xb7\xb1\0" /* offset 6348 */
+  "\xe5\xb7\xbe\0" /* offset 6352 */
+  "\xe5\xb9\xb2\0" /* offset 6356 */
+  "\xe5\xb9\xba\0" /* offset 6360 */
+  "\xe5\xb9\xbf\0" /* offset 6364 */
+  "\xe5\xbb\xb4\0" /* offset 6368 */
+  "\xe5\xbb\xbe\0" /* offset 6372 */
+  "\xe5\xbc\x8b\0" /* offset 6376 */
+  "\xe5\xbc\x93\0" /* offset 6380 */
+  "\xe5\xbd\x90\0" /* offset 6384 */
+  "\xe5\xbd\xa1\0" /* offset 6388 */
+  "\xe5\xbd\xb3\0" /* offset 6392 */
+  "\xe5\xbf\x83\0" /* offset 6396 */
+  "\xe6\x88\x88\0" /* offset 6400 */
+  "\xe6\x88\xb6\0" /* offset 6404 */
+  "\xe6\x89\x8b\0" /* offset 6408 */
+  "\xe6\x94\xaf\0" /* offset 6412 */
+  "\xe6\x94\xb4\0" /* offset 6416 */
+  "\xe6\x96\x87\0" /* offset 6420 */
+  "\xe6\x96\x97\0" /* offset 6424 */
+  "\xe6\x96\xa4\0" /* offset 6428 */
+  "\xe6\x96\xb9\0" /* offset 6432 */
+  "\xe6\x97\xa0\0" /* offset 6436 */
+  "\xe6\x97\xa5\0" /* offset 6440 */
+  "\xe6\x9b\xb0\0" /* offset 6444 */
+  "\xe6\x9c\x88\0" /* offset 6448 */
+  "\xe6\x9c\xa8\0" /* offset 6452 */
+  "\xe6\xac\xa0\0" /* offset 6456 */
+  "\xe6\xad\xa2\0" /* offset 6460 */
+  "\xe6\xad\xb9\0" /* offset 6464 */
+  "\xe6\xae\xb3\0" /* offset 6468 */
+  "\xe6\xaf\x8b\0" /* offset 6472 */
+  "\xe6\xaf\x94\0" /* offset 6476 */
+  "\xe6\xaf\x9b\0" /* offset 6480 */
+  "\xe6\xb0\x8f\0" /* offset 6484 */
+  "\xe6\xb0\x94\0" /* offset 6488 */
+  "\xe6\xb0\xb4\0" /* offset 6492 */
+  "\xe7\x81\xab\0" /* offset 6496 */
+  "\xe7\x88\xaa\0" /* offset 6500 */
+  "\xe7\x88\xb6\0" /* offset 6504 */
+  "\xe7\x88\xbb\0" /* offset 6508 */
+  "\xe7\x88\xbf\0" /* offset 6512 */
+  "\xe7\x89\x87\0" /* offset 6516 */
+  "\xe7\x89\x99\0" /* offset 6520 */
+  "\xe7\x89\x9b\0" /* offset 6524 */
+  "\xe7\x8a\xac\0" /* offset 6528 */
+  "\xe7\x8e\x84\0" /* offset 6532 */
+  "\xe7\x8e\x89\0" /* offset 6536 */
+  "\xe7\x93\x9c\0" /* offset 6540 */
+  "\xe7\x93\xa6\0" /* offset 6544 */
+  "\xe7\x94\x98\0" /* offset 6548 */
+  "\xe7\x94\x9f\0" /* offset 6552 */
+  "\xe7\x94\xa8\0" /* offset 6556 */
+  "\xe7\x94\xb0\0" /* offset 6560 */
+  "\xe7\x96\x8b\0" /* offset 6564 */
+  "\xe7\x96\x92\0" /* offset 6568 */
+  "\xe7\x99\xb6\0" /* offset 6572 */
+  "\xe7\x99\xbd\0" /* offset 6576 */
+  "\xe7\x9a\xae\0" /* offset 6580 */
+  "\xe7\x9a\xbf\0" /* offset 6584 */
+  "\xe7\x9b\xae\0" /* offset 6588 */
+  "\xe7\x9f\x9b\0" /* offset 6592 */
+  "\xe7\x9f\xa2\0" /* offset 6596 */
+  "\xe7\x9f\xb3\0" /* offset 6600 */
+  "\xe7\xa4\xba\0" /* offset 6604 */
+  "\xe7\xa6\xb8\0" /* offset 6608 */
+  "\xe7\xa6\xbe\0" /* offset 6612 */
+  "\xe7\xa9\xb4\0" /* offset 6616 */
+  "\xe7\xab\x8b\0" /* offset 6620 */
+  "\xe7\xab\xb9\0" /* offset 6624 */
+  "\xe7\xb1\xb3\0" /* offset 6628 */
+  "\xe7\xb3\xb8\0" /* offset 6632 */
+  "\xe7\xbc\xb6\0" /* offset 6636 */
+  "\xe7\xbd\x91\0" /* offset 6640 */
+  "\xe7\xbe\x8a\0" /* offset 6644 */
+  "\xe7\xbe\xbd\0" /* offset 6648 */
+  "\xe8\x80\x81\0" /* offset 6652 */
+  "\xe8\x80\x8c\0" /* offset 6656 */
+  "\xe8\x80\x92\0" /* offset 6660 */
+  "\xe8\x80\xb3\0" /* offset 6664 */
+  "\xe8\x81\xbf\0" /* offset 6668 */
+  "\xe8\x82\x89\0" /* offset 6672 */
+  "\xe8\x87\xa3\0" /* offset 6676 */
+  "\xe8\x87\xaa\0" /* offset 6680 */
+  "\xe8\x87\xb3\0" /* offset 6684 */
+  "\xe8\x87\xbc\0" /* offset 6688 */
+  "\xe8\x88\x8c\0" /* offset 6692 */
+  "\xe8\x88\x9b\0" /* offset 6696 */
+  "\xe8\x88\x9f\0" /* offset 6700 */
+  "\xe8\x89\xae\0" /* offset 6704 */
+  "\xe8\x89\xb2\0" /* offset 6708 */
+  "\xe8\x89\xb8\0" /* offset 6712 */
+  "\xe8\x99\x8d\0" /* offset 6716 */
+  "\xe8\x99\xab\0" /* offset 6720 */
+  "\xe8\xa1\x80\0" /* offset 6724 */
+  "\xe8\xa1\x8c\0" /* offset 6728 */
+  "\xe8\xa1\xa3\0" /* offset 6732 */
+  "\xe8\xa5\xbe\0" /* offset 6736 */
+  "\xe8\xa6\x8b\0" /* offset 6740 */
+  "\xe8\xa7\x92\0" /* offset 6744 */
+  "\xe8\xa8\x80\0" /* offset 6748 */
+  "\xe8\xb0\xb7\0" /* offset 6752 */
+  "\xe8\xb1\x86\0" /* offset 6756 */
+  "\xe8\xb1\x95\0" /* offset 6760 */
+  "\xe8\xb1\xb8\0" /* offset 6764 */
+  "\xe8\xb2\x9d\0" /* offset 6768 */
+  "\xe8\xb5\xa4\0" /* offset 6772 */
+  "\xe8\xb5\xb0\0" /* offset 6776 */
+  "\xe8\xb6\xb3\0" /* offset 6780 */
+  "\xe8\xba\xab\0" /* offset 6784 */
+  "\xe8\xbb\x8a\0" /* offset 6788 */
+  "\xe8\xbe\x9b\0" /* offset 6792 */
+  "\xe8\xbe\xb0\0" /* offset 6796 */
+  "\xe8\xbe\xb5\0" /* offset 6800 */
+  "\xe9\x82\x91\0" /* offset 6804 */
+  "\xe9\x85\x89\0" /* offset 6808 */
+  "\xe9\x87\x86\0" /* offset 6812 */
+  "\xe9\x87\x8c\0" /* offset 6816 */
+  "\xe9\x87\x91\0" /* offset 6820 */
+  "\xe9\x95\xb7\0" /* offset 6824 */
+  "\xe9\x96\x80\0" /* offset 6828 */
+  "\xe9\x98\x9c\0" /* offset 6832 */
+  "\xe9\x9a\xb6\0" /* offset 6836 */
+  "\xe9\x9a\xb9\0" /* offset 6840 */
+  "\xe9\x9b\xa8\0" /* offset 6844 */
+  "\xe9\x9d\x91\0" /* offset 6848 */
+  "\xe9\x9d\x9e\0" /* offset 6852 */
+  "\xe9\x9d\xa2\0" /* offset 6856 */
+  "\xe9\x9d\xa9\0" /* offset 6860 */
+  "\xe9\x9f\x8b\0" /* offset 6864 */
+  "\xe9\x9f\xad\0" /* offset 6868 */
+  "\xe9\x9f\xb3\0" /* offset 6872 */
+  "\xe9\xa0\x81\0" /* offset 6876 */
+  "\xe9\xa2\xa8\0" /* offset 6880 */
+  "\xe9\xa3\x9b\0" /* offset 6884 */
+  "\xe9\xa3\x9f\0" /* offset 6888 */
+  "\xe9\xa6\x96\0" /* offset 6892 */
+  "\xe9\xa6\x99\0" /* offset 6896 */
+  "\xe9\xa6\xac\0" /* offset 6900 */
+  "\xe9\xaa\xa8\0" /* offset 6904 */
+  "\xe9\xab\x98\0" /* offset 6908 */
+  "\xe9\xab\x9f\0" /* offset 6912 */
+  "\xe9\xac\xa5\0" /* offset 6916 */
+  "\xe9\xac\xaf\0" /* offset 6920 */
+  "\xe9\xac\xb2\0" /* offset 6924 */
+  "\xe9\xac\xbc\0" /* offset 6928 */
+  "\xe9\xad\x9a\0" /* offset 6932 */
+  "\xe9\xb3\xa5\0" /* offset 6936 */
+  "\xe9\xb9\xb5\0" /* offset 6940 */
+  "\xe9\xb9\xbf\0" /* offset 6944 */
+  "\xe9\xba\xa5\0" /* offset 6948 */
+  "\xe9\xba\xbb\0" /* offset 6952 */
+  "\xe9\xbb\x83\0" /* offset 6956 */
+  "\xe9\xbb\x8d\0" /* offset 6960 */
+  "\xe9\xbb\x91\0" /* offset 6964 */
+  "\xe9\xbb\xb9\0" /* offset 6968 */
+  "\xe9\xbb\xbd\0" /* offset 6972 */
+  "\xe9\xbc\x8e\0" /* offset 6976 */
+  "\xe9\xbc\x93\0" /* offset 6980 */
+  "\xe9\xbc\xa0\0" /* offset 6984 */
+  "\xe9\xbc\xbb\0" /* offset 6988 */
+  "\xe9\xbd\x8a\0" /* offset 6992 */
+  "\xe9\xbd\x92\0" /* offset 6996 */
+  "\xe9\xbe\x8d\0" /* offset 7000 */
+  "\xe9\xbe\x9c\0" /* offset 7004 */
+  "\xe9\xbe\xa0\0" /* offset 7008 */
+  "\xe3\x80\x92\0" /* offset 7012 */
+  "\xe5\x8d\x84\0" /* offset 7016 */
+  "\xe5\x8d\x85\0" /* offset 7020 */
+  "\xe3\x81\x8b\xe3\x82\x99\0" /* offset 7024 */
+  "\xe3\x81\x8d\xe3\x82\x99\0" /* offset 7031 */
+  "\xe3\x81\x8f\xe3\x82\x99\0" /* offset 7038 */
+  "\xe3\x81\x91\xe3\x82\x99\0" /* offset 7045 */
+  "\xe3\x81\x93\xe3\x82\x99\0" /* offset 7052 */
+  "\xe3\x81\x95\xe3\x82\x99\0" /* offset 7059 */
+  "\xe3\x81\x97\xe3\x82\x99\0" /* offset 7066 */
+  "\xe3\x81\x99\xe3\x82\x99\0" /* offset 7073 */
+  "\xe3\x81\x9b\xe3\x82\x99\0" /* offset 7080 */
+  "\xe3\x81\x9d\xe3\x82\x99\0" /* offset 7087 */
+  "\xe3\x81\x9f\xe3\x82\x99\0" /* offset 7094 */
+  "\xe3\x81\xa1\xe3\x82\x99\0" /* offset 7101 */
+  "\xe3\x81\xa4\xe3\x82\x99\0" /* offset 7108 */
+  "\xe3\x81\xa6\xe3\x82\x99\0" /* offset 7115 */
+  "\xe3\x81\xa8\xe3\x82\x99\0" /* offset 7122 */
+  "\xe3\x81\xaf\xe3\x82\x99\0" /* offset 7129 */
+  "\xe3\x81\xaf\xe3\x82\x9a\0" /* offset 7136 */
+  "\xe3\x81\xb2\xe3\x82\x99\0" /* offset 7143 */
+  "\xe3\x81\xb2\xe3\x82\x9a\0" /* offset 7150 */
+  "\xe3\x81\xb5\xe3\x82\x99\0" /* offset 7157 */
+  "\xe3\x81\xb5\xe3\x82\x9a\0" /* offset 7164 */
+  "\xe3\x81\xb8\xe3\x82\x99\0" /* offset 7171 */
+  "\xe3\x81\xb8\xe3\x82\x9a\0" /* offset 7178 */
+  "\xe3\x81\xbb\xe3\x82\x99\0" /* offset 7185 */
+  "\xe3\x81\xbb\xe3\x82\x9a\0" /* offset 7192 */
+  "\xe3\x81\x86\xe3\x82\x99\0" /* offset 7199 */
+  "\x20\xe3\x82\x99\0" /* offset 7206 */
+  "\x20\xe3\x82\x9a\0" /* offset 7211 */
+  "\xe3\x82\x9d\xe3\x82\x99\0" /* offset 7216 */
+  "\xe3\x82\x88\xe3\x82\x8a\0" /* offset 7223 */
+  "\xe3\x82\xab\xe3\x82\x99\0" /* offset 7230 */
+  "\xe3\x82\xad\xe3\x82\x99\0" /* offset 7237 */
+  "\xe3\x82\xaf\xe3\x82\x99\0" /* offset 7244 */
+  "\xe3\x82\xb1\xe3\x82\x99\0" /* offset 7251 */
+  "\xe3\x82\xb3\xe3\x82\x99\0" /* offset 7258 */
+  "\xe3\x82\xb5\xe3\x82\x99\0" /* offset 7265 */
+  "\xe3\x82\xb7\xe3\x82\x99\0" /* offset 7272 */
+  "\xe3\x82\xb9\xe3\x82\x99\0" /* offset 7279 */
+  "\xe3\x82\xbb\xe3\x82\x99\0" /* offset 7286 */
+  "\xe3\x82\xbd\xe3\x82\x99\0" /* offset 7293 */
+  "\xe3\x82\xbf\xe3\x82\x99\0" /* offset 7300 */
+  "\xe3\x83\x81\xe3\x82\x99\0" /* offset 7307 */
+  "\xe3\x83\x84\xe3\x82\x99\0" /* offset 7314 */
+  "\xe3\x83\x86\xe3\x82\x99\0" /* offset 7321 */
+  "\xe3\x83\x88\xe3\x82\x99\0" /* offset 7328 */
+  "\xe3\x83\x8f\xe3\x82\x99\0" /* offset 7335 */
+  "\xe3\x83\x8f\xe3\x82\x9a\0" /* offset 7342 */
+  "\xe3\x83\x92\xe3\x82\x99\0" /* offset 7349 */
+  "\xe3\x83\x92\xe3\x82\x9a\0" /* offset 7356 */
+  "\xe3\x83\x95\xe3\x82\x99\0" /* offset 7363 */
+  "\xe3\x83\x95\xe3\x82\x9a\0" /* offset 7370 */
+  "\xe3\x83\x98\xe3\x82\x99\0" /* offset 7377 */
+  "\xe3\x83\x98\xe3\x82\x9a\0" /* offset 7384 */
+  "\xe3\x83\x9b\xe3\x82\x99\0" /* offset 7391 */
+  "\xe3\x83\x9b\xe3\x82\x9a\0" /* offset 7398 */
+  "\xe3\x82\xa6\xe3\x82\x99\0" /* offset 7405 */
+  "\xe3\x83\xaf\xe3\x82\x99\0" /* offset 7412 */
+  "\xe3\x83\xb0\xe3\x82\x99\0" /* offset 7419 */
+  "\xe3\x83\xb1\xe3\x82\x99\0" /* offset 7426 */
+  "\xe3\x83\xb2\xe3\x82\x99\0" /* offset 7433 */
+  "\xe3\x83\xbd\xe3\x82\x99\0" /* offset 7440 */
+  "\xe3\x82\xb3\xe3\x83\x88\0" /* offset 7447 */
+  "\xe1\x84\x80\0" /* offset 7454 */
+  "\xe1\x84\x81\0" /* offset 7458 */
+  "\xe1\x86\xaa\0" /* offset 7462 */
+  "\xe1\x84\x82\0" /* offset 7466 */
+  "\xe1\x86\xac\0" /* offset 7470 */
+  "\xe1\x86\xad\0" /* offset 7474 */
+  "\xe1\x84\x83\0" /* offset 7478 */
+  "\xe1\x84\x84\0" /* offset 7482 */
+  "\xe1\x84\x85\0" /* offset 7486 */
+  "\xe1\x86\xb0\0" /* offset 7490 */
+  "\xe1\x86\xb1\0" /* offset 7494 */
+  "\xe1\x86\xb2\0" /* offset 7498 */
+  "\xe1\x86\xb3\0" /* offset 7502 */
+  "\xe1\x86\xb4\0" /* offset 7506 */
+  "\xe1\x86\xb5\0" /* offset 7510 */
+  "\xe1\x84\x9a\0" /* offset 7514 */
+  "\xe1\x84\x86\0" /* offset 7518 */
+  "\xe1\x84\x87\0" /* offset 7522 */
+  "\xe1\x84\x88\0" /* offset 7526 */
+  "\xe1\x84\xa1\0" /* offset 7530 */
+  "\xe1\x84\x89\0" /* offset 7534 */
+  "\xe1\x84\x8a\0" /* offset 7538 */
+  "\xe1\x84\x8b\0" /* offset 7542 */
+  "\xe1\x84\x8c\0" /* offset 7546 */
+  "\xe1\x84\x8d\0" /* offset 7550 */
+  "\xe1\x84\x8e\0" /* offset 7554 */
+  "\xe1\x84\x8f\0" /* offset 7558 */
+  "\xe1\x84\x90\0" /* offset 7562 */
+  "\xe1\x84\x91\0" /* offset 7566 */
+  "\xe1\x84\x92\0" /* offset 7570 */
+  "\xe1\x85\xa1\0" /* offset 7574 */
+  "\xe1\x85\xa2\0" /* offset 7578 */
+  "\xe1\x85\xa3\0" /* offset 7582 */
+  "\xe1\x85\xa4\0" /* offset 7586 */
+  "\xe1\x85\xa5\0" /* offset 7590 */
+  "\xe1\x85\xa6\0" /* offset 7594 */
+  "\xe1\x85\xa7\0" /* offset 7598 */
+  "\xe1\x85\xa8\0" /* offset 7602 */
+  "\xe1\x85\xa9\0" /* offset 7606 */
+  "\xe1\x85\xaa\0" /* offset 7610 */
+  "\xe1\x85\xab\0" /* offset 7614 */
+  "\xe1\x85\xac\0" /* offset 7618 */
+  "\xe1\x85\xad\0" /* offset 7622 */
+  "\xe1\x85\xae\0" /* offset 7626 */
+  "\xe1\x85\xaf\0" /* offset 7630 */
+  "\xe1\x85\xb0\0" /* offset 7634 */
+  "\xe1\x85\xb1\0" /* offset 7638 */
+  "\xe1\x85\xb2\0" /* offset 7642 */
+  "\xe1\x85\xb3\0" /* offset 7646 */
+  "\xe1\x85\xb4\0" /* offset 7650 */
+  "\xe1\x85\xb5\0" /* offset 7654 */
+  "\xe1\x85\xa0\0" /* offset 7658 */
+  "\xe1\x84\x94\0" /* offset 7662 */
+  "\xe1\x84\x95\0" /* offset 7666 */
+  "\xe1\x87\x87\0" /* offset 7670 */
+  "\xe1\x87\x88\0" /* offset 7674 */
+  "\xe1\x87\x8c\0" /* offset 7678 */
+  "\xe1\x87\x8e\0" /* offset 7682 */
+  "\xe1\x87\x93\0" /* offset 7686 */
+  "\xe1\x87\x97\0" /* offset 7690 */
+  "\xe1\x87\x99\0" /* offset 7694 */
+  "\xe1\x84\x9c\0" /* offset 7698 */
+  "\xe1\x87\x9d\0" /* offset 7702 */
+  "\xe1\x87\x9f\0" /* offset 7706 */
+  "\xe1\x84\x9d\0" /* offset 7710 */
+  "\xe1\x84\x9e\0" /* offset 7714 */
+  "\xe1\x84\xa0\0" /* offset 7718 */
+  "\xe1\x84\xa2\0" /* offset 7722 */
+  "\xe1\x84\xa3\0" /* offset 7726 */
+  "\xe1\x84\xa7\0" /* offset 7730 */
+  "\xe1\x84\xa9\0" /* offset 7734 */
+  "\xe1\x84\xab\0" /* offset 7738 */
+  "\xe1\x84\xac\0" /* offset 7742 */
+  "\xe1\x84\xad\0" /* offset 7746 */
+  "\xe1\x84\xae\0" /* offset 7750 */
+  "\xe1\x84\xaf\0" /* offset 7754 */
+  "\xe1\x84\xb2\0" /* offset 7758 */
+  "\xe1\x84\xb6\0" /* offset 7762 */
+  "\xe1\x85\x80\0" /* offset 7766 */
+  "\xe1\x85\x87\0" /* offset 7770 */
+  "\xe1\x85\x8c\0" /* offset 7774 */
+  "\xe1\x87\xb1\0" /* offset 7778 */
+  "\xe1\x87\xb2\0" /* offset 7782 */
+  "\xe1\x85\x97\0" /* offset 7786 */
+  "\xe1\x85\x98\0" /* offset 7790 */
+  "\xe1\x85\x99\0" /* offset 7794 */
+  "\xe1\x86\x84\0" /* offset 7798 */
+  "\xe1\x86\x85\0" /* offset 7802 */
+  "\xe1\x86\x88\0" /* offset 7806 */
+  "\xe1\x86\x91\0" /* offset 7810 */
+  "\xe1\x86\x92\0" /* offset 7814 */
+  "\xe1\x86\x94\0" /* offset 7818 */
+  "\xe1\x86\x9e\0" /* offset 7822 */
+  "\xe1\x86\xa1\0" /* offset 7826 */
+  "\xe4\xb8\x89\0" /* offset 7830 */
+  "\xe5\x9b\x9b\0" /* offset 7834 */
+  "\xe4\xb8\x8a\0" /* offset 7838 */
+  "\xe4\xb8\xad\0" /* offset 7842 */
+  "\xe4\xb8\x8b\0" /* offset 7846 */
+  "\xe7\x94\xb2\0" /* offset 7850 */
+  "\xe4\xb8\x99\0" /* offset 7854 */
+  "\xe4\xb8\x81\0" /* offset 7858 */
+  "\xe5\xa4\xa9\0" /* offset 7862 */
+  "\xe5\x9c\xb0\0" /* offset 7866 */
+  "\x28\xe1\x84\x80\x29\0" /* offset 7870 */
+  "\x28\xe1\x84\x82\x29\0" /* offset 7876 */
+  "\x28\xe1\x84\x83\x29\0" /* offset 7882 */
+  "\x28\xe1\x84\x85\x29\0" /* offset 7888 */
+  "\x28\xe1\x84\x86\x29\0" /* offset 7894 */
+  "\x28\xe1\x84\x87\x29\0" /* offset 7900 */
+  "\x28\xe1\x84\x89\x29\0" /* offset 7906 */
+  "\x28\xe1\x84\x8b\x29\0" /* offset 7912 */
+  "\x28\xe1\x84\x8c\x29\0" /* offset 7918 */
+  "\x28\xe1\x84\x8e\x29\0" /* offset 7924 */
+  "\x28\xe1\x84\x8f\x29\0" /* offset 7930 */
+  "\x28\xe1\x84\x90\x29\0" /* offset 7936 */
+  "\x28\xe1\x84\x91\x29\0" /* offset 7942 */
+  "\x28\xe1\x84\x92\x29\0" /* offset 7948 */
+  "\x28\xe1\x84\x80\xe1\x85\xa1\x29\0" /* offset 7954 */
+  "\x28\xe1\x84\x82\xe1\x85\xa1\x29\0" /* offset 7963 */
+  "\x28\xe1\x84\x83\xe1\x85\xa1\x29\0" /* offset 7972 */
+  "\x28\xe1\x84\x85\xe1\x85\xa1\x29\0" /* offset 7981 */
+  "\x28\xe1\x84\x86\xe1\x85\xa1\x29\0" /* offset 7990 */
+  "\x28\xe1\x84\x87\xe1\x85\xa1\x29\0" /* offset 7999 */
+  "\x28\xe1\x84\x89\xe1\x85\xa1\x29\0" /* offset 8008 */
+  "\x28\xe1\x84\x8b\xe1\x85\xa1\x29\0" /* offset 8017 */
+  "\x28\xe1\x84\x8c\xe1\x85\xa1\x29\0" /* offset 8026 */
+  "\x28\xe1\x84\x8e\xe1\x85\xa1\x29\0" /* offset 8035 */
+  "\x28\xe1\x84\x8f\xe1\x85\xa1\x29\0" /* offset 8044 */
+  "\x28\xe1\x84\x90\xe1\x85\xa1\x29\0" /* offset 8053 */
+  "\x28\xe1\x84\x91\xe1\x85\xa1\x29\0" /* offset 8062 */
+  "\x28\xe1\x84\x92\xe1\x85\xa1\x29\0" /* offset 8071 */
+  "\x28\xe1\x84\x8c\xe1\x85\xae\x29\0" /* offset 8080 */
+  "\x28\xe1\x84\x8b\xe1\x85\xa9\xe1\x84\x8c\xe1\x85\xa5\xe1\x86\xab\x29\0" /* offset 8089 */
+  "\x28\xe1\x84\x8b\xe1\x85\xa9\xe1\x84\x92\xe1\x85\xae\x29\0" /* offset 8107 */
+  "\x28\xe4\xb8\x80\x29\0" /* offset 8122 */
+  "\x28\xe4\xba\x8c\x29\0" /* offset 8128 */
+  "\x28\xe4\xb8\x89\x29\0" /* offset 8134 */
+  "\x28\xe5\x9b\x9b\x29\0" /* offset 8140 */
+  "\x28\xe4\xba\x94\x29\0" /* offset 8146 */
+  "\x28\xe5\x85\xad\x29\0" /* offset 8152 */
+  "\x28\xe4\xb8\x83\x29\0" /* offset 8158 */
+  "\x28\xe5\x85\xab\x29\0" /* offset 8164 */
+  "\x28\xe4\xb9\x9d\x29\0" /* offset 8170 */
+  "\x28\xe5\x8d\x81\x29\0" /* offset 8176 */
+  "\x28\xe6\x9c\x88\x29\0" /* offset 8182 */
+  "\x28\xe7\x81\xab\x29\0" /* offset 8188 */
+  "\x28\xe6\xb0\xb4\x29\0" /* offset 8194 */
+  "\x28\xe6\x9c\xa8\x29\0" /* offset 8200 */
+  "\x28\xe9\x87\x91\x29\0" /* offset 8206 */
+  "\x28\xe5\x9c\x9f\x29\0" /* offset 8212 */
+  "\x28\xe6\x97\xa5\x29\0" /* offset 8218 */
+  "\x28\xe6\xa0\xaa\x29\0" /* offset 8224 */
+  "\x28\xe6\x9c\x89\x29\0" /* offset 8230 */
+  "\x28\xe7\xa4\xbe\x29\0" /* offset 8236 */
+  "\x28\xe5\x90\x8d\x29\0" /* offset 8242 */
+  "\x28\xe7\x89\xb9\x29\0" /* offset 8248 */
+  "\x28\xe8\xb2\xa1\x29\0" /* offset 8254 */
+  "\x28\xe7\xa5\x9d\x29\0" /* offset 8260 */
+  "\x28\xe5\x8a\xb4\x29\0" /* offset 8266 */
+  "\x28\xe4\xbb\xa3\x29\0" /* offset 8272 */
+  "\x28\xe5\x91\xbc\x29\0" /* offset 8278 */
+  "\x28\xe5\xad\xa6\x29\0" /* offset 8284 */
+  "\x28\xe7\x9b\xa3\x29\0" /* offset 8290 */
+  "\x28\xe4\xbc\x81\x29\0" /* offset 8296 */
+  "\x28\xe8\xb3\x87\x29\0" /* offset 8302 */
+  "\x28\xe5\x8d\x94\x29\0" /* offset 8308 */
+  "\x28\xe7\xa5\xad\x29\0" /* offset 8314 */
+  "\x28\xe4\xbc\x91\x29\0" /* offset 8320 */
+  "\x28\xe8\x87\xaa\x29\0" /* offset 8326 */
+  "\x28\xe8\x87\xb3\x29\0" /* offset 8332 */
+  "\x50\x54\x45\0" /* offset 8338 */
+  "\x32\x31\0" /* offset 8342 */
+  "\x32\x32\0" /* offset 8345 */
+  "\x32\x33\0" /* offset 8348 */
+  "\x32\x34\0" /* offset 8351 */
+  "\x32\x35\0" /* offset 8354 */
+  "\x32\x36\0" /* offset 8357 */
+  "\x32\x37\0" /* offset 8360 */
+  "\x32\x38\0" /* offset 8363 */
+  "\x32\x39\0" /* offset 8366 */
+  "\x33\x30\0" /* offset 8369 */
+  "\x33\x31\0" /* offset 8372 */
+  "\x33\x32\0" /* offset 8375 */
+  "\x33\x33\0" /* offset 8378 */
+  "\x33\x34\0" /* offset 8381 */
+  "\x33\x35\0" /* offset 8384 */
+  "\xe1\x84\x80\xe1\x85\xa1\0" /* offset 8387 */
+  "\xe1\x84\x82\xe1\x85\xa1\0" /* offset 8394 */
+  "\xe1\x84\x83\xe1\x85\xa1\0" /* offset 8401 */
+  "\xe1\x84\x85\xe1\x85\xa1\0" /* offset 8408 */
+  "\xe1\x84\x86\xe1\x85\xa1\0" /* offset 8415 */
+  "\xe1\x84\x87\xe1\x85\xa1\0" /* offset 8422 */
+  "\xe1\x84\x89\xe1\x85\xa1\0" /* offset 8429 */
+  "\xe1\x84\x8b\xe1\x85\xa1\0" /* offset 8436 */
+  "\xe1\x84\x8c\xe1\x85\xa1\0" /* offset 8443 */
+  "\xe1\x84\x8e\xe1\x85\xa1\0" /* offset 8450 */
+  "\xe1\x84\x8f\xe1\x85\xa1\0" /* offset 8457 */
+  "\xe1\x84\x90\xe1\x85\xa1\0" /* offset 8464 */
+  "\xe1\x84\x91\xe1\x85\xa1\0" /* offset 8471 */
+  "\xe1\x84\x92\xe1\x85\xa1\0" /* offset 8478 */
+  "\xe1\x84\x8e\xe1\x85\xa1\xe1\x86\xb7\xe1\x84\x80\xe1\x85\xa9\0" /* offset 8485 */
+  "\xe1\x84\x8c\xe1\x85\xae\xe1\x84\x8b\xe1\x85\xb4\0" /* offset 8501 */
+  "\xe1\x84\x8b\xe1\x85\xae\0" /* offset 8514 */
+  "\xe4\xba\x94\0" /* offset 8521 */
+  "\xe5\x85\xad\0" /* offset 8525 */
+  "\xe4\xb8\x83\0" /* offset 8529 */
+  "\xe4\xb9\x9d\0" /* offset 8533 */
+  "\xe6\xa0\xaa\0" /* offset 8537 */
+  "\xe6\x9c\x89\0" /* offset 8541 */
+  "\xe7\xa4\xbe\0" /* offset 8545 */
+  "\xe5\x90\x8d\0" /* offset 8549 */
+  "\xe7\x89\xb9\0" /* offset 8553 */
+  "\xe8\xb2\xa1\0" /* offset 8557 */
+  "\xe7\xa5\x9d\0" /* offset 8561 */
+  "\xe5\x8a\xb4\0" /* offset 8565 */
+  "\xe7\xa7\x98\0" /* offset 8569 */
+  "\xe7\x94\xb7\0" /* offset 8573 */
+  "\xe9\x81\xa9\0" /* offset 8577 */
+  "\xe5\x84\xaa\0" /* offset 8581 */
+  "\xe5\x8d\xb0\0" /* offset 8585 */
+  "\xe6\xb3\xa8\0" /* offset 8589 */
+  "\xe9\xa0\x85\0" /* offset 8593 */
+  "\xe4\xbc\x91\0" /* offset 8597 */
+  "\xe5\x86\x99\0" /* offset 8601 */
+  "\xe6\xad\xa3\0" /* offset 8605 */
+  "\xe5\xb7\xa6\0" /* offset 8609 */
+  "\xe5\x8f\xb3\0" /* offset 8613 */
+  "\xe5\x8c\xbb\0" /* offset 8617 */
+  "\xe5\xae\x97\0" /* offset 8621 */
+  "\xe5\xad\xa6\0" /* offset 8625 */
+  "\xe7\x9b\xa3\0" /* offset 8629 */
+  "\xe4\xbc\x81\0" /* offset 8633 */
+  "\xe8\xb3\x87\0" /* offset 8637 */
+  "\xe5\x8d\x94\0" /* offset 8641 */
+  "\xe5\xa4\x9c\0" /* offset 8645 */
+  "\x33\x36\0" /* offset 8649 */
+  "\x33\x37\0" /* offset 8652 */
+  "\x33\x38\0" /* offset 8655 */
+  "\x33\x39\0" /* offset 8658 */
+  "\x34\x30\0" /* offset 8661 */
+  "\x34\x31\0" /* offset 8664 */
+  "\x34\x32\0" /* offset 8667 */
+  "\x34\x33\0" /* offset 8670 */
+  "\x34\x34\0" /* offset 8673 */
+  "\x34\x35\0" /* offset 8676 */
+  "\x34\x36\0" /* offset 8679 */
+  "\x34\x37\0" /* offset 8682 */
+  "\x34\x38\0" /* offset 8685 */
+  "\x34\x39\0" /* offset 8688 */
+  "\x35\x30\0" /* offset 8691 */
+  "\x31\xe6\x9c\x88\0" /* offset 8694 */
+  "\x32\xe6\x9c\x88\0" /* offset 8699 */
+  "\x33\xe6\x9c\x88\0" /* offset 8704 */
+  "\x34\xe6\x9c\x88\0" /* offset 8709 */
+  "\x35\xe6\x9c\x88\0" /* offset 8714 */
+  "\x36\xe6\x9c\x88\0" /* offset 8719 */
+  "\x37\xe6\x9c\x88\0" /* offset 8724 */
+  "\x38\xe6\x9c\x88\0" /* offset 8729 */
+  "\x39\xe6\x9c\x88\0" /* offset 8734 */
+  "\x31\x30\xe6\x9c\x88\0" /* offset 8739 */
+  "\x31\x31\xe6\x9c\x88\0" /* offset 8745 */
+  "\x31\x32\xe6\x9c\x88\0" /* offset 8751 */
+  "\x48\x67\0" /* offset 8757 */
+  "\x65\x72\x67\0" /* offset 8760 */
+  "\x65\x56\0" /* offset 8764 */
+  "\x4c\x54\x44\0" /* offset 8767 */
+  "\xe3\x82\xa2\0" /* offset 8771 */
+  "\xe3\x82\xa4\0" /* offset 8775 */
+  "\xe3\x82\xa6\0" /* offset 8779 */
+  "\xe3\x82\xa8\0" /* offset 8783 */
+  "\xe3\x82\xaa\0" /* offset 8787 */
+  "\xe3\x82\xab\0" /* offset 8791 */
+  "\xe3\x82\xad\0" /* offset 8795 */
+  "\xe3\x82\xaf\0" /* offset 8799 */
+  "\xe3\x82\xb1\0" /* offset 8803 */
+  "\xe3\x82\xb3\0" /* offset 8807 */
+  "\xe3\x82\xb5\0" /* offset 8811 */
+  "\xe3\x82\xb7\0" /* offset 8815 */
+  "\xe3\x82\xb9\0" /* offset 8819 */
+  "\xe3\x82\xbb\0" /* offset 8823 */
+  "\xe3\x82\xbd\0" /* offset 8827 */
+  "\xe3\x82\xbf\0" /* offset 8831 */
+  "\xe3\x83\x81\0" /* offset 8835 */
+  "\xe3\x83\x84\0" /* offset 8839 */
+  "\xe3\x83\x86\0" /* offset 8843 */
+  "\xe3\x83\x88\0" /* offset 8847 */
+  "\xe3\x83\x8a\0" /* offset 8851 */
+  "\xe3\x83\x8b\0" /* offset 8855 */
+  "\xe3\x83\x8c\0" /* offset 8859 */
+  "\xe3\x83\x8d\0" /* offset 8863 */
+  "\xe3\x83\x8e\0" /* offset 8867 */
+  "\xe3\x83\x8f\0" /* offset 8871 */
+  "\xe3\x83\x92\0" /* offset 8875 */
+  "\xe3\x83\x95\0" /* offset 8879 */
+  "\xe3\x83\x98\0" /* offset 8883 */
+  "\xe3\x83\x9b\0" /* offset 8887 */
+  "\xe3\x83\x9e\0" /* offset 8891 */
+  "\xe3\x83\x9f\0" /* offset 8895 */
+  "\xe3\x83\xa0\0" /* offset 8899 */
+  "\xe3\x83\xa1\0" /* offset 8903 */
+  "\xe3\x83\xa2\0" /* offset 8907 */
+  "\xe3\x83\xa4\0" /* offset 8911 */
+  "\xe3\x83\xa6\0" /* offset 8915 */
+  "\xe3\x83\xa8\0" /* offset 8919 */
+  "\xe3\x83\xa9\0" /* offset 8923 */
+  "\xe3\x83\xaa\0" /* offset 8927 */
+  "\xe3\x83\xab\0" /* offset 8931 */
+  "\xe3\x83\xac\0" /* offset 8935 */
+  "\xe3\x83\xad\0" /* offset 8939 */
+  "\xe3\x83\xaf\0" /* offset 8943 */
+  "\xe3\x83\xb0\0" /* offset 8947 */
+  "\xe3\x83\xb1\0" /* offset 8951 */
+  "\xe3\x83\xb2\0" /* offset 8955 */
+  "\xe3\x82\xa2\xe3\x83\x8f\xe3\x82\x9a\xe3\x83\xbc\xe3\x83\x88\0" /* offset 8959 */
+  "\xe3\x82\xa2\xe3\x83\xab\xe3\x83\x95\xe3\x82\xa1\0" /* offset 8975 */
+  "\xe3\x82\xa2\xe3\x83\xb3\xe3\x83\x98\xe3\x82\x9a\xe3\x82\xa2\0" /* offset 8988 */
+  "\xe3\x82\xa2\xe3\x83\xbc\xe3\x83\xab\0" /* offset 9004 */
+  "\xe3\x82\xa4\xe3\x83\x8b\xe3\x83\xb3\xe3\x82\xaf\xe3\x82\x99\0" /* offset 9014 */
+  "\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x81\0" /* offset 9030 */
+  "\xe3\x82\xa6\xe3\x82\xa9\xe3\x83\xb3\0" /* offset 9040 */
+  "\xe3\x82\xa8\xe3\x82\xb9\xe3\x82\xaf\xe3\x83\xbc\xe3\x83\x88\xe3\x82\x99\0" /* offset 9050 */
+  "\xe3\x82\xa8\xe3\x83\xbc\xe3\x82\xab\xe3\x83\xbc\0" /* offset 9069 */
+  "\xe3\x82\xaa\xe3\x83\xb3\xe3\x82\xb9\0" /* offset 9082 */
+  "\xe3\x82\xaa\xe3\x83\xbc\xe3\x83\xa0\0" /* offset 9092 */
+  "\xe3\x82\xab\xe3\x82\xa4\xe3\x83\xaa\0" /* offset 9102 */
+  "\xe3\x82\xab\xe3\x83\xa9\xe3\x83\x83\xe3\x83\x88\0" /* offset 9112 */
+  "\xe3\x82\xab\xe3\x83\xad\xe3\x83\xaa\xe3\x83\xbc\0" /* offset 9125 */
+  "\xe3\x82\xab\xe3\x82\x99\xe3\x83\xad\xe3\x83\xb3\0" /* offset 9138 */
+  "\xe3\x82\xab\xe3\x82\x99\xe3\x83\xb3\xe3\x83\x9e\0" /* offset 9151 */
+  "\xe3\x82\xad\xe3\x82\x99\xe3\x82\xab\xe3\x82\x99\0" /* offset 9164 */
+  "\xe3\x82\xad\xe3\x82\x99\xe3\x83\x8b\xe3\x83\xbc\0" /* offset 9177 */
+  "\xe3\x82\xad\xe3\x83\xa5\xe3\x83\xaa\xe3\x83\xbc\0" /* offset 9190 */
+  "\xe3\x82\xad\xe3\x82\x99\xe3\x83\xab\xe3\x82\xbf\xe3\x82\x99\xe3\x83\xbc\0" /* offset 9203 */
+  "\xe3\x82\xad\xe3\x83\xad\0" /* offset 9222 */
+  "\xe3\x82\xad\xe3\x83\xad\xe3\x82\xaf\xe3\x82\x99\xe3\x83\xa9\xe3\x83\xa0\0" /* offset 9229 */
+  "\xe3\x82\xad\xe3\x83\xad\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88\xe3\x83\xab\0" /* offset 9248 */
+  "\xe3\x82\xad\xe3\x83\xad\xe3\x83\xaf\xe3\x83\x83\xe3\x83\x88\0" /* offset 9267 */
+  "\xe3\x82\xaf\xe3\x82\x99\xe3\x83\xa9\xe3\x83\xa0\0" /* offset 9283 */
+  "\xe3\x82\xaf\xe3\x82\x99\xe3\x83\xa9\xe3\x83\xa0\xe3\x83\x88\xe3\x83\xb3\0" /* offset 9296 */
+  "\xe3\x82\xaf\xe3\x83\xab\xe3\x82\xbb\xe3\x82\x99\xe3\x82\xa4\xe3\x83\xad\0" /* offset 9315 */
+  "\xe3\x82\xaf\xe3\x83\xad\xe3\x83\xbc\xe3\x83\x8d\0" /* offset 9334 */
+  "\xe3\x82\xb1\xe3\x83\xbc\xe3\x82\xb9\0" /* offset 9347 */
+  "\xe3\x82\xb3\xe3\x83\xab\xe3\x83\x8a\0" /* offset 9357 */
+  "\xe3\x82\xb3\xe3\x83\xbc\xe3\x83\x9b\xe3\x82\x9a\0" /* offset 9367 */
+  "\xe3\x82\xb5\xe3\x82\xa4\xe3\x82\xaf\xe3\x83\xab\0" /* offset 9380 */
+  "\xe3\x82\xb5\xe3\x83\xb3\xe3\x83\x81\xe3\x83\xbc\xe3\x83\xa0\0" /* offset 9393 */
+  "\xe3\x82\xb7\xe3\x83\xaa\xe3\x83\xb3\xe3\x82\xaf\xe3\x82\x99\0" /* offset 9409 */
+  "\xe3\x82\xbb\xe3\x83\xb3\xe3\x83\x81\0" /* offset 9425 */
+  "\xe3\x82\xbb\xe3\x83\xb3\xe3\x83\x88\0" /* offset 9435 */
+  "\xe3\x82\xbf\xe3\x82\x99\xe3\x83\xbc\xe3\x82\xb9\0" /* offset 9445 */
+  "\xe3\x83\x86\xe3\x82\x99\xe3\x82\xb7\0" /* offset 9458 */
+  "\xe3\x83\x88\xe3\x82\x99\xe3\x83\xab\0" /* offset 9468 */
+  "\xe3\x83\x88\xe3\x83\xb3\0" /* offset 9478 */
+  "\xe3\x83\x8a\xe3\x83\x8e\0" /* offset 9485 */
+  "\xe3\x83\x8e\xe3\x83\x83\xe3\x83\x88\0" /* offset 9492 */
+  "\xe3\x83\x8f\xe3\x82\xa4\xe3\x83\x84\0" /* offset 9502 */
+  "\xe3\x83\x8f\xe3\x82\x9a\xe3\x83\xbc\xe3\x82\xbb\xe3\x83\xb3\xe3\x83\x88\0" /* offset 9512 */
+  "\xe3\x83\x8f\xe3\x82\x9a\xe3\x83\xbc\xe3\x83\x84\0" /* offset 9531 */
+  "\xe3\x83\x8f\xe3\x82\x99\xe3\x83\xbc\xe3\x83\xac\xe3\x83\xab\0" /* offset 9544 */
+  "\xe3\x83\x92\xe3\x82\x9a\xe3\x82\xa2\xe3\x82\xb9\xe3\x83\x88\xe3\x83\xab\0" /* offset 9560 */
+  "\xe3\x83\x92\xe3\x82\x9a\xe3\x82\xaf\xe3\x83\xab\0" /* offset 9579 */
+  "\xe3\x83\x92\xe3\x82\x9a\xe3\x82\xb3\0" /* offset 9592 */
+  "\xe3\x83\x92\xe3\x82\x99\xe3\x83\xab\0" /* offset 9602 */
+  "\xe3\x83\x95\xe3\x82\xa1\xe3\x83\xa9\xe3\x83\x83\xe3\x83\x88\xe3\x82\x99\0" /* offset 9612 */
+  "\xe3\x83\x95\xe3\x82\xa3\xe3\x83\xbc\xe3\x83\x88\0" /* offset 9631 */
+  "\xe3\x83\x95\xe3\x82\x99\xe3\x83\x83\xe3\x82\xb7\xe3\x82\xa7\xe3\x83\xab\0" /* offset 9644 */
+  "\xe3\x83\x95\xe3\x83\xa9\xe3\x83\xb3\0" /* offset 9663 */
+  "\xe3\x83\x98\xe3\x82\xaf\xe3\x82\xbf\xe3\x83\xbc\xe3\x83\xab\0" /* offset 9673 */
+  "\xe3\x83\x98\xe3\x82\x9a\xe3\x82\xbd\0" /* offset 9689 */
+  "\xe3\x83\x98\xe3\x82\x9a\xe3\x83\x8b\xe3\x83\x92\0" /* offset 9699 */
+  "\xe3\x83\x98\xe3\x83\xab\xe3\x83\x84\0" /* offset 9712 */
+  "\xe3\x83\x98\xe3\x82\x9a\xe3\x83\xb3\xe3\x82\xb9\0" /* offset 9722 */
+  "\xe3\x83\x98\xe3\x82\x9a\xe3\x83\xbc\xe3\x82\xb7\xe3\x82\x99\0" /* offset 9735 */
+  "\xe3\x83\x98\xe3\x82\x99\xe3\x83\xbc\xe3\x82\xbf\0" /* offset 9751 */
+  "\xe3\x83\x9b\xe3\x82\x9a\xe3\x82\xa4\xe3\x83\xb3\xe3\x83\x88\0" /* offset 9764 */
+  "\xe3\x83\x9b\xe3\x82\x99\xe3\x83\xab\xe3\x83\x88\0" /* offset 9780 */
+  "\xe3\x83\x9b\xe3\x83\xb3\0" /* offset 9793 */
+  "\xe3\x83\x9b\xe3\x82\x9a\xe3\x83\xb3\xe3\x83\x88\xe3\x82\x99\0" /* offset 9800 */
+  "\xe3\x83\x9b\xe3\x83\xbc\xe3\x83\xab\0" /* offset 9816 */
+  "\xe3\x83\x9b\xe3\x83\xbc\xe3\x83\xb3\0" /* offset 9826 */
+  "\xe3\x83\x9e\xe3\x82\xa4\xe3\x82\xaf\xe3\x83\xad\0" /* offset 9836 */
+  "\xe3\x83\x9e\xe3\x82\xa4\xe3\x83\xab\0" /* offset 9849 */
+  "\xe3\x83\x9e\xe3\x83\x83\xe3\x83\x8f\0" /* offset 9859 */
+  "\xe3\x83\x9e\xe3\x83\xab\xe3\x82\xaf\0" /* offset 9869 */
+  "\xe3\x83\x9e\xe3\x83\xb3\xe3\x82\xb7\xe3\x83\xa7\xe3\x83\xb3\0" /* offset 9879 */
+  "\xe3\x83\x9f\xe3\x82\xaf\xe3\x83\xad\xe3\x83\xb3\0" /* offset 9895 */
+  "\xe3\x83\x9f\xe3\x83\xaa\0" /* offset 9908 */
+  "\xe3\x83\x9f\xe3\x83\xaa\xe3\x83\x8f\xe3\x82\x99\xe3\x83\xbc\xe3\x83\xab\0" /* offset 9915 */
+  "\xe3\x83\xa1\xe3\x82\xab\xe3\x82\x99\0" /* offset 9934 */
+  "\xe3\x83\xa1\xe3\x82\xab\xe3\x82\x99\xe3\x83\x88\xe3\x83\xb3\0" /* offset 9944 */
+  "\xe3\x83\xa1\xe3\x83\xbc\xe3\x83\x88\xe3\x83\xab\0" /* offset 9960 */
+  "\xe3\x83\xa4\xe3\x83\xbc\xe3\x83\x88\xe3\x82\x99\0" /* offset 9973 */
+  "\xe3\x83\xa4\xe3\x83\xbc\xe3\x83\xab\0" /* offset 9986 */
+  "\xe3\x83\xa6\xe3\x82\xa2\xe3\x83\xb3\0" /* offset 9996 */
+  "\xe3\x83\xaa\xe3\x83\x83\xe3\x83\x88\xe3\x83\xab\0" /* offset 10006 */
+  "\xe3\x83\xaa\xe3\x83\xa9\0" /* offset 10019 */
+  "\xe3\x83\xab\xe3\x83\x92\xe3\x82\x9a\xe3\x83\xbc\0" /* offset 10026 */
+  "\xe3\x83\xab\xe3\x83\xbc\xe3\x83\x95\xe3\x82\x99\xe3\x83\xab\0" /* offset 10039 */
+  "\xe3\x83\xac\xe3\x83\xa0\0" /* offset 10055 */
+  "\xe3\x83\xac\xe3\x83\xb3\xe3\x83\x88\xe3\x82\xb1\xe3\x82\x99\xe3\x83\xb3\0" /* offset 10062 */
+  "\xe3\x83\xaf\xe3\x83\x83\xe3\x83\x88\0" /* offset 10081 */
+  "\x30\xe7\x82\xb9\0" /* offset 10091 */
+  "\x31\xe7\x82\xb9\0" /* offset 10096 */
+  "\x32\xe7\x82\xb9\0" /* offset 10101 */
+  "\x33\xe7\x82\xb9\0" /* offset 10106 */
+  "\x34\xe7\x82\xb9\0" /* offset 10111 */
+  "\x35\xe7\x82\xb9\0" /* offset 10116 */
+  "\x36\xe7\x82\xb9\0" /* offset 10121 */
+  "\x37\xe7\x82\xb9\0" /* offset 10126 */
+  "\x38\xe7\x82\xb9\0" /* offset 10131 */
+  "\x39\xe7\x82\xb9\0" /* offset 10136 */
+  "\x31\x30\xe7\x82\xb9\0" /* offset 10141 */
+  "\x31\x31\xe7\x82\xb9\0" /* offset 10147 */
+  "\x31\x32\xe7\x82\xb9\0" /* offset 10153 */
+  "\x31\x33\xe7\x82\xb9\0" /* offset 10159 */
+  "\x31\x34\xe7\x82\xb9\0" /* offset 10165 */
+  "\x31\x35\xe7\x82\xb9\0" /* offset 10171 */
+  "\x31\x36\xe7\x82\xb9\0" /* offset 10177 */
+  "\x31\x37\xe7\x82\xb9\0" /* offset 10183 */
+  "\x31\x38\xe7\x82\xb9\0" /* offset 10189 */
+  "\x31\x39\xe7\x82\xb9\0" /* offset 10195 */
+  "\x32\x30\xe7\x82\xb9\0" /* offset 10201 */
+  "\x32\x31\xe7\x82\xb9\0" /* offset 10207 */
+  "\x32\x32\xe7\x82\xb9\0" /* offset 10213 */
+  "\x32\x33\xe7\x82\xb9\0" /* offset 10219 */
+  "\x32\x34\xe7\x82\xb9\0" /* offset 10225 */
+  "\x68\x50\x61\0" /* offset 10231 */
+  "\x64\x61\0" /* offset 10235 */
+  "\x41\x55\0" /* offset 10238 */
+  "\x62\x61\x72\0" /* offset 10241 */
+  "\x6f\x56\0" /* offset 10245 */
+  "\x70\x63\0" /* offset 10248 */
+  "\x64\x6d\0" /* offset 10251 */
+  "\x64\x6d\x32\0" /* offset 10254 */
+  "\x64\x6d\x33\0" /* offset 10258 */
+  "\x49\x55\0" /* offset 10262 */
+  "\xe5\xb9\xb3\xe6\x88\x90\0" /* offset 10265 */
+  "\xe6\x98\xad\xe5\x92\x8c\0" /* offset 10272 */
+  "\xe5\xa4\xa7\xe6\xad\xa3\0" /* offset 10279 */
+  "\xe6\x98\x8e\xe6\xb2\xbb\0" /* offset 10286 */
+  "\xe6\xa0\xaa\xe5\xbc\x8f\xe4\xbc\x9a\xe7\xa4\xbe\0" /* offset 10293 */
+  "\x70\x41\0" /* offset 10306 */
+  "\x6e\x41\0" /* offset 10309 */
+  "\xce\xbc\x41\0" /* offset 10312 */
+  "\x6d\x41\0" /* offset 10316 */
+  "\x6b\x41\0" /* offset 10319 */
+  "\x4b\x42\0" /* offset 10322 */
+  "\x4d\x42\0" /* offset 10325 */
+  "\x47\x42\0" /* offset 10328 */
+  "\x63\x61\x6c\0" /* offset 10331 */
+  "\x6b\x63\x61\x6c\0" /* offset 10335 */
+  "\x70\x46\0" /* offset 10340 */
+  "\x6e\x46\0" /* offset 10343 */
+  "\xce\xbc\x46\0" /* offset 10346 */
+  "\xce\xbc\x67\0" /* offset 10350 */
+  "\x6d\x67\0" /* offset 10354 */
+  "\x6b\x67\0" /* offset 10357 */
+  "\x48\x7a\0" /* offset 10360 */
+  "\x6b\x48\x7a\0" /* offset 10363 */
+  "\x4d\x48\x7a\0" /* offset 10367 */
+  "\x47\x48\x7a\0" /* offset 10371 */
+  "\x54\x48\x7a\0" /* offset 10375 */
+  "\xce\xbc\x6c\0" /* offset 10379 */
+  "\x6d\x6c\0" /* offset 10383 */
+  "\x64\x6c\0" /* offset 10386 */
+  "\x6b\x6c\0" /* offset 10389 */
+  "\x66\x6d\0" /* offset 10392 */
+  "\x6e\x6d\0" /* offset 10395 */
+  "\xce\xbc\x6d\0" /* offset 10398 */
+  "\x6d\x6d\0" /* offset 10402 */
+  "\x63\x6d\0" /* offset 10405 */
+  "\x6b\x6d\0" /* offset 10408 */
+  "\x6d\x6d\x32\0" /* offset 10411 */
+  "\x63\x6d\x32\0" /* offset 10415 */
+  "\x6d\x32\0" /* offset 10419 */
+  "\x6b\x6d\x32\0" /* offset 10422 */
+  "\x6d\x6d\x33\0" /* offset 10426 */
+  "\x63\x6d\x33\0" /* offset 10430 */
+  "\x6d\x33\0" /* offset 10434 */
+  "\x6b\x6d\x33\0" /* offset 10437 */
+  "\x6d\xe2\x88\x95\x73\0" /* offset 10441 */
+  "\x6d\xe2\x88\x95\x73\x32\0" /* offset 10447 */
+  "\x50\x61\0" /* offset 10454 */
+  "\x6b\x50\x61\0" /* offset 10457 */
+  "\x4d\x50\x61\0" /* offset 10461 */
+  "\x47\x50\x61\0" /* offset 10465 */
+  "\x72\x61\x64\0" /* offset 10469 */
+  "\x72\x61\x64\xe2\x88\x95\x73\0" /* offset 10473 */
+  "\x72\x61\x64\xe2\x88\x95\x73\x32\0" /* offset 10481 */
+  "\x70\x73\0" /* offset 10490 */
+  "\x6e\x73\0" /* offset 10493 */
+  "\xce\xbc\x73\0" /* offset 10496 */
+  "\x6d\x73\0" /* offset 10500 */
+  "\x70\x56\0" /* offset 10503 */
+  "\x6e\x56\0" /* offset 10506 */
+  "\xce\xbc\x56\0" /* offset 10509 */
+  "\x6d\x56\0" /* offset 10513 */
+  "\x6b\x56\0" /* offset 10516 */
+  "\x4d\x56\0" /* offset 10519 */
+  "\x70\x57\0" /* offset 10522 */
+  "\x6e\x57\0" /* offset 10525 */
+  "\xce\xbc\x57\0" /* offset 10528 */
+  "\x6d\x57\0" /* offset 10532 */
+  "\x6b\x57\0" /* offset 10535 */
+  "\x4d\x57\0" /* offset 10538 */
+  "\x6b\xce\xa9\0" /* offset 10541 */
+  "\x4d\xce\xa9\0" /* offset 10545 */
+  "\x61\x2e\x6d\x2e\0" /* offset 10549 */
+  "\x42\x71\0" /* offset 10554 */
+  "\x63\x63\0" /* offset 10557 */
+  "\x63\x64\0" /* offset 10560 */
+  "\x43\xe2\x88\x95\x6b\x67\0" /* offset 10563 */
+  "\x43\x6f\x2e\0" /* offset 10570 */
+  "\x64\x42\0" /* offset 10574 */
+  "\x47\x79\0" /* offset 10577 */
+  "\x68\x61\0" /* offset 10580 */
+  "\x48\x50\0" /* offset 10583 */
+  "\x69\x6e\0" /* offset 10586 */
+  "\x4b\x4b\0" /* offset 10589 */
+  "\x4b\x4d\0" /* offset 10592 */
+  "\x6b\x74\0" /* offset 10595 */
+  "\x6c\x6d\0" /* offset 10598 */
+  "\x6c\x6e\0" /* offset 10601 */
+  "\x6c\x6f\x67\0" /* offset 10604 */
+  "\x6c\x78\0" /* offset 10608 */
+  "\x6d\x62\0" /* offset 10611 */
+  "\x6d\x69\x6c\0" /* offset 10614 */
+  "\x6d\x6f\x6c\0" /* offset 10618 */
+  "\x50\x48\0" /* offset 10622 */
+  "\x70\x2e\x6d\x2e\0" /* offset 10625 */
+  "\x50\x50\x4d\0" /* offset 10630 */
+  "\x50\x52\0" /* offset 10634 */
+  "\x73\x72\0" /* offset 10637 */
+  "\x53\x76\0" /* offset 10640 */
+  "\x57\x62\0" /* offset 10643 */
+  "\x56\xe2\x88\x95\x6d\0" /* offset 10646 */
+  "\x41\xe2\x88\x95\x6d\0" /* offset 10652 */
+  "\x31\xe6\x97\xa5\0" /* offset 10658 */
+  "\x32\xe6\x97\xa5\0" /* offset 10663 */
+  "\x33\xe6\x97\xa5\0" /* offset 10668 */
+  "\x34\xe6\x97\xa5\0" /* offset 10673 */
+  "\x35\xe6\x97\xa5\0" /* offset 10678 */
+  "\x36\xe6\x97\xa5\0" /* offset 10683 */
+  "\x37\xe6\x97\xa5\0" /* offset 10688 */
+  "\x38\xe6\x97\xa5\0" /* offset 10693 */
+  "\x39\xe6\x97\xa5\0" /* offset 10698 */
+  "\x31\x30\xe6\x97\xa5\0" /* offset 10703 */
+  "\x31\x31\xe6\x97\xa5\0" /* offset 10709 */
+  "\x31\x32\xe6\x97\xa5\0" /* offset 10715 */
+  "\x31\x33\xe6\x97\xa5\0" /* offset 10721 */
+  "\x31\x34\xe6\x97\xa5\0" /* offset 10727 */
+  "\x31\x35\xe6\x97\xa5\0" /* offset 10733 */
+  "\x31\x36\xe6\x97\xa5\0" /* offset 10739 */
+  "\x31\x37\xe6\x97\xa5\0" /* offset 10745 */
+  "\x31\x38\xe6\x97\xa5\0" /* offset 10751 */
+  "\x31\x39\xe6\x97\xa5\0" /* offset 10757 */
+  "\x32\x30\xe6\x97\xa5\0" /* offset 10763 */
+  "\x32\x31\xe6\x97\xa5\0" /* offset 10769 */
+  "\x32\x32\xe6\x97\xa5\0" /* offset 10775 */
+  "\x32\x33\xe6\x97\xa5\0" /* offset 10781 */
+  "\x32\x34\xe6\x97\xa5\0" /* offset 10787 */
+  "\x32\x35\xe6\x97\xa5\0" /* offset 10793 */
+  "\x32\x36\xe6\x97\xa5\0" /* offset 10799 */
+  "\x32\x37\xe6\x97\xa5\0" /* offset 10805 */
+  "\x32\x38\xe6\x97\xa5\0" /* offset 10811 */
+  "\x32\x39\xe6\x97\xa5\0" /* offset 10817 */
+  "\x33\x30\xe6\x97\xa5\0" /* offset 10823 */
+  "\x33\x31\xe6\x97\xa5\0" /* offset 10829 */
+  "\x67\x61\x6c\0" /* offset 10835 */
+  "\xe8\xb1\x88\0" /* offset 10839 */
+  "\xe6\x9b\xb4\0" /* offset 10843 */
+  "\xe8\xb3\x88\0" /* offset 10847 */
+  "\xe6\xbb\x91\0" /* offset 10851 */
+  "\xe4\xb8\xb2\0" /* offset 10855 */
+  "\xe5\x8f\xa5\0" /* offset 10859 */
+  "\xe5\xa5\x91\0" /* offset 10863 */
+  "\xe5\x96\x87\0" /* offset 10867 */
+  "\xe5\xa5\x88\0" /* offset 10871 */
+  "\xe6\x87\xb6\0" /* offset 10875 */
+  "\xe7\x99\xa9\0" /* offset 10879 */
+  "\xe7\xbe\x85\0" /* offset 10883 */
+  "\xe8\x98\xbf\0" /* offset 10887 */
+  "\xe8\x9e\xba\0" /* offset 10891 */
+  "\xe8\xa3\xb8\0" /* offset 10895 */
+  "\xe9\x82\x8f\0" /* offset 10899 */
+  "\xe6\xa8\x82\0" /* offset 10903 */
+  "\xe6\xb4\x9b\0" /* offset 10907 */
+  "\xe7\x83\x99\0" /* offset 10911 */
+  "\xe7\x8f\x9e\0" /* offset 10915 */
+  "\xe8\x90\xbd\0" /* offset 10919 */
+  "\xe9\x85\xaa\0" /* offset 10923 */
+  "\xe9\xa7\xb1\0" /* offset 10927 */
+  "\xe4\xba\x82\0" /* offset 10931 */
+  "\xe5\x8d\xb5\0" /* offset 10935 */
+  "\xe6\xac\x84\0" /* offset 10939 */
+  "\xe7\x88\x9b\0" /* offset 10943 */
+  "\xe8\x98\xad\0" /* offset 10947 */
+  "\xe9\xb8\x9e\0" /* offset 10951 */
+  "\xe5\xb5\x90\0" /* offset 10955 */
+  "\xe6\xbf\xab\0" /* offset 10959 */
+  "\xe8\x97\x8d\0" /* offset 10963 */
+  "\xe8\xa5\xa4\0" /* offset 10967 */
+  "\xe6\x8b\x89\0" /* offset 10971 */
+  "\xe8\x87\x98\0" /* offset 10975 */
+  "\xe8\xa0\x9f\0" /* offset 10979 */
+  "\xe5\xbb\x8a\0" /* offset 10983 */
+  "\xe6\x9c\x97\0" /* offset 10987 */
+  "\xe6\xb5\xaa\0" /* offset 10991 */
+  "\xe7\x8b\xbc\0" /* offset 10995 */
+  "\xe9\x83\x8e\0" /* offset 10999 */
+  "\xe4\xbe\x86\0" /* offset 11003 */
+  "\xe5\x86\xb7\0" /* offset 11007 */
+  "\xe5\x8b\x9e\0" /* offset 11011 */
+  "\xe6\x93\x84\0" /* offset 11015 */
+  "\xe6\xab\x93\0" /* offset 11019 */
+  "\xe7\x88\x90\0" /* offset 11023 */
+  "\xe7\x9b\xa7\0" /* offset 11027 */
+  "\xe8\x98\x86\0" /* offset 11031 */
+  "\xe8\x99\x9c\0" /* offset 11035 */
+  "\xe8\xb7\xaf\0" /* offset 11039 */
+  "\xe9\x9c\xb2\0" /* offset 11043 */
+  "\xe9\xad\xaf\0" /* offset 11047 */
+  "\xe9\xb7\xba\0" /* offset 11051 */
+  "\xe7\xa2\x8c\0" /* offset 11055 */
+  "\xe7\xa5\xbf\0" /* offset 11059 */
+  "\xe7\xb6\xa0\0" /* offset 11063 */
+  "\xe8\x8f\x89\0" /* offset 11067 */
+  "\xe9\x8c\x84\0" /* offset 11071 */
+  "\xe8\xab\x96\0" /* offset 11075 */
+  "\xe5\xa3\x9f\0" /* offset 11079 */
+  "\xe5\xbc\x84\0" /* offset 11083 */
+  "\xe7\xb1\xa0\0" /* offset 11087 */
+  "\xe8\x81\xbe\0" /* offset 11091 */
+  "\xe7\x89\xa2\0" /* offset 11095 */
+  "\xe7\xa3\x8a\0" /* offset 11099 */
+  "\xe8\xb3\x82\0" /* offset 11103 */
+  "\xe9\x9b\xb7\0" /* offset 11107 */
+  "\xe5\xa3\x98\0" /* offset 11111 */
+  "\xe5\xb1\xa2\0" /* offset 11115 */
+  "\xe6\xa8\x93\0" /* offset 11119 */
+  "\xe6\xb7\x9a\0" /* offset 11123 */
+  "\xe6\xbc\x8f\0" /* offset 11127 */
+  "\xe7\xb4\xaf\0" /* offset 11131 */
+  "\xe7\xb8\xb7\0" /* offset 11135 */
+  "\xe9\x99\x8b\0" /* offset 11139 */
+  "\xe5\x8b\x92\0" /* offset 11143 */
+  "\xe8\x82\x8b\0" /* offset 11147 */
+  "\xe5\x87\x9c\0" /* offset 11151 */
+  "\xe5\x87\x8c\0" /* offset 11155 */
+  "\xe7\xa8\x9c\0" /* offset 11159 */
+  "\xe7\xb6\xbe\0" /* offset 11163 */
+  "\xe8\x8f\xb1\0" /* offset 11167 */
+  "\xe9\x99\xb5\0" /* offset 11171 */
+  "\xe8\xae\x80\0" /* offset 11175 */
+  "\xe6\x8b\x8f\0" /* offset 11179 */
+  "\xe8\xab\xbe\0" /* offset 11183 */
+  "\xe4\xb8\xb9\0" /* offset 11187 */
+  "\xe5\xaf\xa7\0" /* offset 11191 */
+  "\xe6\x80\x92\0" /* offset 11195 */
+  "\xe7\x8e\x87\0" /* offset 11199 */
+  "\xe7\x95\xb0\0" /* offset 11203 */
+  "\xe5\x8c\x97\0" /* offset 11207 */
+  "\xe7\xa3\xbb\0" /* offset 11211 */
+  "\xe4\xbe\xbf\0" /* offset 11215 */
+  "\xe5\xbe\xa9\0" /* offset 11219 */
+  "\xe4\xb8\x8d\0" /* offset 11223 */
+  "\xe6\xb3\x8c\0" /* offset 11227 */
+  "\xe6\x95\xb8\0" /* offset 11231 */
+  "\xe7\xb4\xa2\0" /* offset 11235 */
+  "\xe5\x8f\x83\0" /* offset 11239 */
+  "\xe5\xa1\x9e\0" /* offset 11243 */
+  "\xe7\x9c\x81\0" /* offset 11247 */
+  "\xe8\x91\x89\0" /* offset 11251 */
+  "\xe8\xaa\xaa\0" /* offset 11255 */
+  "\xe6\xae\xba\0" /* offset 11259 */
+  "\xe6\xb2\x88\0" /* offset 11263 */
+  "\xe6\x8b\xbe\0" /* offset 11267 */
+  "\xe8\x8b\xa5\0" /* offset 11271 */
+  "\xe6\x8e\xa0\0" /* offset 11275 */
+  "\xe7\x95\xa5\0" /* offset 11279 */
+  "\xe4\xba\xae\0" /* offset 11283 */
+  "\xe5\x85\xa9\0" /* offset 11287 */
+  "\xe5\x87\x89\0" /* offset 11291 */
+  "\xe6\xa2\x81\0" /* offset 11295 */
+  "\xe7\xb3\xa7\0" /* offset 11299 */
+  "\xe8\x89\xaf\0" /* offset 11303 */
+  "\xe8\xab\x92\0" /* offset 11307 */
+  "\xe9\x87\x8f\0" /* offset 11311 */
+  "\xe5\x8b\xb5\0" /* offset 11315 */
+  "\xe5\x91\x82\0" /* offset 11319 */
+  "\xe5\xbb\xac\0" /* offset 11323 */
+  "\xe6\x97\x85\0" /* offset 11327 */
+  "\xe6\xbf\xbe\0" /* offset 11331 */
+  "\xe7\xa4\xaa\0" /* offset 11335 */
+  "\xe9\x96\xad\0" /* offset 11339 */
+  "\xe9\xa9\xaa\0" /* offset 11343 */
+  "\xe9\xba\x97\0" /* offset 11347 */
+  "\xe9\xbb\x8e\0" /* offset 11351 */
+  "\xe6\x9b\x86\0" /* offset 11355 */
+  "\xe6\xad\xb7\0" /* offset 11359 */
+  "\xe8\xbd\xa2\0" /* offset 11363 */
+  "\xe5\xb9\xb4\0" /* offset 11367 */
+  "\xe6\x86\x90\0" /* offset 11371 */
+  "\xe6\x88\x80\0" /* offset 11375 */
+  "\xe6\x92\x9a\0" /* offset 11379 */
+  "\xe6\xbc\xa3\0" /* offset 11383 */
+  "\xe7\x85\x89\0" /* offset 11387 */
+  "\xe7\x92\x89\0" /* offset 11391 */
+  "\xe7\xa7\x8a\0" /* offset 11395 */
+  "\xe7\xb7\xb4\0" /* offset 11399 */
+  "\xe8\x81\xaf\0" /* offset 11403 */
+  "\xe8\xbc\xa6\0" /* offset 11407 */
+  "\xe8\x93\xae\0" /* offset 11411 */
+  "\xe9\x80\xa3\0" /* offset 11415 */
+  "\xe9\x8d\x8a\0" /* offset 11419 */
+  "\xe5\x88\x97\0" /* offset 11423 */
+  "\xe5\x8a\xa3\0" /* offset 11427 */
+  "\xe5\x92\xbd\0" /* offset 11431 */
+  "\xe7\x83\x88\0" /* offset 11435 */
+  "\xe8\xa3\x82\0" /* offset 11439 */
+  "\xe5\xbb\x89\0" /* offset 11443 */
+  "\xe5\xbf\xb5\0" /* offset 11447 */
+  "\xe6\x8d\xbb\0" /* offset 11451 */
+  "\xe6\xae\xae\0" /* offset 11455 */
+  "\xe7\xb0\xbe\0" /* offset 11459 */
+  "\xe7\x8d\xb5\0" /* offset 11463 */
+  "\xe4\xbb\xa4\0" /* offset 11467 */
+  "\xe5\x9b\xb9\0" /* offset 11471 */
+  "\xe5\xb6\xba\0" /* offset 11475 */
+  "\xe6\x80\x9c\0" /* offset 11479 */
+  "\xe7\x8e\xb2\0" /* offset 11483 */
+  "\xe7\x91\xa9\0" /* offset 11487 */
+  "\xe7\xbe\x9a\0" /* offset 11491 */
+  "\xe8\x81\x86\0" /* offset 11495 */
+  "\xe9\x88\xb4\0" /* offset 11499 */
+  "\xe9\x9b\xb6\0" /* offset 11503 */
+  "\xe9\x9d\x88\0" /* offset 11507 */
+  "\xe9\xa0\x98\0" /* offset 11511 */
+  "\xe4\xbe\x8b\0" /* offset 11515 */
+  "\xe7\xa6\xae\0" /* offset 11519 */
+  "\xe9\x86\xb4\0" /* offset 11523 */
+  "\xe9\x9a\xb8\0" /* offset 11527 */
+  "\xe6\x83\xa1\0" /* offset 11531 */
+  "\xe4\xba\x86\0" /* offset 11535 */
+  "\xe5\x83\x9a\0" /* offset 11539 */
+  "\xe5\xaf\xae\0" /* offset 11543 */
+  "\xe5\xb0\xbf\0" /* offset 11547 */
+  "\xe6\x96\x99\0" /* offset 11551 */
+  "\xe7\x87\x8e\0" /* offset 11555 */
+  "\xe7\x99\x82\0" /* offset 11559 */
+  "\xe8\x93\xbc\0" /* offset 11563 */
+  "\xe9\x81\xbc\0" /* offset 11567 */
+  "\xe6\x9a\x88\0" /* offset 11571 */
+  "\xe9\x98\xae\0" /* offset 11575 */
+  "\xe5\x8a\x89\0" /* offset 11579 */
+  "\xe6\x9d\xbb\0" /* offset 11583 */
+  "\xe6\x9f\xb3\0" /* offset 11587 */
+  "\xe6\xb5\x81\0" /* offset 11591 */
+  "\xe6\xba\x9c\0" /* offset 11595 */
+  "\xe7\x90\x89\0" /* offset 11599 */
+  "\xe7\x95\x99\0" /* offset 11603 */
+  "\xe7\xa1\xab\0" /* offset 11607 */
+  "\xe7\xb4\x90\0" /* offset 11611 */
+  "\xe9\xa1\x9e\0" /* offset 11615 */
+  "\xe6\x88\xae\0" /* offset 11619 */
+  "\xe9\x99\xb8\0" /* offset 11623 */
+  "\xe5\x80\xab\0" /* offset 11627 */
+  "\xe5\xb4\x99\0" /* offset 11631 */
+  "\xe6\xb7\xaa\0" /* offset 11635 */
+  "\xe8\xbc\xaa\0" /* offset 11639 */
+  "\xe5\xbe\x8b\0" /* offset 11643 */
+  "\xe6\x85\x84\0" /* offset 11647 */
+  "\xe6\xa0\x97\0" /* offset 11651 */
+  "\xe9\x9a\x86\0" /* offset 11655 */
+  "\xe5\x88\xa9\0" /* offset 11659 */
+  "\xe5\x90\x8f\0" /* offset 11663 */
+  "\xe5\xb1\xa5\0" /* offset 11667 */
+  "\xe6\x98\x93\0" /* offset 11671 */
+  "\xe6\x9d\x8e\0" /* offset 11675 */
+  "\xe6\xa2\xa8\0" /* offset 11679 */
+  "\xe6\xb3\xa5\0" /* offset 11683 */
+  "\xe7\x90\x86\0" /* offset 11687 */
+  "\xe7\x97\xa2\0" /* offset 11691 */
+  "\xe7\xbd\xb9\0" /* offset 11695 */
+  "\xe8\xa3\x8f\0" /* offset 11699 */
+  "\xe8\xa3\xa1\0" /* offset 11703 */
+  "\xe9\x9b\xa2\0" /* offset 11707 */
+  "\xe5\x8c\xbf\0" /* offset 11711 */
+  "\xe6\xba\xba\0" /* offset 11715 */
+  "\xe5\x90\x9d\0" /* offset 11719 */
+  "\xe7\x87\x90\0" /* offset 11723 */
+  "\xe7\x92\x98\0" /* offset 11727 */
+  "\xe8\x97\xba\0" /* offset 11731 */
+  "\xe9\x9a\xa3\0" /* offset 11735 */
+  "\xe9\xb1\x97\0" /* offset 11739 */
+  "\xe9\xba\x9f\0" /* offset 11743 */
+  "\xe6\x9e\x97\0" /* offset 11747 */
+  "\xe6\xb7\x8b\0" /* offset 11751 */
+  "\xe8\x87\xa8\0" /* offset 11755 */
+  "\xe7\xac\xa0\0" /* offset 11759 */
+  "\xe7\xb2\x92\0" /* offset 11763 */
+  "\xe7\x8b\x80\0" /* offset 11767 */
+  "\xe7\x82\x99\0" /* offset 11771 */
+  "\xe8\xad\x98\0" /* offset 11775 */
+  "\xe4\xbb\x80\0" /* offset 11779 */
+  "\xe8\x8c\xb6\0" /* offset 11783 */
+  "\xe5\x88\xba\0" /* offset 11787 */
+  "\xe5\x88\x87\0" /* offset 11791 */
+  "\xe5\xba\xa6\0" /* offset 11795 */
+  "\xe6\x8b\x93\0" /* offset 11799 */
+  "\xe7\xb3\x96\0" /* offset 11803 */
+  "\xe5\xae\x85\0" /* offset 11807 */
+  "\xe6\xb4\x9e\0" /* offset 11811 */
+  "\xe6\x9a\xb4\0" /* offset 11815 */
+  "\xe8\xbc\xbb\0" /* offset 11819 */
+  "\xe9\x99\x8d\0" /* offset 11823 */
+  "\xe5\xbb\x93\0" /* offset 11827 */
+  "\xe5\x85\x80\0" /* offset 11831 */
+  "\xe5\x97\x80\0" /* offset 11835 */
+  "\xe5\xa1\x9a\0" /* offset 11839 */
+  "\xe6\x99\xb4\0" /* offset 11843 */
+  "\xe5\x87\x9e\0" /* offset 11847 */
+  "\xe7\x8c\xaa\0" /* offset 11851 */
+  "\xe7\x9b\x8a\0" /* offset 11855 */
+  "\xe7\xa4\xbc\0" /* offset 11859 */
+  "\xe7\xa5\x9e\0" /* offset 11863 */
+  "\xe7\xa5\xa5\0" /* offset 11867 */
+  "\xe7\xa6\x8f\0" /* offset 11871 */
+  "\xe9\x9d\x96\0" /* offset 11875 */
+  "\xe7\xb2\xbe\0" /* offset 11879 */
+  "\xe8\x98\x92\0" /* offset 11883 */
+  "\xe8\xab\xb8\0" /* offset 11887 */
+  "\xe9\x80\xb8\0" /* offset 11891 */
+  "\xe9\x83\xbd\0" /* offset 11895 */
+  "\xe9\xa3\xaf\0" /* offset 11899 */
+  "\xe9\xa3\xbc\0" /* offset 11903 */
+  "\xe9\xa4\xa8\0" /* offset 11907 */
+  "\xe9\xb6\xb4\0" /* offset 11911 */
+  "\xe4\xbe\xae\0" /* offset 11915 */
+  "\xe5\x83\xa7\0" /* offset 11919 */
+  "\xe5\x85\x8d\0" /* offset 11923 */
+  "\xe5\x8b\x89\0" /* offset 11927 */
+  "\xe5\x8b\xa4\0" /* offset 11931 */
+  "\xe5\x8d\x91\0" /* offset 11935 */
+  "\xe5\x96\x9d\0" /* offset 11939 */
+  "\xe5\x98\x86\0" /* offset 11943 */
+  "\xe5\x99\xa8\0" /* offset 11947 */
+  "\xe5\xa1\x80\0" /* offset 11951 */
+  "\xe5\xa2\xa8\0" /* offset 11955 */
+  "\xe5\xb1\xa4\0" /* offset 11959 */
+  "\xe6\x82\x94\0" /* offset 11963 */
+  "\xe6\x85\xa8\0" /* offset 11967 */
+  "\xe6\x86\x8e\0" /* offset 11971 */
+  "\xe6\x87\xb2\0" /* offset 11975 */
+  "\xe6\x95\x8f\0" /* offset 11979 */
+  "\xe6\x97\xa2\0" /* offset 11983 */
+  "\xe6\x9a\x91\0" /* offset 11987 */
+  "\xe6\xa2\x85\0" /* offset 11991 */
+  "\xe6\xb5\xb7\0" /* offset 11995 */
+  "\xe6\xb8\x9a\0" /* offset 11999 */
+  "\xe6\xbc\xa2\0" /* offset 12003 */
+  "\xe7\x85\xae\0" /* offset 12007 */
+  "\xe7\x88\xab\0" /* offset 12011 */
+  "\xe7\x90\xa2\0" /* offset 12015 */
+  "\xe7\xa2\x91\0" /* offset 12019 */
+  "\xe7\xa5\x89\0" /* offset 12023 */
+  "\xe7\xa5\x88\0" /* offset 12027 */
+  "\xe7\xa5\x90\0" /* offset 12031 */
+  "\xe7\xa5\x96\0" /* offset 12035 */
+  "\xe7\xa6\x8d\0" /* offset 12039 */
+  "\xe7\xa6\x8e\0" /* offset 12043 */
+  "\xe7\xa9\x80\0" /* offset 12047 */
+  "\xe7\xaa\x81\0" /* offset 12051 */
+  "\xe7\xaf\x80\0" /* offset 12055 */
+  "\xe7\xb8\x89\0" /* offset 12059 */
+  "\xe7\xb9\x81\0" /* offset 12063 */
+  "\xe7\xbd\xb2\0" /* offset 12067 */
+  "\xe8\x80\x85\0" /* offset 12071 */
+  "\xe8\x87\xad\0" /* offset 12075 */
+  "\xe8\x89\xb9\0" /* offset 12079 */
+  "\xe8\x91\x97\0" /* offset 12083 */
+  "\xe8\xa4\x90\0" /* offset 12087 */
+  "\xe8\xa6\x96\0" /* offset 12091 */
+  "\xe8\xac\x81\0" /* offset 12095 */
+  "\xe8\xac\xb9\0" /* offset 12099 */
+  "\xe8\xb3\x93\0" /* offset 12103 */
+  "\xe8\xb4\x88\0" /* offset 12107 */
+  "\xe8\xbe\xb6\0" /* offset 12111 */
+  "\xe9\x9b\xa3\0" /* offset 12115 */
+  "\xe9\x9f\xbf\0" /* offset 12119 */
+  "\xe9\xa0\xbb\0" /* offset 12123 */
+  "\xe4\xb8\xa6\0" /* offset 12127 */
+  "\xe5\x86\xb5\0" /* offset 12131 */
+  "\xe5\x85\xa8\0" /* offset 12135 */
+  "\xe4\xbe\x80\0" /* offset 12139 */
+  "\xe5\x85\x85\0" /* offset 12143 */
+  "\xe5\x86\x80\0" /* offset 12147 */
+  "\xe5\x8b\x87\0" /* offset 12151 */
+  "\xe5\x8b\xba\0" /* offset 12155 */
+  "\xe5\x95\x95\0" /* offset 12159 */
+  "\xe5\x96\x99\0" /* offset 12163 */
+  "\xe5\x97\xa2\0" /* offset 12167 */
+  "\xe5\xa2\xb3\0" /* offset 12171 */
+  "\xe5\xa5\x84\0" /* offset 12175 */
+  "\xe5\xa5\x94\0" /* offset 12179 */
+  "\xe5\xa9\xa2\0" /* offset 12183 */
+  "\xe5\xac\xa8\0" /* offset 12187 */
+  "\xe5\xbb\x92\0" /* offset 12191 */
+  "\xe5\xbb\x99\0" /* offset 12195 */
+  "\xe5\xbd\xa9\0" /* offset 12199 */
+  "\xe5\xbe\xad\0" /* offset 12203 */
+  "\xe6\x83\x98\0" /* offset 12207 */
+  "\xe6\x85\x8e\0" /* offset 12211 */
+  "\xe6\x84\x88\0" /* offset 12215 */
+  "\xe6\x85\xa0\0" /* offset 12219 */
+  "\xe6\x88\xb4\0" /* offset 12223 */
+  "\xe6\x8f\x84\0" /* offset 12227 */
+  "\xe6\x90\x9c\0" /* offset 12231 */
+  "\xe6\x91\x92\0" /* offset 12235 */
+  "\xe6\x95\x96\0" /* offset 12239 */
+  "\xe6\x9c\x9b\0" /* offset 12243 */
+  "\xe6\x9d\x96\0" /* offset 12247 */
+  "\xe6\xbb\x9b\0" /* offset 12251 */
+  "\xe6\xbb\x8b\0" /* offset 12255 */
+  "\xe7\x80\x9e\0" /* offset 12259 */
+  "\xe7\x9e\xa7\0" /* offset 12263 */
+  "\xe7\x88\xb5\0" /* offset 12267 */
+  "\xe7\x8a\xaf\0" /* offset 12271 */
+  "\xe7\x91\xb1\0" /* offset 12275 */
+  "\xe7\x94\x86\0" /* offset 12279 */
+  "\xe7\x94\xbb\0" /* offset 12283 */
+  "\xe7\x98\x9d\0" /* offset 12287 */
+  "\xe7\x98\x9f\0" /* offset 12291 */
+  "\xe7\x9b\x9b\0" /* offset 12295 */
+  "\xe7\x9b\xb4\0" /* offset 12299 */
+  "\xe7\x9d\x8a\0" /* offset 12303 */
+  "\xe7\x9d\x80\0" /* offset 12307 */
+  "\xe7\xa3\x8c\0" /* offset 12311 */
+  "\xe7\xaa\xb1\0" /* offset 12315 */
+  "\xe7\xb1\xbb\0" /* offset 12319 */
+  "\xe7\xb5\x9b\0" /* offset 12323 */
+  "\xe7\xbc\xbe\0" /* offset 12327 */
+  "\xe8\x8d\x92\0" /* offset 12331 */
+  "\xe8\x8f\xaf\0" /* offset 12335 */
+  "\xe8\x9d\xb9\0" /* offset 12339 */
+  "\xe8\xa5\x81\0" /* offset 12343 */
+  "\xe8\xa6\x86\0" /* offset 12347 */
+  "\xe8\xaa\xbf\0" /* offset 12351 */
+  "\xe8\xab\x8b\0" /* offset 12355 */
+  "\xe8\xab\xad\0" /* offset 12359 */
+  "\xe8\xae\x8a\0" /* offset 12363 */
+  "\xe8\xbc\xb8\0" /* offset 12367 */
+  "\xe9\x81\xb2\0" /* offset 12371 */
+  "\xe9\x86\x99\0" /* offset 12375 */
+  "\xe9\x89\xb6\0" /* offset 12379 */
+  "\xe9\x99\xbc\0" /* offset 12383 */
+  "\xe9\x9f\x9b\0" /* offset 12387 */
+  "\xe9\xa0\x8b\0" /* offset 12391 */
+  "\xe9\xac\x92\0" /* offset 12395 */
+  "\xf0\xa2\xa1\x8a\0" /* offset 12399 */
+  "\xf0\xa2\xa1\x84\0" /* offset 12404 */
+  "\xf0\xa3\x8f\x95\0" /* offset 12409 */
+  "\xe3\xae\x9d\0" /* offset 12414 */
+  "\xe4\x80\x98\0" /* offset 12418 */
+  "\xe4\x80\xb9\0" /* offset 12422 */
+  "\xf0\xa5\x89\x89\0" /* offset 12426 */
+  "\xf0\xa5\xb3\x90\0" /* offset 12431 */
+  "\xf0\xa7\xbb\x93\0" /* offset 12436 */
+  "\xe9\xbd\x83\0" /* offset 12441 */
+  "\xe9\xbe\x8e\0" /* offset 12445 */
+  "\x66\x66\0" /* offset 12449 */
+  "\x66\x69\0" /* offset 12452 */
+  "\x66\x6c\0" /* offset 12455 */
+  "\x66\x66\x69\0" /* offset 12458 */
+  "\x66\x66\x6c\0" /* offset 12462 */
+  "\x73\x74\0" /* offset 12466 */
+  "\xd5\xb4\xd5\xb6\0" /* offset 12469 */
+  "\xd5\xb4\xd5\xa5\0" /* offset 12474 */
+  "\xd5\xb4\xd5\xab\0" /* offset 12479 */
+  "\xd5\xbe\xd5\xb6\0" /* offset 12484 */
+  "\xd5\xb4\xd5\xad\0" /* offset 12489 */
+  "\xd7\x99\xd6\xb4\0" /* offset 12494 */
+  "\xd7\xb2\xd6\xb7\0" /* offset 12499 */
+  "\xd7\xa2\0" /* offset 12504 */
+  "\xd7\x94\0" /* offset 12507 */
+  "\xd7\x9b\0" /* offset 12510 */
+  "\xd7\x9c\0" /* offset 12513 */
+  "\xd7\x9d\0" /* offset 12516 */
+  "\xd7\xa8\0" /* offset 12519 */
+  "\xd7\xaa\0" /* offset 12522 */
+  "\xd7\xa9\xd7\x81\0" /* offset 12525 */
+  "\xd7\xa9\xd7\x82\0" /* offset 12530 */
+  "\xd7\xa9\xd6\xbc\xd7\x81\0" /* offset 12535 */
+  "\xd7\xa9\xd6\xbc\xd7\x82\0" /* offset 12542 */
+  "\xd7\x90\xd6\xb7\0" /* offset 12549 */
+  "\xd7\x90\xd6\xb8\0" /* offset 12554 */
+  "\xd7\x90\xd6\xbc\0" /* offset 12559 */
+  "\xd7\x91\xd6\xbc\0" /* offset 12564 */
+  "\xd7\x92\xd6\xbc\0" /* offset 12569 */
+  "\xd7\x93\xd6\xbc\0" /* offset 12574 */
+  "\xd7\x94\xd6\xbc\0" /* offset 12579 */
+  "\xd7\x95\xd6\xbc\0" /* offset 12584 */
+  "\xd7\x96\xd6\xbc\0" /* offset 12589 */
+  "\xd7\x98\xd6\xbc\0" /* offset 12594 */
+  "\xd7\x99\xd6\xbc\0" /* offset 12599 */
+  "\xd7\x9a\xd6\xbc\0" /* offset 12604 */
+  "\xd7\x9b\xd6\xbc\0" /* offset 12609 */
+  "\xd7\x9c\xd6\xbc\0" /* offset 12614 */
+  "\xd7\x9e\xd6\xbc\0" /* offset 12619 */
+  "\xd7\xa0\xd6\xbc\0" /* offset 12624 */
+  "\xd7\xa1\xd6\xbc\0" /* offset 12629 */
+  "\xd7\xa3\xd6\xbc\0" /* offset 12634 */
+  "\xd7\xa4\xd6\xbc\0" /* offset 12639 */
+  "\xd7\xa6\xd6\xbc\0" /* offset 12644 */
+  "\xd7\xa7\xd6\xbc\0" /* offset 12649 */
+  "\xd7\xa8\xd6\xbc\0" /* offset 12654 */
+  "\xd7\xa9\xd6\xbc\0" /* offset 12659 */
+  "\xd7\xaa\xd6\xbc\0" /* offset 12664 */
+  "\xd7\x95\xd6\xb9\0" /* offset 12669 */
+  "\xd7\x91\xd6\xbf\0" /* offset 12674 */
+  "\xd7\x9b\xd6\xbf\0" /* offset 12679 */
+  "\xd7\xa4\xd6\xbf\0" /* offset 12684 */
+  "\xd7\x90\xd7\x9c\0" /* offset 12689 */
+  "\xd9\xb1\0" /* offset 12694 */
+  "\xd9\xbb\0" /* offset 12697 */
+  "\xd9\xbe\0" /* offset 12700 */
+  "\xda\x80\0" /* offset 12703 */
+  "\xd9\xba\0" /* offset 12706 */
+  "\xd9\xbf\0" /* offset 12709 */
+  "\xd9\xb9\0" /* offset 12712 */
+  "\xda\xa4\0" /* offset 12715 */
+  "\xda\xa6\0" /* offset 12718 */
+  "\xda\x84\0" /* offset 12721 */
+  "\xda\x83\0" /* offset 12724 */
+  "\xda\x86\0" /* offset 12727 */
+  "\xda\x87\0" /* offset 12730 */
+  "\xda\x8d\0" /* offset 12733 */
+  "\xda\x8c\0" /* offset 12736 */
+  "\xda\x8e\0" /* offset 12739 */
+  "\xda\x88\0" /* offset 12742 */
+  "\xda\x98\0" /* offset 12745 */
+  "\xda\x91\0" /* offset 12748 */
+  "\xda\xa9\0" /* offset 12751 */
+  "\xda\xaf\0" /* offset 12754 */
+  "\xda\xb3\0" /* offset 12757 */
+  "\xda\xb1\0" /* offset 12760 */
+  "\xda\xba\0" /* offset 12763 */
+  "\xda\xbb\0" /* offset 12766 */
+  "\xdb\x81\0" /* offset 12769 */
+  "\xda\xbe\0" /* offset 12772 */
+  "\xdb\x92\0" /* offset 12775 */
+  "\xda\xad\0" /* offset 12778 */
+  "\xdb\x87\0" /* offset 12781 */
+  "\xdb\x86\0" /* offset 12784 */
+  "\xdb\x88\0" /* offset 12787 */
+  "\xdb\x8b\0" /* offset 12790 */
+  "\xdb\x85\0" /* offset 12793 */
+  "\xdb\x89\0" /* offset 12796 */
+  "\xdb\x90\0" /* offset 12799 */
+  "\xd9\x89\0" /* offset 12802 */
+  "\xd9\x8a\xd9\x94\xd8\xa7\0" /* offset 12805 */
+  "\xd9\x8a\xd9\x94\xdb\x95\0" /* offset 12812 */
+  "\xd9\x8a\xd9\x94\xd9\x88\0" /* offset 12819 */
+  "\xd9\x8a\xd9\x94\xdb\x87\0" /* offset 12826 */
+  "\xd9\x8a\xd9\x94\xdb\x86\0" /* offset 12833 */
+  "\xd9\x8a\xd9\x94\xdb\x88\0" /* offset 12840 */
+  "\xd9\x8a\xd9\x94\xdb\x90\0" /* offset 12847 */
+  "\xd9\x8a\xd9\x94\xd9\x89\0" /* offset 12854 */
+  "\xdb\x8c\0" /* offset 12861 */
+  "\xd9\x8a\xd9\x94\xd8\xac\0" /* offset 12864 */
+  "\xd9\x8a\xd9\x94\xd8\xad\0" /* offset 12871 */
+  "\xd9\x8a\xd9\x94\xd9\x85\0" /* offset 12878 */
+  "\xd9\x8a\xd9\x94\xd9\x8a\0" /* offset 12885 */
+  "\xd8\xa8\xd8\xac\0" /* offset 12892 */
+  "\xd8\xa8\xd8\xad\0" /* offset 12897 */
+  "\xd8\xa8\xd8\xae\0" /* offset 12902 */
+  "\xd8\xa8\xd9\x85\0" /* offset 12907 */
+  "\xd8\xa8\xd9\x89\0" /* offset 12912 */
+  "\xd8\xa8\xd9\x8a\0" /* offset 12917 */
+  "\xd8\xaa\xd8\xac\0" /* offset 12922 */
+  "\xd8\xaa\xd8\xad\0" /* offset 12927 */
+  "\xd8\xaa\xd8\xae\0" /* offset 12932 */
+  "\xd8\xaa\xd9\x85\0" /* offset 12937 */
+  "\xd8\xaa\xd9\x89\0" /* offset 12942 */
+  "\xd8\xaa\xd9\x8a\0" /* offset 12947 */
+  "\xd8\xab\xd8\xac\0" /* offset 12952 */
+  "\xd8\xab\xd9\x85\0" /* offset 12957 */
+  "\xd8\xab\xd9\x89\0" /* offset 12962 */
+  "\xd8\xab\xd9\x8a\0" /* offset 12967 */
+  "\xd8\xac\xd8\xad\0" /* offset 12972 */
+  "\xd8\xac\xd9\x85\0" /* offset 12977 */
+  "\xd8\xad\xd8\xac\0" /* offset 12982 */
+  "\xd8\xad\xd9\x85\0" /* offset 12987 */
+  "\xd8\xae\xd8\xac\0" /* offset 12992 */
+  "\xd8\xae\xd8\xad\0" /* offset 12997 */
+  "\xd8\xae\xd9\x85\0" /* offset 13002 */
+  "\xd8\xb3\xd8\xac\0" /* offset 13007 */
+  "\xd8\xb3\xd8\xad\0" /* offset 13012 */
+  "\xd8\xb3\xd8\xae\0" /* offset 13017 */
+  "\xd8\xb3\xd9\x85\0" /* offset 13022 */
+  "\xd8\xb5\xd8\xad\0" /* offset 13027 */
+  "\xd8\xb5\xd9\x85\0" /* offset 13032 */
+  "\xd8\xb6\xd8\xac\0" /* offset 13037 */
+  "\xd8\xb6\xd8\xad\0" /* offset 13042 */
+  "\xd8\xb6\xd8\xae\0" /* offset 13047 */
+  "\xd8\xb6\xd9\x85\0" /* offset 13052 */
+  "\xd8\xb7\xd8\xad\0" /* offset 13057 */
+  "\xd8\xb7\xd9\x85\0" /* offset 13062 */
+  "\xd8\xb8\xd9\x85\0" /* offset 13067 */
+  "\xd8\xb9\xd8\xac\0" /* offset 13072 */
+  "\xd8\xb9\xd9\x85\0" /* offset 13077 */
+  "\xd8\xba\xd8\xac\0" /* offset 13082 */
+  "\xd8\xba\xd9\x85\0" /* offset 13087 */
+  "\xd9\x81\xd8\xac\0" /* offset 13092 */
+  "\xd9\x81\xd8\xad\0" /* offset 13097 */
+  "\xd9\x81\xd8\xae\0" /* offset 13102 */
+  "\xd9\x81\xd9\x85\0" /* offset 13107 */
+  "\xd9\x81\xd9\x89\0" /* offset 13112 */
+  "\xd9\x81\xd9\x8a\0" /* offset 13117 */
+  "\xd9\x82\xd8\xad\0" /* offset 13122 */
+  "\xd9\x82\xd9\x85\0" /* offset 13127 */
+  "\xd9\x82\xd9\x89\0" /* offset 13132 */
+  "\xd9\x82\xd9\x8a\0" /* offset 13137 */
+  "\xd9\x83\xd8\xa7\0" /* offset 13142 */
+  "\xd9\x83\xd8\xac\0" /* offset 13147 */
+  "\xd9\x83\xd8\xad\0" /* offset 13152 */
+  "\xd9\x83\xd8\xae\0" /* offset 13157 */
+  "\xd9\x83\xd9\x84\0" /* offset 13162 */
+  "\xd9\x83\xd9\x85\0" /* offset 13167 */
+  "\xd9\x83\xd9\x89\0" /* offset 13172 */
+  "\xd9\x83\xd9\x8a\0" /* offset 13177 */
+  "\xd9\x84\xd8\xac\0" /* offset 13182 */
+  "\xd9\x84\xd8\xad\0" /* offset 13187 */
+  "\xd9\x84\xd8\xae\0" /* offset 13192 */
+  "\xd9\x84\xd9\x85\0" /* offset 13197 */
+  "\xd9\x84\xd9\x89\0" /* offset 13202 */
+  "\xd9\x84\xd9\x8a\0" /* offset 13207 */
+  "\xd9\x85\xd8\xac\0" /* offset 13212 */
+  "\xd9\x85\xd8\xad\0" /* offset 13217 */
+  "\xd9\x85\xd8\xae\0" /* offset 13222 */
+  "\xd9\x85\xd9\x85\0" /* offset 13227 */
+  "\xd9\x85\xd9\x89\0" /* offset 13232 */
+  "\xd9\x85\xd9\x8a\0" /* offset 13237 */
+  "\xd9\x86\xd8\xac\0" /* offset 13242 */
+  "\xd9\x86\xd8\xad\0" /* offset 13247 */
+  "\xd9\x86\xd8\xae\0" /* offset 13252 */
+  "\xd9\x86\xd9\x85\0" /* offset 13257 */
+  "\xd9\x86\xd9\x89\0" /* offset 13262 */
+  "\xd9\x86\xd9\x8a\0" /* offset 13267 */
+  "\xd9\x87\xd8\xac\0" /* offset 13272 */
+  "\xd9\x87\xd9\x85\0" /* offset 13277 */
+  "\xd9\x87\xd9\x89\0" /* offset 13282 */
+  "\xd9\x87\xd9\x8a\0" /* offset 13287 */
+  "\xd9\x8a\xd8\xac\0" /* offset 13292 */
+  "\xd9\x8a\xd8\xad\0" /* offset 13297 */
+  "\xd9\x8a\xd8\xae\0" /* offset 13302 */
+  "\xd9\x8a\xd9\x85\0" /* offset 13307 */
+  "\xd9\x8a\xd9\x89\0" /* offset 13312 */
+  "\xd9\x8a\xd9\x8a\0" /* offset 13317 */
+  "\xd8\xb0\xd9\xb0\0" /* offset 13322 */
+  "\xd8\xb1\xd9\xb0\0" /* offset 13327 */
+  "\xd9\x89\xd9\xb0\0" /* offset 13332 */
+  "\x20\xd9\x8c\xd9\x91\0" /* offset 13337 */
+  "\x20\xd9\x8d\xd9\x91\0" /* offset 13343 */
+  "\x20\xd9\x8e\xd9\x91\0" /* offset 13349 */
+  "\x20\xd9\x8f\xd9\x91\0" /* offset 13355 */
+  "\x20\xd9\x90\xd9\x91\0" /* offset 13361 */
+  "\x20\xd9\x91\xd9\xb0\0" /* offset 13367 */
+  "\xd9\x8a\xd9\x94\xd8\xb1\0" /* offset 13373 */
+  "\xd9\x8a\xd9\x94\xd8\xb2\0" /* offset 13380 */
+  "\xd9\x8a\xd9\x94\xd9\x86\0" /* offset 13387 */
+  "\xd8\xa8\xd8\xb1\0" /* offset 13394 */
+  "\xd8\xa8\xd8\xb2\0" /* offset 13399 */
+  "\xd8\xa8\xd9\x86\0" /* offset 13404 */
+  "\xd8\xaa\xd8\xb1\0" /* offset 13409 */
+  "\xd8\xaa\xd8\xb2\0" /* offset 13414 */
+  "\xd8\xaa\xd9\x86\0" /* offset 13419 */
+  "\xd8\xab\xd8\xb1\0" /* offset 13424 */
+  "\xd8\xab\xd8\xb2\0" /* offset 13429 */
+  "\xd8\xab\xd9\x86\0" /* offset 13434 */
+  "\xd9\x85\xd8\xa7\0" /* offset 13439 */
+  "\xd9\x86\xd8\xb1\0" /* offset 13444 */
+  "\xd9\x86\xd8\xb2\0" /* offset 13449 */
+  "\xd9\x86\xd9\x86\0" /* offset 13454 */
+  "\xd9\x8a\xd8\xb1\0" /* offset 13459 */
+  "\xd9\x8a\xd8\xb2\0" /* offset 13464 */
+  "\xd9\x8a\xd9\x86\0" /* offset 13469 */
+  "\xd9\x8a\xd9\x94\xd8\xae\0" /* offset 13474 */
+  "\xd9\x8a\xd9\x94\xd9\x87\0" /* offset 13481 */
+  "\xd8\xa8\xd9\x87\0" /* offset 13488 */
+  "\xd8\xaa\xd9\x87\0" /* offset 13493 */
+  "\xd8\xb5\xd8\xae\0" /* offset 13498 */
+  "\xd9\x84\xd9\x87\0" /* offset 13503 */
+  "\xd9\x86\xd9\x87\0" /* offset 13508 */
+  "\xd9\x87\xd9\xb0\0" /* offset 13513 */
+  "\xd9\x8a\xd9\x87\0" /* offset 13518 */
+  "\xd8\xab\xd9\x87\0" /* offset 13523 */
+  "\xd8\xb3\xd9\x87\0" /* offset 13528 */
+  "\xd8\xb4\xd9\x85\0" /* offset 13533 */
+  "\xd8\xb4\xd9\x87\0" /* offset 13538 */
+  "\xd9\x80\xd9\x8e\xd9\x91\0" /* offset 13543 */
+  "\xd9\x80\xd9\x8f\xd9\x91\0" /* offset 13550 */
+  "\xd9\x80\xd9\x90\xd9\x91\0" /* offset 13557 */
+  "\xd8\xb7\xd9\x89\0" /* offset 13564 */
+  "\xd8\xb7\xd9\x8a\0" /* offset 13569 */
+  "\xd8\xb9\xd9\x89\0" /* offset 13574 */
+  "\xd8\xb9\xd9\x8a\0" /* offset 13579 */
+  "\xd8\xba\xd9\x89\0" /* offset 13584 */
+  "\xd8\xba\xd9\x8a\0" /* offset 13589 */
+  "\xd8\xb3\xd9\x89\0" /* offset 13594 */
+  "\xd8\xb3\xd9\x8a\0" /* offset 13599 */
+  "\xd8\xb4\xd9\x89\0" /* offset 13604 */
+  "\xd8\xb4\xd9\x8a\0" /* offset 13609 */
+  "\xd8\xad\xd9\x89\0" /* offset 13614 */
+  "\xd8\xad\xd9\x8a\0" /* offset 13619 */
+  "\xd8\xac\xd9\x89\0" /* offset 13624 */
+  "\xd8\xac\xd9\x8a\0" /* offset 13629 */
+  "\xd8\xae\xd9\x89\0" /* offset 13634 */
+  "\xd8\xae\xd9\x8a\0" /* offset 13639 */
+  "\xd8\xb5\xd9\x89\0" /* offset 13644 */
+  "\xd8\xb5\xd9\x8a\0" /* offset 13649 */
+  "\xd8\xb6\xd9\x89\0" /* offset 13654 */
+  "\xd8\xb6\xd9\x8a\0" /* offset 13659 */
+  "\xd8\xb4\xd8\xac\0" /* offset 13664 */
+  "\xd8\xb4\xd8\xad\0" /* offset 13669 */
+  "\xd8\xb4\xd8\xae\0" /* offset 13674 */
+  "\xd8\xb4\xd8\xb1\0" /* offset 13679 */
+  "\xd8\xb3\xd8\xb1\0" /* offset 13684 */
+  "\xd8\xb5\xd8\xb1\0" /* offset 13689 */
+  "\xd8\xb6\xd8\xb1\0" /* offset 13694 */
+  "\xd8\xa7\xd9\x8b\0" /* offset 13699 */
+  "\xd8\xaa\xd8\xac\xd9\x85\0" /* offset 13704 */
+  "\xd8\xaa\xd8\xad\xd8\xac\0" /* offset 13711 */
+  "\xd8\xaa\xd8\xad\xd9\x85\0" /* offset 13718 */
+  "\xd8\xaa\xd8\xae\xd9\x85\0" /* offset 13725 */
+  "\xd8\xaa\xd9\x85\xd8\xac\0" /* offset 13732 */
+  "\xd8\xaa\xd9\x85\xd8\xad\0" /* offset 13739 */
+  "\xd8\xaa\xd9\x85\xd8\xae\0" /* offset 13746 */
+  "\xd8\xac\xd9\x85\xd8\xad\0" /* offset 13753 */
+  "\xd8\xad\xd9\x85\xd9\x8a\0" /* offset 13760 */
+  "\xd8\xad\xd9\x85\xd9\x89\0" /* offset 13767 */
+  "\xd8\xb3\xd8\xad\xd8\xac\0" /* offset 13774 */
+  "\xd8\xb3\xd8\xac\xd8\xad\0" /* offset 13781 */
+  "\xd8\xb3\xd8\xac\xd9\x89\0" /* offset 13788 */
+  "\xd8\xb3\xd9\x85\xd8\xad\0" /* offset 13795 */
+  "\xd8\xb3\xd9\x85\xd8\xac\0" /* offset 13802 */
+  "\xd8\xb3\xd9\x85\xd9\x85\0" /* offset 13809 */
+  "\xd8\xb5\xd8\xad\xd8\xad\0" /* offset 13816 */
+  "\xd8\xb5\xd9\x85\xd9\x85\0" /* offset 13823 */
+  "\xd8\xb4\xd8\xad\xd9\x85\0" /* offset 13830 */
+  "\xd8\xb4\xd8\xac\xd9\x8a\0" /* offset 13837 */
+  "\xd8\xb4\xd9\x85\xd8\xae\0" /* offset 13844 */
+  "\xd8\xb4\xd9\x85\xd9\x85\0" /* offset 13851 */
+  "\xd8\xb6\xd8\xad\xd9\x89\0" /* offset 13858 */
+  "\xd8\xb6\xd8\xae\xd9\x85\0" /* offset 13865 */
+  "\xd8\xb7\xd9\x85\xd8\xad\0" /* offset 13872 */
+  "\xd8\xb7\xd9\x85\xd9\x85\0" /* offset 13879 */
+  "\xd8\xb7\xd9\x85\xd9\x8a\0" /* offset 13886 */
+  "\xd8\xb9\xd8\xac\xd9\x85\0" /* offset 13893 */
+  "\xd8\xb9\xd9\x85\xd9\x85\0" /* offset 13900 */
+  "\xd8\xb9\xd9\x85\xd9\x89\0" /* offset 13907 */
+  "\xd8\xba\xd9\x85\xd9\x85\0" /* offset 13914 */
+  "\xd8\xba\xd9\x85\xd9\x8a\0" /* offset 13921 */
+  "\xd8\xba\xd9\x85\xd9\x89\0" /* offset 13928 */
+  "\xd9\x81\xd8\xae\xd9\x85\0" /* offset 13935 */
+  "\xd9\x82\xd9\x85\xd8\xad\0" /* offset 13942 */
+  "\xd9\x82\xd9\x85\xd9\x85\0" /* offset 13949 */
+  "\xd9\x84\xd8\xad\xd9\x85\0" /* offset 13956 */
+  "\xd9\x84\xd8\xad\xd9\x8a\0" /* offset 13963 */
+  "\xd9\x84\xd8\xad\xd9\x89\0" /* offset 13970 */
+  "\xd9\x84\xd8\xac\xd8\xac\0" /* offset 13977 */
+  "\xd9\x84\xd8\xae\xd9\x85\0" /* offset 13984 */
+  "\xd9\x84\xd9\x85\xd8\xad\0" /* offset 13991 */
+  "\xd9\x85\xd8\xad\xd8\xac\0" /* offset 13998 */
+  "\xd9\x85\xd8\xad\xd9\x85\0" /* offset 14005 */
+  "\xd9\x85\xd8\xad\xd9\x8a\0" /* offset 14012 */
+  "\xd9\x85\xd8\xac\xd8\xad\0" /* offset 14019 */
+  "\xd9\x85\xd8\xac\xd9\x85\0" /* offset 14026 */
+  "\xd9\x85\xd8\xae\xd8\xac\0" /* offset 14033 */
+  "\xd9\x85\xd8\xae\xd9\x85\0" /* offset 14040 */
+  "\xd9\x85\xd8\xac\xd8\xae\0" /* offset 14047 */
+  "\xd9\x87\xd9\x85\xd8\xac\0" /* offset 14054 */
+  "\xd9\x87\xd9\x85\xd9\x85\0" /* offset 14061 */
+  "\xd9\x86\xd8\xad\xd9\x85\0" /* offset 14068 */
+  "\xd9\x86\xd8\xad\xd9\x89\0" /* offset 14075 */
+  "\xd9\x86\xd8\xac\xd9\x85\0" /* offset 14082 */
+  "\xd9\x86\xd8\xac\xd9\x89\0" /* offset 14089 */
+  "\xd9\x86\xd9\x85\xd9\x8a\0" /* offset 14096 */
+  "\xd9\x86\xd9\x85\xd9\x89\0" /* offset 14103 */
+  "\xd9\x8a\xd9\x85\xd9\x85\0" /* offset 14110 */
+  "\xd8\xa8\xd8\xae\xd9\x8a\0" /* offset 14117 */
+  "\xd8\xaa\xd8\xac\xd9\x8a\0" /* offset 14124 */
+  "\xd8\xaa\xd8\xac\xd9\x89\0" /* offset 14131 */
+  "\xd8\xaa\xd8\xae\xd9\x8a\0" /* offset 14138 */
+  "\xd8\xaa\xd8\xae\xd9\x89\0" /* offset 14145 */
+  "\xd8\xaa\xd9\x85\xd9\x8a\0" /* offset 14152 */
+  "\xd8\xaa\xd9\x85\xd9\x89\0" /* offset 14159 */
+  "\xd8\xac\xd9\x85\xd9\x8a\0" /* offset 14166 */
+  "\xd8\xac\xd8\xad\xd9\x89\0" /* offset 14173 */
+  "\xd8\xac\xd9\x85\xd9\x89\0" /* offset 14180 */
+  "\xd8\xb3\xd8\xae\xd9\x89\0" /* offset 14187 */
+  "\xd8\xb5\xd8\xad\xd9\x8a\0" /* offset 14194 */
+  "\xd8\xb4\xd8\xad\xd9\x8a\0" /* offset 14201 */
+  "\xd8\xb6\xd8\xad\xd9\x8a\0" /* offset 14208 */
+  "\xd9\x84\xd8\xac\xd9\x8a\0" /* offset 14215 */
+  "\xd9\x84\xd9\x85\xd9\x8a\0" /* offset 14222 */
+  "\xd9\x8a\xd8\xad\xd9\x8a\0" /* offset 14229 */
+  "\xd9\x8a\xd8\xac\xd9\x8a\0" /* offset 14236 */
+  "\xd9\x8a\xd9\x85\xd9\x8a\0" /* offset 14243 */
+  "\xd9\x85\xd9\x85\xd9\x8a\0" /* offset 14250 */
+  "\xd9\x82\xd9\x85\xd9\x8a\0" /* offset 14257 */
+  "\xd9\x86\xd8\xad\xd9\x8a\0" /* offset 14264 */
+  "\xd8\xb9\xd9\x85\xd9\x8a\0" /* offset 14271 */
+  "\xd9\x83\xd9\x85\xd9\x8a\0" /* offset 14278 */
+  "\xd9\x86\xd8\xac\xd8\xad\0" /* offset 14285 */
+  "\xd9\x85\xd8\xae\xd9\x8a\0" /* offset 14292 */
+  "\xd9\x84\xd8\xac\xd9\x85\0" /* offset 14299 */
+  "\xd9\x83\xd9\x85\xd9\x85\0" /* offset 14306 */
+  "\xd8\xac\xd8\xad\xd9\x8a\0" /* offset 14313 */
+  "\xd8\xad\xd8\xac\xd9\x8a\0" /* offset 14320 */
+  "\xd9\x85\xd8\xac\xd9\x8a\0" /* offset 14327 */
+  "\xd9\x81\xd9\x85\xd9\x8a\0" /* offset 14334 */
+  "\xd8\xa8\xd8\xad\xd9\x8a\0" /* offset 14341 */
+  "\xd8\xb3\xd8\xae\xd9\x8a\0" /* offset 14348 */
+  "\xd9\x86\xd8\xac\xd9\x8a\0" /* offset 14355 */
+  "\xd8\xb5\xd9\x84\xdb\x92\0" /* offset 14362 */
+  "\xd9\x82\xd9\x84\xdb\x92\0" /* offset 14369 */
+  "\xd8\xa7\xd9\x84\xd9\x84\xd9\x87\0" /* offset 14376 */
+  "\xd8\xa7\xd9\x83\xd8\xa8\xd8\xb1\0" /* offset 14385 */
+  "\xd9\x85\xd8\xad\xd9\x85\xd8\xaf\0" /* offset 14394 */
+  "\xd8\xb5\xd9\x84\xd8\xb9\xd9\x85\0" /* offset 14403 */
+  "\xd8\xb1\xd8\xb3\xd9\x88\xd9\x84\0" /* offset 14412 */
+  "\xd8\xb9\xd9\x84\xd9\x8a\xd9\x87\0" /* offset 14421 */
+  "\xd9\x88\xd8\xb3\xd9\x84\xd9\x85\0" /* offset 14430 */
+  "\xd8\xb5\xd9\x84\xd9\x89\0" /* offset 14439 */
+  "\xd8\xb5\xd9\x84\xd9\x89\x20\xd8\xa7\xd9\x84\xd9\x84\xd9\x87\x20\xd8\xb9\xd9\x84\xd9\x8a\xd9\x87\x20\xd9\x88\xd8\xb3\xd9\x84\xd9\x85\0" /* offset 14446 */
+  "\xd8\xac\xd9\x84\x20\xd8\xac\xd9\x84\xd8\xa7\xd9\x84\xd9\x87\0" /* offset 14480 */
+  "\xd8\xb1\xdb\x8c\xd8\xa7\xd9\x84\0" /* offset 14496 */
+  "\x2c\0" /* offset 14505 */
+  "\xe3\x80\x81\0" /* offset 14507 */
+  "\xe3\x80\x82\0" /* offset 14511 */
+  "\x3a\0" /* offset 14515 */
+  "\x21\0" /* offset 14517 */
+  "\x3f\0" /* offset 14519 */
+  "\xe3\x80\x96\0" /* offset 14521 */
+  "\xe3\x80\x97\0" /* offset 14525 */
+  "\xe2\x80\x94\0" /* offset 14529 */
+  "\xe2\x80\x93\0" /* offset 14533 */
+  "\x5f\0" /* offset 14537 */
+  "\x7b\0" /* offset 14539 */
+  "\x7d\0" /* offset 14541 */
+  "\xe3\x80\x94\0" /* offset 14543 */
+  "\xe3\x80\x95\0" /* offset 14547 */
+  "\xe3\x80\x90\0" /* offset 14551 */
+  "\xe3\x80\x91\0" /* offset 14555 */
+  "\xe3\x80\x8a\0" /* offset 14559 */
+  "\xe3\x80\x8b\0" /* offset 14563 */
+  "\xe3\x80\x8c\0" /* offset 14567 */
+  "\xe3\x80\x8d\0" /* offset 14571 */
+  "\xe3\x80\x8e\0" /* offset 14575 */
+  "\xe3\x80\x8f\0" /* offset 14579 */
+  "\x5b\0" /* offset 14583 */
+  "\x5d\0" /* offset 14585 */
+  "\x23\0" /* offset 14587 */
+  "\x26\0" /* offset 14589 */
+  "\x2a\0" /* offset 14591 */
+  "\x2d\0" /* offset 14593 */
+  "\x3c\0" /* offset 14595 */
+  "\x3e\0" /* offset 14597 */
+  "\x5c\0" /* offset 14599 */
+  "\x24\0" /* offset 14601 */
+  "\x25\0" /* offset 14603 */
+  "\x40\0" /* offset 14605 */
+  "\x20\xd9\x8b\0" /* offset 14607 */
+  "\xd9\x80\xd9\x8b\0" /* offset 14611 */
+  "\x20\xd9\x8c\0" /* offset 14616 */
+  "\x20\xd9\x8d\0" /* offset 14620 */
+  "\x20\xd9\x8e\0" /* offset 14624 */
+  "\xd9\x80\xd9\x8e\0" /* offset 14628 */
+  "\x20\xd9\x8f\0" /* offset 14633 */
+  "\xd9\x80\xd9\x8f\0" /* offset 14637 */
+  "\x20\xd9\x90\0" /* offset 14642 */
+  "\xd9\x80\xd9\x90\0" /* offset 14646 */
+  "\x20\xd9\x91\0" /* offset 14651 */
+  "\xd9\x80\xd9\x91\0" /* offset 14655 */
+  "\x20\xd9\x92\0" /* offset 14660 */
+  "\xd9\x80\xd9\x92\0" /* offset 14664 */
+  "\xd8\xa1\0" /* offset 14669 */
+  "\xd8\xa7\0" /* offset 14672 */
+  "\xd8\xa8\0" /* offset 14675 */
+  "\xd8\xa9\0" /* offset 14678 */
+  "\xd8\xaa\0" /* offset 14681 */
+  "\xd8\xab\0" /* offset 14684 */
+  "\xd8\xac\0" /* offset 14687 */
+  "\xd8\xad\0" /* offset 14690 */
+  "\xd8\xae\0" /* offset 14693 */
+  "\xd8\xaf\0" /* offset 14696 */
+  "\xd8\xb0\0" /* offset 14699 */
+  "\xd8\xb1\0" /* offset 14702 */
+  "\xd8\xb2\0" /* offset 14705 */
+  "\xd8\xb3\0" /* offset 14708 */
+  "\xd8\xb4\0" /* offset 14711 */
+  "\xd8\xb5\0" /* offset 14714 */
+  "\xd8\xb6\0" /* offset 14717 */
+  "\xd8\xb7\0" /* offset 14720 */
+  "\xd8\xb8\0" /* offset 14723 */
+  "\xd8\xb9\0" /* offset 14726 */
+  "\xd8\xba\0" /* offset 14729 */
+  "\xd9\x81\0" /* offset 14732 */
+  "\xd9\x82\0" /* offset 14735 */
+  "\xd9\x83\0" /* offset 14738 */
+  "\xd9\x84\0" /* offset 14741 */
+  "\xd9\x85\0" /* offset 14744 */
+  "\xd9\x86\0" /* offset 14747 */
+  "\xd9\x87\0" /* offset 14750 */
+  "\xd9\x88\0" /* offset 14753 */
+  "\xd9\x8a\0" /* offset 14756 */
+  "\xd9\x84\xd8\xa7\xd9\x93\0" /* offset 14759 */
+  "\xd9\x84\xd8\xa7\xd9\x94\0" /* offset 14766 */
+  "\xd9\x84\xd8\xa7\xd9\x95\0" /* offset 14773 */
+  "\xd9\x84\xd8\xa7\0" /* offset 14780 */
+  "\x22\0" /* offset 14785 */
+  "\x27\0" /* offset 14787 */
+  "\x2f\0" /* offset 14789 */
+  "\x5e\0" /* offset 14791 */
+  "\x7c\0" /* offset 14793 */
+  "\x7e\0" /* offset 14795 */
+  "\xe2\xa6\x85\0" /* offset 14797 */
+  "\xe2\xa6\x86\0" /* offset 14801 */
+  "\xe3\x83\xbb\0" /* offset 14805 */
+  "\xe3\x82\xa1\0" /* offset 14809 */
+  "\xe3\x82\xa3\0" /* offset 14813 */
+  "\xe3\x82\xa5\0" /* offset 14817 */
+  "\xe3\x82\xa7\0" /* offset 14821 */
+  "\xe3\x82\xa9\0" /* offset 14825 */
+  "\xe3\x83\xa3\0" /* offset 14829 */
+  "\xe3\x83\xa5\0" /* offset 14833 */
+  "\xe3\x83\xa7\0" /* offset 14837 */
+  "\xe3\x83\x83\0" /* offset 14841 */
+  "\xe3\x83\xbc\0" /* offset 14845 */
+  "\xe3\x83\xb3\0" /* offset 14849 */
+  "\xe3\x82\x99\0" /* offset 14853 */
+  "\xe3\x82\x9a\0" /* offset 14857 */
+  "\xc2\xa2\0" /* offset 14861 */
+  "\xc2\xa3\0" /* offset 14864 */
+  "\xc2\xac\0" /* offset 14867 */
+  "\xc2\xa6\0" /* offset 14870 */
+  "\xc2\xa5\0" /* offset 14873 */
+  "\xe2\x82\xa9\0" /* offset 14876 */
+  "\xe2\x94\x82\0" /* offset 14880 */
+  "\xe2\x86\x90\0" /* offset 14884 */
+  "\xe2\x86\x91\0" /* offset 14888 */
+  "\xe2\x86\x92\0" /* offset 14892 */
+  "\xe2\x86\x93\0" /* offset 14896 */
+  "\xe2\x96\xa0\0" /* offset 14900 */
+  "\xe2\x97\x8b\0" /* offset 14904 */
+  "\xf0\x9d\x85\x97\xf0\x9d\x85\xa5\0" /* offset 14908 */
+  "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\0" /* offset 14917 */
+  "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xae\0" /* offset 14926 */
+  "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xaf\0" /* offset 14939 */
+  "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xb0\0" /* offset 14952 */
+  "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xb1\0" /* offset 14965 */
+  "\xf0\x9d\x85\x98\xf0\x9d\x85\xa5\xf0\x9d\x85\xb2\0" /* offset 14978 */
+  "\xf0\x9d\x86\xb9\xf0\x9d\x85\xa5\0" /* offset 14991 */
+  "\xf0\x9d\x86\xba\xf0\x9d\x85\xa5\0" /* offset 15000 */
+  "\xf0\x9d\x86\xb9\xf0\x9d\x85\xa5\xf0\x9d\x85\xae\0" /* offset 15009 */
+  "\xf0\x9d\x86\xba\xf0\x9d\x85\xa5\xf0\x9d\x85\xae\0" /* offset 15022 */
+  "\xf0\x9d\x86\xb9\xf0\x9d\x85\xa5\xf0\x9d\x85\xaf\0" /* offset 15035 */
+  "\xf0\x9d\x86\xba\xf0\x9d\x85\xa5\xf0\x9d\x85\xaf\0" /* offset 15048 */
+  "\xc4\xb1\0" /* offset 15061 */
+  "\xc8\xb7\0" /* offset 15064 */
+  "\xce\x91\0" /* offset 15067 */
+  "\xce\x92\0" /* offset 15070 */
+  "\xce\x94\0" /* offset 15073 */
+  "\xce\x95\0" /* offset 15076 */
+  "\xce\x96\0" /* offset 15079 */
+  "\xce\x97\0" /* offset 15082 */
+  "\xce\x99\0" /* offset 15085 */
+  "\xce\x9a\0" /* offset 15088 */
+  "\xce\x9b\0" /* offset 15091 */
+  "\xce\x9c\0" /* offset 15094 */
+  "\xce\x9d\0" /* offset 15097 */
+  "\xce\x9e\0" /* offset 15100 */
+  "\xce\x9f\0" /* offset 15103 */
+  "\xce\xa1\0" /* offset 15106 */
+  "\xce\xa4\0" /* offset 15109 */
+  "\xce\xa6\0" /* offset 15112 */
+  "\xce\xa7\0" /* offset 15115 */
+  "\xce\xa8\0" /* offset 15118 */
+  "\xe2\x88\x87\0" /* offset 15121 */
+  "\xce\xb1\0" /* offset 15125 */
+  "\xce\xb6\0" /* offset 15128 */
+  "\xce\xb7\0" /* offset 15131 */
+  "\xce\xbb\0" /* offset 15134 */
+  "\xce\xbd\0" /* offset 15137 */
+  "\xce\xbe\0" /* offset 15140 */
+  "\xce\xbf\0" /* offset 15143 */
+  "\xcf\x83\0" /* offset 15146 */
+  "\xcf\x84\0" /* offset 15149 */
+  "\xcf\x85\0" /* offset 15152 */
+  "\xcf\x88\0" /* offset 15155 */
+  "\xcf\x89\0" /* offset 15158 */
+  "\xe2\x88\x82\0" /* offset 15161 */
+  "\xcf\x9c\0" /* offset 15165 */
+  "\xcf\x9d\0" /* offset 15168 */
+  "\xe4\xb8\xbd\0" /* offset 15171 */
+  "\xe4\xb8\xb8\0" /* offset 15175 */
+  "\xe4\xb9\x81\0" /* offset 15179 */
+  "\xf0\xa0\x84\xa2\0" /* offset 15183 */
+  "\xe4\xbd\xa0\0" /* offset 15188 */
+  "\xe4\xbe\xbb\0" /* offset 15192 */
+  "\xe5\x80\x82\0" /* offset 15196 */
+  "\xe5\x81\xba\0" /* offset 15200 */
+  "\xe5\x82\x99\0" /* offset 15204 */
+  "\xe5\x83\x8f\0" /* offset 15208 */
+  "\xe3\x92\x9e\0" /* offset 15212 */
+  "\xf0\xa0\x98\xba\0" /* offset 15216 */
+  "\xe5\x85\x94\0" /* offset 15221 */
+  "\xe5\x85\xa4\0" /* offset 15225 */
+  "\xe5\x85\xb7\0" /* offset 15229 */
+  "\xf0\xa0\x94\x9c\0" /* offset 15233 */
+  "\xe3\x92\xb9\0" /* offset 15238 */
+  "\xe5\x85\xa7\0" /* offset 15242 */
+  "\xe5\x86\x8d\0" /* offset 15246 */
+  "\xf0\xa0\x95\x8b\0" /* offset 15250 */
+  "\xe5\x86\x97\0" /* offset 15255 */
+  "\xe5\x86\xa4\0" /* offset 15259 */
+  "\xe4\xbb\x8c\0" /* offset 15263 */
+  "\xe5\x86\xac\0" /* offset 15267 */
+  "\xf0\xa9\x87\x9f\0" /* offset 15271 */
+  "\xe5\x88\x83\0" /* offset 15276 */
+  "\xe3\x93\x9f\0" /* offset 15280 */
+  "\xe5\x88\xbb\0" /* offset 15284 */
+  "\xe5\x89\x86\0" /* offset 15288 */
+  "\xe5\x89\xb2\0" /* offset 15292 */
+  "\xe5\x89\xb7\0" /* offset 15296 */
+  "\xe3\x94\x95\0" /* offset 15300 */
+  "\xe5\x8c\x85\0" /* offset 15304 */
+  "\xe5\x8c\x86\0" /* offset 15308 */
+  "\xe5\x8d\x89\0" /* offset 15312 */
+  "\xe5\x8d\x9a\0" /* offset 15316 */
+  "\xe5\x8d\xb3\0" /* offset 15320 */
+  "\xe5\x8d\xbd\0" /* offset 15324 */
+  "\xe5\x8d\xbf\0" /* offset 15328 */
+  "\xf0\xa0\xa8\xac\0" /* offset 15332 */
+  "\xe7\x81\xb0\0" /* offset 15337 */
+  "\xe5\x8f\x8a\0" /* offset 15341 */
+  "\xe5\x8f\x9f\0" /* offset 15345 */
+  "\xf0\xa0\xad\xa3\0" /* offset 15349 */
+  "\xe5\x8f\xab\0" /* offset 15354 */
+  "\xe5\x8f\xb1\0" /* offset 15358 */
+  "\xe5\x90\x86\0" /* offset 15362 */
+  "\xe5\x92\x9e\0" /* offset 15366 */
+  "\xe5\x90\xb8\0" /* offset 15370 */
+  "\xe5\x91\x88\0" /* offset 15374 */
+  "\xe5\x91\xa8\0" /* offset 15378 */
+  "\xe5\x92\xa2\0" /* offset 15382 */
+  "\xe5\x93\xb6\0" /* offset 15386 */
+  "\xe5\x94\x90\0" /* offset 15390 */
+  "\xe5\x95\x93\0" /* offset 15394 */
+  "\xe5\x95\xa3\0" /* offset 15398 */
+  "\xe5\x96\x84\0" /* offset 15402 */
+  "\xe5\x96\xab\0" /* offset 15406 */
+  "\xe5\x96\xb3\0" /* offset 15410 */
+  "\xe5\x97\x82\0" /* offset 15414 */
+  "\xe5\x9c\x96\0" /* offset 15418 */
+  "\xe5\x9c\x97\0" /* offset 15422 */
+  "\xe5\x99\x91\0" /* offset 15426 */
+  "\xe5\x99\xb4\0" /* offset 15430 */
+  "\xe5\xa3\xae\0" /* offset 15434 */
+  "\xe5\x9f\x8e\0" /* offset 15438 */
+  "\xe5\x9f\xb4\0" /* offset 15442 */
+  "\xe5\xa0\x8d\0" /* offset 15446 */
+  "\xe5\x9e\x8b\0" /* offset 15450 */
+  "\xe5\xa0\xb2\0" /* offset 15454 */
+  "\xe5\xa0\xb1\0" /* offset 15458 */
+  "\xe5\xa2\xac\0" /* offset 15462 */
+  "\xf0\xa1\x93\xa4\0" /* offset 15466 */
+  "\xe5\xa3\xb2\0" /* offset 15471 */
+  "\xe5\xa3\xb7\0" /* offset 15475 */
+  "\xe5\xa4\x86\0" /* offset 15479 */
+  "\xe5\xa4\x9a\0" /* offset 15483 */
+  "\xe5\xa4\xa2\0" /* offset 15487 */
+  "\xe5\xa5\xa2\0" /* offset 15491 */
+  "\xf0\xa1\x9a\xa8\0" /* offset 15495 */
+  "\xf0\xa1\x9b\xaa\0" /* offset 15500 */
+  "\xe5\xa7\xac\0" /* offset 15505 */
+  "\xe5\xa8\x9b\0" /* offset 15509 */
+  "\xe5\xa8\xa7\0" /* offset 15513 */
+  "\xe5\xa7\x98\0" /* offset 15517 */
+  "\xe5\xa9\xa6\0" /* offset 15521 */
+  "\xe3\x9b\xae\0" /* offset 15525 */
+  "\xe3\x9b\xbc\0" /* offset 15529 */
+  "\xe5\xac\x88\0" /* offset 15533 */
+  "\xe5\xac\xbe\0" /* offset 15537 */
+  "\xf0\xa1\xa7\x88\0" /* offset 15541 */
+  "\xe5\xaf\x83\0" /* offset 15546 */
+  "\xe5\xaf\x98\0" /* offset 15550 */
+  "\xe5\xaf\xb3\0" /* offset 15554 */
+  "\xf0\xa1\xac\x98\0" /* offset 15558 */
+  "\xe5\xaf\xbf\0" /* offset 15563 */
+  "\xe5\xb0\x86\0" /* offset 15567 */
+  "\xe5\xbd\x93\0" /* offset 15571 */
+  "\xe3\x9e\x81\0" /* offset 15575 */
+  "\xe5\xb1\xa0\0" /* offset 15579 */
+  "\xe5\xb3\x80\0" /* offset 15583 */
+  "\xe5\xb2\x8d\0" /* offset 15587 */
+  "\xf0\xa1\xb7\xa4\0" /* offset 15591 */
+  "\xe5\xb5\x83\0" /* offset 15596 */
+  "\xf0\xa1\xb7\xa6\0" /* offset 15600 */
+  "\xe5\xb5\xae\0" /* offset 15605 */
+  "\xe5\xb5\xab\0" /* offset 15609 */
+  "\xe5\xb5\xbc\0" /* offset 15613 */
+  "\xe5\xb7\xa1\0" /* offset 15617 */
+  "\xe5\xb7\xa2\0" /* offset 15621 */
+  "\xe3\xa0\xaf\0" /* offset 15625 */
+  "\xe5\xb7\xbd\0" /* offset 15629 */
+  "\xe5\xb8\xa8\0" /* offset 15633 */
+  "\xe5\xb8\xbd\0" /* offset 15637 */
+  "\xe5\xb9\xa9\0" /* offset 15641 */
+  "\xe3\xa1\xa2\0" /* offset 15645 */
+  "\xf0\xa2\x86\x83\0" /* offset 15649 */
+  "\xe3\xa1\xbc\0" /* offset 15654 */
+  "\xe5\xba\xb0\0" /* offset 15658 */
+  "\xe5\xba\xb3\0" /* offset 15662 */
+  "\xe5\xba\xb6\0" /* offset 15666 */
+  "\xf0\xaa\x8e\x92\0" /* offset 15670 */
+  "\xf0\xa2\x8c\xb1\0" /* offset 15675 */
+  "\xe8\x88\x81\0" /* offset 15680 */
+  "\xe5\xbc\xa2\0" /* offset 15684 */
+  "\xe3\xa3\x87\0" /* offset 15688 */
+  "\xf0\xa3\x8a\xb8\0" /* offset 15692 */
+  "\xf0\xa6\x87\x9a\0" /* offset 15697 */
+  "\xe5\xbd\xa2\0" /* offset 15702 */
+  "\xe5\xbd\xab\0" /* offset 15706 */
+  "\xe3\xa3\xa3\0" /* offset 15710 */
+  "\xe5\xbe\x9a\0" /* offset 15714 */
+  "\xe5\xbf\x8d\0" /* offset 15718 */
+  "\xe5\xbf\x97\0" /* offset 15722 */
+  "\xe5\xbf\xb9\0" /* offset 15726 */
+  "\xe6\x82\x81\0" /* offset 15730 */
+  "\xe3\xa4\xba\0" /* offset 15734 */
+  "\xe3\xa4\x9c\0" /* offset 15738 */
+  "\xf0\xa2\x9b\x94\0" /* offset 15742 */
+  "\xe6\x83\x87\0" /* offset 15747 */
+  "\xe6\x85\x88\0" /* offset 15751 */
+  "\xe6\x85\x8c\0" /* offset 15755 */
+  "\xe6\x85\xba\0" /* offset 15759 */
+  "\xe6\x86\xb2\0" /* offset 15763 */
+  "\xe6\x86\xa4\0" /* offset 15767 */
+  "\xe6\x86\xaf\0" /* offset 15771 */
+  "\xe6\x87\x9e\0" /* offset 15775 */
+  "\xe6\x88\x90\0" /* offset 15779 */
+  "\xe6\x88\x9b\0" /* offset 15783 */
+  "\xe6\x89\x9d\0" /* offset 15787 */
+  "\xe6\x8a\xb1\0" /* offset 15791 */
+  "\xe6\x8b\x94\0" /* offset 15795 */
+  "\xe6\x8d\x90\0" /* offset 15799 */
+  "\xf0\xa2\xac\x8c\0" /* offset 15803 */
+  "\xe6\x8c\xbd\0" /* offset 15808 */
+  "\xe6\x8b\xbc\0" /* offset 15812 */
+  "\xe6\x8d\xa8\0" /* offset 15816 */
+  "\xe6\x8e\x83\0" /* offset 15820 */
+  "\xe6\x8f\xa4\0" /* offset 15824 */
+  "\xf0\xa2\xaf\xb1\0" /* offset 15828 */
+  "\xe6\x90\xa2\0" /* offset 15833 */
+  "\xe6\x8f\x85\0" /* offset 15837 */
+  "\xe6\x8e\xa9\0" /* offset 15841 */
+  "\xe3\xa8\xae\0" /* offset 15845 */
+  "\xe6\x91\xa9\0" /* offset 15849 */
+  "\xe6\x91\xbe\0" /* offset 15853 */
+  "\xe6\x92\x9d\0" /* offset 15857 */
+  "\xe6\x91\xb7\0" /* offset 15861 */
+  "\xe3\xa9\xac\0" /* offset 15865 */
+  "\xe6\x95\xac\0" /* offset 15869 */
+  "\xf0\xa3\x80\x8a\0" /* offset 15873 */
+  "\xe6\x97\xa3\0" /* offset 15878 */
+  "\xe6\x9b\xb8\0" /* offset 15882 */
+  "\xe6\x99\x89\0" /* offset 15886 */
+  "\xe3\xac\x99\0" /* offset 15890 */
+  "\xe3\xac\x88\0" /* offset 15894 */
+  "\xe3\xab\xa4\0" /* offset 15898 */
+  "\xe5\x86\x92\0" /* offset 15902 */
+  "\xe5\x86\x95\0" /* offset 15906 */
+  "\xe6\x9c\x80\0" /* offset 15910 */
+  "\xe6\x9a\x9c\0" /* offset 15914 */
+  "\xe8\x82\xad\0" /* offset 15918 */
+  "\xe4\x8f\x99\0" /* offset 15922 */
+  "\xe6\x9c\xa1\0" /* offset 15926 */
+  "\xe6\x9d\x9e\0" /* offset 15930 */
+  "\xe6\x9d\x93\0" /* offset 15934 */
+  "\xf0\xa3\x8f\x83\0" /* offset 15938 */
+  "\xe3\xad\x89\0" /* offset 15943 */
+  "\xe6\x9f\xba\0" /* offset 15947 */
+  "\xe6\x9e\x85\0" /* offset 15951 */
+  "\xe6\xa1\x92\0" /* offset 15955 */
+  "\xf0\xa3\x91\xad\0" /* offset 15959 */
+  "\xe6\xa2\x8e\0" /* offset 15964 */
+  "\xe6\xa0\x9f\0" /* offset 15968 */
+  "\xe6\xa4\x94\0" /* offset 15972 */
+  "\xe6\xa5\x82\0" /* offset 15976 */
+  "\xe6\xa6\xa3\0" /* offset 15980 */
+  "\xe6\xa7\xaa\0" /* offset 15984 */
+  "\xe6\xaa\xa8\0" /* offset 15988 */
+  "\xf0\xa3\x9a\xa3\0" /* offset 15992 */
+  "\xe6\xab\x9b\0" /* offset 15997 */
+  "\xe3\xb0\x98\0" /* offset 16001 */
+  "\xe6\xac\xa1\0" /* offset 16005 */
+  "\xf0\xa3\xa2\xa7\0" /* offset 16009 */
+  "\xe6\xad\x94\0" /* offset 16014 */
+  "\xe3\xb1\x8e\0" /* offset 16018 */
+  "\xe6\xad\xb2\0" /* offset 16022 */
+  "\xe6\xae\x9f\0" /* offset 16026 */
+  "\xe6\xae\xbb\0" /* offset 16030 */
+  "\xf0\xa3\xaa\x8d\0" /* offset 16034 */
+  "\xf0\xa1\xb4\x8b\0" /* offset 16039 */
+  "\xf0\xa3\xab\xba\0" /* offset 16044 */
+  "\xe6\xb1\x8e\0" /* offset 16049 */
+  "\xf0\xa3\xb2\xbc\0" /* offset 16053 */
+  "\xe6\xb2\xbf\0" /* offset 16058 */
+  "\xe6\xb3\x8d\0" /* offset 16062 */
+  "\xe6\xb1\xa7\0" /* offset 16066 */
+  "\xe6\xb4\x96\0" /* offset 16070 */
+  "\xe6\xb4\xbe\0" /* offset 16074 */
+  "\xe6\xb5\xa9\0" /* offset 16078 */
+  "\xe6\xb5\xb8\0" /* offset 16082 */
+  "\xe6\xb6\x85\0" /* offset 16086 */
+  "\xf0\xa3\xb4\x9e\0" /* offset 16090 */
+  "\xe6\xb4\xb4\0" /* offset 16095 */
+  "\xe6\xb8\xaf\0" /* offset 16099 */
+  "\xe6\xb9\xae\0" /* offset 16103 */
+  "\xe3\xb4\xb3\0" /* offset 16107 */
+  "\xe6\xbb\x87\0" /* offset 16111 */
+  "\xf0\xa3\xbb\x91\0" /* offset 16115 */
+  "\xe6\xb7\xb9\0" /* offset 16120 */
+  "\xe6\xbd\xae\0" /* offset 16124 */
+  "\xf0\xa3\xbd\x9e\0" /* offset 16128 */
+  "\xf0\xa3\xbe\x8e\0" /* offset 16133 */
+  "\xe6\xbf\x86\0" /* offset 16138 */
+  "\xe7\x80\xb9\0" /* offset 16142 */
+  "\xe7\x80\x9b\0" /* offset 16146 */
+  "\xe3\xb6\x96\0" /* offset 16150 */
+  "\xe7\x81\x8a\0" /* offset 16154 */
+  "\xe7\x81\xbd\0" /* offset 16158 */
+  "\xe7\x81\xb7\0" /* offset 16162 */
+  "\xe7\x82\xad\0" /* offset 16166 */
+  "\xf0\xa0\x94\xa5\0" /* offset 16170 */
+  "\xe7\x85\x85\0" /* offset 16175 */
+  "\xf0\xa4\x89\xa3\0" /* offset 16179 */
+  "\xe7\x86\x9c\0" /* offset 16184 */
+  "\xf0\xa4\x8e\xab\0" /* offset 16188 */
+  "\xe7\x88\xa8\0" /* offset 16193 */
+  "\xe7\x89\x90\0" /* offset 16197 */
+  "\xf0\xa4\x98\x88\0" /* offset 16201 */
+  "\xe7\x8a\x80\0" /* offset 16206 */
+  "\xe7\x8a\x95\0" /* offset 16210 */
+  "\xf0\xa4\x9c\xb5\0" /* offset 16214 */
+  "\xf0\xa4\xa0\x94\0" /* offset 16219 */
+  "\xe7\x8d\xba\0" /* offset 16224 */
+  "\xe7\x8e\x8b\0" /* offset 16228 */
+  "\xe3\xba\xac\0" /* offset 16232 */
+  "\xe7\x8e\xa5\0" /* offset 16236 */
+  "\xe3\xba\xb8\0" /* offset 16240 */
+  "\xe7\x91\x87\0" /* offset 16244 */
+  "\xe7\x91\x9c\0" /* offset 16248 */
+  "\xe7\x92\x85\0" /* offset 16252 */
+  "\xe7\x93\x8a\0" /* offset 16256 */
+  "\xe3\xbc\x9b\0" /* offset 16260 */
+  "\xe7\x94\xa4\0" /* offset 16264 */
+  "\xf0\xa4\xb0\xb6\0" /* offset 16268 */
+  "\xe7\x94\xbe\0" /* offset 16273 */
+  "\xf0\xa4\xb2\x92\0" /* offset 16277 */
+  "\xf0\xa2\x86\x9f\0" /* offset 16282 */
+  "\xe7\x98\x90\0" /* offset 16287 */
+  "\xf0\xa4\xbe\xa1\0" /* offset 16291 */
+  "\xf0\xa4\xbe\xb8\0" /* offset 16296 */
+  "\xf0\xa5\x81\x84\0" /* offset 16301 */
+  "\xe3\xbf\xbc\0" /* offset 16306 */
+  "\xe4\x80\x88\0" /* offset 16310 */
+  "\xf0\xa5\x83\xb3\0" /* offset 16314 */
+  "\xf0\xa5\x83\xb2\0" /* offset 16319 */
+  "\xf0\xa5\x84\x99\0" /* offset 16324 */
+  "\xf0\xa5\x84\xb3\0" /* offset 16329 */
+  "\xe7\x9c\x9e\0" /* offset 16334 */
+  "\xe7\x9c\x9f\0" /* offset 16338 */
+  "\xe7\x9e\x8b\0" /* offset 16342 */
+  "\xe4\x81\x86\0" /* offset 16346 */
+  "\xe4\x82\x96\0" /* offset 16350 */
+  "\xf0\xa5\x90\x9d\0" /* offset 16354 */
+  "\xe7\xa1\x8e\0" /* offset 16359 */
+  "\xe4\x83\xa3\0" /* offset 16363 */
+  "\xf0\xa5\x98\xa6\0" /* offset 16367 */
+  "\xf0\xa5\x9a\x9a\0" /* offset 16372 */
+  "\xf0\xa5\x9b\x85\0" /* offset 16377 */
+  "\xe7\xa7\xab\0" /* offset 16382 */
+  "\xe4\x84\xaf\0" /* offset 16386 */
+  "\xe7\xa9\x8a\0" /* offset 16390 */
+  "\xe7\xa9\x8f\0" /* offset 16394 */
+  "\xf0\xa5\xa5\xbc\0" /* offset 16398 */
+  "\xf0\xa5\xaa\xa7\0" /* offset 16403 */
+  "\xe7\xab\xae\0" /* offset 16408 */
+  "\xe4\x88\x82\0" /* offset 16412 */
+  "\xf0\xa5\xae\xab\0" /* offset 16416 */
+  "\xe7\xaf\x86\0" /* offset 16421 */
+  "\xe7\xaf\x89\0" /* offset 16425 */
+  "\xe4\x88\xa7\0" /* offset 16429 */
+  "\xf0\xa5\xb2\x80\0" /* offset 16433 */
+  "\xe7\xb3\x92\0" /* offset 16438 */
+  "\xe4\x8a\xa0\0" /* offset 16442 */
+  "\xe7\xb3\xa8\0" /* offset 16446 */
+  "\xe7\xb3\xa3\0" /* offset 16450 */
+  "\xe7\xb4\x80\0" /* offset 16454 */
+  "\xf0\xa5\xbe\x86\0" /* offset 16458 */
+  "\xe7\xb5\xa3\0" /* offset 16463 */
+  "\xe4\x8c\x81\0" /* offset 16467 */
+  "\xe7\xb7\x87\0" /* offset 16471 */
+  "\xe7\xb8\x82\0" /* offset 16475 */
+  "\xe7\xb9\x85\0" /* offset 16479 */
+  "\xe4\x8c\xb4\0" /* offset 16483 */
+  "\xf0\xa6\x88\xa8\0" /* offset 16487 */
+  "\xf0\xa6\x89\x87\0" /* offset 16492 */
+  "\xe4\x8d\x99\0" /* offset 16497 */
+  "\xf0\xa6\x8b\x99\0" /* offset 16501 */
+  "\xe7\xbd\xba\0" /* offset 16506 */
+  "\xf0\xa6\x8c\xbe\0" /* offset 16510 */
+  "\xe7\xbe\x95\0" /* offset 16515 */
+  "\xe7\xbf\xba\0" /* offset 16519 */
+  "\xf0\xa6\x93\x9a\0" /* offset 16523 */
+  "\xf0\xa6\x94\xa3\0" /* offset 16528 */
+  "\xe8\x81\xa0\0" /* offset 16533 */
+  "\xf0\xa6\x96\xa8\0" /* offset 16537 */
+  "\xe8\x81\xb0\0" /* offset 16542 */
+  "\xf0\xa3\x8d\x9f\0" /* offset 16546 */
+  "\xe4\x8f\x95\0" /* offset 16551 */
+  "\xe8\x82\xb2\0" /* offset 16555 */
+  "\xe8\x84\x83\0" /* offset 16559 */
+  "\xe4\x90\x8b\0" /* offset 16563 */
+  "\xe8\x84\xbe\0" /* offset 16567 */
+  "\xe5\xaa\xb5\0" /* offset 16571 */
+  "\xf0\xa6\x9e\xa7\0" /* offset 16575 */
+  "\xf0\xa6\x9e\xb5\0" /* offset 16580 */
+  "\xf0\xa3\x8e\x93\0" /* offset 16585 */
+  "\xf0\xa3\x8e\x9c\0" /* offset 16590 */
+  "\xe8\x88\x84\0" /* offset 16595 */
+  "\xe8\xbe\x9e\0" /* offset 16599 */
+  "\xe4\x91\xab\0" /* offset 16603 */
+  "\xe8\x8a\x91\0" /* offset 16607 */
+  "\xe8\x8a\x8b\0" /* offset 16611 */
+  "\xe8\x8a\x9d\0" /* offset 16615 */
+  "\xe5\x8a\xb3\0" /* offset 16619 */
+  "\xe8\x8a\xb1\0" /* offset 16623 */
+  "\xe8\x8a\xb3\0" /* offset 16627 */
+  "\xe8\x8a\xbd\0" /* offset 16631 */
+  "\xe8\x8b\xa6\0" /* offset 16635 */
+  "\xf0\xa6\xac\xbc\0" /* offset 16639 */
+  "\xe8\x8c\x9d\0" /* offset 16644 */
+  "\xe8\x8d\xa3\0" /* offset 16648 */
+  "\xe8\x8e\xad\0" /* offset 16652 */
+  "\xe8\x8c\xa3\0" /* offset 16656 */
+  "\xe8\x8e\xbd\0" /* offset 16660 */
+  "\xe8\x8f\xa7\0" /* offset 16664 */
+  "\xe8\x8d\x93\0" /* offset 16668 */
+  "\xe8\x8f\x8a\0" /* offset 16672 */
+  "\xe8\x8f\x8c\0" /* offset 16676 */
+  "\xe8\x8f\x9c\0" /* offset 16680 */
+  "\xf0\xa6\xb0\xb6\0" /* offset 16684 */
+  "\xf0\xa6\xb5\xab\0" /* offset 16689 */
+  "\xf0\xa6\xb3\x95\0" /* offset 16694 */
+  "\xe4\x94\xab\0" /* offset 16699 */
+  "\xe8\x93\xb1\0" /* offset 16703 */
+  "\xe8\x93\xb3\0" /* offset 16707 */
+  "\xe8\x94\x96\0" /* offset 16711 */
+  "\xf0\xa7\x8f\x8a\0" /* offset 16715 */
+  "\xe8\x95\xa4\0" /* offset 16720 */
+  "\xf0\xa6\xbc\xac\0" /* offset 16724 */
+  "\xe4\x95\x9d\0" /* offset 16729 */
+  "\xe4\x95\xa1\0" /* offset 16733 */
+  "\xf0\xa6\xbe\xb1\0" /* offset 16737 */
+  "\xf0\xa7\x83\x92\0" /* offset 16742 */
+  "\xe4\x95\xab\0" /* offset 16747 */
+  "\xe8\x99\x90\0" /* offset 16751 */
+  "\xe8\x99\xa7\0" /* offset 16755 */
+  "\xe8\x99\xa9\0" /* offset 16759 */
+  "\xe8\x9a\xa9\0" /* offset 16763 */
+  "\xe8\x9a\x88\0" /* offset 16767 */
+  "\xe8\x9c\x8e\0" /* offset 16771 */
+  "\xe8\x9b\xa2\0" /* offset 16775 */
+  "\xe8\x9c\xa8\0" /* offset 16779 */
+  "\xe8\x9d\xab\0" /* offset 16783 */
+  "\xe8\x9e\x86\0" /* offset 16787 */
+  "\xe4\x97\x97\0" /* offset 16791 */
+  "\xe8\x9f\xa1\0" /* offset 16795 */
+  "\xe8\xa0\x81\0" /* offset 16799 */
+  "\xe4\x97\xb9\0" /* offset 16803 */
+  "\xe8\xa1\xa0\0" /* offset 16807 */
+  "\xf0\xa7\x99\xa7\0" /* offset 16811 */
+  "\xe8\xa3\x97\0" /* offset 16816 */
+  "\xe8\xa3\x9e\0" /* offset 16820 */
+  "\xe4\x98\xb5\0" /* offset 16824 */
+  "\xe8\xa3\xba\0" /* offset 16828 */
+  "\xe3\x92\xbb\0" /* offset 16832 */
+  "\xf0\xa7\xa2\xae\0" /* offset 16836 */
+  "\xf0\xa7\xa5\xa6\0" /* offset 16841 */
+  "\xe4\x9a\xbe\0" /* offset 16846 */
+  "\xe4\x9b\x87\0" /* offset 16850 */
+  "\xe8\xaa\xa0\0" /* offset 16854 */
+  "\xf0\xa7\xb2\xa8\0" /* offset 16858 */
+  "\xe8\xb2\xab\0" /* offset 16863 */
+  "\xe8\xb3\x81\0" /* offset 16867 */
+  "\xe8\xb4\x9b\0" /* offset 16871 */
+  "\xe8\xb5\xb7\0" /* offset 16875 */
+  "\xf0\xa7\xbc\xaf\0" /* offset 16879 */
+  "\xf0\xa0\xa0\x84\0" /* offset 16884 */
+  "\xe8\xb7\x8b\0" /* offset 16889 */
+  "\xe8\xb6\xbc\0" /* offset 16893 */
+  "\xe8\xb7\xb0\0" /* offset 16897 */
+  "\xf0\xa0\xa3\x9e\0" /* offset 16901 */
+  "\xe8\xbb\x94\0" /* offset 16906 */
+  "\xf0\xa8\x97\x92\0" /* offset 16910 */
+  "\xf0\xa8\x97\xad\0" /* offset 16915 */
+  "\xe9\x82\x94\0" /* offset 16920 */
+  "\xe9\x83\xb1\0" /* offset 16924 */
+  "\xe9\x84\x91\0" /* offset 16928 */
+  "\xf0\xa8\x9c\xae\0" /* offset 16932 */
+  "\xe9\x84\x9b\0" /* offset 16937 */
+  "\xe9\x88\xb8\0" /* offset 16941 */
+  "\xe9\x8b\x97\0" /* offset 16945 */
+  "\xe9\x8b\x98\0" /* offset 16949 */
+  "\xe9\x89\xbc\0" /* offset 16953 */
+  "\xe9\x8f\xb9\0" /* offset 16957 */
+  "\xe9\x90\x95\0" /* offset 16961 */
+  "\xf0\xa8\xaf\xba\0" /* offset 16965 */
+  "\xe9\x96\x8b\0" /* offset 16970 */
+  "\xe4\xa6\x95\0" /* offset 16974 */
+  "\xe9\x96\xb7\0" /* offset 16978 */
+  "\xf0\xa8\xb5\xb7\0" /* offset 16982 */
+  "\xe4\xa7\xa6\0" /* offset 16987 */
+  "\xe9\x9b\x83\0" /* offset 16991 */
+  "\xe5\xb6\xb2\0" /* offset 16995 */
+  "\xe9\x9c\xa3\0" /* offset 16999 */
+  "\xf0\xa9\x85\x85\0" /* offset 17003 */
+  "\xf0\xa9\x88\x9a\0" /* offset 17008 */
+  "\xe4\xa9\xae\0" /* offset 17013 */
+  "\xe4\xa9\xb6\0" /* offset 17017 */
+  "\xe9\x9f\xa0\0" /* offset 17021 */
+  "\xf0\xa9\x90\x8a\0" /* offset 17025 */
+  "\xe4\xaa\xb2\0" /* offset 17030 */
+  "\xf0\xa9\x92\x96\0" /* offset 17034 */
+  "\xe9\xa0\xa9\0" /* offset 17039 */
+  "\xf0\xa9\x96\xb6\0" /* offset 17043 */
+  "\xe9\xa3\xa2\0" /* offset 17048 */
+  "\xe4\xac\xb3\0" /* offset 17052 */
+  "\xe9\xa4\xa9\0" /* offset 17056 */
+  "\xe9\xa6\xa7\0" /* offset 17060 */
+  "\xe9\xa7\x82\0" /* offset 17064 */
+  "\xe9\xa7\xbe\0" /* offset 17068 */
+  "\xe4\xaf\x8e\0" /* offset 17072 */
+  "\xf0\xa9\xac\xb0\0" /* offset 17076 */
+  "\xe9\xb1\x80\0" /* offset 17081 */
+  "\xe9\xb3\xbd\0" /* offset 17085 */
+  "\xe4\xb3\x8e\0" /* offset 17089 */
+  "\xe4\xb3\xad\0" /* offset 17093 */
+  "\xe9\xb5\xa7\0" /* offset 17097 */
+  "\xf0\xaa\x83\x8e\0" /* offset 17101 */
+  "\xe4\xb3\xb8\0" /* offset 17106 */
+  "\xf0\xaa\x84\x85\0" /* offset 17110 */
+  "\xf0\xaa\x88\x8e\0" /* offset 17115 */
+  "\xf0\xaa\x8a\x91\0" /* offset 17120 */
+  "\xe4\xb5\x96\0" /* offset 17125 */
+  "\xe9\xbb\xbe\0" /* offset 17129 */
+  "\xe9\xbc\x85\0" /* offset 17133 */
+  "\xe9\xbc\x8f\0" /* offset 17137 */
+  "\xe9\xbc\x96\0" /* offset 17141 */
+  "\xf0\xaa\x98\x80\0" /* offset 17145 */;
+
+#endif /* DECOMP_H */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/guniprop.c b/resource/csdk/connectivity/lib/android/glib-master/glib/guniprop.c
new file mode 100644 (file)
index 0000000..6390574
--- /dev/null
@@ -0,0 +1,1304 @@
+/* guniprop.c - Unicode character properties.
+ *
+ * Copyright (C) 1999 Tom Tromey
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <stddef.h>
+#include <string.h>
+#include <locale.h>
+
+#include "gmem.h"
+#include "gstring.h"
+#include "gtestutils.h"
+#include "gtypes.h"
+#include "gunicode.h"
+#include "gunichartables.h"
+#include "gmirroringtable.h"
+#include "gscripttable.h"
+#include "gunicodeprivate.h"
+#ifdef G_OS_WIN32
+#include "gwin32.h"
+#endif
+
+#define ATTR_TABLE(Page) (((Page) <= G_UNICODE_LAST_PAGE_PART1) \
+                          ? attr_table_part1[Page] \
+                          : attr_table_part2[(Page) - 0xe00])
+
+#define ATTTABLE(Page, Char) \
+  ((ATTR_TABLE(Page) == G_UNICODE_MAX_TABLE_INDEX) ? 0 : (attr_data[ATTR_TABLE(Page)][Char]))
+
+#define TTYPE_PART1(Page, Char) \
+  ((type_table_part1[Page] >= G_UNICODE_MAX_TABLE_INDEX) \
+   ? (type_table_part1[Page] - G_UNICODE_MAX_TABLE_INDEX) \
+   : (type_data[type_table_part1[Page]][Char]))
+
+#define TTYPE_PART2(Page, Char) \
+  ((type_table_part2[Page] >= G_UNICODE_MAX_TABLE_INDEX) \
+   ? (type_table_part2[Page] - G_UNICODE_MAX_TABLE_INDEX) \
+   : (type_data[type_table_part2[Page]][Char]))
+
+#define TYPE(Char) \
+  (((Char) <= G_UNICODE_LAST_CHAR_PART1) \
+   ? TTYPE_PART1 ((Char) >> 8, (Char) & 0xff) \
+   : (((Char) >= 0xe0000 && (Char) <= G_UNICODE_LAST_CHAR) \
+      ? TTYPE_PART2 (((Char) - 0xe0000) >> 8, (Char) & 0xff) \
+      : G_UNICODE_UNASSIGNED))
+
+
+#define IS(Type, Class)        (((guint)1 << (Type)) & (Class))
+#define OR(Type, Rest) (((guint)1 << (Type)) | (Rest))
+
+
+
+#define ISALPHA(Type)  IS ((Type),                             \
+                           OR (G_UNICODE_LOWERCASE_LETTER,     \
+                           OR (G_UNICODE_UPPERCASE_LETTER,     \
+                           OR (G_UNICODE_TITLECASE_LETTER,     \
+                           OR (G_UNICODE_MODIFIER_LETTER,      \
+                           OR (G_UNICODE_OTHER_LETTER,         0))))))
+
+#define ISALDIGIT(Type)        IS ((Type),                             \
+                           OR (G_UNICODE_DECIMAL_NUMBER,       \
+                           OR (G_UNICODE_LETTER_NUMBER,        \
+                           OR (G_UNICODE_OTHER_NUMBER,         \
+                           OR (G_UNICODE_LOWERCASE_LETTER,     \
+                           OR (G_UNICODE_UPPERCASE_LETTER,     \
+                           OR (G_UNICODE_TITLECASE_LETTER,     \
+                           OR (G_UNICODE_MODIFIER_LETTER,      \
+                           OR (G_UNICODE_OTHER_LETTER,         0)))))))))
+
+#define ISMARK(Type)   IS ((Type),                             \
+                           OR (G_UNICODE_NON_SPACING_MARK,     \
+                           OR (G_UNICODE_COMBINING_MARK,       \
+                           OR (G_UNICODE_ENCLOSING_MARK,       0))))
+
+#define ISZEROWIDTHTYPE(Type)  IS ((Type),                     \
+                           OR (G_UNICODE_NON_SPACING_MARK,     \
+                           OR (G_UNICODE_ENCLOSING_MARK,       \
+                           OR (G_UNICODE_FORMAT,               0))))
+
+/**
+ * g_unichar_isalnum:
+ * @c: a Unicode character
+ * 
+ * Determines whether a character is alphanumeric.
+ * Given some UTF-8 text, obtain a character value
+ * with g_utf8_get_char().
+ * 
+ * Return value: %TRUE if @c is an alphanumeric character
+ **/
+gboolean
+g_unichar_isalnum (gunichar c)
+{
+  return ISALDIGIT (TYPE (c)) ? TRUE : FALSE;
+}
+
+/**
+ * g_unichar_isalpha:
+ * @c: a Unicode character
+ * 
+ * Determines whether a character is alphabetic (i.e. a letter).
+ * Given some UTF-8 text, obtain a character value with
+ * g_utf8_get_char().
+ * 
+ * Return value: %TRUE if @c is an alphabetic character
+ **/
+gboolean
+g_unichar_isalpha (gunichar c)
+{
+  return ISALPHA (TYPE (c)) ? TRUE : FALSE;
+}
+
+
+/**
+ * g_unichar_iscntrl:
+ * @c: a Unicode character
+ * 
+ * Determines whether a character is a control character.
+ * Given some UTF-8 text, obtain a character value with
+ * g_utf8_get_char().
+ * 
+ * Return value: %TRUE if @c is a control character
+ **/
+gboolean
+g_unichar_iscntrl (gunichar c)
+{
+  return TYPE (c) == G_UNICODE_CONTROL;
+}
+
+/**
+ * g_unichar_isdigit:
+ * @c: a Unicode character
+ * 
+ * Determines whether a character is numeric (i.e. a digit).  This
+ * covers ASCII 0-9 and also digits in other languages/scripts.  Given
+ * some UTF-8 text, obtain a character value with g_utf8_get_char().
+ * 
+ * Return value: %TRUE if @c is a digit
+ **/
+gboolean
+g_unichar_isdigit (gunichar c)
+{
+  return TYPE (c) == G_UNICODE_DECIMAL_NUMBER;
+}
+
+
+/**
+ * g_unichar_isgraph:
+ * @c: a Unicode character
+ * 
+ * Determines whether a character is printable and not a space
+ * (returns %FALSE for control characters, format characters, and
+ * spaces). g_unichar_isprint() is similar, but returns %TRUE for
+ * spaces. Given some UTF-8 text, obtain a character value with
+ * g_utf8_get_char().
+ * 
+ * Return value: %TRUE if @c is printable unless it's a space
+ **/
+gboolean
+g_unichar_isgraph (gunichar c)
+{
+  return !IS (TYPE(c),
+             OR (G_UNICODE_CONTROL,
+             OR (G_UNICODE_FORMAT,
+             OR (G_UNICODE_UNASSIGNED,
+             OR (G_UNICODE_SURROGATE,
+             OR (G_UNICODE_SPACE_SEPARATOR,
+            0))))));
+}
+
+/**
+ * g_unichar_islower:
+ * @c: a Unicode character
+ * 
+ * Determines whether a character is a lowercase letter.
+ * Given some UTF-8 text, obtain a character value with
+ * g_utf8_get_char().
+ * 
+ * Return value: %TRUE if @c is a lowercase letter
+ **/
+gboolean
+g_unichar_islower (gunichar c)
+{
+  return TYPE (c) == G_UNICODE_LOWERCASE_LETTER;
+}
+
+
+/**
+ * g_unichar_isprint:
+ * @c: a Unicode character
+ * 
+ * Determines whether a character is printable.
+ * Unlike g_unichar_isgraph(), returns %TRUE for spaces.
+ * Given some UTF-8 text, obtain a character value with
+ * g_utf8_get_char().
+ * 
+ * Return value: %TRUE if @c is printable
+ **/
+gboolean
+g_unichar_isprint (gunichar c)
+{
+  return !IS (TYPE(c),
+             OR (G_UNICODE_CONTROL,
+             OR (G_UNICODE_FORMAT,
+             OR (G_UNICODE_UNASSIGNED,
+             OR (G_UNICODE_SURROGATE,
+            0)))));
+}
+
+/**
+ * g_unichar_ispunct:
+ * @c: a Unicode character
+ * 
+ * Determines whether a character is punctuation or a symbol.
+ * Given some UTF-8 text, obtain a character value with
+ * g_utf8_get_char().
+ * 
+ * Return value: %TRUE if @c is a punctuation or symbol character
+ **/
+gboolean
+g_unichar_ispunct (gunichar c)
+{
+  return IS (TYPE(c),
+            OR (G_UNICODE_CONNECT_PUNCTUATION,
+            OR (G_UNICODE_DASH_PUNCTUATION,
+            OR (G_UNICODE_CLOSE_PUNCTUATION,
+            OR (G_UNICODE_FINAL_PUNCTUATION,
+            OR (G_UNICODE_INITIAL_PUNCTUATION,
+            OR (G_UNICODE_OTHER_PUNCTUATION,
+            OR (G_UNICODE_OPEN_PUNCTUATION,
+            OR (G_UNICODE_CURRENCY_SYMBOL,
+            OR (G_UNICODE_MODIFIER_SYMBOL,
+            OR (G_UNICODE_MATH_SYMBOL,
+            OR (G_UNICODE_OTHER_SYMBOL,
+           0)))))))))))) ? TRUE : FALSE;
+}
+
+/**
+ * g_unichar_isspace:
+ * @c: a Unicode character
+ * 
+ * Determines whether a character is a space, tab, or line separator
+ * (newline, carriage return, etc.).  Given some UTF-8 text, obtain a
+ * character value with g_utf8_get_char().
+ *
+ * (Note: don't use this to do word breaking; you have to use
+ * Pango or equivalent to get word breaking right, the algorithm
+ * is fairly complex.)
+ *  
+ * Return value: %TRUE if @c is a space character
+ **/
+gboolean
+g_unichar_isspace (gunichar c)
+{
+  switch (c)
+    {
+      /* special-case these since Unicode thinks they are not spaces */
+    case '\t':
+    case '\n':
+    case '\r':
+    case '\f':
+      return TRUE;
+      break;
+      
+    default:
+      {
+       return IS (TYPE(c),
+                  OR (G_UNICODE_SPACE_SEPARATOR,
+                  OR (G_UNICODE_LINE_SEPARATOR,
+                   OR (G_UNICODE_PARAGRAPH_SEPARATOR,
+                 0)))) ? TRUE : FALSE;
+      }
+      break;
+    }
+}
+
+/**
+ * g_unichar_ismark:
+ * @c: a Unicode character
+ *
+ * Determines whether a character is a mark (non-spacing mark,
+ * combining mark, or enclosing mark in Unicode speak).
+ * Given some UTF-8 text, obtain a character value
+ * with g_utf8_get_char().
+ *
+ * Note: in most cases where isalpha characters are allowed,
+ * ismark characters should be allowed to as they are essential
+ * for writing most European languages as well as many non-Latin
+ * scripts.
+ *
+ * Return value: %TRUE if @c is a mark character
+ *
+ * Since: 2.14
+ **/
+gboolean
+g_unichar_ismark (gunichar c)
+{
+  return ISMARK (TYPE (c));
+}
+
+/**
+ * g_unichar_isupper:
+ * @c: a Unicode character
+ * 
+ * Determines if a character is uppercase.
+ * 
+ * Return value: %TRUE if @c is an uppercase character
+ **/
+gboolean
+g_unichar_isupper (gunichar c)
+{
+  return TYPE (c) == G_UNICODE_UPPERCASE_LETTER;
+}
+
+/**
+ * g_unichar_istitle:
+ * @c: a Unicode character
+ * 
+ * Determines if a character is titlecase. Some characters in
+ * Unicode which are composites, such as the DZ digraph
+ * have three case variants instead of just two. The titlecase
+ * form is used at the beginning of a word where only the
+ * first letter is capitalized. The titlecase form of the DZ
+ * digraph is U+01F2 LATIN CAPITAL LETTTER D WITH SMALL LETTER Z.
+ * 
+ * Return value: %TRUE if the character is titlecase
+ **/
+gboolean
+g_unichar_istitle (gunichar c)
+{
+  unsigned int i;
+  for (i = 0; i < G_N_ELEMENTS (title_table); ++i)
+    if (title_table[i][0] == c)
+      return TRUE;
+  return FALSE;
+}
+
+/**
+ * g_unichar_isxdigit:
+ * @c: a Unicode character.
+ * 
+ * Determines if a character is a hexidecimal digit.
+ * 
+ * Return value: %TRUE if the character is a hexadecimal digit
+ **/
+gboolean
+g_unichar_isxdigit (gunichar c)
+{
+  return ((c >= 'a' && c <= 'f')
+         || (c >= 'A' && c <= 'F')
+         || (TYPE (c) == G_UNICODE_DECIMAL_NUMBER));
+}
+
+/**
+ * g_unichar_isdefined:
+ * @c: a Unicode character
+ * 
+ * Determines if a given character is assigned in the Unicode
+ * standard.
+ *
+ * Return value: %TRUE if the character has an assigned value
+ **/
+gboolean
+g_unichar_isdefined (gunichar c)
+{
+  return !IS (TYPE(c),
+             OR (G_UNICODE_UNASSIGNED,
+             OR (G_UNICODE_SURROGATE,
+            0)));
+}
+
+/**
+ * g_unichar_iszerowidth:
+ * @c: a Unicode character
+ * 
+ * Determines if a given character typically takes zero width when rendered.
+ * The return value is %TRUE for all non-spacing and enclosing marks
+ * (e.g., combining accents), format characters, zero-width
+ * space, but not U+00AD SOFT HYPHEN.
+ *
+ * A typical use of this function is with one of g_unichar_iswide() or
+ * g_unichar_iswide_cjk() to determine the number of cells a string occupies
+ * when displayed on a grid display (terminals).  However, note that not all
+ * terminals support zero-width rendering of zero-width marks.
+ *
+ * Return value: %TRUE if the character has zero width
+ *
+ * Since: 2.14
+ **/
+gboolean
+g_unichar_iszerowidth (gunichar c)
+{
+  if (G_UNLIKELY (c == 0x00AD))
+    return FALSE;
+
+  if (G_UNLIKELY (ISZEROWIDTHTYPE (TYPE (c))))
+    return TRUE;
+
+  if (G_UNLIKELY ((c >= 0x1160 && c < 0x1200) ||
+                 c == 0x200B))
+    return TRUE;
+
+  return FALSE;
+}
+
+struct Interval
+{
+  gunichar start, end;
+};
+
+static int
+interval_compare (const void *key, const void *elt)
+{
+  gunichar c = GPOINTER_TO_UINT (key);
+  struct Interval *interval = (struct Interval *)elt;
+
+  if (c < interval->start)
+    return -1;
+  if (c > interval->end)
+    return +1;
+
+  return 0;
+}
+
+/**
+ * g_unichar_iswide:
+ * @c: a Unicode character
+ * 
+ * Determines if a character is typically rendered in a double-width
+ * cell.
+ * 
+ * Return value: %TRUE if the character is wide
+ **/
+gboolean
+g_unichar_iswide (gunichar c)
+{
+  /* sorted list of intervals of East_Asian_Width = W and F characters
+   * from Unicode 5.1.0.  produced by mungling output of:
+   * grep ';[FW]\>' EastAsianWidth.txt */
+  static const struct Interval wide[] = {
+    {0x1100, 0x1159}, {0x115F, 0x115F}, {0x2329, 0x232A}, {0x2E80, 0x2E99},
+    {0x2E9B, 0x2EF3}, {0x2F00, 0x2FD5}, {0x2FF0, 0x2FFB}, {0x3000, 0x303E},
+    {0x3041, 0x3096}, {0x3099, 0x30FF}, {0x3105, 0x312D}, {0x3131, 0x318E},
+    {0x3190, 0x31B7}, {0x31C0, 0x31E3}, {0x31F0, 0x321E}, {0x3220, 0x3243},
+    {0x3250, 0x32FE}, {0x3300, 0x4DB5}, {0x4E00, 0x9FC3}, {0xA000, 0xA48C},
+    {0xA490, 0xA4C6}, {0xAC00, 0xD7A3}, {0xF900, 0xFA2D}, {0xFA30, 0xFA6A},
+    {0xFA70, 0xFAD9}, {0xFE10, 0xFE19}, {0xFE30, 0xFE52}, {0xFE54, 0xFE66},
+    {0xFE68, 0xFE6B}, {0xFF01, 0xFF60}, {0xFFE0, 0xFFE6}, {0x20000, 0x2FFFD},
+    {0x30000, 0x3FFFD}
+  };
+
+  if (bsearch (GUINT_TO_POINTER (c), wide, G_N_ELEMENTS (wide), sizeof wide[0],
+              interval_compare))
+    return TRUE;
+
+  return FALSE;
+}
+
+
+/**
+ * g_unichar_iswide_cjk:
+ * @c: a Unicode character
+ * 
+ * Determines if a character is typically rendered in a double-width
+ * cell under legacy East Asian locales.  If a character is wide according to
+ * g_unichar_iswide(), then it is also reported wide with this function, but
+ * the converse is not necessarily true.  See the
+ * <ulink url="http://www.unicode.org/reports/tr11/">Unicode Standard
+ * Annex #11</ulink> for details.
+ *
+ * If a character passes the g_unichar_iswide() test then it will also pass
+ * this test, but not the other way around.  Note that some characters may
+ * pas both this test and g_unichar_iszerowidth().
+ * 
+ * Return value: %TRUE if the character is wide in legacy East Asian locales
+ *
+ * Since: 2.12
+ */
+gboolean
+g_unichar_iswide_cjk (gunichar c)
+{
+  /* sorted list of intervals of East_Asian_Width = A and F characters
+   * from Unicode 5.1.0.  produced by mungling output of:
+   * grep ';[A]\>' EastAsianWidth.txt */
+  static const struct Interval ambiguous[] = {
+    {0x00A1, 0x00A1}, {0x00A4, 0x00A4}, {0x00A7, 0x00A8}, {0x00AA, 0x00AA},
+    {0x00AD, 0x00AE}, {0x00B0, 0x00B4}, {0x00B6, 0x00BA}, {0x00BC, 0x00BF},
+    {0x00C6, 0x00C6}, {0x00D0, 0x00D0}, {0x00D7, 0x00D8}, {0x00DE, 0x00E1},
+    {0x00E6, 0x00E6}, {0x00E8, 0x00EA}, {0x00EC, 0x00ED}, {0x00F0, 0x00F0},
+    {0x00F2, 0x00F3}, {0x00F7, 0x00FA}, {0x00FC, 0x00FC}, {0x00FE, 0x00FE},
+    {0x0101, 0x0101}, {0x0111, 0x0111}, {0x0113, 0x0113}, {0x011B, 0x011B},
+    {0x0126, 0x0127}, {0x012B, 0x012B}, {0x0131, 0x0133}, {0x0138, 0x0138},
+    {0x013F, 0x0142}, {0x0144, 0x0144}, {0x0148, 0x014B}, {0x014D, 0x014D},
+    {0x0152, 0x0153}, {0x0166, 0x0167}, {0x016B, 0x016B}, {0x01CE, 0x01CE},
+    {0x01D0, 0x01D0}, {0x01D2, 0x01D2}, {0x01D4, 0x01D4}, {0x01D6, 0x01D6},
+    {0x01D8, 0x01D8}, {0x01DA, 0x01DA}, {0x01DC, 0x01DC}, {0x0251, 0x0251},
+    {0x0261, 0x0261}, {0x02C4, 0x02C4}, {0x02C7, 0x02C7}, {0x02C9, 0x02CB},
+    {0x02CD, 0x02CD}, {0x02D0, 0x02D0}, {0x02D8, 0x02DB}, {0x02DD, 0x02DD},
+    {0x02DF, 0x02DF}, {0x0300, 0x036F}, {0x0391, 0x03A1}, {0x03A3, 0x03A9},
+    {0x03B1, 0x03C1}, {0x03C3, 0x03C9}, {0x0401, 0x0401}, {0x0410, 0x044F},
+    {0x0451, 0x0451}, {0x2010, 0x2010}, {0x2013, 0x2016}, {0x2018, 0x2019},
+    {0x201C, 0x201D}, {0x2020, 0x2022}, {0x2024, 0x2027}, {0x2030, 0x2030},
+    {0x2032, 0x2033}, {0x2035, 0x2035}, {0x203B, 0x203B}, {0x203E, 0x203E},
+    {0x2074, 0x2074}, {0x207F, 0x207F}, {0x2081, 0x2084}, {0x20AC, 0x20AC},
+    {0x2103, 0x2103}, {0x2105, 0x2105}, {0x2109, 0x2109}, {0x2113, 0x2113},
+    {0x2116, 0x2116}, {0x2121, 0x2122}, {0x2126, 0x2126}, {0x212B, 0x212B},
+    {0x2153, 0x2154}, {0x215B, 0x215E}, {0x2160, 0x216B}, {0x2170, 0x2179},
+    {0x2190, 0x2199}, {0x21B8, 0x21B9}, {0x21D2, 0x21D2}, {0x21D4, 0x21D4},
+    {0x21E7, 0x21E7}, {0x2200, 0x2200}, {0x2202, 0x2203}, {0x2207, 0x2208},
+    {0x220B, 0x220B}, {0x220F, 0x220F}, {0x2211, 0x2211}, {0x2215, 0x2215},
+    {0x221A, 0x221A}, {0x221D, 0x2220}, {0x2223, 0x2223}, {0x2225, 0x2225},
+    {0x2227, 0x222C}, {0x222E, 0x222E}, {0x2234, 0x2237}, {0x223C, 0x223D},
+    {0x2248, 0x2248}, {0x224C, 0x224C}, {0x2252, 0x2252}, {0x2260, 0x2261},
+    {0x2264, 0x2267}, {0x226A, 0x226B}, {0x226E, 0x226F}, {0x2282, 0x2283},
+    {0x2286, 0x2287}, {0x2295, 0x2295}, {0x2299, 0x2299}, {0x22A5, 0x22A5},
+    {0x22BF, 0x22BF}, {0x2312, 0x2312}, {0x2460, 0x24E9}, {0x24EB, 0x254B},
+    {0x2550, 0x2573}, {0x2580, 0x258F}, {0x2592, 0x2595}, {0x25A0, 0x25A1},
+    {0x25A3, 0x25A9}, {0x25B2, 0x25B3}, {0x25B6, 0x25B7}, {0x25BC, 0x25BD},
+    {0x25C0, 0x25C1}, {0x25C6, 0x25C8}, {0x25CB, 0x25CB}, {0x25CE, 0x25D1},
+    {0x25E2, 0x25E5}, {0x25EF, 0x25EF}, {0x2605, 0x2606}, {0x2609, 0x2609},
+    {0x260E, 0x260F}, {0x2614, 0x2615}, {0x261C, 0x261C}, {0x261E, 0x261E},
+    {0x2640, 0x2640}, {0x2642, 0x2642}, {0x2660, 0x2661}, {0x2663, 0x2665},
+    {0x2667, 0x266A}, {0x266C, 0x266D}, {0x266F, 0x266F}, {0x273D, 0x273D},
+    {0x2776, 0x277F}, {0xE000, 0xF8FF}, {0xFE00, 0xFE0F}, {0xFFFD, 0xFFFD},
+    {0xE0100, 0xE01EF}, {0xF0000, 0xFFFFD}, {0x100000, 0x10FFFD}
+  };
+
+  if (g_unichar_iswide (c))
+    return TRUE;
+
+  if (bsearch (GUINT_TO_POINTER (c), ambiguous, G_N_ELEMENTS (ambiguous), sizeof ambiguous[0],
+              interval_compare))
+    return TRUE;
+
+  return FALSE;
+}
+
+
+/**
+ * g_unichar_toupper:
+ * @c: a Unicode character
+ * 
+ * Converts a character to uppercase.
+ * 
+ * Return value: the result of converting @c to uppercase.
+ *               If @c is not an lowercase or titlecase character,
+ *               or has no upper case equivalent @c is returned unchanged.
+ **/
+gunichar
+g_unichar_toupper (gunichar c)
+{
+  int t = TYPE (c);
+  if (t == G_UNICODE_LOWERCASE_LETTER)
+    {
+      gunichar val = ATTTABLE (c >> 8, c & 0xff);
+      if (val >= 0x1000000)
+       {
+         const gchar *p = special_case_table + val - 0x1000000;
+          val = g_utf8_get_char (p);
+       }
+      /* Some lowercase letters, e.g., U+000AA, FEMININE ORDINAL INDICATOR,
+       * do not have an uppercase equivalent, in which case val will be
+       * zero. 
+       */
+      return val ? val : c;
+    }
+  else if (t == G_UNICODE_TITLECASE_LETTER)
+    {
+      unsigned int i;
+      for (i = 0; i < G_N_ELEMENTS (title_table); ++i)
+       {
+         if (title_table[i][0] == c)
+           return title_table[i][1];
+       }
+    }
+  return c;
+}
+
+/**
+ * g_unichar_tolower:
+ * @c: a Unicode character.
+ * 
+ * Converts a character to lower case.
+ * 
+ * Return value: the result of converting @c to lower case.
+ *               If @c is not an upperlower or titlecase character,
+ *               or has no lowercase equivalent @c is returned unchanged.
+ **/
+gunichar
+g_unichar_tolower (gunichar c)
+{
+  int t = TYPE (c);
+  if (t == G_UNICODE_UPPERCASE_LETTER)
+    {
+      gunichar val = ATTTABLE (c >> 8, c & 0xff);
+      if (val >= 0x1000000)
+       {
+         const gchar *p = special_case_table + val - 0x1000000;
+         return g_utf8_get_char (p);
+       }
+      else
+       {
+         /* Not all uppercase letters are guaranteed to have a lowercase
+          * equivalent.  If this is the case, val will be zero. */
+         return val ? val : c;
+       }
+    }
+  else if (t == G_UNICODE_TITLECASE_LETTER)
+    {
+      unsigned int i;
+      for (i = 0; i < G_N_ELEMENTS (title_table); ++i)
+       {
+         if (title_table[i][0] == c)
+           return title_table[i][2];
+       }
+    }
+  return c;
+}
+
+/**
+ * g_unichar_totitle:
+ * @c: a Unicode character
+ * 
+ * Converts a character to the titlecase.
+ * 
+ * Return value: the result of converting @c to titlecase.
+ *               If @c is not an uppercase or lowercase character,
+ *               @c is returned unchanged.
+ **/
+gunichar
+g_unichar_totitle (gunichar c)
+{
+  unsigned int i;
+  for (i = 0; i < G_N_ELEMENTS (title_table); ++i)
+    {
+      if (title_table[i][0] == c || title_table[i][1] == c
+         || title_table[i][2] == c)
+       return title_table[i][0];
+    }
+    
+  if (TYPE (c) == G_UNICODE_LOWERCASE_LETTER)
+    return g_unichar_toupper (c);
+
+  return c;
+}
+
+/**
+ * g_unichar_digit_value:
+ * @c: a Unicode character
+ *
+ * Determines the numeric value of a character as a decimal
+ * digit.
+ *
+ * Return value: If @c is a decimal digit (according to
+ * g_unichar_isdigit()), its numeric value. Otherwise, -1.
+ **/
+int
+g_unichar_digit_value (gunichar c)
+{
+  if (TYPE (c) == G_UNICODE_DECIMAL_NUMBER)
+    return ATTTABLE (c >> 8, c & 0xff);
+  return -1;
+}
+
+/**
+ * g_unichar_xdigit_value:
+ * @c: a Unicode character
+ *
+ * Determines the numeric value of a character as a hexidecimal
+ * digit.
+ *
+ * Return value: If @c is a hex digit (according to
+ * g_unichar_isxdigit()), its numeric value. Otherwise, -1.
+ **/
+int
+g_unichar_xdigit_value (gunichar c)
+{
+  if (c >= 'A' && c <= 'F')
+    return c - 'A' + 10;
+  if (c >= 'a' && c <= 'f')
+    return c - 'a' + 10;
+  if (TYPE (c) == G_UNICODE_DECIMAL_NUMBER)
+    return ATTTABLE (c >> 8, c & 0xff);
+  return -1;
+}
+
+/**
+ * g_unichar_type:
+ * @c: a Unicode character
+ * 
+ * Classifies a Unicode character by type.
+ * 
+ * Return value: the type of the character.
+ **/
+GUnicodeType
+g_unichar_type (gunichar c)
+{
+  return TYPE (c);
+}
+
+/*
+ * Case mapping functions
+ */
+
+typedef enum {
+  LOCALE_NORMAL,
+  LOCALE_TURKIC,
+  LOCALE_LITHUANIAN
+} LocaleType;
+
+static LocaleType
+get_locale_type (void)
+{
+#ifdef G_OS_WIN32
+  char *tem = g_win32_getlocale ();
+  char locale[2];
+
+  locale[0] = tem[0];
+  locale[1] = tem[1];
+  g_free (tem);
+#else
+  const char *locale = setlocale (LC_CTYPE, NULL);
+#endif
+
+  switch (locale[0])
+    {
+   case 'a':
+      if (locale[1] == 'z')
+       return LOCALE_TURKIC;
+      break;
+    case 'l':
+      if (locale[1] == 't')
+       return LOCALE_LITHUANIAN;
+      break;
+    case 't':
+      if (locale[1] == 'r')
+       return LOCALE_TURKIC;
+      break;
+    }
+
+  return LOCALE_NORMAL;
+}
+
+static gint
+output_marks (const char **p_inout,
+             char        *out_buffer,
+             gboolean     remove_dot)
+{
+  const char *p = *p_inout;
+  gint len = 0;
+  
+  while (*p)
+    {
+      gunichar c = g_utf8_get_char (p);
+      
+      if (ISMARK (TYPE (c)))
+       {
+         if (!remove_dot || c != 0x307 /* COMBINING DOT ABOVE */)
+           len += g_unichar_to_utf8 (c, out_buffer ? out_buffer + len : NULL);
+         p = g_utf8_next_char (p);
+       }
+      else
+       break;
+    }
+
+  *p_inout = p;
+  return len;
+}
+
+static gint
+output_special_case (gchar *out_buffer,
+                    int    offset,
+                    int    type,
+                    int    which)
+{
+  const gchar *p = special_case_table + offset;
+  gint len;
+
+  if (type != G_UNICODE_TITLECASE_LETTER)
+    p = g_utf8_next_char (p);
+
+  if (which == 1)
+    p += strlen (p) + 1;
+
+  len = strlen (p);
+  if (out_buffer)
+    memcpy (out_buffer, p, len);
+
+  return len;
+}
+
+static gsize
+real_toupper (const gchar *str,
+             gssize       max_len,
+             gchar       *out_buffer,
+             LocaleType   locale_type)
+{
+  const gchar *p = str;
+  const char *last = NULL;
+  gsize len = 0;
+  gboolean last_was_i = FALSE;
+
+  while ((max_len < 0 || p < str + max_len) && *p)
+    {
+      gunichar c = g_utf8_get_char (p);
+      int t = TYPE (c);
+      gunichar val;
+
+      last = p;
+      p = g_utf8_next_char (p);
+
+      if (locale_type == LOCALE_LITHUANIAN)
+       {
+         if (c == 'i')
+           last_was_i = TRUE;
+         else 
+           {
+             if (last_was_i)
+               {
+                 /* Nasty, need to remove any dot above. Though
+                  * I think only E WITH DOT ABOVE occurs in practice
+                  * which could simplify this considerably.
+                  */
+                 gsize decomp_len, i;
+                 gunichar *decomp;
+
+                 decomp = g_unicode_canonical_decomposition (c, &decomp_len);
+                 for (i=0; i < decomp_len; i++)
+                   {
+                     if (decomp[i] != 0x307 /* COMBINING DOT ABOVE */)
+                       len += g_unichar_to_utf8 (g_unichar_toupper (decomp[i]), out_buffer ? out_buffer + len : NULL);
+                   }
+                 g_free (decomp);
+                 
+                 len += output_marks (&p, out_buffer ? out_buffer + len : NULL, TRUE);
+
+                 continue;
+               }
+
+             if (!ISMARK (t))
+               last_was_i = FALSE;
+           }
+       }
+      
+      if (locale_type == LOCALE_TURKIC && c == 'i')
+       {
+         /* i => LATIN CAPITAL LETTER I WITH DOT ABOVE */
+         len += g_unichar_to_utf8 (0x130, out_buffer ? out_buffer + len : NULL); 
+       }
+      else if (c == 0x0345)    /* COMBINING GREEK YPOGEGRAMMENI */
+       {
+         /* Nasty, need to move it after other combining marks .. this would go away if
+          * we normalized first.
+          */
+         len += output_marks (&p, out_buffer ? out_buffer + len : NULL, FALSE);
+
+         /* And output as GREEK CAPITAL LETTER IOTA */
+         len += g_unichar_to_utf8 (0x399, out_buffer ? out_buffer + len : NULL);         
+       }
+      else if (IS (t,
+                  OR (G_UNICODE_LOWERCASE_LETTER,
+                  OR (G_UNICODE_TITLECASE_LETTER,
+                 0))))
+       {
+         val = ATTTABLE (c >> 8, c & 0xff);
+
+         if (val >= 0x1000000)
+           {
+             len += output_special_case (out_buffer ? out_buffer + len : NULL, val - 0x1000000, t,
+                                         t == G_UNICODE_LOWERCASE_LETTER ? 0 : 1);
+           }
+         else
+           {
+             if (t == G_UNICODE_TITLECASE_LETTER)
+               {
+                 unsigned int i;
+                 for (i = 0; i < G_N_ELEMENTS (title_table); ++i)
+                   {
+                     if (title_table[i][0] == c)
+                       {
+                         val = title_table[i][1];
+                         break;
+                       }
+                   }
+               }
+
+             /* Some lowercase letters, e.g., U+000AA, FEMININE ORDINAL INDICATOR,
+              * do not have an uppercase equivalent, in which case val will be
+              * zero. */
+             len += g_unichar_to_utf8 (val ? val : c, out_buffer ? out_buffer + len : NULL);
+           }
+       }
+      else
+       {
+         gsize char_len = g_utf8_skip[*(guchar *)last];
+
+         if (out_buffer)
+           memcpy (out_buffer + len, last, char_len);
+
+         len += char_len;
+       }
+
+    }
+
+  return len;
+}
+
+/**
+ * g_utf8_strup:
+ * @str: a UTF-8 encoded string
+ * @len: length of @str, in bytes, or -1 if @str is nul-terminated.
+ * 
+ * Converts all Unicode characters in the string that have a case
+ * to uppercase. The exact manner that this is done depends
+ * on the current locale, and may result in the number of
+ * characters in the string increasing. (For instance, the
+ * German ess-zet will be changed to SS.)
+ * 
+ * Return value: a newly allocated string, with all characters
+ *    converted to uppercase.  
+ **/
+gchar *
+g_utf8_strup (const gchar *str,
+             gssize       len)
+{
+  gsize result_len;
+  LocaleType locale_type;
+  gchar *result;
+
+  g_return_val_if_fail (str != NULL, NULL);
+
+  locale_type = get_locale_type ();
+  
+  /*
+   * We use a two pass approach to keep memory management simple
+   */
+  result_len = real_toupper (str, len, NULL, locale_type);
+  result = g_malloc (result_len + 1);
+  real_toupper (str, len, result, locale_type);
+  result[result_len] = '\0';
+
+  return result;
+}
+
+/* traverses the string checking for characters with combining class == 230
+ * until a base character is found */
+static gboolean
+has_more_above (const gchar *str)
+{
+  const gchar *p = str;
+  gint combining_class;
+
+  while (*p)
+    {
+      combining_class = g_unichar_combining_class (g_utf8_get_char (p));
+      if (combining_class == 230)
+        return TRUE;
+      else if (combining_class == 0)
+        break;
+
+      p = g_utf8_next_char (p);
+    }
+
+  return FALSE;
+}
+
+static gsize
+real_tolower (const gchar *str,
+             gssize       max_len,
+             gchar       *out_buffer,
+             LocaleType   locale_type)
+{
+  const gchar *p = str;
+  const char *last = NULL;
+  gsize len = 0;
+
+  while ((max_len < 0 || p < str + max_len) && *p)
+    {
+      gunichar c = g_utf8_get_char (p);
+      int t = TYPE (c);
+      gunichar val;
+
+      last = p;
+      p = g_utf8_next_char (p);
+
+      if (locale_type == LOCALE_TURKIC && c == 'I')
+       {
+          if (g_utf8_get_char (p) == 0x0307)
+            {
+              /* I + COMBINING DOT ABOVE => i (U+0069) */
+              len += g_unichar_to_utf8 (0x0069, out_buffer ? out_buffer + len : NULL); 
+              p = g_utf8_next_char (p);
+            }
+          else
+            {
+              /* I => LATIN SMALL LETTER DOTLESS I */
+              len += g_unichar_to_utf8 (0x131, out_buffer ? out_buffer + len : NULL); 
+            }
+        }
+      /* Introduce an explicit dot above when lowercasing capital I's and J's
+       * whenever there are more accents above. [SpecialCasing.txt] */
+      else if (locale_type == LOCALE_LITHUANIAN && 
+               (c == 0x00cc || c == 0x00cd || c == 0x0128))
+        {
+          len += g_unichar_to_utf8 (0x0069, out_buffer ? out_buffer + len : NULL); 
+          len += g_unichar_to_utf8 (0x0307, out_buffer ? out_buffer + len : NULL); 
+
+          switch (c)
+            {
+            case 0x00cc: 
+              len += g_unichar_to_utf8 (0x0300, out_buffer ? out_buffer + len : NULL); 
+              break;
+            case 0x00cd: 
+              len += g_unichar_to_utf8 (0x0301, out_buffer ? out_buffer + len : NULL); 
+              break;
+            case 0x0128: 
+              len += g_unichar_to_utf8 (0x0303, out_buffer ? out_buffer + len : NULL); 
+              break;
+            }
+        }
+      else if (locale_type == LOCALE_LITHUANIAN && 
+               (c == 'I' || c == 'J' || c == 0x012e) && 
+               has_more_above (p))
+        {
+          len += g_unichar_to_utf8 (g_unichar_tolower (c), out_buffer ? out_buffer + len : NULL); 
+          len += g_unichar_to_utf8 (0x0307, out_buffer ? out_buffer + len : NULL); 
+        }
+      else if (c == 0x03A3)    /* GREEK CAPITAL LETTER SIGMA */
+       {
+         if ((max_len < 0 || p < str + max_len) && *p)
+           {
+             gunichar next_c = g_utf8_get_char (p);
+             int next_type = TYPE(next_c);
+
+             /* SIGMA mapps differently depending on whether it is
+              * final or not. The following simplified test would
+              * fail in the case of combining marks following the
+              * sigma, but I don't think that occurs in real text.
+              * The test here matches that in ICU.
+              */
+             if (ISALPHA (next_type)) /* Lu,Ll,Lt,Lm,Lo */
+               val = 0x3c3;    /* GREEK SMALL SIGMA */
+             else
+               val = 0x3c2;    /* GREEK SMALL FINAL SIGMA */
+           }
+         else
+           val = 0x3c2;        /* GREEK SMALL FINAL SIGMA */
+
+         len += g_unichar_to_utf8 (val, out_buffer ? out_buffer + len : NULL);
+       }
+      else if (IS (t,
+                  OR (G_UNICODE_UPPERCASE_LETTER,
+                  OR (G_UNICODE_TITLECASE_LETTER,
+                 0))))
+       {
+         val = ATTTABLE (c >> 8, c & 0xff);
+
+         if (val >= 0x1000000)
+           {
+             len += output_special_case (out_buffer ? out_buffer + len : NULL, val - 0x1000000, t, 0);
+           }
+         else
+           {
+             if (t == G_UNICODE_TITLECASE_LETTER)
+               {
+                 unsigned int i;
+                 for (i = 0; i < G_N_ELEMENTS (title_table); ++i)
+                   {
+                     if (title_table[i][0] == c)
+                       {
+                         val = title_table[i][2];
+                         break;
+                       }
+                   }
+               }
+
+             /* Not all uppercase letters are guaranteed to have a lowercase
+              * equivalent.  If this is the case, val will be zero. */
+             len += g_unichar_to_utf8 (val ? val : c, out_buffer ? out_buffer + len : NULL);
+           }
+       }
+      else
+       {
+         gsize char_len = g_utf8_skip[*(guchar *)last];
+
+         if (out_buffer)
+           memcpy (out_buffer + len, last, char_len);
+
+         len += char_len;
+       }
+
+    }
+
+  return len;
+}
+
+/**
+ * g_utf8_strdown:
+ * @str: a UTF-8 encoded string
+ * @len: length of @str, in bytes, or -1 if @str is nul-terminated.
+ * 
+ * Converts all Unicode characters in the string that have a case
+ * to lowercase. The exact manner that this is done depends
+ * on the current locale, and may result in the number of
+ * characters in the string changing.
+ * 
+ * Return value: a newly allocated string, with all characters
+ *    converted to lowercase.  
+ **/
+gchar *
+g_utf8_strdown (const gchar *str,
+               gssize       len)
+{
+  gsize result_len;
+  LocaleType locale_type;
+  gchar *result;
+
+  g_return_val_if_fail (str != NULL, NULL);
+
+  locale_type = get_locale_type ();
+  
+  /*
+   * We use a two pass approach to keep memory management simple
+   */
+  result_len = real_tolower (str, len, NULL, locale_type);
+  result = g_malloc (result_len + 1);
+  real_tolower (str, len, result, locale_type);
+  result[result_len] = '\0';
+
+  return result;
+}
+
+/**
+ * g_utf8_casefold:
+ * @str: a UTF-8 encoded string
+ * @len: length of @str, in bytes, or -1 if @str is nul-terminated.
+ * 
+ * Converts a string into a form that is independent of case. The
+ * result will not correspond to any particular case, but can be
+ * compared for equality or ordered with the results of calling
+ * g_utf8_casefold() on other strings.
+ * 
+ * Note that calling g_utf8_casefold() followed by g_utf8_collate() is
+ * only an approximation to the correct linguistic case insensitive
+ * ordering, though it is a fairly good one. Getting this exactly
+ * right would require a more sophisticated collation function that
+ * takes case sensitivity into account. GLib does not currently
+ * provide such a function.
+ * 
+ * Return value: a newly allocated string, that is a
+ *   case independent form of @str.
+ **/
+gchar *
+g_utf8_casefold (const gchar *str,
+                gssize       len)
+{
+  GString *result;
+  const char *p;
+
+  g_return_val_if_fail (str != NULL, NULL);
+
+  result = g_string_new (NULL);
+  p = str;
+  while ((len < 0 || p < str + len) && *p)
+    {
+      gunichar ch = g_utf8_get_char (p);
+
+      int start = 0;
+      int end = G_N_ELEMENTS (casefold_table);
+
+      if (ch >= casefold_table[start].ch &&
+          ch <= casefold_table[end - 1].ch)
+       {
+         while (TRUE)
+           {
+             int half = (start + end) / 2;
+             if (ch == casefold_table[half].ch)
+               {
+                 g_string_append (result, casefold_table[half].data);
+                 goto next;
+               }
+             else if (half == start)
+               break;
+             else if (ch > casefold_table[half].ch)
+               start = half;
+             else
+               end = half;
+           }
+       }
+
+      g_string_append_unichar (result, g_unichar_tolower (ch));
+      
+    next:
+      p = g_utf8_next_char (p);
+    }
+
+  return g_string_free (result, FALSE); 
+}
+
+/**
+ * g_unichar_get_mirror_char:
+ * @ch: a Unicode character
+ * @mirrored_ch: location to store the mirrored character
+ * 
+ * In Unicode, some characters are <firstterm>mirrored</firstterm>. This
+ * means that their images are mirrored horizontally in text that is laid
+ * out from right to left. For instance, "(" would become its mirror image,
+ * ")", in right-to-left text.
+ *
+ * If @ch has the Unicode mirrored property and there is another unicode
+ * character that typically has a glyph that is the mirror image of @ch's
+ * glyph and @mirrored_ch is set, it puts that character in the address
+ * pointed to by @mirrored_ch.  Otherwise the original character is put.
+ *
+ * Return value: %TRUE if @ch has a mirrored character, %FALSE otherwise
+ *
+ * Since: 2.4
+ **/
+gboolean
+g_unichar_get_mirror_char (gunichar ch,
+                           gunichar *mirrored_ch)
+{
+  gboolean found;
+  gunichar mirrored;
+
+  mirrored = GLIB_GET_MIRRORING(ch);
+
+  found = ch != mirrored;
+  if (mirrored_ch)
+    *mirrored_ch = mirrored;
+
+  return found;
+
+}
+
+#define G_SCRIPT_TABLE_MIDPOINT (G_N_ELEMENTS (g_script_table) / 2)
+
+static inline GUnicodeScript
+g_unichar_get_script_bsearch (gunichar ch)
+{
+  int lower = 0;
+  int upper = G_N_ELEMENTS (g_script_table) - 1;
+  static int saved_mid = G_SCRIPT_TABLE_MIDPOINT;
+  int mid = saved_mid;
+
+
+  do 
+    {
+      if (ch < g_script_table[mid].start)
+       upper = mid - 1;
+      else if (ch >= g_script_table[mid].start + g_script_table[mid].chars)
+       lower = mid + 1;
+      else
+       return g_script_table[saved_mid = mid].script;
+
+      mid = (lower + upper) / 2;
+    }
+  while (lower <= upper);
+
+  return G_UNICODE_SCRIPT_UNKNOWN;
+}
+
+/**
+ * g_unichar_get_script:
+ * @ch: a Unicode character
+ * 
+ * Looks up the #GUnicodeScript for a particular character (as defined 
+ * by Unicode Standard Annex #24). No check is made for @ch being a
+ * valid Unicode character; if you pass in invalid character, the
+ * result is undefined.
+ *
+ * This function is equivalent to pango_script_for_unichar() and the
+ * two are interchangeable.
+ * 
+ * Return value: the #GUnicodeScript for the character.
+ *
+ * Since: 2.14
+ */
+GUnicodeScript
+g_unichar_get_script (gunichar ch)
+{
+  if (ch < G_EASY_SCRIPTS_RANGE)
+    return g_script_easy_table[ch];
+  else 
+    return g_unichar_get_script_bsearch (ch); 
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gurifuncs.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gurifuncs.c
new file mode 100644 (file)
index 0000000..6a77244
--- /dev/null
@@ -0,0 +1,249 @@
+/* GIO - GLib Input, Output and Streaming Library
+ * 
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#include "config.h"
+
+#include "gurifuncs.h"
+
+#include <glib/gstrfuncs.h>
+#include <glib/gmessages.h>
+#include <glib/gstring.h>
+#include <glib/gmem.h>
+
+#include <string.h>
+
+#include "config.h"
+
+/**
+ * SECTION:gurifuncs
+ * @short_description: URI Functions
+ * 
+ * Functions for manipulating Universal Resource Identifiers (URIs) as 
+ * defined by <ulink url="http://www.ietf.org/rfc/rfc3986.txt">
+ * RFC 3986</ulink>. It is highly recommended that you have read and
+ * understand RFC 3986 for understanding this API.
+ */
+
+static int
+unescape_character (const char *scanner)
+{
+  int first_digit;
+  int second_digit;
+  
+  first_digit = g_ascii_xdigit_value (*scanner++);
+  if (first_digit < 0)
+    return -1;
+
+  second_digit = g_ascii_xdigit_value (*scanner++);
+  if (second_digit < 0)
+    return -1;
+
+  return (first_digit << 4) | second_digit;
+}
+
+/**
+ * g_uri_unescape_segment:
+ * @escaped_string: a string.
+ * @escaped_string_end: a string.
+ * @illegal_characters: an optional string of illegal characters not to be allowed.
+ * 
+ * Unescapes a segment of an escaped string.
+ *
+ * If any of the characters in @illegal_characters or the character zero appears
+ * as an escaped character in @escaped_string then that is an error and %NULL
+ * will be returned. This is useful it you want to avoid for instance having a
+ * slash being expanded in an escaped path element, which might confuse pathname
+ * handling.
+ *
+ * Returns: an unescaped version of @escaped_string or %NULL on error.
+ * The returned string should be freed when no longer needed.
+ *
+ * Since: 2.16
+ **/
+char *
+g_uri_unescape_segment (const char *escaped_string,
+                       const char *escaped_string_end,
+                       const char *illegal_characters)
+{
+  const char *in;
+  char *out, *result;
+  gint character;
+  
+  if (escaped_string == NULL)
+    return NULL;
+  
+  if (escaped_string_end == NULL)
+    escaped_string_end = escaped_string + strlen (escaped_string);
+  
+  result = g_malloc (escaped_string_end - escaped_string + 1);
+  
+  out = result;
+  for (in = escaped_string; in < escaped_string_end; in++)
+    {
+      character = *in;
+      
+      if (*in == '%')
+       {
+         in++;
+         
+         if (escaped_string_end - in < 2)
+           {
+             /* Invalid escaped char (to short) */
+             g_free (result);
+             return NULL;
+           }
+         
+         character = unescape_character (in);
+         
+         /* Check for an illegal character. We consider '\0' illegal here. */
+         if (character <= 0 ||
+             (illegal_characters != NULL &&
+              strchr (illegal_characters, (char)character) != NULL))
+           {
+             g_free (result);
+             return NULL;
+           }
+         
+         in++; /* The other char will be eaten in the loop header */
+       }
+      *out++ = (char)character;
+    }
+  
+  *out = '\0';
+  
+  return result;
+}
+
+/**
+ * g_uri_unescape_string:
+ * @escaped_string: an escaped string to be unescaped.
+ * @illegal_characters: an optional string of illegal characters not to be allowed.
+ * 
+ * Unescapes a whole escaped string.
+ * 
+ * If any of the characters in @illegal_characters or the character zero appears
+ * as an escaped character in @escaped_string then that is an error and %NULL
+ * will be returned. This is useful it you want to avoid for instance having a
+ * slash being expanded in an escaped path element, which might confuse pathname
+ * handling.
+ *
+ * Returns: an unescaped version of @escaped_string. The returned string 
+ * should be freed when no longer needed.
+ *
+ * Since: 2.16
+ **/
+char *
+g_uri_unescape_string (const char *escaped_string,
+                      const char *illegal_characters)
+{
+  return g_uri_unescape_segment (escaped_string, NULL, illegal_characters);
+}
+
+/**
+ * g_uri_parse_scheme:
+ * @uri: a valid URI.
+ * 
+ * Gets the scheme portion of a URI string. RFC 3986 decodes the scheme as:
+ * <programlisting>
+ * URI = scheme ":" hier-part [ "?" query ] [ "#" fragment ] 
+ * </programlisting>
+ * Common schemes include "file", "http", "svn+ssh", etc.
+ * 
+ * Returns: The "Scheme" component of the URI, or %NULL on error. 
+ * The returned string should be freed when no longer needed.
+ *
+ * Since: 2.16
+ **/
+char *
+g_uri_parse_scheme (const char  *uri)
+{
+  const char *p;
+  char c;
+
+  g_return_val_if_fail (uri != NULL, NULL);
+
+  /* From RFC 3986 Decodes:
+   * URI         = scheme ":" hier-part [ "?" query ] [ "#" fragment ]
+   */ 
+
+  p = uri;
+  
+  /* Decode scheme:
+     scheme      = ALPHA *( ALPHA / DIGIT / "+" / "-" / "." )
+  */
+
+  if (!g_ascii_isalpha (*p))
+    return NULL;
+  
+  while (1)
+    {
+      c = *p++;
+      
+      if (c == ':')
+       break;
+      
+      if (!(g_ascii_isalnum(c) ||
+           c == '+' ||
+           c == '-' ||
+           c == '.'))
+       return NULL;
+    }
+  
+  return g_strndup (uri, p - uri - 1);
+}
+
+/**
+ * g_uri_escape_string:
+ * @unescaped: the unescaped input string.
+ * @reserved_chars_allowed: a string of reserved characters that are
+ *      allowed to be used, or %NULL.
+ * @allow_utf8: %TRUE if the result can include UTF-8 characters.
+ * 
+ * Escapes a string for use in a URI.
+ *
+ * Normally all characters that are not "unreserved" (i.e. ASCII alphanumerical
+ * characters plus dash, dot, underscore and tilde) are escaped.
+ * But if you specify characters in @reserved_chars_allowed they are not
+ * escaped. This is useful for the "reserved" characters in the URI
+ * specification, since those are allowed unescaped in some portions of
+ * a URI. 
+ * 
+ * Returns: an escaped version of @unescaped. The returned string should be 
+ * freed when no longer needed.
+ *
+ * Since: 2.16
+ **/
+char *
+g_uri_escape_string (const char *unescaped,
+                    const char  *reserved_chars_allowed,
+                    gboolean     allow_utf8)
+{
+  GString *s;
+
+  g_return_val_if_fail (unescaped != NULL, NULL);
+
+  s = g_string_sized_new (strlen (unescaped) + 10);
+  
+  g_string_append_uri_escaped (s, unescaped, reserved_chars_allowed, allow_utf8);
+  
+  return g_string_free (s, FALSE);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gurifuncs.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gurifuncs.h
new file mode 100644 (file)
index 0000000..bbc8f88
--- /dev/null
@@ -0,0 +1,81 @@
+/* GIO - GLib Input, Output and Streaming Library
+ *
+ * Copyright (C) 2006-2007 Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place, Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Alexander Larsson <alexl@redhat.com>
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_URI_FUNCS_H__
+#define __G_URI_FUNCS_H__
+
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+/**
+ * G_URI_RESERVED_CHARS_GENERIC_DELIMITERS:
+ * 
+ * Generic delimiters characters as defined in RFC 3986. Includes ":/?#[]@".
+ **/
+#define G_URI_RESERVED_CHARS_GENERIC_DELIMITERS ":/?#[]@"
+
+/**
+ * G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS
+ * 
+ * Subcomponent delimiter characters as defined in RFC 3986. Includes "!$&'()*+,;=".
+ **/
+#define G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS "!$&'()*+,;="
+
+/**
+ * G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT:
+ * 
+ * Allowed characters in path elements. Includes "!$&'()*+,;=:@".
+ **/
+#define G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS ":@"
+
+/**
+ * G_URI_RESERVED_CHARS_ALLOWED_IN_PATH:
+ * 
+ * Allowed characters in a path. Includes "!$&'()*+,;=:@/".
+ **/
+#define G_URI_RESERVED_CHARS_ALLOWED_IN_PATH G_URI_RESERVED_CHARS_ALLOWED_IN_PATH_ELEMENT "/"
+
+/**
+ * G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO:
+ * 
+ * Allowed characters in userinfo as defined in RFC 3986. Includes "!$&'()*+,;=:".
+ **/
+#define G_URI_RESERVED_CHARS_ALLOWED_IN_USERINFO G_URI_RESERVED_CHARS_SUBCOMPONENT_DELIMITERS ":"
+
+char *   g_uri_unescape_string       (const char *escaped_string,
+                                     const char *illegal_characters);
+char *   g_uri_unescape_segment      (const char *escaped_string,
+                                     const char *escaped_string_end,
+                                     const char *illegal_characters);
+char *   g_uri_parse_scheme          (const char *uri);
+char *   g_uri_escape_string         (const char *unescaped,
+                                     const char *reserved_chars_allowed,
+                                     gboolean    allow_utf8);
+
+G_END_DECLS
+
+#endif /* __G_URI_FUNCS_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gutf8.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gutf8.c
new file mode 100644 (file)
index 0000000..98f4707
--- /dev/null
@@ -0,0 +1,1902 @@
+/* gutf8.c - Operations on UTF-8 strings.
+ *
+ * Copyright (C) 1999 Tom Tromey
+ * Copyright (C) 2000 Red Hat, Inc.
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#ifdef HAVE_CODESET
+#include <langinfo.h>
+#endif
+#include <string.h>
+
+#ifdef G_PLATFORM_WIN32
+#include <stdio.h>
+#define STRICT
+#include <windows.h>
+#undef STRICT
+#endif
+
+#include "libcharset/libcharset.h"
+
+#include "gconvert.h"
+#include "ghash.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "gtypes.h"
+#include "gthread.h"
+#include "glibintl.h"
+
+#define UTF8_COMPUTE(Char, Mask, Len)                                        \
+  if (Char < 128)                                                            \
+    {                                                                        \
+      Len = 1;                                                               \
+      Mask = 0x7f;                                                           \
+    }                                                                        \
+  else if ((Char & 0xe0) == 0xc0)                                            \
+    {                                                                        \
+      Len = 2;                                                               \
+      Mask = 0x1f;                                                           \
+    }                                                                        \
+  else if ((Char & 0xf0) == 0xe0)                                            \
+    {                                                                        \
+      Len = 3;                                                               \
+      Mask = 0x0f;                                                           \
+    }                                                                        \
+  else if ((Char & 0xf8) == 0xf0)                                            \
+    {                                                                        \
+      Len = 4;                                                               \
+      Mask = 0x07;                                                           \
+    }                                                                        \
+  else if ((Char & 0xfc) == 0xf8)                                            \
+    {                                                                        \
+      Len = 5;                                                               \
+      Mask = 0x03;                                                           \
+    }                                                                        \
+  else if ((Char & 0xfe) == 0xfc)                                            \
+    {                                                                        \
+      Len = 6;                                                               \
+      Mask = 0x01;                                                           \
+    }                                                                        \
+  else                                                                       \
+    Len = -1;
+
+#define UTF8_LENGTH(Char)              \
+  ((Char) < 0x80 ? 1 :                 \
+   ((Char) < 0x800 ? 2 :               \
+    ((Char) < 0x10000 ? 3 :            \
+     ((Char) < 0x200000 ? 4 :          \
+      ((Char) < 0x4000000 ? 5 : 6)))))
+   
+
+#define UTF8_GET(Result, Chars, Count, Mask, Len)                            \
+  (Result) = (Chars)[0] & (Mask);                                            \
+  for ((Count) = 1; (Count) < (Len); ++(Count))                                      \
+    {                                                                        \
+      if (((Chars)[(Count)] & 0xc0) != 0x80)                                 \
+       {                                                                     \
+         (Result) = -1;                                                      \
+         break;                                                              \
+       }                                                                     \
+      (Result) <<= 6;                                                        \
+      (Result) |= ((Chars)[(Count)] & 0x3f);                                 \
+    }
+    
+/*
+ * Check whether a Unicode (5.2) char is in a valid range.
+ *
+ * The first check comes from the Unicode guarantee to never encode
+ * a point above 0x0010ffff, since UTF-16 couldn't represent it.
+ * 
+ * The second check covers surrogate pairs (category Cs).
+ * 
+ * The last two checks cover "Noncharacter": defined as:
+ *   "A code point that is permanently reserved for
+ *    internal use, and that should never be interchanged. In
+ *    Unicode 3.1, these consist of the values U+nFFFE and U+nFFFF
+ *    (where n is from 0 to 10_16) and the values U+FDD0..U+FDEF."
+ *
+ * @param Char the character
+ */
+#define UNICODE_VALID(Char)                   \
+    ((Char) < 0x110000 &&                     \
+     (((Char) & 0xFFFFF800) != 0xD800) &&     \
+     ((Char) < 0xFDD0 || (Char) > 0xFDEF) &&  \
+     ((Char) & 0xFFFE) != 0xFFFE)
+   
+     
+static const gchar utf8_skip_data[256] = {
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,3,4,4,4,4,4,4,4,4,5,5,5,5,6,6,1,1
+};
+
+const gchar * const g_utf8_skip = utf8_skip_data;
+
+/**
+ * g_utf8_find_prev_char:
+ * @str: pointer to the beginning of a UTF-8 encoded string
+ * @p: pointer to some position within @str
+ * 
+ * Given a position @p with a UTF-8 encoded string @str, find the start
+ * of the previous UTF-8 character starting before @p. Returns %NULL if no
+ * UTF-8 characters are present in @str before @p.
+ *
+ * @p does not have to be at the beginning of a UTF-8 character. No check
+ * is made to see if the character found is actually valid other than
+ * it starts with an appropriate byte.
+ *
+ * Return value: a pointer to the found character or %NULL.
+ **/
+gchar *
+g_utf8_find_prev_char (const char *str,
+                      const char *p)
+{
+  for (--p; p >= str; --p)
+    {
+      if ((*p & 0xc0) != 0x80)
+       return (gchar *)p;
+    }
+  return NULL;
+}
+
+/**
+ * g_utf8_find_next_char:
+ * @p: a pointer to a position within a UTF-8 encoded string
+ * @end: a pointer to the byte following the end of the string,
+ * or %NULL to indicate that the string is nul-terminated.
+ *
+ * Finds the start of the next UTF-8 character in the string after @p.
+ *
+ * @p does not have to be at the beginning of a UTF-8 character. No check
+ * is made to see if the character found is actually valid other than
+ * it starts with an appropriate byte.
+ * 
+ * Return value: a pointer to the found character or %NULL
+ **/
+gchar *
+g_utf8_find_next_char (const gchar *p,
+                      const gchar *end)
+{
+  if (*p)
+    {
+      if (end)
+       for (++p; p < end && (*p & 0xc0) == 0x80; ++p)
+         ;
+      else
+       for (++p; (*p & 0xc0) == 0x80; ++p)
+         ;
+    }
+  return (p == end) ? NULL : (gchar *)p;
+}
+
+/**
+ * g_utf8_prev_char:
+ * @p: a pointer to a position within a UTF-8 encoded string
+ *
+ * Finds the previous UTF-8 character in the string before @p.
+ *
+ * @p does not have to be at the beginning of a UTF-8 character. No check
+ * is made to see if the character found is actually valid other than
+ * it starts with an appropriate byte. If @p might be the first
+ * character of the string, you must use g_utf8_find_prev_char() instead.
+ * 
+ * Return value: a pointer to the found character.
+ **/
+gchar *
+g_utf8_prev_char (const gchar *p)
+{
+  while (TRUE)
+    {
+      p--;
+      if ((*p & 0xc0) != 0x80)
+       return (gchar *)p;
+    }
+}
+
+/**
+ * g_utf8_strlen:
+ * @p: pointer to the start of a UTF-8 encoded string
+ * @max: the maximum number of bytes to examine. If @max
+ *       is less than 0, then the string is assumed to be
+ *       nul-terminated. If @max is 0, @p will not be examined and
+ *       may be %NULL.
+ *
+ * Computes the length of the string in characters, not including
+ * the terminating nul character.
+ *
+ * Return value: the length of the string in characters
+ **/
+glong
+g_utf8_strlen (const gchar *p,
+               gssize       max)
+{
+  glong len = 0;
+  const gchar *start = p;
+  g_return_val_if_fail (p != NULL || max == 0, 0);
+
+  if (max < 0)
+    {
+      while (*p)
+        {
+          p = g_utf8_next_char (p);
+          ++len;
+        }
+    }
+  else
+    {
+      if (max == 0 || !*p)
+        return 0;
+
+      p = g_utf8_next_char (p);
+
+      while (p - start < max && *p)
+        {
+          ++len;
+          p = g_utf8_next_char (p);
+        }
+
+      /* only do the last len increment if we got a complete
+       * char (don't count partial chars)
+       */
+      if (p - start <= max)
+        ++len;
+    }
+
+  return len;
+}
+
+/**
+ * g_utf8_get_char:
+ * @p: a pointer to Unicode character encoded as UTF-8
+ * 
+ * Converts a sequence of bytes encoded as UTF-8 to a Unicode character.
+ * If @p does not point to a valid UTF-8 encoded character, results are
+ * undefined. If you are not sure that the bytes are complete
+ * valid Unicode characters, you should use g_utf8_get_char_validated()
+ * instead.
+ * 
+ * Return value: the resulting character
+ **/
+gunichar
+g_utf8_get_char (const gchar *p)
+{
+  int i, mask = 0, len;
+  gunichar result;
+  unsigned char c = (unsigned char) *p;
+
+  UTF8_COMPUTE (c, mask, len);
+  if (len == -1)
+    return (gunichar)-1;
+  UTF8_GET (result, p, i, mask, len);
+
+  return result;
+}
+
+/**
+ * g_utf8_offset_to_pointer:
+ * @str: a UTF-8 encoded string
+ * @offset: a character offset within @str
+ *
+ * Converts from an integer character offset to a pointer to a position
+ * within the string.
+ *
+ * Since 2.10, this function allows to pass a negative @offset to
+ * step backwards. It is usually worth stepping backwards from the end
+ * instead of forwards if @offset is in the last fourth of the string,
+ * since moving forward is about 3 times faster than moving backward.
+ *
+ * <note><para>
+ * This function doesn't abort when reaching the end of @str. Therefore
+ * you should be sure that @offset is within string boundaries before
+ * calling that function. Call g_utf8_strlen() when unsure.
+ *
+ * This limitation exists as this function is called frequently during
+ * text rendering and therefore has to be as fast as possible.
+ * </para></note>
+ *
+ * Return value: the resulting pointer
+ **/
+gchar *
+g_utf8_offset_to_pointer  (const gchar *str,
+                          glong        offset)
+{
+  const gchar *s = str;
+
+  if (offset > 0) 
+    while (offset--)
+      s = g_utf8_next_char (s);
+  else
+    {
+      const char *s1;
+
+      /* This nice technique for fast backwards stepping 
+       * through a UTF-8 string was dubbed "stutter stepping" 
+       * by its inventor, Larry Ewing.
+       */
+      while (offset)
+       {
+         s1 = s;
+         s += offset;
+         while ((*s & 0xc0) == 0x80)
+           s--;
+
+         offset += g_utf8_pointer_to_offset (s, s1);
+       }
+    }
+
+  return (gchar *)s;
+}
+
+/**
+ * g_utf8_pointer_to_offset:
+ * @str: a UTF-8 encoded string
+ * @pos: a pointer to a position within @str
+ * 
+ * Converts from a pointer to position within a string to a integer
+ * character offset.
+ *
+ * Since 2.10, this function allows @pos to be before @str, and returns
+ * a negative offset in this case.
+ * 
+ * Return value: the resulting character offset
+ **/
+glong    
+g_utf8_pointer_to_offset (const gchar *str,
+                         const gchar *pos)
+{
+  const gchar *s = str;
+  glong offset = 0;    
+
+  if (pos < str) 
+    offset = - g_utf8_pointer_to_offset (pos, str);
+  else
+    while (s < pos)
+      {
+       s = g_utf8_next_char (s);
+       offset++;
+      }
+  
+  return offset;
+}
+
+
+/**
+ * g_utf8_strncpy:
+ * @dest: buffer to fill with characters from @src
+ * @src: UTF-8 encoded string
+ * @n: character count
+ * 
+ * Like the standard C strncpy() function, but 
+ * copies a given number of characters instead of a given number of 
+ * bytes. The @src string must be valid UTF-8 encoded text. 
+ * (Use g_utf8_validate() on all text before trying to use UTF-8 
+ * utility functions with it.)
+ * 
+ * Return value: @dest
+ **/
+gchar *
+g_utf8_strncpy (gchar       *dest,
+               const gchar *src,
+               gsize        n)
+{
+  const gchar *s = src;
+  while (n && *s)
+    {
+      s = g_utf8_next_char(s);
+      n--;
+    }
+  strncpy(dest, src, s - src);
+  dest[s - src] = 0;
+  return dest;
+}
+
+G_LOCK_DEFINE_STATIC (aliases);
+
+static GHashTable *
+get_alias_hash (void)
+{
+  static GHashTable *alias_hash = NULL;
+  const char *aliases;
+
+  G_LOCK (aliases);
+
+  if (!alias_hash)
+    {
+      alias_hash = g_hash_table_new (g_str_hash, g_str_equal);
+      
+      aliases = _g_locale_get_charset_aliases ();
+      while (*aliases != '\0')
+       {
+         const char *canonical;
+         const char *alias;
+         const char **alias_array;
+         int count = 0;
+         
+         alias = aliases;
+         aliases += strlen (aliases) + 1;
+         canonical = aliases;
+         aliases += strlen (aliases) + 1;
+         
+         alias_array = g_hash_table_lookup (alias_hash, canonical);
+         if (alias_array)
+           {
+             while (alias_array[count])
+               count++;
+           }
+         
+         alias_array = g_renew (const char *, alias_array, count + 2);
+         alias_array[count] = alias;
+         alias_array[count + 1] = NULL;
+         
+         g_hash_table_insert (alias_hash, (char *)canonical, alias_array);
+       }
+    }
+
+  G_UNLOCK (aliases);
+
+  return alias_hash;
+}
+
+/* As an abuse of the alias table, the following routines gets
+ * the charsets that are aliases for the canonical name.
+ */
+G_GNUC_INTERNAL const char ** 
+_g_charset_get_aliases (const char *canonical_name)
+{
+  GHashTable *alias_hash = get_alias_hash ();
+
+  return g_hash_table_lookup (alias_hash, canonical_name);
+}
+
+static gboolean
+g_utf8_get_charset_internal (const char  *raw_data,
+                            const char **a)
+{
+  const char *charset = getenv("CHARSET");
+
+  if (charset && *charset)
+    {
+      *a = charset;
+
+      if (charset && strstr (charset, "UTF-8"))
+       return TRUE;
+      else
+       return FALSE;
+    }
+
+  /* The libcharset code tries to be thread-safe without
+   * a lock, but has a memory leak and a missing memory
+   * barrier, so we lock for it
+   */
+  G_LOCK (aliases);
+  charset = _g_locale_charset_unalias (raw_data);
+  G_UNLOCK (aliases);
+  
+  if (charset && *charset)
+    {
+      *a = charset;
+      
+      if (charset && strstr (charset, "UTF-8"))
+       return TRUE;
+      else
+       return FALSE;
+    }
+
+  /* Assume this for compatibility at present.  */
+  *a = "US-ASCII";
+  
+  return FALSE;
+}
+
+typedef struct _GCharsetCache GCharsetCache;
+
+struct _GCharsetCache {
+  gboolean is_utf8;
+  gchar *raw;
+  gchar *charset;
+};
+
+static void
+charset_cache_free (gpointer data)
+{
+  GCharsetCache *cache = data;
+  g_free (cache->raw);
+  g_free (cache->charset);
+  g_free (cache);
+}
+
+/**
+ * g_get_charset:
+ * @charset: return location for character set name
+ * 
+ * Obtains the character set for the <link linkend="setlocale">current 
+ * locale</link>; you might use this character set as an argument to 
+ * g_convert(), to convert from the current locale's encoding to some 
+ * other encoding. (Frequently g_locale_to_utf8() and g_locale_from_utf8()
+ * are nice shortcuts, though.)
+ *
+ * On Windows the character set returned by this function is the
+ * so-called system default ANSI code-page. That is the character set
+ * used by the "narrow" versions of C library and Win32 functions that
+ * handle file names. It might be different from the character set
+ * used by the C library's current locale.
+ *
+ * The return value is %TRUE if the locale's encoding is UTF-8, in that
+ * case you can perhaps avoid calling g_convert().
+ *
+ * The string returned in @charset is not allocated, and should not be
+ * freed.
+ * 
+ * Return value: %TRUE if the returned charset is UTF-8
+ **/
+gboolean
+g_get_charset (G_CONST_RETURN char **charset) 
+{
+  static GStaticPrivate cache_private = G_STATIC_PRIVATE_INIT;
+  GCharsetCache *cache = g_static_private_get (&cache_private);
+  const gchar *raw;
+
+  if (!cache)
+    {
+      cache = g_new0 (GCharsetCache, 1);
+      g_static_private_set (&cache_private, cache, charset_cache_free);
+    }
+
+  raw = _g_locale_charset_raw ();
+  
+  if (!(cache->raw && strcmp (cache->raw, raw) == 0))
+    {
+      const gchar *new_charset;
+           
+      g_free (cache->raw);
+      g_free (cache->charset);
+      cache->raw = g_strdup (raw);
+      cache->is_utf8 = g_utf8_get_charset_internal (raw, &new_charset);
+      cache->charset = g_strdup (new_charset);
+    }
+
+  if (charset)
+    *charset = cache->charset;
+  
+  return cache->is_utf8;
+}
+
+/* unicode_strchr */
+
+/**
+ * g_unichar_to_utf8:
+ * @c: a Unicode character code
+ * @outbuf: output buffer, must have at least 6 bytes of space.
+ *       If %NULL, the length will be computed and returned
+ *       and nothing will be written to @outbuf.
+ * 
+ * Converts a single character to UTF-8.
+ * 
+ * Return value: number of bytes written
+ **/
+int
+g_unichar_to_utf8 (gunichar c,
+                  gchar   *outbuf)
+{
+  /* If this gets modified, also update the copy in g_string_insert_unichar() */
+  guint len = 0;    
+  int first;
+  int i;
+
+  if (c < 0x80)
+    {
+      first = 0;
+      len = 1;
+    }
+  else if (c < 0x800)
+    {
+      first = 0xc0;
+      len = 2;
+    }
+  else if (c < 0x10000)
+    {
+      first = 0xe0;
+      len = 3;
+    }
+   else if (c < 0x200000)
+    {
+      first = 0xf0;
+      len = 4;
+    }
+  else if (c < 0x4000000)
+    {
+      first = 0xf8;
+      len = 5;
+    }
+  else
+    {
+      first = 0xfc;
+      len = 6;
+    }
+
+  if (outbuf)
+    {
+      for (i = len - 1; i > 0; --i)
+       {
+         outbuf[i] = (c & 0x3f) | 0x80;
+         c >>= 6;
+       }
+      outbuf[0] = c | first;
+    }
+
+  return len;
+}
+
+/**
+ * g_utf8_strchr:
+ * @p: a nul-terminated UTF-8 encoded string
+ * @len: the maximum length of @p
+ * @c: a Unicode character
+ * 
+ * Finds the leftmost occurrence of the given Unicode character
+ * in a UTF-8 encoded string, while limiting the search to @len bytes.
+ * If @len is -1, allow unbounded search.
+ * 
+ * Return value: %NULL if the string does not contain the character, 
+ *   otherwise, a pointer to the start of the leftmost occurrence of 
+ *   the character in the string.
+ **/
+gchar *
+g_utf8_strchr (const char *p,
+              gssize      len,
+              gunichar    c)
+{
+  gchar ch[10];
+
+  gint charlen = g_unichar_to_utf8 (c, ch);
+  ch[charlen] = '\0';
+  
+  return g_strstr_len (p, len, ch);
+}
+
+
+/**
+ * g_utf8_strrchr:
+ * @p: a nul-terminated UTF-8 encoded string
+ * @len: the maximum length of @p
+ * @c: a Unicode character
+ * 
+ * Find the rightmost occurrence of the given Unicode character
+ * in a UTF-8 encoded string, while limiting the search to @len bytes.
+ * If @len is -1, allow unbounded search.
+ * 
+ * Return value: %NULL if the string does not contain the character, 
+ *   otherwise, a pointer to the start of the rightmost occurrence of the 
+ *   character in the string.
+ **/
+gchar *
+g_utf8_strrchr (const char *p,
+               gssize      len,
+               gunichar    c)
+{
+  gchar ch[10];
+
+  gint charlen = g_unichar_to_utf8 (c, ch);
+  ch[charlen] = '\0';
+  
+  return g_strrstr_len (p, len, ch);
+}
+
+
+/* Like g_utf8_get_char, but take a maximum length
+ * and return (gunichar)-2 on incomplete trailing character;
+ * also check for malformed or overlong sequences
+ * and return (gunichar)-1 in this case.
+ */
+static inline gunichar
+g_utf8_get_char_extended (const  gchar *p,
+                         gssize max_len)
+{
+  guint i, len;
+  gunichar min_code;
+  gunichar wc = (guchar) *p;
+
+  if (wc < 0x80)
+    {
+      return wc;
+    }
+  else if (G_UNLIKELY (wc < 0xc0))
+    {
+      return (gunichar)-1;
+    }
+  else if (wc < 0xe0)
+    {
+      len = 2;
+      wc &= 0x1f;
+      min_code = 1 << 7;
+    }
+  else if (wc < 0xf0)
+    {
+      len = 3;
+      wc &= 0x0f;
+      min_code = 1 << 11;
+    }
+  else if (wc < 0xf8)
+    {
+      len = 4;
+      wc &= 0x07;
+      min_code = 1 << 16;
+    }
+  else if (wc < 0xfc)
+    {
+      len = 5;
+      wc &= 0x03;
+      min_code = 1 << 21;
+    }
+  else if (wc < 0xfe)
+    {
+      len = 6;
+      wc &= 0x01;
+      min_code = 1 << 26;
+    }
+  else
+    {
+      return (gunichar)-1;
+    }
+
+  if (G_UNLIKELY (max_len >= 0 && len > max_len))
+    {
+      for (i = 1; i < max_len; i++)
+       {
+         if ((((guchar *)p)[i] & 0xc0) != 0x80)
+           return (gunichar)-1;
+       }
+      return (gunichar)-2;
+    }
+
+  for (i = 1; i < len; ++i)
+    {
+      gunichar ch = ((guchar *)p)[i];
+
+      if (G_UNLIKELY ((ch & 0xc0) != 0x80))
+       {
+         if (ch)
+           return (gunichar)-1;
+         else
+           return (gunichar)-2;
+       }
+
+      wc <<= 6;
+      wc |= (ch & 0x3f);
+    }
+
+  if (G_UNLIKELY (wc < min_code))
+    return (gunichar)-1;
+
+  return wc;
+}
+
+/**
+ * g_utf8_get_char_validated:
+ * @p: a pointer to Unicode character encoded as UTF-8
+ * @max_len: the maximum number of bytes to read, or -1, for no maximum or
+ *           if @p is nul-terminated
+ * 
+ * Convert a sequence of bytes encoded as UTF-8 to a Unicode character.
+ * This function checks for incomplete characters, for invalid characters
+ * such as characters that are out of the range of Unicode, and for
+ * overlong encodings of valid characters.
+ * 
+ * Return value: the resulting character. If @p points to a partial
+ *    sequence at the end of a string that could begin a valid 
+ *    character (or if @max_len is zero), returns (gunichar)-2; 
+ *    otherwise, if @p does not point to a valid UTF-8 encoded 
+ *    Unicode character, returns (gunichar)-1.
+ **/
+gunichar
+g_utf8_get_char_validated (const  gchar *p,
+                          gssize max_len)
+{
+  gunichar result;
+
+  if (max_len == 0)
+    return (gunichar)-2;
+
+  result = g_utf8_get_char_extended (p, max_len);
+
+  if (result & 0x80000000)
+    return result;
+  else if (!UNICODE_VALID (result))
+    return (gunichar)-1;
+  else
+    return result;
+}
+
+/**
+ * g_utf8_to_ucs4_fast:
+ * @str: a UTF-8 encoded string
+ * @len: the maximum length of @str to use, in bytes. If @len < 0,
+ *       then the string is nul-terminated.
+ * @items_written: location to store the number of characters in the
+ *                 result, or %NULL.
+ *
+ * Convert a string from UTF-8 to a 32-bit fixed width
+ * representation as UCS-4, assuming valid UTF-8 input.
+ * This function is roughly twice as fast as g_utf8_to_ucs4()
+ * but does no error checking on the input.
+ * 
+ * Return value: a pointer to a newly allocated UCS-4 string.
+ *               This value must be freed with g_free().
+ **/
+gunichar *
+g_utf8_to_ucs4_fast (const gchar *str,
+                    glong        len,              
+                    glong       *items_written)    
+{
+  gint j, charlen;
+  gunichar *result;
+  gint n_chars, i;
+  const gchar *p;
+
+  g_return_val_if_fail (str != NULL, NULL);
+
+  p = str;
+  n_chars = 0;
+  if (len < 0)
+    {
+      while (*p)
+       {
+         p = g_utf8_next_char (p);
+         ++n_chars;
+       }
+    }
+  else
+    {
+      while (p < str + len && *p)
+       {
+         p = g_utf8_next_char (p);
+         ++n_chars;
+       }
+    }
+  
+  result = g_new (gunichar, n_chars + 1);
+  
+  p = str;
+  for (i=0; i < n_chars; i++)
+    {
+      gunichar wc = ((unsigned char *)p)[0];
+
+      if (wc < 0x80)
+       {
+         result[i] = wc;
+         p++;
+       }
+      else
+       { 
+         if (wc < 0xe0)
+           {
+             charlen = 2;
+             wc &= 0x1f;
+           }
+         else if (wc < 0xf0)
+           {
+             charlen = 3;
+             wc &= 0x0f;
+           }
+         else if (wc < 0xf8)
+           {
+             charlen = 4;
+             wc &= 0x07;
+           }
+         else if (wc < 0xfc)
+           {
+             charlen = 5;
+             wc &= 0x03;
+           }
+         else
+           {
+             charlen = 6;
+             wc &= 0x01;
+           }
+
+         for (j = 1; j < charlen; j++)
+           {
+             wc <<= 6;
+             wc |= ((unsigned char *)p)[j] & 0x3f;
+           }
+
+         result[i] = wc;
+         p += charlen;
+       }
+    }
+  result[i] = 0;
+
+  if (items_written)
+    *items_written = i;
+
+  return result;
+}
+
+/**
+ * g_utf8_to_ucs4:
+ * @str: a UTF-8 encoded string
+ * @len: the maximum length of @str to use, in bytes. If @len < 0,
+ *       then the string is nul-terminated.
+ * @items_read: location to store number of bytes read, or %NULL.
+ *              If %NULL, then %G_CONVERT_ERROR_PARTIAL_INPUT will be
+ *              returned in case @str contains a trailing partial
+ *              character. If an error occurs then the index of the
+ *              invalid input is stored here.
+ * @items_written: location to store number of characters written or %NULL.
+ *                 The value here stored does not include the trailing 0
+ *                 character. 
+ * @error: location to store the error occuring, or %NULL to ignore
+ *         errors. Any of the errors in #GConvertError other than
+ *         %G_CONVERT_ERROR_NO_CONVERSION may occur.
+ *
+ * Convert a string from UTF-8 to a 32-bit fixed width
+ * representation as UCS-4. A trailing 0 will be added to the
+ * string after the converted text.
+ * 
+ * Return value: a pointer to a newly allocated UCS-4 string.
+ *               This value must be freed with g_free(). If an
+ *               error occurs, %NULL will be returned and
+ *               @error set.
+ **/
+gunichar *
+g_utf8_to_ucs4 (const gchar *str,
+               glong        len,             
+               glong       *items_read,      
+               glong       *items_written,   
+               GError     **error)
+{
+  gunichar *result = NULL;
+  gint n_chars, i;
+  const gchar *in;
+  
+  in = str;
+  n_chars = 0;
+  while ((len < 0 || str + len - in > 0) && *in)
+    {
+      gunichar wc = g_utf8_get_char_extended (in, len < 0 ? 6 : str + len - in);
+      if (wc & 0x80000000)
+       {
+         if (wc == (gunichar)-2)
+           {
+             if (items_read)
+               break;
+             else
+               g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
+                                     _("Partial character sequence at end of input"));
+           }
+         else
+           g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                                 _("Invalid byte sequence in conversion input"));
+
+         goto err_out;
+       }
+
+      n_chars++;
+
+      in = g_utf8_next_char (in);
+    }
+
+  result = g_new (gunichar, n_chars + 1);
+  
+  in = str;
+  for (i=0; i < n_chars; i++)
+    {
+      result[i] = g_utf8_get_char (in);
+      in = g_utf8_next_char (in);
+    }
+  result[i] = 0;
+
+  if (items_written)
+    *items_written = n_chars;
+
+ err_out:
+  if (items_read)
+    *items_read = in - str;
+
+  return result;
+}
+
+/**
+ * g_ucs4_to_utf8:
+ * @str: a UCS-4 encoded string
+ * @len: the maximum length (number of characters) of @str to use. 
+ *       If @len < 0, then the string is nul-terminated.
+ * @items_read: location to store number of characters read, or %NULL.
+ * @items_written: location to store number of bytes written or %NULL.
+ *                 The value here stored does not include the trailing 0
+ *                 byte. 
+ * @error: location to store the error occuring, or %NULL to ignore
+ *         errors. Any of the errors in #GConvertError other than
+ *         %G_CONVERT_ERROR_NO_CONVERSION may occur.
+ *
+ * Convert a string from a 32-bit fixed width representation as UCS-4.
+ * to UTF-8. The result will be terminated with a 0 byte.
+ * 
+ * Return value: a pointer to a newly allocated UTF-8 string.
+ *               This value must be freed with g_free(). If an
+ *               error occurs, %NULL will be returned and
+ *               @error set. In that case, @items_read will be
+ *               set to the position of the first invalid input 
+ *               character.
+ **/
+gchar *
+g_ucs4_to_utf8 (const gunichar *str,
+               glong           len,              
+               glong          *items_read,       
+               glong          *items_written,    
+               GError        **error)
+{
+  gint result_length;
+  gchar *result = NULL;
+  gchar *p;
+  gint i;
+
+  result_length = 0;
+  for (i = 0; len < 0 || i < len ; i++)
+    {
+      if (!str[i])
+       break;
+
+      if (str[i] >= 0x80000000)
+       {
+         g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                               _("Character out of range for UTF-8"));
+         goto err_out;
+       }
+      
+      result_length += UTF8_LENGTH (str[i]);
+    }
+
+  result = g_malloc (result_length + 1);
+  p = result;
+
+  i = 0;
+  while (p < result + result_length)
+    p += g_unichar_to_utf8 (str[i++], p);
+  
+  *p = '\0';
+
+  if (items_written)
+    *items_written = p - result;
+
+ err_out:
+  if (items_read)
+    *items_read = i;
+
+  return result;
+}
+
+#define SURROGATE_VALUE(h,l) (((h) - 0xd800) * 0x400 + (l) - 0xdc00 + 0x10000)
+
+/**
+ * g_utf16_to_utf8:
+ * @str: a UTF-16 encoded string
+ * @len: the maximum length (number of <type>gunichar2</type>) of @str to use. 
+ *       If @len < 0, then the string is nul-terminated.
+ * @items_read: location to store number of words read, or %NULL.
+ *              If %NULL, then %G_CONVERT_ERROR_PARTIAL_INPUT will be
+ *              returned in case @str contains a trailing partial
+ *              character. If an error occurs then the index of the
+ *              invalid input is stored here.
+ * @items_written: location to store number of bytes written, or %NULL.
+ *                 The value stored here does not include the trailing
+ *                 0 byte.
+ * @error: location to store the error occuring, or %NULL to ignore
+ *         errors. Any of the errors in #GConvertError other than
+ *         %G_CONVERT_ERROR_NO_CONVERSION may occur.
+ *
+ * Convert a string from UTF-16 to UTF-8. The result will be
+ * terminated with a 0 byte.
+ *
+ * Note that the input is expected to be already in native endianness,
+ * an initial byte-order-mark character is not handled specially.
+ * g_convert() can be used to convert a byte buffer of UTF-16 data of
+ * ambiguous endianess.
+ *
+ * Further note that this function does not validate the result
+ * string; it may e.g. include embedded NUL characters. The only
+ * validation done by this function is to ensure that the input can
+ * be correctly interpreted as UTF-16, i.e. it doesn't contain
+ * things unpaired surrogates.
+ *
+ * Return value: a pointer to a newly allocated UTF-8 string.
+ *               This value must be freed with g_free(). If an
+ *               error occurs, %NULL will be returned and
+ *               @error set.
+ **/
+gchar *
+g_utf16_to_utf8 (const gunichar2  *str,
+                glong             len,
+                glong            *items_read,
+                glong            *items_written,
+                GError          **error)
+{
+  /* This function and g_utf16_to_ucs4 are almost exactly identical - The lines that differ
+   * are marked.
+   */
+  const gunichar2 *in;
+  gchar *out;
+  gchar *result = NULL;
+  gint n_bytes;
+  gunichar high_surrogate;
+
+  g_return_val_if_fail (str != NULL, NULL);
+
+  n_bytes = 0;
+  in = str;
+  high_surrogate = 0;
+  while ((len < 0 || in - str < len) && *in)
+    {
+      gunichar2 c = *in;
+      gunichar wc;
+
+      if (c >= 0xdc00 && c < 0xe000) /* low surrogate */
+       {
+         if (high_surrogate)
+           {
+             wc = SURROGATE_VALUE (high_surrogate, c);
+             high_surrogate = 0;
+           }
+         else
+           {
+             g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                                   _("Invalid sequence in conversion input"));
+             goto err_out;
+           }
+       }
+      else
+       {
+         if (high_surrogate)
+           {
+             g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                                   _("Invalid sequence in conversion input"));
+             goto err_out;
+           }
+
+         if (c >= 0xd800 && c < 0xdc00) /* high surrogate */
+           {
+             high_surrogate = c;
+             goto next1;
+           }
+         else
+           wc = c;
+       }
+
+      /********** DIFFERENT for UTF8/UCS4 **********/
+      n_bytes += UTF8_LENGTH (wc);
+
+    next1:
+      in++;
+    }
+
+  if (high_surrogate && !items_read)
+    {
+      g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
+                           _("Partial character sequence at end of input"));
+      goto err_out;
+    }
+  
+  /* At this point, everything is valid, and we just need to convert
+   */
+  /********** DIFFERENT for UTF8/UCS4 **********/
+  result = g_malloc (n_bytes + 1);
+  
+  high_surrogate = 0;
+  out = result;
+  in = str;
+  while (out < result + n_bytes)
+    {
+      gunichar2 c = *in;
+      gunichar wc;
+
+      if (c >= 0xdc00 && c < 0xe000) /* low surrogate */
+       {
+         wc = SURROGATE_VALUE (high_surrogate, c);
+         high_surrogate = 0;
+       }
+      else if (c >= 0xd800 && c < 0xdc00) /* high surrogate */
+       {
+         high_surrogate = c;
+         goto next2;
+       }
+      else
+       wc = c;
+
+      /********** DIFFERENT for UTF8/UCS4 **********/
+      out += g_unichar_to_utf8 (wc, out);
+
+    next2:
+      in++;
+    }
+  
+  /********** DIFFERENT for UTF8/UCS4 **********/
+  *out = '\0';
+
+  if (items_written)
+    /********** DIFFERENT for UTF8/UCS4 **********/
+    *items_written = out - result;
+
+ err_out:
+  if (items_read)
+    *items_read = in - str;
+
+  return result;
+}
+
+/**
+ * g_utf16_to_ucs4:
+ * @str: a UTF-16 encoded string
+ * @len: the maximum length (number of <type>gunichar2</type>) of @str to use. 
+ *       If @len < 0, then the string is nul-terminated.
+ * @items_read: location to store number of words read, or %NULL.
+ *              If %NULL, then %G_CONVERT_ERROR_PARTIAL_INPUT will be
+ *              returned in case @str contains a trailing partial
+ *              character. If an error occurs then the index of the
+ *              invalid input is stored here.
+ * @items_written: location to store number of characters written, or %NULL.
+ *                 The value stored here does not include the trailing
+ *                 0 character.
+ * @error: location to store the error occuring, or %NULL to ignore
+ *         errors. Any of the errors in #GConvertError other than
+ *         %G_CONVERT_ERROR_NO_CONVERSION may occur.
+ *
+ * Convert a string from UTF-16 to UCS-4. The result will be
+ * nul-terminated.
+ * 
+ * Return value: a pointer to a newly allocated UCS-4 string.
+ *               This value must be freed with g_free(). If an
+ *               error occurs, %NULL will be returned and
+ *               @error set.
+ **/
+gunichar *
+g_utf16_to_ucs4 (const gunichar2  *str,
+                glong             len,              
+                glong            *items_read,       
+                glong            *items_written,    
+                GError          **error)
+{
+  const gunichar2 *in;
+  gchar *out;
+  gchar *result = NULL;
+  gint n_bytes;
+  gunichar high_surrogate;
+
+  g_return_val_if_fail (str != NULL, NULL);
+
+  n_bytes = 0;
+  in = str;
+  high_surrogate = 0;
+  while ((len < 0 || in - str < len) && *in)
+    {
+      gunichar2 c = *in;
+      gunichar wc;
+
+      if (c >= 0xdc00 && c < 0xe000) /* low surrogate */
+       {
+         if (high_surrogate)
+           {
+             wc = SURROGATE_VALUE (high_surrogate, c);
+             high_surrogate = 0;
+           }
+         else
+           {
+             g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                                   _("Invalid sequence in conversion input"));
+             goto err_out;
+           }
+       }
+      else
+       {
+         if (high_surrogate)
+           {
+             g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                                   _("Invalid sequence in conversion input"));
+             goto err_out;
+           }
+
+         if (c >= 0xd800 && c < 0xdc00) /* high surrogate */
+           {
+             high_surrogate = c;
+             goto next1;
+           }
+         else
+           wc = c;
+       }
+
+      /********** DIFFERENT for UTF8/UCS4 **********/
+      n_bytes += sizeof (gunichar);
+
+    next1:
+      in++;
+    }
+
+  if (high_surrogate && !items_read)
+    {
+      g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
+                           _("Partial character sequence at end of input"));
+      goto err_out;
+    }
+  
+  /* At this point, everything is valid, and we just need to convert
+   */
+  /********** DIFFERENT for UTF8/UCS4 **********/
+  result = g_malloc (n_bytes + 4);
+  
+  high_surrogate = 0;
+  out = result;
+  in = str;
+  while (out < result + n_bytes)
+    {
+      gunichar2 c = *in;
+      gunichar wc;
+
+      if (c >= 0xdc00 && c < 0xe000) /* low surrogate */
+       {
+         wc = SURROGATE_VALUE (high_surrogate, c);
+         high_surrogate = 0;
+       }
+      else if (c >= 0xd800 && c < 0xdc00) /* high surrogate */
+       {
+         high_surrogate = c;
+         goto next2;
+       }
+      else
+       wc = c;
+
+      /********** DIFFERENT for UTF8/UCS4 **********/
+      *(gunichar *)out = wc;
+      out += sizeof (gunichar);
+
+    next2:
+      in++;
+    }
+
+  /********** DIFFERENT for UTF8/UCS4 **********/
+  *(gunichar *)out = 0;
+
+  if (items_written)
+    /********** DIFFERENT for UTF8/UCS4 **********/
+    *items_written = (out - result) / sizeof (gunichar);
+
+ err_out:
+  if (items_read)
+    *items_read = in - str;
+
+  return (gunichar *)result;
+}
+
+/**
+ * g_utf8_to_utf16:
+ * @str: a UTF-8 encoded string
+ * @len: the maximum length (number of bytes) of @str to use.
+ *       If @len < 0, then the string is nul-terminated.
+ * @items_read: location to store number of bytes read, or %NULL.
+ *              If %NULL, then %G_CONVERT_ERROR_PARTIAL_INPUT will be
+ *              returned in case @str contains a trailing partial
+ *              character. If an error occurs then the index of the
+ *              invalid input is stored here.
+ * @items_written: location to store number of <type>gunichar2</type> written,
+ *                 or %NULL.
+ *                 The value stored here does not include the trailing 0.
+ * @error: location to store the error occuring, or %NULL to ignore
+ *         errors. Any of the errors in #GConvertError other than
+ *         %G_CONVERT_ERROR_NO_CONVERSION may occur.
+ *
+ * Convert a string from UTF-8 to UTF-16. A 0 character will be
+ * added to the result after the converted text.
+ *
+ * Return value: a pointer to a newly allocated UTF-16 string.
+ *               This value must be freed with g_free(). If an
+ *               error occurs, %NULL will be returned and
+ *               @error set.
+ **/
+gunichar2 *
+g_utf8_to_utf16 (const gchar *str,
+                glong        len,
+                glong       *items_read,
+                glong       *items_written,
+                GError     **error)
+{
+  gunichar2 *result = NULL;
+  gint n16;
+  const gchar *in;
+  gint i;
+
+  g_return_val_if_fail (str != NULL, NULL);
+
+  in = str;
+  n16 = 0;
+  while ((len < 0 || str + len - in > 0) && *in)
+    {
+      gunichar wc = g_utf8_get_char_extended (in, len < 0 ? 6 : str + len - in);
+      if (wc & 0x80000000)
+       {
+         if (wc == (gunichar)-2)
+           {
+             if (items_read)
+               break;
+             else
+               g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_PARTIAL_INPUT,
+                                     _("Partial character sequence at end of input"));
+           }
+         else
+           g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                                 _("Invalid byte sequence in conversion input"));
+
+         goto err_out;
+       }
+
+      if (wc < 0xd800)
+       n16 += 1;
+      else if (wc < 0xe000)
+       {
+         g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                               _("Invalid sequence in conversion input"));
+
+         goto err_out;
+       }
+      else if (wc < 0x10000)
+       n16 += 1;
+      else if (wc < 0x110000)
+       n16 += 2;
+      else
+       {
+         g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                               _("Character out of range for UTF-16"));
+
+         goto err_out;
+       }
+      
+      in = g_utf8_next_char (in);
+    }
+
+  result = g_new (gunichar2, n16 + 1);
+  
+  in = str;
+  for (i = 0; i < n16;)
+    {
+      gunichar wc = g_utf8_get_char (in);
+
+      if (wc < 0x10000)
+       {
+         result[i++] = wc;
+       }
+      else
+       {
+         result[i++] = (wc - 0x10000) / 0x400 + 0xd800;
+         result[i++] = (wc - 0x10000) % 0x400 + 0xdc00;
+       }
+      
+      in = g_utf8_next_char (in);
+    }
+
+  result[i] = 0;
+
+  if (items_written)
+    *items_written = n16;
+
+ err_out:
+  if (items_read)
+    *items_read = in - str;
+  
+  return result;
+}
+
+/**
+ * g_ucs4_to_utf16:
+ * @str: a UCS-4 encoded string
+ * @len: the maximum length (number of characters) of @str to use. 
+ *       If @len < 0, then the string is nul-terminated.
+ * @items_read: location to store number of bytes read, or %NULL.
+ *              If an error occurs then the index of the invalid input
+ *              is stored here.
+ * @items_written: location to store number of <type>gunichar2</type> 
+ *                 written, or %NULL. The value stored here does not 
+ *                 include the trailing 0.
+ * @error: location to store the error occuring, or %NULL to ignore
+ *         errors. Any of the errors in #GConvertError other than
+ *         %G_CONVERT_ERROR_NO_CONVERSION may occur.
+ *
+ * Convert a string from UCS-4 to UTF-16. A 0 character will be
+ * added to the result after the converted text.
+ * 
+ * Return value: a pointer to a newly allocated UTF-16 string.
+ *               This value must be freed with g_free(). If an
+ *               error occurs, %NULL will be returned and
+ *               @error set.
+ **/
+gunichar2 *
+g_ucs4_to_utf16 (const gunichar  *str,
+                glong            len,              
+                glong           *items_read,       
+                glong           *items_written,    
+                GError         **error)
+{
+  gunichar2 *result = NULL;
+  gint n16;
+  gint i, j;
+
+  n16 = 0;
+  i = 0;
+  while ((len < 0 || i < len) && str[i])
+    {
+      gunichar wc = str[i];
+
+      if (wc < 0xd800)
+       n16 += 1;
+      else if (wc < 0xe000)
+       {
+         g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                               _("Invalid sequence in conversion input"));
+
+         goto err_out;
+       }
+      else if (wc < 0x10000)
+       n16 += 1;
+      else if (wc < 0x110000)
+       n16 += 2;
+      else
+       {
+         g_set_error_literal (error, G_CONVERT_ERROR, G_CONVERT_ERROR_ILLEGAL_SEQUENCE,
+                               _("Character out of range for UTF-16"));
+
+         goto err_out;
+       }
+
+      i++;
+    }
+  
+  result = g_new (gunichar2, n16 + 1);
+  
+  for (i = 0, j = 0; j < n16; i++)
+    {
+      gunichar wc = str[i];
+
+      if (wc < 0x10000)
+       {
+         result[j++] = wc;
+       }
+      else
+       {
+         result[j++] = (wc - 0x10000) / 0x400 + 0xd800;
+         result[j++] = (wc - 0x10000) % 0x400 + 0xdc00;
+       }
+    }
+  result[j] = 0;
+
+  if (items_written)
+    *items_written = n16;
+  
+ err_out:
+  if (items_read)
+    *items_read = i;
+  
+  return result;
+}
+
+#define CONTINUATION_CHAR                           \
+ G_STMT_START {                                     \
+  if ((*(guchar *)p & 0xc0) != 0x80) /* 10xxxxxx */ \
+    goto error;                                     \
+  val <<= 6;                                        \
+  val |= (*(guchar *)p) & 0x3f;                     \
+ } G_STMT_END
+
+static const gchar *
+fast_validate (const char *str)
+
+{
+  gunichar val = 0;
+  gunichar min = 0;
+  const gchar *p;
+
+  for (p = str; *p; p++)
+    {
+      if (*(guchar *)p < 128)
+       /* done */;
+      else 
+       {
+         const gchar *last;
+         
+         last = p;
+         if ((*(guchar *)p & 0xe0) == 0xc0) /* 110xxxxx */
+           {
+             if (G_UNLIKELY ((*(guchar *)p & 0x1e) == 0))
+               goto error;
+             p++;
+             if (G_UNLIKELY ((*(guchar *)p & 0xc0) != 0x80)) /* 10xxxxxx */
+               goto error;
+           }
+         else
+           {
+             if ((*(guchar *)p & 0xf0) == 0xe0) /* 1110xxxx */
+               {
+                 min = (1 << 11);
+                 val = *(guchar *)p & 0x0f;
+                 goto TWO_REMAINING;
+               }
+             else if ((*(guchar *)p & 0xf8) == 0xf0) /* 11110xxx */
+               {
+                 min = (1 << 16);
+                 val = *(guchar *)p & 0x07;
+               }
+             else
+               goto error;
+             
+             p++;
+             CONTINUATION_CHAR;
+           TWO_REMAINING:
+             p++;
+             CONTINUATION_CHAR;
+             p++;
+             CONTINUATION_CHAR;
+             
+             if (G_UNLIKELY (val < min))
+               goto error;
+
+             if (G_UNLIKELY (!UNICODE_VALID(val)))
+               goto error;
+           } 
+         
+         continue;
+         
+       error:
+         return last;
+       }
+    }
+
+  return p;
+}
+
+static const gchar *
+fast_validate_len (const char *str,
+                  gssize      max_len)
+
+{
+  gunichar val = 0;
+  gunichar min = 0;
+  const gchar *p;
+
+  g_assert (max_len >= 0);
+
+  for (p = str; ((p - str) < max_len) && *p; p++)
+    {
+      if (*(guchar *)p < 128)
+       /* done */;
+      else 
+       {
+         const gchar *last;
+         
+         last = p;
+         if ((*(guchar *)p & 0xe0) == 0xc0) /* 110xxxxx */
+           {
+             if (G_UNLIKELY (max_len - (p - str) < 2))
+               goto error;
+             
+             if (G_UNLIKELY ((*(guchar *)p & 0x1e) == 0))
+               goto error;
+             p++;
+             if (G_UNLIKELY ((*(guchar *)p & 0xc0) != 0x80)) /* 10xxxxxx */
+               goto error;
+           }
+         else
+           {
+             if ((*(guchar *)p & 0xf0) == 0xe0) /* 1110xxxx */
+               {
+                 if (G_UNLIKELY (max_len - (p - str) < 3))
+                   goto error;
+                 
+                 min = (1 << 11);
+                 val = *(guchar *)p & 0x0f;
+                 goto TWO_REMAINING;
+               }
+             else if ((*(guchar *)p & 0xf8) == 0xf0) /* 11110xxx */
+               {
+                 if (G_UNLIKELY (max_len - (p - str) < 4))
+                   goto error;
+                 
+                 min = (1 << 16);
+                 val = *(guchar *)p & 0x07;
+               }
+             else
+               goto error;
+             
+             p++;
+             CONTINUATION_CHAR;
+           TWO_REMAINING:
+             p++;
+             CONTINUATION_CHAR;
+             p++;
+             CONTINUATION_CHAR;
+             
+             if (G_UNLIKELY (val < min))
+               goto error;
+             if (G_UNLIKELY (!UNICODE_VALID(val)))
+               goto error;
+           } 
+         
+         continue;
+         
+       error:
+         return last;
+       }
+    }
+
+  return p;
+}
+
+/**
+ * g_utf8_validate:
+ * @str: a pointer to character data
+ * @max_len: max bytes to validate, or -1 to go until NUL
+ * @end: return location for end of valid data
+ * 
+ * Validates UTF-8 encoded text. @str is the text to validate;
+ * if @str is nul-terminated, then @max_len can be -1, otherwise
+ * @max_len should be the number of bytes to validate.
+ * If @end is non-%NULL, then the end of the valid range
+ * will be stored there (i.e. the start of the first invalid 
+ * character if some bytes were invalid, or the end of the text 
+ * being validated otherwise).
+ *
+ * Note that g_utf8_validate() returns %FALSE if @max_len is 
+ * positive and NUL is met before @max_len bytes have been read.
+ *
+ * Returns %TRUE if all of @str was valid. Many GLib and GTK+
+ * routines <emphasis>require</emphasis> valid UTF-8 as input;
+ * so data read from a file or the network should be checked
+ * with g_utf8_validate() before doing anything else with it.
+ * 
+ * Return value: %TRUE if the text was valid UTF-8
+ **/
+gboolean
+g_utf8_validate (const char   *str,
+                gssize        max_len,    
+                const gchar **end)
+
+{
+  const gchar *p;
+
+  if (max_len < 0)
+    p = fast_validate (str);
+  else
+    p = fast_validate_len (str, max_len);
+
+  if (end)
+    *end = p;
+
+  if ((max_len >= 0 && p != str + max_len) ||
+      (max_len < 0 && *p != '\0'))
+    return FALSE;
+  else
+    return TRUE;
+}
+
+/**
+ * g_unichar_validate:
+ * @ch: a Unicode character
+ * 
+ * Checks whether @ch is a valid Unicode character. Some possible
+ * integer values of @ch will not be valid. 0 is considered a valid
+ * character, though it's normally a string terminator.
+ * 
+ * Return value: %TRUE if @ch is a valid Unicode character
+ **/
+gboolean
+g_unichar_validate (gunichar ch)
+{
+  return UNICODE_VALID (ch);
+}
+
+/**
+ * g_utf8_strreverse:
+ * @str: a UTF-8 encoded string
+ * @len: the maximum length of @str to use, in bytes. If @len < 0,
+ *       then the string is nul-terminated.
+ *
+ * Reverses a UTF-8 string. @str must be valid UTF-8 encoded text. 
+ * (Use g_utf8_validate() on all text before trying to use UTF-8 
+ * utility functions with it.)
+ *
+ * This function is intended for programmatic uses of reversed strings.
+ * It pays no attention to decomposed characters, combining marks, byte 
+ * order marks, directional indicators (LRM, LRO, etc) and similar 
+ * characters which might need special handling when reversing a string 
+ * for display purposes.
+ *
+ * Note that unlike g_strreverse(), this function returns
+ * newly-allocated memory, which should be freed with g_free() when
+ * no longer needed. 
+ *
+ * Returns: a newly-allocated string which is the reverse of @str.
+ *
+ * Since: 2.2
+ */
+gchar *
+g_utf8_strreverse (const gchar *str,
+                  gssize       len)
+{
+  gchar *r, *result;
+  const gchar *p;
+
+  if (len < 0)
+    len = strlen (str);
+
+  result = g_new (gchar, len + 1);
+  r = result + len;
+  p = str;
+  while (r > result)
+    {
+      gchar *m, skip = g_utf8_skip[*(guchar*) p];
+      r -= skip;
+      for (m = r; skip; skip--)
+        *m++ = *p++;
+    }
+  result[len] = 0;
+
+  return result;
+}
+
+
+gchar *
+_g_utf8_make_valid (const gchar *name)
+{
+  GString *string;
+  const gchar *remainder, *invalid;
+  gint remaining_bytes, valid_bytes;
+
+  g_return_val_if_fail (name != NULL, NULL);
+
+  string = NULL;
+  remainder = name;
+  remaining_bytes = strlen (name);
+
+  while (remaining_bytes != 0) 
+    {
+      if (g_utf8_validate (remainder, remaining_bytes, &invalid)) 
+       break;
+      valid_bytes = invalid - remainder;
+    
+      if (string == NULL) 
+       string = g_string_sized_new (remaining_bytes);
+
+      g_string_append_len (string, remainder, valid_bytes);
+      /* append U+FFFD REPLACEMENT CHARACTER */
+      g_string_append (string, "\357\277\275");
+      
+      remaining_bytes -= valid_bytes + 1;
+      remainder = invalid + 1;
+    }
+  
+  if (string == NULL)
+    return g_strdup (name);
+  
+  g_string_append (string, remainder);
+
+  g_assert (g_utf8_validate (string->str, -1, NULL));
+  
+  return g_string_free (string, FALSE);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gutils.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gutils.c
new file mode 100644 (file)
index 0000000..b3d9ba6
--- /dev/null
@@ -0,0 +1,3621 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1998  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/* 
+ * MT safe for the unix part, FIXME: make the win32 part MT safe as well.
+ */
+
+#include "config.h"
+
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <stdarg.h>
+#include <stdlib.h>
+#include <stdio.h>
+#include <locale.h>
+#include <string.h>
+#include <ctype.h>             /* For tolower() */
+#include <errno.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#ifdef HAVE_PWD_H
+#include <pwd.h>
+#endif
+#include <sys/types.h>
+#ifdef HAVE_SYS_PARAM_H
+#include <sys/param.h>
+#endif
+#ifdef HAVE_CRT_EXTERNS_H 
+#include <crt_externs.h> /* for _NSGetEnviron */
+#endif
+
+/* implement gutils's inline functions
+ */
+#define        G_IMPLEMENT_INLINES 1
+#define        __G_UTILS_C__
+#include "gutils.h"
+
+#include "gfileutils.h"
+#include "ghash.h"
+#include "gslist.h"
+#include "gprintfint.h"
+#include "gthread.h"
+#include "gthreadprivate.h"
+#include "gtestutils.h"
+#include "gunicode.h"
+#include "gstrfuncs.h"
+#include "glibintl.h"
+
+#ifdef G_PLATFORM_WIN32
+#include "garray.h"
+#include "gconvert.h"
+#include "gwin32.h"
+#endif
+
+#ifdef MAXPATHLEN
+#define        G_PATH_LENGTH   MAXPATHLEN
+#elif  defined (PATH_MAX)
+#define        G_PATH_LENGTH   PATH_MAX
+#elif   defined (_PC_PATH_MAX)
+#define        G_PATH_LENGTH   sysconf(_PC_PATH_MAX)
+#else  
+#define G_PATH_LENGTH   2048
+#endif
+
+#ifdef G_PLATFORM_WIN32
+#  define STRICT               /* Strict typing, please */
+#  include <windows.h>
+#  undef STRICT
+#  ifndef GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
+#    define GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT 2
+#    define GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS 4
+#  endif
+#  include <lmcons.h>          /* For UNLEN */
+#endif /* G_PLATFORM_WIN32 */
+
+#ifdef G_OS_WIN32
+#  include <direct.h>
+#  include <shlobj.h>
+   /* older SDK (e.g. msvc 5.0) does not have these*/
+#  ifndef CSIDL_MYMUSIC
+#    define CSIDL_MYMUSIC 13
+#  endif
+#  ifndef CSIDL_MYVIDEO
+#    define CSIDL_MYVIDEO 14
+#  endif
+#  ifndef CSIDL_INTERNET_CACHE
+#    define CSIDL_INTERNET_CACHE 32
+#  endif
+#  ifndef CSIDL_COMMON_APPDATA
+#    define CSIDL_COMMON_APPDATA 35
+#  endif
+#  ifndef CSIDL_MYPICTURES
+#    define CSIDL_MYPICTURES 0x27
+#  endif
+#  ifndef CSIDL_COMMON_DOCUMENTS
+#    define CSIDL_COMMON_DOCUMENTS 46
+#  endif
+#  ifndef CSIDL_PROFILE
+#    define CSIDL_PROFILE 40
+#  endif
+#  include <process.h>
+#endif
+
+#ifdef HAVE_CARBON
+#include <CoreServices/CoreServices.h>
+#endif
+
+#ifdef HAVE_CODESET
+#include <langinfo.h>
+#endif
+
+const guint glib_major_version = GLIB_MAJOR_VERSION;
+const guint glib_minor_version = GLIB_MINOR_VERSION;
+const guint glib_micro_version = GLIB_MICRO_VERSION;
+const guint glib_interface_age = GLIB_INTERFACE_AGE;
+const guint glib_binary_age = GLIB_BINARY_AGE;
+
+#ifdef G_PLATFORM_WIN32
+
+static HMODULE glib_dll = NULL;
+
+#ifdef DLL_EXPORT
+
+BOOL WINAPI
+DllMain (HINSTANCE hinstDLL,
+        DWORD     fdwReason,
+        LPVOID    lpvReserved)
+{
+  if (fdwReason == DLL_PROCESS_ATTACH)
+      glib_dll = hinstDLL;
+
+  return TRUE;
+}
+
+#endif
+
+gchar *
+_glib_get_dll_directory (void)
+{
+  gchar *retval;
+  gchar *p;
+  wchar_t wc_fn[MAX_PATH];
+
+#ifdef DLL_EXPORT
+  if (glib_dll == NULL)
+    return NULL;
+#endif
+
+  /* This code is different from that in
+   * g_win32_get_package_installation_directory_of_module() in that
+   * here we return the actual folder where the GLib DLL is. We don't
+   * do the check for it being in a "bin" or "lib" subfolder and then
+   * returning the parent of that.
+   *
+   * In a statically built GLib, glib_dll will be NULL and we will
+   * thus look up the application's .exe file's location.
+   */
+  if (!GetModuleFileNameW (glib_dll, wc_fn, MAX_PATH))
+    return NULL;
+
+  retval = g_utf16_to_utf8 (wc_fn, -1, NULL, NULL, NULL);
+
+  p = strrchr (retval, G_DIR_SEPARATOR);
+  if (p == NULL)
+    {
+      /* Wtf? */
+      return NULL;
+    }
+  *p = '\0';
+
+  return retval;
+}
+
+#endif
+
+/**
+ * glib_check_version:
+ * @required_major: the required major version.
+ * @required_minor: the required minor version.
+ * @required_micro: the required micro version.
+ *
+ * Checks that the GLib library in use is compatible with the
+ * given version. Generally you would pass in the constants
+ * #GLIB_MAJOR_VERSION, #GLIB_MINOR_VERSION, #GLIB_MICRO_VERSION
+ * as the three arguments to this function; that produces
+ * a check that the library in use is compatible with
+ * the version of GLib the application or module was compiled
+ * against.
+ *
+ * Compatibility is defined by two things: first the version
+ * of the running library is newer than the version
+ * @required_major.required_minor.@required_micro. Second
+ * the running library must be binary compatible with the
+ * version @required_major.required_minor.@required_micro
+ * (same major version.)
+ *
+ * Return value: %NULL if the GLib library is compatible with the
+ *   given version, or a string describing the version mismatch.
+ *   The returned string is owned by GLib and must not be modified
+ *   or freed.
+ *
+ * Since: 2.6
+ **/
+const gchar *
+glib_check_version (guint required_major,
+                    guint required_minor,
+                    guint required_micro)
+{
+  gint glib_effective_micro = 100 * GLIB_MINOR_VERSION + GLIB_MICRO_VERSION;
+  gint required_effective_micro = 100 * required_minor + required_micro;
+
+  if (required_major > GLIB_MAJOR_VERSION)
+    return "GLib version too old (major mismatch)";
+  if (required_major < GLIB_MAJOR_VERSION)
+    return "GLib version too new (major mismatch)";
+  if (required_effective_micro < glib_effective_micro - GLIB_BINARY_AGE)
+    return "GLib version too new (micro mismatch)";
+  if (required_effective_micro > glib_effective_micro)
+    return "GLib version too old (micro mismatch)";
+  return NULL;
+}
+
+#if !defined (HAVE_MEMMOVE) && !defined (HAVE_WORKING_BCOPY)
+/**
+ * g_memmove: 
+ * @dest: the destination address to copy the bytes to.
+ * @src: the source address to copy the bytes from.
+ * @len: the number of bytes to copy.
+ *
+ * Copies a block of memory @len bytes long, from @src to @dest.
+ * The source and destination areas may overlap.
+ *
+ * In order to use this function, you must include 
+ * <filename>string.h</filename> yourself, because this macro will 
+ * typically simply resolve to memmove() and GLib does not include 
+ * <filename>string.h</filename> for you.
+ */
+void 
+g_memmove (gpointer      dest, 
+          gconstpointer src, 
+          gulong        len)
+{
+  gchar* destptr = dest;
+  const gchar* srcptr = src;
+  if (src + len < dest || dest + len < src)
+    {
+      bcopy (src, dest, len);
+      return;
+    }
+  else if (dest <= src)
+    {
+      while (len--)
+       *(destptr++) = *(srcptr++);
+    }
+  else
+    {
+      destptr += len;
+      srcptr += len;
+      while (len--)
+       *(--destptr) = *(--srcptr);
+    }
+}
+#endif /* !HAVE_MEMMOVE && !HAVE_WORKING_BCOPY */
+
+#ifdef G_OS_WIN32
+#undef g_atexit
+#endif
+
+/**
+ * g_atexit:
+ * @func: the function to call on normal program termination.
+ * 
+ * Specifies a function to be called at normal program termination.
+ *
+ * Since GLib 2.8.2, on Windows g_atexit() actually is a preprocessor
+ * macro that maps to a call to the atexit() function in the C
+ * library. This means that in case the code that calls g_atexit(),
+ * i.e. atexit(), is in a DLL, the function will be called when the
+ * DLL is detached from the program. This typically makes more sense
+ * than that the function is called when the GLib DLL is detached,
+ * which happened earlier when g_atexit() was a function in the GLib
+ * DLL.
+ *
+ * The behaviour of atexit() in the context of dynamically loaded
+ * modules is not formally specified and varies wildly.
+ *
+ * On POSIX systems, calling g_atexit() (or atexit()) in a dynamically
+ * loaded module which is unloaded before the program terminates might
+ * well cause a crash at program exit.
+ *
+ * Some POSIX systems implement atexit() like Windows, and have each
+ * dynamically loaded module maintain an own atexit chain that is
+ * called when the module is unloaded.
+ *
+ * On other POSIX systems, before a dynamically loaded module is
+ * unloaded, the registered atexit functions (if any) residing in that
+ * module are called, regardless where the code that registered them
+ * resided. This is presumably the most robust approach.
+ *
+ * As can be seen from the above, for portability it's best to avoid
+ * calling g_atexit() (or atexit()) except in the main executable of a
+ * program.
+ */
+void
+g_atexit (GVoidFunc func)
+{
+  gint result;
+  const gchar *error = NULL;
+
+  /* keep this in sync with glib.h */
+
+#ifdef G_NATIVE_ATEXIT
+  result = ATEXIT (func);
+  if (result)
+    error = g_strerror (errno);
+#elif defined (HAVE_ATEXIT)
+#  ifdef NeXT /* @#%@! NeXTStep */
+  result = !atexit ((void (*)(void)) func);
+  if (result)
+    error = g_strerror (errno);
+#  else
+  result = atexit ((void (*)(void)) func);
+  if (result)
+    error = g_strerror (errno);
+#  endif /* NeXT */
+#elif defined (HAVE_ON_EXIT)
+  result = on_exit ((void (*)(int, void *)) func, NULL);
+  if (result)
+    error = g_strerror (errno);
+#else
+  result = 0;
+  error = "no implementation";
+#endif /* G_NATIVE_ATEXIT */
+
+  if (error)
+    g_error ("Could not register atexit() function: %s", error);
+}
+
+/* Based on execvp() from GNU Libc.
+ * Some of this code is cut-and-pasted into gspawn.c
+ */
+
+static gchar*
+my_strchrnul (const gchar *str, 
+             gchar        c)
+{
+  gchar *p = (gchar*)str;
+  while (*p && (*p != c))
+    ++p;
+
+  return p;
+}
+
+#ifdef G_OS_WIN32
+
+static gchar *inner_find_program_in_path (const gchar *program);
+
+gchar*
+g_find_program_in_path (const gchar *program)
+{
+  const gchar *last_dot = strrchr (program, '.');
+
+  if (last_dot == NULL ||
+      strchr (last_dot, '\\') != NULL ||
+      strchr (last_dot, '/') != NULL)
+    {
+      const gint program_length = strlen (program);
+      gchar *pathext = g_build_path (";",
+                                    ".exe;.cmd;.bat;.com",
+                                    g_getenv ("PATHEXT"),
+                                    NULL);
+      gchar *p;
+      gchar *decorated_program;
+      gchar *retval;
+
+      p = pathext;
+      do
+       {
+         gchar *q = my_strchrnul (p, ';');
+
+         decorated_program = g_malloc (program_length + (q-p) + 1);
+         memcpy (decorated_program, program, program_length);
+         memcpy (decorated_program+program_length, p, q-p);
+         decorated_program [program_length + (q-p)] = '\0';
+         
+         retval = inner_find_program_in_path (decorated_program);
+         g_free (decorated_program);
+
+         if (retval != NULL)
+           {
+             g_free (pathext);
+             return retval;
+           }
+         p = q;
+       } while (*p++ != '\0');
+      g_free (pathext);
+      return NULL;
+    }
+  else
+    return inner_find_program_in_path (program);
+}
+
+#endif
+
+/**
+ * g_find_program_in_path:
+ * @program: a program name in the GLib file name encoding
+ * 
+ * Locates the first executable named @program in the user's path, in the
+ * same way that execvp() would locate it. Returns an allocated string
+ * with the absolute path name, or %NULL if the program is not found in
+ * the path. If @program is already an absolute path, returns a copy of
+ * @program if @program exists and is executable, and %NULL otherwise.
+ *  
+ * On Windows, if @program does not have a file type suffix, tries
+ * with the suffixes .exe, .cmd, .bat and .com, and the suffixes in
+ * the <envar>PATHEXT</envar> environment variable. 
+ * 
+ * On Windows, it looks for the file in the same way as CreateProcess() 
+ * would. This means first in the directory where the executing
+ * program was loaded from, then in the current directory, then in the
+ * Windows 32-bit system directory, then in the Windows directory, and
+ * finally in the directories in the <envar>PATH</envar> environment 
+ * variable. If the program is found, the return value contains the 
+ * full name including the type suffix.
+ *
+ * Return value: absolute path, or %NULL
+ **/
+#ifdef G_OS_WIN32
+static gchar *
+inner_find_program_in_path (const gchar *program)
+#else
+gchar*
+g_find_program_in_path (const gchar *program)
+#endif
+{
+  const gchar *path, *p;
+  gchar *name, *freeme;
+#ifdef G_OS_WIN32
+  const gchar *path_copy;
+  gchar *filename = NULL, *appdir = NULL;
+  gchar *sysdir = NULL, *windir = NULL;
+  int n;
+  wchar_t wfilename[MAXPATHLEN], wsysdir[MAXPATHLEN],
+    wwindir[MAXPATHLEN];
+#endif
+  gsize len;
+  gsize pathlen;
+
+  g_return_val_if_fail (program != NULL, NULL);
+
+  /* If it is an absolute path, or a relative path including subdirectories,
+   * don't look in PATH.
+   */
+  if (g_path_is_absolute (program)
+      || strchr (program, G_DIR_SEPARATOR) != NULL
+#ifdef G_OS_WIN32
+      || strchr (program, '/') != NULL
+#endif
+      )
+    {
+      if (g_file_test (program, G_FILE_TEST_IS_EXECUTABLE) &&
+         !g_file_test (program, G_FILE_TEST_IS_DIR))
+        return g_strdup (program);
+      else
+        return NULL;
+    }
+  
+  path = g_getenv ("PATH");
+#if defined(G_OS_UNIX) || defined(G_OS_BEOS)
+  if (path == NULL)
+    {
+      /* There is no `PATH' in the environment.  The default
+       * search path in GNU libc is the current directory followed by
+       * the path `confstr' returns for `_CS_PATH'.
+       */
+      
+      /* In GLib we put . last, for security, and don't use the
+       * unportable confstr(); UNIX98 does not actually specify
+       * what to search if PATH is unset. POSIX may, dunno.
+       */
+      
+      path = "/bin:/usr/bin:.";
+    }
+#else
+  n = GetModuleFileNameW (NULL, wfilename, MAXPATHLEN);
+  if (n > 0 && n < MAXPATHLEN)
+    filename = g_utf16_to_utf8 (wfilename, -1, NULL, NULL, NULL);
+  
+  n = GetSystemDirectoryW (wsysdir, MAXPATHLEN);
+  if (n > 0 && n < MAXPATHLEN)
+    sysdir = g_utf16_to_utf8 (wsysdir, -1, NULL, NULL, NULL);
+  
+  n = GetWindowsDirectoryW (wwindir, MAXPATHLEN);
+  if (n > 0 && n < MAXPATHLEN)
+    windir = g_utf16_to_utf8 (wwindir, -1, NULL, NULL, NULL);
+  
+  if (filename)
+    {
+      appdir = g_path_get_dirname (filename);
+      g_free (filename);
+    }
+  
+  path = g_strdup (path);
+
+  if (windir)
+    {
+      const gchar *tem = path;
+      path = g_strconcat (windir, ";", path, NULL);
+      g_free ((gchar *) tem);
+      g_free (windir);
+    }
+  
+  if (sysdir)
+    {
+      const gchar *tem = path;
+      path = g_strconcat (sysdir, ";", path, NULL);
+      g_free ((gchar *) tem);
+      g_free (sysdir);
+    }
+  
+  {
+    const gchar *tem = path;
+    path = g_strconcat (".;", path, NULL);
+    g_free ((gchar *) tem);
+  }
+  
+  if (appdir)
+    {
+      const gchar *tem = path;
+      path = g_strconcat (appdir, ";", path, NULL);
+      g_free ((gchar *) tem);
+      g_free (appdir);
+    }
+
+  path_copy = path;
+#endif
+  
+  len = strlen (program) + 1;
+  pathlen = strlen (path);
+  freeme = name = g_malloc (pathlen + len + 1);
+  
+  /* Copy the file name at the top, including '\0'  */
+  memcpy (name + pathlen + 1, program, len);
+  name = name + pathlen;
+  /* And add the slash before the filename  */
+  *name = G_DIR_SEPARATOR;
+  
+  p = path;
+  do
+    {
+      char *startp;
+
+      path = p;
+      p = my_strchrnul (path, G_SEARCHPATH_SEPARATOR);
+
+      if (p == path)
+        /* Two adjacent colons, or a colon at the beginning or the end
+         * of `PATH' means to search the current directory.
+         */
+        startp = name + 1;
+      else
+        startp = memcpy (name - (p - path), path, p - path);
+
+      if (g_file_test (startp, G_FILE_TEST_IS_EXECUTABLE) &&
+         !g_file_test (startp, G_FILE_TEST_IS_DIR))
+        {
+          gchar *ret;
+          ret = g_strdup (startp);
+          g_free (freeme);
+#ifdef G_OS_WIN32
+         g_free ((gchar *) path_copy);
+#endif
+          return ret;
+        }
+    }
+  while (*p++ != '\0');
+  
+  g_free (freeme);
+#ifdef G_OS_WIN32
+  g_free ((gchar *) path_copy);
+#endif
+
+  return NULL;
+}
+
+static gboolean
+debug_key_matches (const gchar *key,
+                  const gchar *token,
+                  guint        length)
+{
+  for (; length; length--, key++, token++)
+    {
+      char k = (*key   == '_') ? '-' : tolower (*key  );
+      char t = (*token == '_') ? '-' : tolower (*token);
+
+      if (k != t)
+        return FALSE;
+    }
+
+  return *key == '\0';
+}
+
+/**
+ * g_parse_debug_string:
+ * @string: a list of debug options separated by colons, spaces, or
+ * commas, or %NULL.
+ * @keys: pointer to an array of #GDebugKey which associate 
+ *     strings with bit flags.
+ * @nkeys: the number of #GDebugKey<!-- -->s in the array.
+ *
+ * Parses a string containing debugging options
+ * into a %guint containing bit flags. This is used 
+ * within GDK and GTK+ to parse the debug options passed on the
+ * command line or through environment variables.
+ *
+ * If @string is equal to "all", all flags are set.  If @string
+ * is equal to "help", all the available keys in @keys are printed
+ * out to standard error.
+ *
+ * Returns: the combined set of bit flags.
+ */
+guint       
+g_parse_debug_string  (const gchar     *string, 
+                      const GDebugKey *keys, 
+                      guint            nkeys)
+{
+  guint i;
+  guint result = 0;
+  
+  if (string == NULL)
+    return 0;
+
+  /* this function is used by gmem.c/gslice.c initialization code,
+   * so introducing malloc dependencies here would require adaptions
+   * of those code portions.
+   */
+  
+  if (!g_ascii_strcasecmp (string, "all"))
+    {
+      for (i=0; i<nkeys; i++)
+       result |= keys[i].value;
+    }
+  else if (!g_ascii_strcasecmp (string, "help"))
+    {
+      /* using stdio directly for the reason stated above */
+      fprintf (stderr, "Supported debug values: ");
+      for (i=0; i<nkeys; i++)
+       fprintf (stderr, " %s", keys[i].key);
+      fprintf (stderr, "\n");
+    }
+  else
+    {
+      const gchar *p = string;
+      const gchar *q;
+      
+      while (*p)
+       {
+         q = strpbrk (p, ":;, \t");
+         if (!q)
+           q = p + strlen(p);
+         
+         for (i = 0; i < nkeys; i++)
+           if (debug_key_matches (keys[i].key, p, q - p))
+             result |= keys[i].value;
+         
+         p = q;
+         if (*p)
+           p++;
+       }
+    }
+  
+  return result;
+}
+
+/**
+ * g_basename:
+ * @file_name: the name of the file.
+ * 
+ * Gets the name of the file without any leading directory components.  
+ * It returns a pointer into the given file name string.
+ * 
+ * Return value: the name of the file without any leading directory components.
+ *
+ * Deprecated:2.2: Use g_path_get_basename() instead, but notice that
+ * g_path_get_basename() allocates new memory for the returned string, unlike
+ * this function which returns a pointer into the argument.
+ **/
+G_CONST_RETURN gchar*
+g_basename (const gchar           *file_name)
+{
+  register gchar *base;
+  
+  g_return_val_if_fail (file_name != NULL, NULL);
+  
+  base = strrchr (file_name, G_DIR_SEPARATOR);
+
+#ifdef G_OS_WIN32
+  {
+    gchar *q = strrchr (file_name, '/');
+    if (base == NULL || (q != NULL && q > base))
+       base = q;
+  }
+#endif
+
+  if (base)
+    return base + 1;
+
+#ifdef G_OS_WIN32
+  if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
+    return (gchar*) file_name + 2;
+#endif /* G_OS_WIN32 */
+  
+  return (gchar*) file_name;
+}
+
+/**
+ * g_path_get_basename:
+ * @file_name: the name of the file.
+ *
+ * Gets the last component of the filename. If @file_name ends with a 
+ * directory separator it gets the component before the last slash. If 
+ * @file_name consists only of directory separators (and on Windows, 
+ * possibly a drive letter), a single separator is returned. If
+ * @file_name is empty, it gets ".".
+ *
+ * Return value: a newly allocated string containing the last component of 
+ *   the filename.
+ */
+gchar*
+g_path_get_basename (const gchar   *file_name)
+{
+  register gssize base;             
+  register gssize last_nonslash;    
+  gsize len;    
+  gchar *retval;
+  g_return_val_if_fail (file_name != NULL, NULL);
+
+  if (file_name[0] == '\0')
+    /* empty string */
+    return g_strdup (".");
+  
+  last_nonslash = strlen (file_name) - 1;
+
+  while (last_nonslash >= 0 && G_IS_DIR_SEPARATOR (file_name [last_nonslash]))
+    last_nonslash--;
+
+  if (last_nonslash == -1)
+    /* string only containing slashes */
+    return g_strdup (G_DIR_SEPARATOR_S);
+
+#ifdef G_OS_WIN32
+  if (last_nonslash == 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
+    /* string only containing slashes and a drive */
+    return g_strdup (G_DIR_SEPARATOR_S);
+#endif /* G_OS_WIN32 */
+
+  base = last_nonslash;
+
+  while (base >=0 && !G_IS_DIR_SEPARATOR (file_name [base]))
+    base--;
+
+#ifdef G_OS_WIN32
+  if (base == -1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
+    base = 1;
+#endif /* G_OS_WIN32 */
+
+  len = last_nonslash - base;
+  retval = g_malloc (len + 1);
+  memcpy (retval, file_name + base + 1, len);
+  retval [len] = '\0';
+  return retval;
+}
+
+/**
+ * g_path_is_absolute:
+ * @file_name: a file name.
+ *
+ * Returns %TRUE if the given @file_name is an absolute file name,
+ * i.e. it contains a full path from the root directory such as "/usr/local"
+ * on UNIX or "C:\windows" on Windows systems.
+ *
+ * Returns: %TRUE if @file_name is an absolute path. 
+ */
+gboolean
+g_path_is_absolute (const gchar *file_name)
+{
+  g_return_val_if_fail (file_name != NULL, FALSE);
+  
+  if (G_IS_DIR_SEPARATOR (file_name[0]))
+    return TRUE;
+
+#ifdef G_OS_WIN32
+  /* Recognize drive letter on native Windows */
+  if (g_ascii_isalpha (file_name[0]) && 
+      file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
+    return TRUE;
+#endif /* G_OS_WIN32 */
+
+  return FALSE;
+}
+
+/**
+ * g_path_skip_root:
+ * @file_name: a file name.
+ *
+ * Returns a pointer into @file_name after the root component, i.e. after
+ * the "/" in UNIX or "C:\" under Windows. If @file_name is not an absolute
+ * path it returns %NULL.
+ *
+ * Returns: a pointer into @file_name after the root component.
+ */
+G_CONST_RETURN gchar*
+g_path_skip_root (const gchar *file_name)
+{
+  g_return_val_if_fail (file_name != NULL, NULL);
+  
+#ifdef G_PLATFORM_WIN32
+  /* Skip \\server\share or //server/share */
+  if (G_IS_DIR_SEPARATOR (file_name[0]) &&
+      G_IS_DIR_SEPARATOR (file_name[1]) &&
+      file_name[2] &&
+      !G_IS_DIR_SEPARATOR (file_name[2]))
+    {
+      gchar *p;
+
+      p = strchr (file_name + 2, G_DIR_SEPARATOR);
+#ifdef G_OS_WIN32
+      {
+       gchar *q = strchr (file_name + 2, '/');
+       if (p == NULL || (q != NULL && q < p))
+         p = q;
+      }
+#endif
+      if (p &&
+         p > file_name + 2 &&
+         p[1])
+       {
+         file_name = p + 1;
+
+         while (file_name[0] && !G_IS_DIR_SEPARATOR (file_name[0]))
+           file_name++;
+
+         /* Possibly skip a backslash after the share name */
+         if (G_IS_DIR_SEPARATOR (file_name[0]))
+           file_name++;
+
+         return (gchar *)file_name;
+       }
+    }
+#endif
+  
+  /* Skip initial slashes */
+  if (G_IS_DIR_SEPARATOR (file_name[0]))
+    {
+      while (G_IS_DIR_SEPARATOR (file_name[0]))
+       file_name++;
+      return (gchar *)file_name;
+    }
+
+#ifdef G_OS_WIN32
+  /* Skip X:\ */
+  if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':' && G_IS_DIR_SEPARATOR (file_name[2]))
+    return (gchar *)file_name + 3;
+#endif
+
+  return NULL;
+}
+
+/**
+ * g_path_get_dirname:
+ * @file_name: the name of the file.
+ *
+ * Gets the directory components of a file name.  If the file name has no
+ * directory components "." is returned.  The returned string should be
+ * freed when no longer needed.
+ * 
+ * Returns: the directory components of the file.
+ */
+gchar*
+g_path_get_dirname (const gchar           *file_name)
+{
+  register gchar *base;
+  register gsize len;    
+  
+  g_return_val_if_fail (file_name != NULL, NULL);
+  
+  base = strrchr (file_name, G_DIR_SEPARATOR);
+#ifdef G_OS_WIN32
+  {
+    gchar *q = strrchr (file_name, '/');
+    if (base == NULL || (q != NULL && q > base))
+       base = q;
+  }
+#endif
+  if (!base)
+    {
+#ifdef G_OS_WIN32
+      if (g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
+       {
+         gchar drive_colon_dot[4];
+
+         drive_colon_dot[0] = file_name[0];
+         drive_colon_dot[1] = ':';
+         drive_colon_dot[2] = '.';
+         drive_colon_dot[3] = '\0';
+
+         return g_strdup (drive_colon_dot);
+       }
+#endif
+    return g_strdup (".");
+    }
+
+  while (base > file_name && G_IS_DIR_SEPARATOR (*base))
+    base--;
+
+#ifdef G_OS_WIN32
+  /* base points to the char before the last slash.
+   *
+   * In case file_name is the root of a drive (X:\) or a child of the
+   * root of a drive (X:\foo), include the slash.
+   *
+   * In case file_name is the root share of an UNC path
+   * (\\server\share), add a slash, returning \\server\share\ .
+   *
+   * In case file_name is a direct child of a share in an UNC path
+   * (\\server\share\foo), include the slash after the share name,
+   * returning \\server\share\ .
+   */
+  if (base == file_name + 1 && g_ascii_isalpha (file_name[0]) && file_name[1] == ':')
+    base++;
+  else if (G_IS_DIR_SEPARATOR (file_name[0]) &&
+          G_IS_DIR_SEPARATOR (file_name[1]) &&
+          file_name[2] &&
+          !G_IS_DIR_SEPARATOR (file_name[2]) &&
+          base >= file_name + 2)
+    {
+      const gchar *p = file_name + 2;
+      while (*p && !G_IS_DIR_SEPARATOR (*p))
+       p++;
+      if (p == base + 1)
+       {
+         len = (guint) strlen (file_name) + 1;
+         base = g_new (gchar, len + 1);
+         strcpy (base, file_name);
+         base[len-1] = G_DIR_SEPARATOR;
+         base[len] = 0;
+         return base;
+       }
+      if (G_IS_DIR_SEPARATOR (*p))
+       {
+         p++;
+         while (*p && !G_IS_DIR_SEPARATOR (*p))
+           p++;
+         if (p == base + 1)
+           base++;
+       }
+    }
+#endif
+
+  len = (guint) 1 + base - file_name;
+  
+  base = g_new (gchar, len + 1);
+  g_memmove (base, file_name, len);
+  base[len] = 0;
+  
+  return base;
+}
+
+/**
+ * g_get_current_dir:
+ *
+ * Gets the current directory.
+ * The returned string should be freed when no longer needed. The encoding 
+ * of the returned string is system defined. On Windows, it is always UTF-8.
+ * 
+ * Returns: the current directory.
+ */
+gchar*
+g_get_current_dir (void)
+{
+#ifdef G_OS_WIN32
+
+  gchar *dir = NULL;
+  wchar_t dummy[2], *wdir;
+  int len;
+
+  len = GetCurrentDirectoryW (2, dummy);
+  wdir = g_new (wchar_t, len);
+
+  if (GetCurrentDirectoryW (len, wdir) == len - 1)
+    dir = g_utf16_to_utf8 (wdir, -1, NULL, NULL, NULL);
+  
+  g_free (wdir);
+
+  if (dir == NULL)
+    dir = g_strdup ("\\");
+
+  return dir;
+
+#else
+
+  gchar *buffer = NULL;
+  gchar *dir = NULL;
+  static gulong max_len = 0;
+
+  if (max_len == 0) 
+    max_len = (G_PATH_LENGTH == -1) ? 2048 : G_PATH_LENGTH;
+  
+  /* We don't use getcwd(3) on SUNOS, because, it does a popen("pwd")
+   * and, if that wasn't bad enough, hangs in doing so.
+   */
+#if    (defined (sun) && !defined (__SVR4)) || !defined(HAVE_GETCWD)
+  buffer = g_new (gchar, max_len + 1);
+  *buffer = 0;
+  dir = getwd (buffer);
+#else  /* !sun || !HAVE_GETCWD */
+  while (max_len < G_MAXULONG / 2)
+    {
+      g_free (buffer);
+      buffer = g_new (gchar, max_len + 1);
+      *buffer = 0;
+      dir = getcwd (buffer, max_len);
+
+      if (dir || errno != ERANGE)
+       break;
+
+      max_len *= 2;
+    }
+#endif /* !sun || !HAVE_GETCWD */
+  
+  if (!dir || !*buffer)
+    {
+      /* hm, should we g_error() out here?
+       * this can happen if e.g. "./" has mode \0000
+       */
+      buffer[0] = G_DIR_SEPARATOR;
+      buffer[1] = 0;
+    }
+
+  dir = g_strdup (buffer);
+  g_free (buffer);
+  
+  return dir;
+#endif /* !Win32 */
+}
+
+/**
+ * g_getenv:
+ * @variable: the environment variable to get, in the GLib file name encoding.
+ * 
+ * Returns the value of an environment variable. The name and value
+ * are in the GLib file name encoding. On UNIX, this means the actual
+ * bytes which might or might not be in some consistent character set
+ * and encoding. On Windows, it is in UTF-8. On Windows, in case the
+ * environment variable's value contains references to other
+ * environment variables, they are expanded.
+ * 
+ * Return value: the value of the environment variable, or %NULL if
+ * the environment variable is not found. The returned string may be
+ * overwritten by the next call to g_getenv(), g_setenv() or
+ * g_unsetenv().
+ **/
+G_CONST_RETURN gchar*
+g_getenv (const gchar *variable)
+{
+#ifndef G_OS_WIN32
+
+  g_return_val_if_fail (variable != NULL, NULL);
+
+  return getenv (variable);
+
+#else /* G_OS_WIN32 */
+
+  GQuark quark;
+  gchar *value;
+  wchar_t dummy[2], *wname, *wvalue;
+  int len;
+
+  g_return_val_if_fail (variable != NULL, NULL);
+  g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), NULL);
+
+  /* On Windows NT, it is relatively typical that environment
+   * variables contain references to other environment variables. If
+   * so, use ExpandEnvironmentStrings(). (In an ideal world, such
+   * environment variables would be stored in the Registry as
+   * REG_EXPAND_SZ type values, and would then get automatically
+   * expanded before a program sees them. But there is broken software
+   * that stores environment variables as REG_SZ values even if they
+   * contain references to other environment variables.)
+   */
+
+  wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL);
+
+  len = GetEnvironmentVariableW (wname, dummy, 2);
+
+  if (len == 0)
+    {
+      g_free (wname);
+      return NULL;
+    }
+  else if (len == 1)
+    len = 2;
+
+  wvalue = g_new (wchar_t, len);
+
+  if (GetEnvironmentVariableW (wname, wvalue, len) != len - 1)
+    {
+      g_free (wname);
+      g_free (wvalue);
+      return NULL;
+    }
+
+  if (wcschr (wvalue, L'%') != NULL)
+    {
+      wchar_t *tem = wvalue;
+
+      len = ExpandEnvironmentStringsW (wvalue, dummy, 2);
+
+      if (len > 0)
+       {
+         wvalue = g_new (wchar_t, len);
+
+         if (ExpandEnvironmentStringsW (tem, wvalue, len) != len)
+           {
+             g_free (wvalue);
+             wvalue = tem;
+           }
+         else
+           g_free (tem);
+       }
+    }
+
+  value = g_utf16_to_utf8 (wvalue, -1, NULL, NULL, NULL);
+
+  g_free (wname);
+  g_free (wvalue);
+
+  quark = g_quark_from_string (value);
+  g_free (value);
+  
+  return g_quark_to_string (quark);
+
+#endif /* G_OS_WIN32 */
+}
+
+/* _g_getenv_nomalloc
+ * this function does a getenv() without doing any kind of allocation
+ * through glib. it's suitable for chars <= 127 only (both, for the
+ * variable name and the contents) and for contents < 1024 chars in
+ * length. also, it aliases "" to a NULL return value.
+ **/
+const gchar*
+_g_getenv_nomalloc (const gchar *variable,
+                    gchar        buffer[1024])
+{
+  const gchar *retval = getenv (variable);
+  if (retval && retval[0])
+    {
+      gint l = strlen (retval);
+      if (l < 1024)
+        {
+          strncpy (buffer, retval, l);
+          buffer[l] = 0;
+          return buffer;
+        }
+    }
+  return NULL;
+}
+
+/**
+ * g_setenv:
+ * @variable: the environment variable to set, must not contain '='.
+ * @value: the value for to set the variable to.
+ * @overwrite: whether to change the variable if it already exists.
+ *
+ * Sets an environment variable. Both the variable's name and value
+ * should be in the GLib file name encoding. On UNIX, this means that
+ * they can be any sequence of bytes. On Windows, they should be in
+ * UTF-8.
+ *
+ * Note that on some systems, when variables are overwritten, the memory 
+ * used for the previous variables and its value isn't reclaimed.
+ *
+ * Returns: %FALSE if the environment variable couldn't be set.
+ *
+ * Since: 2.4
+ */
+gboolean
+g_setenv (const gchar *variable, 
+         const gchar *value, 
+         gboolean     overwrite)
+{
+#ifndef G_OS_WIN32
+
+  gint result;
+#ifndef HAVE_SETENV
+  gchar *string;
+#endif
+
+  g_return_val_if_fail (variable != NULL, FALSE);
+  g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE);
+
+#ifdef HAVE_SETENV
+  result = setenv (variable, value, overwrite);
+#else
+  if (!overwrite && getenv (variable) != NULL)
+    return TRUE;
+  
+  /* This results in a leak when you overwrite existing
+   * settings. It would be fairly easy to fix this by keeping
+   * our own parallel array or hash table.
+   */
+  string = g_strconcat (variable, "=", value, NULL);
+  result = putenv (string);
+#endif
+  return result == 0;
+
+#else /* G_OS_WIN32 */
+
+  gboolean retval;
+  wchar_t *wname, *wvalue, *wassignment;
+  gchar *tem;
+
+  g_return_val_if_fail (variable != NULL, FALSE);
+  g_return_val_if_fail (strchr (variable, '=') == NULL, FALSE);
+  g_return_val_if_fail (g_utf8_validate (variable, -1, NULL), FALSE);
+  g_return_val_if_fail (g_utf8_validate (value, -1, NULL), FALSE);
+
+  if (!overwrite && g_getenv (variable) != NULL)
+    return TRUE;
+
+  /* We want to (if possible) set both the environment variable copy
+   * kept by the C runtime and the one kept by the system.
+   *
+   * We can't use only the C runtime's putenv or _wputenv() as that
+   * won't work for arbitrary Unicode strings in a "non-Unicode" app
+   * (with main() and not wmain()). In a "main()" app the C runtime
+   * initializes the C runtime's environment table by converting the
+   * real (wide char) environment variables to system codepage, thus
+   * breaking those that aren't representable in the system codepage.
+   *
+   * As the C runtime's putenv() will also set the system copy, we do
+   * the putenv() first, then call SetEnvironmentValueW ourselves.
+   */
+
+  wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL);
+  wvalue = g_utf8_to_utf16 (value, -1, NULL, NULL, NULL);
+  tem = g_strconcat (variable, "=", value, NULL);
+  wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL);
+    
+  g_free (tem);
+  _wputenv (wassignment);
+  g_free (wassignment);
+
+  retval = (SetEnvironmentVariableW (wname, wvalue) != 0);
+
+  g_free (wname);
+  g_free (wvalue);
+
+  return retval;
+
+#endif /* G_OS_WIN32 */
+}
+
+#ifdef HAVE__NSGETENVIRON
+#define environ (*_NSGetEnviron())
+#elif !defined(G_OS_WIN32)
+
+/* According to the Single Unix Specification, environ is not in 
+ * any system header, although unistd.h often declares it.
+ */
+extern char **environ;
+#endif
+
+/**
+ * g_unsetenv:
+ * @variable: the environment variable to remove, must not contain '='.
+ * 
+ * Removes an environment variable from the environment.
+ *
+ * Note that on some systems, when variables are overwritten, the memory 
+ * used for the previous variables and its value isn't reclaimed.
+ * Furthermore, this function can't be guaranteed to operate in a 
+ * threadsafe way.
+ *
+ * Since: 2.4 
+ **/
+void
+g_unsetenv (const gchar *variable)
+{
+#ifndef G_OS_WIN32
+
+#ifdef HAVE_UNSETENV
+  g_return_if_fail (variable != NULL);
+  g_return_if_fail (strchr (variable, '=') == NULL);
+
+  unsetenv (variable);
+#else /* !HAVE_UNSETENV */
+  int len;
+  gchar **e, **f;
+
+  g_return_if_fail (variable != NULL);
+  g_return_if_fail (strchr (variable, '=') == NULL);
+
+  len = strlen (variable);
+  
+  /* Mess directly with the environ array.
+   * This seems to be the only portable way to do this.
+   *
+   * Note that we remove *all* environment entries for
+   * the variable name, not just the first.
+   */
+  e = f = environ;
+  while (*e != NULL) 
+    {
+      if (strncmp (*e, variable, len) != 0 || (*e)[len] != '=') 
+       {
+         *f = *e;
+         f++;
+       }
+      e++;
+    }
+  *f = NULL;
+#endif /* !HAVE_UNSETENV */
+
+#else  /* G_OS_WIN32 */
+
+  wchar_t *wname, *wassignment;
+  gchar *tem;
+
+  g_return_if_fail (variable != NULL);
+  g_return_if_fail (strchr (variable, '=') == NULL);
+  g_return_if_fail (g_utf8_validate (variable, -1, NULL));
+
+  wname = g_utf8_to_utf16 (variable, -1, NULL, NULL, NULL);
+  tem = g_strconcat (variable, "=", NULL);
+  wassignment = g_utf8_to_utf16 (tem, -1, NULL, NULL, NULL);
+    
+  g_free (tem);
+  _wputenv (wassignment);
+  g_free (wassignment);
+
+  SetEnvironmentVariableW (wname, NULL);
+
+  g_free (wname);
+
+#endif /* G_OS_WIN32 */
+}
+
+/**
+ * g_listenv:
+ *
+ * Gets the names of all variables set in the environment.
+ * 
+ * Returns: a %NULL-terminated list of strings which must be freed
+ * with g_strfreev().
+ *
+ * Programs that want to be portable to Windows should typically use
+ * this function and g_getenv() instead of using the environ array
+ * from the C library directly. On Windows, the strings in the environ
+ * array are in system codepage encoding, while in most of the typical
+ * use cases for environment variables in GLib-using programs you want
+ * the UTF-8 encoding that this function and g_getenv() provide.
+ *
+ * Since: 2.8
+ */
+gchar **
+g_listenv (void)
+{
+#ifndef G_OS_WIN32
+  gchar **result, *eq;
+  gint len, i, j;
+
+  len = g_strv_length (environ);
+  result = g_new0 (gchar *, len + 1);
+  
+  j = 0;
+  for (i = 0; i < len; i++)
+    {
+      eq = strchr (environ[i], '=');
+      if (eq)
+       result[j++] = g_strndup (environ[i], eq - environ[i]);
+    }
+
+  result[j] = NULL;
+
+  return result;
+#else
+  gchar **result, *eq;
+  gint len = 0, j;
+  wchar_t *p, *q;
+
+  p = (wchar_t *) GetEnvironmentStringsW ();
+  if (p != NULL)
+    {
+      q = p;
+      while (*q)
+       {
+         q += wcslen (q) + 1;
+         len++;
+       }
+    }
+  result = g_new0 (gchar *, len + 1);
+
+  j = 0;
+  q = p;
+  while (*q)
+    {
+      result[j] = g_utf16_to_utf8 (q, -1, NULL, NULL, NULL);
+      if (result[j] != NULL)
+       {
+         eq = strchr (result[j], '=');
+         if (eq && eq > result[j])
+           {
+             *eq = '\0';
+             j++;
+           }
+         else
+           g_free (result[j]);
+       }
+      q += wcslen (q) + 1;
+    }
+  result[j] = NULL;
+  FreeEnvironmentStringsW (p);
+
+  return result;
+#endif
+}
+
+G_LOCK_DEFINE_STATIC (g_utils_global);
+
+static gchar   *g_tmp_dir = NULL;
+static gchar   *g_user_name = NULL;
+static gchar   *g_real_name = NULL;
+static gchar   *g_home_dir = NULL;
+static gchar   *g_host_name = NULL;
+
+#ifdef G_OS_WIN32
+/* System codepage versions of the above, kept at file level so that they,
+ * too, are produced only once.
+ */
+static gchar   *g_tmp_dir_cp = NULL;
+static gchar   *g_user_name_cp = NULL;
+static gchar   *g_real_name_cp = NULL;
+static gchar   *g_home_dir_cp = NULL;
+#endif
+
+static  gchar   *g_user_data_dir = NULL;
+static  gchar  **g_system_data_dirs = NULL;
+static  gchar   *g_user_cache_dir = NULL;
+static  gchar   *g_user_config_dir = NULL;
+static  gchar  **g_system_config_dirs = NULL;
+
+static  gchar  **g_user_special_dirs = NULL;
+
+/* fifteen minutes of fame for everybody */
+#define G_USER_DIRS_EXPIRE      15 * 60
+
+#ifdef G_OS_WIN32
+
+static gchar *
+get_special_folder (int csidl)
+{
+  wchar_t path[MAX_PATH+1];
+  HRESULT hr;
+  LPITEMIDLIST pidl = NULL;
+  BOOL b;
+  gchar *retval = NULL;
+
+  hr = SHGetSpecialFolderLocation (NULL, csidl, &pidl);
+  if (hr == S_OK)
+    {
+      b = SHGetPathFromIDListW (pidl, path);
+      if (b)
+       retval = g_utf16_to_utf8 (path, -1, NULL, NULL, NULL);
+      CoTaskMemFree (pidl);
+    }
+  return retval;
+}
+
+static char *
+get_windows_directory_root (void)
+{
+  wchar_t wwindowsdir[MAX_PATH];
+
+  if (GetWindowsDirectoryW (wwindowsdir, G_N_ELEMENTS (wwindowsdir)))
+    {
+      /* Usually X:\Windows, but in terminal server environments
+       * might be an UNC path, AFAIK.
+       */
+      char *windowsdir = g_utf16_to_utf8 (wwindowsdir, -1, NULL, NULL, NULL);
+      char *p;
+
+      if (windowsdir == NULL)
+       return g_strdup ("C:\\");
+
+      p = (char *) g_path_skip_root (windowsdir);
+      if (G_IS_DIR_SEPARATOR (p[-1]) && p[-2] != ':')
+       p--;
+      *p = '\0';
+      return windowsdir;
+    }
+  else
+    return g_strdup ("C:\\");
+}
+
+#endif
+
+/* HOLDS: g_utils_global_lock */
+static void
+g_get_any_init_do (void)
+{
+  gchar hostname[100];
+
+  g_tmp_dir = g_strdup (g_getenv ("TMPDIR"));
+  if (g_tmp_dir == NULL || *g_tmp_dir == '\0')
+    g_tmp_dir = g_strdup (g_getenv ("TMP"));
+  if (g_tmp_dir == NULL || *g_tmp_dir == '\0')
+    g_tmp_dir = g_strdup (g_getenv ("TEMP"));
+
+#ifdef G_OS_WIN32
+  if (g_tmp_dir == NULL || *g_tmp_dir == '\0')
+    g_tmp_dir = get_windows_directory_root ();
+#else  
+#ifdef P_tmpdir
+  if (g_tmp_dir == NULL || *g_tmp_dir == '\0')
+    {
+      gsize k;    
+      g_tmp_dir = g_strdup (P_tmpdir);
+      k = strlen (g_tmp_dir);
+      if (k > 1 && G_IS_DIR_SEPARATOR (g_tmp_dir[k - 1]))
+       g_tmp_dir[k - 1] = '\0';
+    }
+#endif
+  
+  if (g_tmp_dir == NULL || *g_tmp_dir == '\0')
+    {
+      g_tmp_dir = g_strdup ("/tmp");
+    }
+#endif /* !G_OS_WIN32 */
+  
+#ifdef G_OS_WIN32
+  /* We check $HOME first for Win32, though it is a last resort for Unix
+   * where we prefer the results of getpwuid().
+   */
+  g_home_dir = g_strdup (g_getenv ("HOME"));
+
+  /* Only believe HOME if it is an absolute path and exists */
+  if (g_home_dir)
+    {
+      if (!(g_path_is_absolute (g_home_dir) &&
+           g_file_test (g_home_dir, G_FILE_TEST_IS_DIR)))
+       {
+         g_free (g_home_dir);
+         g_home_dir = NULL;
+       }
+    }
+  
+  /* In case HOME is Unix-style (it happens), convert it to
+   * Windows style.
+   */
+  if (g_home_dir)
+    {
+      gchar *p;
+      while ((p = strchr (g_home_dir, '/')) != NULL)
+       *p = '\\';
+    }
+
+  if (!g_home_dir)
+    {
+      /* USERPROFILE is probably the closest equivalent to $HOME? */
+      if (g_getenv ("USERPROFILE") != NULL)
+       g_home_dir = g_strdup (g_getenv ("USERPROFILE"));
+    }
+
+  if (!g_home_dir)
+    g_home_dir = get_special_folder (CSIDL_PROFILE);
+  
+  if (!g_home_dir)
+    g_home_dir = get_windows_directory_root ();
+#endif /* G_OS_WIN32 */
+  
+#ifdef HAVE_PWD_H
+  {
+    struct passwd *pw = NULL;
+    gpointer buffer = NULL;
+    gint error;
+    gchar *logname;
+
+#  if defined (HAVE_POSIX_GETPWUID_R) || defined (HAVE_NONPOSIX_GETPWUID_R)
+    struct passwd pwd;
+#    ifdef _SC_GETPW_R_SIZE_MAX  
+    /* This reurns the maximum length */
+    glong bufsize = sysconf (_SC_GETPW_R_SIZE_MAX);
+    
+    if (bufsize < 0)
+      bufsize = 64;
+#    else /* _SC_GETPW_R_SIZE_MAX */
+    glong bufsize = 64;
+#    endif /* _SC_GETPW_R_SIZE_MAX */
+
+    logname = (gchar *) g_getenv ("LOGNAME");
+        
+    do
+      {
+       g_free (buffer);
+       /* we allocate 6 extra bytes to work around a bug in 
+        * Mac OS < 10.3. See #156446
+        */
+       buffer = g_malloc (bufsize + 6);
+       errno = 0;
+       
+#    ifdef HAVE_POSIX_GETPWUID_R
+       if (logname) {
+         error = getpwnam_r (logname, &pwd, buffer, bufsize, &pw);
+         if (!pw || (pw->pw_uid != getuid ())) {
+           /* LOGNAME is lying, fall back to looking up the uid */
+           error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
+         }
+       } else {
+         error = getpwuid_r (getuid (), &pwd, buffer, bufsize, &pw);
+       }
+       error = error < 0 ? errno : error;
+#    else /* HAVE_NONPOSIX_GETPWUID_R */
+   /* HPUX 11 falls into the HAVE_POSIX_GETPWUID_R case */
+#      if defined(_AIX) || defined(__hpux)
+       error = getpwuid_r (getuid (), &pwd, buffer, bufsize);
+       pw = error == 0 ? &pwd : NULL;
+#      else /* !_AIX */
+       if (logname) {
+         pw = getpwnam_r (logname, &pwd, buffer, bufsize);
+         if (!pw || (pw->pw_uid != getuid ())) {
+           /* LOGNAME is lying, fall back to looking up the uid */
+           pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
+         }
+       } else {
+         pw = getpwuid_r (getuid (), &pwd, buffer, bufsize);
+       }
+       error = pw ? 0 : errno;
+#      endif /* !_AIX */            
+#    endif /* HAVE_NONPOSIX_GETPWUID_R */
+       
+       if (!pw)
+         {
+           /* we bail out prematurely if the user id can't be found
+            * (should be pretty rare case actually), or if the buffer
+            * should be sufficiently big and lookups are still not
+            * successfull.
+            */
+           if (error == 0 || error == ENOENT)
+             {
+               g_warning ("getpwuid_r(): failed due to unknown user id (%lu)",
+                          (gulong) getuid ());
+               break;
+             }
+           if (bufsize > 32 * 1024)
+             {
+               g_warning ("getpwuid_r(): failed due to: %s.",
+                          g_strerror (error));
+               break;
+             }
+           
+           bufsize *= 2;
+         }
+      }
+    while (!pw);
+#  endif /* HAVE_POSIX_GETPWUID_R || HAVE_NONPOSIX_GETPWUID_R */
+    
+    if (!pw)
+      {
+#ifdef BUILD_WITH_ANDROID
+       pw = getpwuid (getuid ());
+#else
+       setpwent ();
+       pw = getpwuid (getuid ());
+       endpwent ();
+#endif
+      }
+    if (pw)
+      {
+       g_user_name = g_strdup (pw->pw_name);
+
+#ifdef HAVE_STRUCT_PASSWD_PW_GECO
+       if (pw->pw_gecos && *pw->pw_gecos != '\0') 
+         {
+           gchar **gecos_fields;
+           gchar **name_parts;
+
+           /* split the gecos field and substitute '&' */
+           gecos_fields = g_strsplit (pw->pw_gecos, ",", 0);
+           name_parts = g_strsplit (gecos_fields[0], "&", 0);
+           pw->pw_name[0] = g_ascii_toupper (pw->pw_name[0]);
+           g_real_name = g_strjoinv (pw->pw_name, name_parts);
+           g_strfreev (gecos_fields);
+           g_strfreev (name_parts);
+         }
+#else
+  g_real_name = g_strdup (g_user_name);
+#endif
+
+       if (!g_home_dir)
+         g_home_dir = g_strdup (pw->pw_dir);
+      }
+    g_free (buffer);
+  }
+  
+#else /* !HAVE_PWD_H */
+  
+#ifdef G_OS_WIN32
+  {
+    guint len = UNLEN+1;
+    wchar_t buffer[UNLEN+1];
+    
+    if (GetUserNameW (buffer, (LPDWORD) &len))
+      {
+       g_user_name = g_utf16_to_utf8 (buffer, -1, NULL, NULL, NULL);
+       g_real_name = g_strdup (g_user_name);
+      }
+  }
+#endif /* G_OS_WIN32 */
+
+#endif /* !HAVE_PWD_H */
+
+#ifndef G_OS_WIN32
+  if (!g_home_dir)
+    g_home_dir = g_strdup (g_getenv ("HOME"));
+#endif
+
+#ifdef __EMX__
+  /* change '\\' in %HOME% to '/' */
+  g_strdelimit (g_home_dir, "\\",'/');
+#endif
+  if (!g_user_name)
+    g_user_name = g_strdup ("somebody");
+  if (!g_real_name)
+    g_real_name = g_strdup ("Unknown");
+
+  {
+#ifndef G_OS_WIN32
+    gboolean hostname_fail = (gethostname (hostname, sizeof (hostname)) == -1);
+#else
+    DWORD size = sizeof (hostname);
+    gboolean hostname_fail = (!GetComputerName (hostname, &size));
+#endif
+    g_host_name = g_strdup (hostname_fail ? "localhost" : hostname);
+  }
+
+#ifdef G_OS_WIN32
+  g_tmp_dir_cp = g_locale_from_utf8 (g_tmp_dir, -1, NULL, NULL, NULL);
+  g_user_name_cp = g_locale_from_utf8 (g_user_name, -1, NULL, NULL, NULL);
+  g_real_name_cp = g_locale_from_utf8 (g_real_name, -1, NULL, NULL, NULL);
+
+  if (!g_tmp_dir_cp)
+    g_tmp_dir_cp = g_strdup ("\\");
+  if (!g_user_name_cp)
+    g_user_name_cp = g_strdup ("somebody");
+  if (!g_real_name_cp)
+    g_real_name_cp = g_strdup ("Unknown");
+
+  /* home_dir might be NULL, unlike tmp_dir, user_name and
+   * real_name.
+   */
+  if (g_home_dir)
+    g_home_dir_cp = g_locale_from_utf8 (g_home_dir, -1, NULL, NULL, NULL);
+  else
+    g_home_dir_cp = NULL;
+#endif /* G_OS_WIN32 */
+}
+
+static inline void
+g_get_any_init (void)
+{
+  if (!g_tmp_dir)
+    g_get_any_init_do ();
+}
+
+static inline void
+g_get_any_init_locked (void)
+{
+  G_LOCK (g_utils_global);
+  g_get_any_init ();
+  G_UNLOCK (g_utils_global);
+}
+
+
+/**
+ * g_get_user_name:
+ *
+ * Gets the user name of the current user. The encoding of the returned
+ * string is system-defined. On UNIX, it might be the preferred file name
+ * encoding, or something else, and there is no guarantee that it is even
+ * consistent on a machine. On Windows, it is always UTF-8.
+ *
+ * Returns: the user name of the current user.
+ */
+G_CONST_RETURN gchar*
+g_get_user_name (void)
+{
+  g_get_any_init_locked ();
+  return g_user_name;
+}
+
+/**
+ * g_get_real_name:
+ *
+ * Gets the real name of the user. This usually comes from the user's entry 
+ * in the <filename>passwd</filename> file. The encoding of the returned 
+ * string is system-defined. (On Windows, it is, however, always UTF-8.) 
+ * If the real user name cannot be determined, the string "Unknown" is 
+ * returned.
+ *
+ * Returns: the user's real name.
+ */
+G_CONST_RETURN gchar*
+g_get_real_name (void)
+{
+  g_get_any_init_locked ();
+  return g_real_name;
+}
+
+/**
+ * g_get_home_dir:
+ *
+ * Gets the current user's home directory as defined in the 
+ * password database.
+ *
+ * Note that in contrast to traditional UNIX tools, this function 
+ * prefers <filename>passwd</filename> entries over the <envar>HOME</envar> 
+ * environment variable. 
+ *
+ * One of the reasons for this decision is that applications in many 
+ * cases need special handling to deal with the case where 
+ * <envar>HOME</envar> is
+ * <simplelist>
+ *   <member>Not owned by the user</member>
+ *   <member>Not writeable</member>
+ *   <member>Not even readable</member>
+ * </simplelist>
+ * Since applications are in general <emphasis>not</emphasis> written 
+ * to deal with these situations it was considered better to make 
+ * g_get_home_dir() not pay attention to <envar>HOME</envar> and to 
+ * return the real home directory for the user. If applications
+ * want to pay attention to <envar>HOME</envar>, they can do:
+ * |[
+ *  const char *homedir = g_getenv ("HOME");
+ *   if (!homedir)
+ *      homedir = g_get_home_dir (<!-- -->);
+ * ]|
+ *
+ * Returns: the current user's home directory
+ */
+G_CONST_RETURN gchar*
+g_get_home_dir (void)
+{
+  g_get_any_init_locked ();
+  return g_home_dir;
+}
+
+/**
+ * g_get_tmp_dir:
+ *
+ * Gets the directory to use for temporary files. This is found from 
+ * inspecting the environment variables <envar>TMPDIR</envar>, 
+ * <envar>TMP</envar>, and <envar>TEMP</envar> in that order. If none 
+ * of those are defined "/tmp" is returned on UNIX and "C:\" on Windows. 
+ * The encoding of the returned string is system-defined. On Windows, 
+ * it is always UTF-8. The return value is never %NULL or the empty string.
+ *
+ * Returns: the directory to use for temporary files.
+ */
+G_CONST_RETURN gchar*
+g_get_tmp_dir (void)
+{
+  g_get_any_init_locked ();
+  return g_tmp_dir;
+}
+
+/**
+ * g_get_host_name:
+ *
+ * Return a name for the machine. 
+ *
+ * The returned name is not necessarily a fully-qualified domain name,
+ * or even present in DNS or some other name service at all. It need
+ * not even be unique on your local network or site, but usually it
+ * is. Callers should not rely on the return value having any specific
+ * properties like uniqueness for security purposes. Even if the name
+ * of the machine is changed while an application is running, the
+ * return value from this function does not change. The returned
+ * string is owned by GLib and should not be modified or freed. If no
+ * name can be determined, a default fixed string "localhost" is
+ * returned.
+ *
+ * Returns: the host name of the machine.
+ *
+ * Since: 2.8
+ */
+const gchar *
+g_get_host_name (void)
+{
+  g_get_any_init_locked ();
+  return g_host_name;
+}
+
+G_LOCK_DEFINE_STATIC (g_prgname);
+static gchar *g_prgname = NULL;
+
+/**
+ * g_get_prgname:
+ *
+ * Gets the name of the program. This name should <emphasis>not</emphasis> 
+ * be localized, contrast with g_get_application_name().
+ * (If you are using GDK or GTK+ the program name is set in gdk_init(), 
+ * which is called by gtk_init(). The program name is found by taking 
+ * the last component of <literal>argv[0]</literal>.)
+ *
+ * Returns: the name of the program. The returned string belongs 
+ * to GLib and must not be modified or freed.
+ */
+gchar*
+g_get_prgname (void)
+{
+  gchar* retval;
+
+  G_LOCK (g_prgname);
+#ifdef G_OS_WIN32
+  if (g_prgname == NULL)
+    {
+      static gboolean beenhere = FALSE;
+
+      if (!beenhere)
+       {
+         gchar *utf8_buf = NULL;
+         wchar_t buf[MAX_PATH+1];
+
+         beenhere = TRUE;
+         if (GetModuleFileNameW (GetModuleHandle (NULL),
+                                 buf, G_N_ELEMENTS (buf)) > 0)
+           utf8_buf = g_utf16_to_utf8 (buf, -1, NULL, NULL, NULL);
+
+         if (utf8_buf)
+           {
+             g_prgname = g_path_get_basename (utf8_buf);
+             g_free (utf8_buf);
+           }
+       }
+    }
+#endif
+  retval = g_prgname;
+  G_UNLOCK (g_prgname);
+
+  return retval;
+}
+
+/**
+ * g_set_prgname:
+ * @prgname: the name of the program.
+ *
+ * Sets the name of the program. This name should <emphasis>not</emphasis> 
+ * be localized, contrast with g_set_application_name(). Note that for 
+ * thread-safety reasons this function can only be called once.
+ */
+void
+g_set_prgname (const gchar *prgname)
+{
+  G_LOCK (g_prgname);
+  g_free (g_prgname);
+  g_prgname = g_strdup (prgname);
+  G_UNLOCK (g_prgname);
+}
+
+G_LOCK_DEFINE_STATIC (g_application_name);
+static gchar *g_application_name = NULL;
+
+/**
+ * g_get_application_name:
+ * 
+ * Gets a human-readable name for the application, as set by
+ * g_set_application_name(). This name should be localized if
+ * possible, and is intended for display to the user.  Contrast with
+ * g_get_prgname(), which gets a non-localized name. If
+ * g_set_application_name() has not been called, returns the result of
+ * g_get_prgname() (which may be %NULL if g_set_prgname() has also not
+ * been called).
+ * 
+ * Return value: human-readable application name. may return %NULL
+ *
+ * Since: 2.2
+ **/
+G_CONST_RETURN gchar*
+g_get_application_name (void)
+{
+  gchar* retval;
+
+  G_LOCK (g_application_name);
+  retval = g_application_name;
+  G_UNLOCK (g_application_name);
+
+  if (retval == NULL)
+    return g_get_prgname ();
+  
+  return retval;
+}
+
+/**
+ * g_set_application_name:
+ * @application_name: localized name of the application
+ *
+ * Sets a human-readable name for the application. This name should be
+ * localized if possible, and is intended for display to the user.
+ * Contrast with g_set_prgname(), which sets a non-localized name.
+ * g_set_prgname() will be called automatically by gtk_init(),
+ * but g_set_application_name() will not.
+ *
+ * Note that for thread safety reasons, this function can only
+ * be called once.
+ *
+ * The application name will be used in contexts such as error messages,
+ * or when displaying an application's name in the task list.
+ * 
+ * Since: 2.2
+ **/
+void
+g_set_application_name (const gchar *application_name)
+{
+  gboolean already_set = FALSE;
+       
+  G_LOCK (g_application_name);
+  if (g_application_name)
+    already_set = TRUE;
+  else
+    g_application_name = g_strdup (application_name);
+  G_UNLOCK (g_application_name);
+
+  if (already_set)
+    g_warning ("g_set_application_name() called multiple times");
+}
+
+/**
+ * g_get_user_data_dir:
+ * 
+ * Returns a base directory in which to access application data such
+ * as icons that is customized for a particular user.  
+ *
+ * On UNIX platforms this is determined using the mechanisms described in
+ * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
+ * XDG Base Directory Specification</ulink>.
+ * In this case the directory retrieved will be XDG_DATA_HOME.
+ *
+ * On Windows is the virtual folder that represents the My Documents
+ * desktop item. See documentation for CSIDL_PERSONAL.
+ *
+ * Return value: a string owned by GLib that must not be modified 
+ *               or freed.
+ * Since: 2.6
+ **/
+G_CONST_RETURN gchar*
+g_get_user_data_dir (void)
+{
+  gchar *data_dir;  
+
+  G_LOCK (g_utils_global);
+
+  if (!g_user_data_dir)
+    {
+#ifdef G_OS_WIN32
+      data_dir = get_special_folder (CSIDL_PERSONAL);
+#else
+      data_dir = (gchar *) g_getenv ("XDG_DATA_HOME");
+
+      if (data_dir && data_dir[0])
+        data_dir = g_strdup (data_dir);
+#endif
+      if (!data_dir || !data_dir[0])
+       {
+         g_get_any_init ();
+
+         if (g_home_dir)
+           data_dir = g_build_filename (g_home_dir, ".local", 
+                                        "share", NULL);
+         else
+           data_dir = g_build_filename (g_tmp_dir, g_user_name, ".local", 
+                                        "share", NULL);
+       }
+
+      g_user_data_dir = data_dir;
+    }
+  else
+    data_dir = g_user_data_dir;
+
+  G_UNLOCK (g_utils_global);
+
+  return data_dir;
+}
+
+static void
+g_init_user_config_dir (void)
+{
+  gchar *config_dir;
+
+  if (!g_user_config_dir)
+    {
+#ifdef G_OS_WIN32
+      config_dir = get_special_folder (CSIDL_APPDATA);
+#else
+      config_dir = (gchar *) g_getenv ("XDG_CONFIG_HOME");
+
+      if (config_dir && config_dir[0])
+       config_dir = g_strdup (config_dir);
+#endif
+      if (!config_dir || !config_dir[0])
+       {
+         g_get_any_init ();
+
+         if (g_home_dir)
+           config_dir = g_build_filename (g_home_dir, ".config", NULL);
+         else
+           config_dir = g_build_filename (g_tmp_dir, g_user_name, ".config", NULL);
+       }
+
+      g_user_config_dir = config_dir;
+    }
+}
+
+/**
+ * g_get_user_config_dir:
+ * 
+ * Returns a base directory in which to store user-specific application 
+ * configuration information such as user preferences and settings. 
+ *
+ * On UNIX platforms this is determined using the mechanisms described in
+ * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
+ * XDG Base Directory Specification</ulink>.
+ * In this case the directory retrieved will be XDG_CONFIG_HOME.
+ *
+ * On Windows is the directory that serves as a common repository for
+ * application-specific data. A typical path is
+ * C:\Documents and Settings\username\Application. See documentation for
+ * CSIDL_APPDATA.
+ *
+ * Return value: a string owned by GLib that must not be modified 
+ *               or freed.
+ * Since: 2.6
+ **/
+G_CONST_RETURN gchar*
+g_get_user_config_dir (void)
+{
+  G_LOCK (g_utils_global);
+
+  g_init_user_config_dir ();
+
+  G_UNLOCK (g_utils_global);
+
+  return g_user_config_dir;
+}
+
+/**
+ * g_get_user_cache_dir:
+ * 
+ * Returns a base directory in which to store non-essential, cached
+ * data specific to particular user.
+ *
+ * On UNIX platforms this is determined using the mechanisms described in
+ * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
+ * XDG Base Directory Specification</ulink>.
+ * In this case the directory retrieved will be XDG_CACHE_HOME.
+ *
+ * On Windows is the directory that serves as a common repository for
+ * temporary Internet files. A typical path is
+ * C:\Documents and Settings\username\Local Settings\Temporary Internet Files.
+ * See documentation for CSIDL_INTERNET_CACHE.
+ *
+ * Return value: a string owned by GLib that must not be modified 
+ *               or freed.
+ * Since: 2.6
+ **/
+G_CONST_RETURN gchar*
+g_get_user_cache_dir (void)
+{
+  gchar *cache_dir;  
+
+  G_LOCK (g_utils_global);
+
+  if (!g_user_cache_dir)
+    {
+#ifdef G_OS_WIN32
+      cache_dir = get_special_folder (CSIDL_INTERNET_CACHE); /* XXX correct? */
+#else
+      cache_dir = (gchar *) g_getenv ("XDG_CACHE_HOME");
+
+      if (cache_dir && cache_dir[0])
+          cache_dir = g_strdup (cache_dir);
+#endif
+      if (!cache_dir || !cache_dir[0])
+       {
+         g_get_any_init ();
+       
+         if (g_home_dir)
+           cache_dir = g_build_filename (g_home_dir, ".cache", NULL);
+         else
+           cache_dir = g_build_filename (g_tmp_dir, g_user_name, ".cache", NULL);
+       }
+      g_user_cache_dir = cache_dir;
+    }
+  else
+    cache_dir = g_user_cache_dir;
+
+  G_UNLOCK (g_utils_global);
+
+  return cache_dir;
+}
+
+#ifdef HAVE_CARBON
+
+static gchar *
+find_folder (OSType type)
+{
+  gchar *filename = NULL;
+  FSRef  found;
+
+  if (FSFindFolder (kUserDomain, type, kDontCreateFolder, &found) == noErr)
+    {
+      CFURLRef url = CFURLCreateFromFSRef (kCFAllocatorSystemDefault, &found);
+
+      if (url)
+       {
+         CFStringRef path = CFURLCopyFileSystemPath (url, kCFURLPOSIXPathStyle);
+
+         if (path)
+           {
+             filename = g_strdup (CFStringGetCStringPtr (path, kCFStringEncodingUTF8));
+
+             if (! filename)
+               {
+                 filename = g_new0 (gchar, CFStringGetLength (path) * 3 + 1);
+
+                 CFStringGetCString (path, filename,
+                                     CFStringGetLength (path) * 3 + 1,
+                                     kCFStringEncodingUTF8);
+               }
+
+             CFRelease (path);
+           }
+
+         CFRelease (url);
+       }
+    }
+
+  return filename;
+}
+
+static void
+load_user_special_dirs (void)
+{
+  g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = find_folder (kDesktopFolderType);
+  g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = find_folder (kDocumentsFolderType);
+  g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = find_folder (kDesktopFolderType); /* XXX correct ? */
+  g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = find_folder (kMusicDocumentsFolderType);
+  g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = find_folder (kPictureDocumentsFolderType);
+  g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = NULL;
+  g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = NULL;
+  g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = find_folder (kMovieDocumentsFolderType);
+}
+
+#endif /* HAVE_CARBON */
+
+#if defined(G_OS_WIN32)
+static void
+load_user_special_dirs (void)
+{
+  typedef HRESULT (WINAPI *t_SHGetKnownFolderPath) (const GUID *rfid,
+                                                   DWORD dwFlags,
+                                                   HANDLE hToken,
+                                                   PWSTR *ppszPath);
+  t_SHGetKnownFolderPath p_SHGetKnownFolderPath;
+
+  static const GUID FOLDERID_Downloads =
+    { 0x374de290, 0x123f, 0x4565, { 0x91, 0x64, 0x39, 0xc4, 0x92, 0x5e, 0x46, 0x7b } };
+  static const GUID FOLDERID_Public =
+    { 0xDFDF76A2, 0xC82A, 0x4D63, { 0x90, 0x6A, 0x56, 0x44, 0xAC, 0x45, 0x73, 0x85 } };
+
+  wchar_t *wcp;
+
+  p_SHGetKnownFolderPath = (t_SHGetKnownFolderPath) GetProcAddress (GetModuleHandle ("shell32.dll"),
+                                                                   "SHGetKnownFolderPath");
+
+  g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
+  g_user_special_dirs[G_USER_DIRECTORY_DOCUMENTS] = get_special_folder (CSIDL_PERSONAL);
+
+  if (p_SHGetKnownFolderPath == NULL)
+    {
+      g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
+    }
+  else
+    {
+      wcp = NULL;
+      (*p_SHGetKnownFolderPath) (&FOLDERID_Downloads, 0, NULL, &wcp);
+      g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL);
+      if (g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] == NULL)
+       g_user_special_dirs[G_USER_DIRECTORY_DOWNLOAD] = get_special_folder (CSIDL_DESKTOPDIRECTORY);
+      CoTaskMemFree (wcp);
+    }
+
+  g_user_special_dirs[G_USER_DIRECTORY_MUSIC] = get_special_folder (CSIDL_MYMUSIC);
+  g_user_special_dirs[G_USER_DIRECTORY_PICTURES] = get_special_folder (CSIDL_MYPICTURES);
+
+  if (p_SHGetKnownFolderPath == NULL)
+    {
+      /* XXX */
+      g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
+    }
+  else
+    {
+      wcp = NULL;
+      (*p_SHGetKnownFolderPath) (&FOLDERID_Public, 0, NULL, &wcp);
+      g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = g_utf16_to_utf8 (wcp, -1, NULL, NULL, NULL);
+      if (g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] == NULL)
+       g_user_special_dirs[G_USER_DIRECTORY_PUBLIC_SHARE] = get_special_folder (CSIDL_COMMON_DOCUMENTS);
+      CoTaskMemFree (wcp);
+    }
+  
+  g_user_special_dirs[G_USER_DIRECTORY_TEMPLATES] = get_special_folder (CSIDL_TEMPLATES);
+  g_user_special_dirs[G_USER_DIRECTORY_VIDEOS] = get_special_folder (CSIDL_MYVIDEO);
+}
+#endif /* G_OS_WIN32 */
+
+static void g_init_user_config_dir (void);
+
+#if defined(G_OS_UNIX) && !defined(HAVE_CARBON)
+
+/* adapted from xdg-user-dir-lookup.c
+ *
+ * Copyright (C) 2007 Red Hat Inc.
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions: 
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software. 
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+static void
+load_user_special_dirs (void)
+{
+  gchar *config_file;
+  gchar *data;
+  gchar **lines;
+  gint n_lines, i;
+  
+  g_init_user_config_dir ();
+  config_file = g_build_filename (g_user_config_dir,
+                                  "user-dirs.dirs",
+                                  NULL);
+  
+  if (!g_file_get_contents (config_file, &data, NULL, NULL))
+    {
+      g_free (config_file);
+      return;
+    }
+
+  lines = g_strsplit (data, "\n", -1);
+  n_lines = g_strv_length (lines);
+  g_free (data);
+  
+  for (i = 0; i < n_lines; i++)
+    {
+      gchar *buffer = lines[i];
+      gchar *d, *p;
+      gint len;
+      gboolean is_relative = FALSE;
+      GUserDirectory directory;
+
+      /* Remove newline at end */
+      len = strlen (buffer);
+      if (len > 0 && buffer[len - 1] == '\n')
+       buffer[len - 1] = 0;
+      
+      p = buffer;
+      while (*p == ' ' || *p == '\t')
+       p++;
+      
+      if (strncmp (p, "XDG_DESKTOP_DIR", strlen ("XDG_DESKTOP_DIR")) == 0)
+        {
+          directory = G_USER_DIRECTORY_DESKTOP;
+          p += strlen ("XDG_DESKTOP_DIR");
+        }
+      else if (strncmp (p, "XDG_DOCUMENTS_DIR", strlen ("XDG_DOCUMENTS_DIR")) == 0)
+        {
+          directory = G_USER_DIRECTORY_DOCUMENTS;
+          p += strlen ("XDG_DOCUMENTS_DIR");
+        }
+      else if (strncmp (p, "XDG_DOWNLOAD_DIR", strlen ("XDG_DOWNLOAD_DIR")) == 0)
+        {
+          directory = G_USER_DIRECTORY_DOWNLOAD;
+          p += strlen ("XDG_DOWNLOAD_DIR");
+        }
+      else if (strncmp (p, "XDG_MUSIC_DIR", strlen ("XDG_MUSIC_DIR")) == 0)
+        {
+          directory = G_USER_DIRECTORY_MUSIC;
+          p += strlen ("XDG_MUSIC_DIR");
+        }
+      else if (strncmp (p, "XDG_PICTURES_DIR", strlen ("XDG_PICTURES_DIR")) == 0)
+        {
+          directory = G_USER_DIRECTORY_PICTURES;
+          p += strlen ("XDG_PICTURES_DIR");
+        }
+      else if (strncmp (p, "XDG_PUBLICSHARE_DIR", strlen ("XDG_PUBLICSHARE_DIR")) == 0)
+        {
+          directory = G_USER_DIRECTORY_PUBLIC_SHARE;
+          p += strlen ("XDG_PUBLICSHARE_DIR");
+        }
+      else if (strncmp (p, "XDG_TEMPLATES_DIR", strlen ("XDG_TEMPLATES_DIR")) == 0)
+        {
+          directory = G_USER_DIRECTORY_TEMPLATES;
+          p += strlen ("XDG_TEMPLATES_DIR");
+        }
+      else if (strncmp (p, "XDG_VIDEOS_DIR", strlen ("XDG_VIDEOS_DIR")) == 0)
+        {
+          directory = G_USER_DIRECTORY_VIDEOS;
+          p += strlen ("XDG_VIDEOS_DIR");
+        }
+      else
+       continue;
+
+      while (*p == ' ' || *p == '\t')
+       p++;
+
+      if (*p != '=')
+       continue;
+      p++;
+
+      while (*p == ' ' || *p == '\t')
+       p++;
+
+      if (*p != '"')
+       continue;
+      p++;
+
+      if (strncmp (p, "$HOME", 5) == 0)
+       {
+         p += 5;
+         is_relative = TRUE;
+       }
+      else if (*p != '/')
+       continue;
+
+      d = strrchr (p, '"');
+      if (!d)
+        continue;
+      *d = 0;
+
+      d = p;
+      
+      /* remove trailing slashes */
+      len = strlen (d);
+      if (d[len - 1] == '/')
+        d[len - 1] = 0;
+      
+      if (is_relative)
+        {
+          g_get_any_init ();
+          g_user_special_dirs[directory] = g_build_filename (g_home_dir, d, NULL);
+        }
+      else
+       g_user_special_dirs[directory] = g_strdup (d);
+    }
+
+  g_strfreev (lines);
+  g_free (config_file);
+}
+
+#endif /* G_OS_UNIX && !HAVE_CARBON */
+
+
+/**
+ * g_reload_user_special_dirs_cache:
+ *
+ * Resets the cache used for g_get_user_special_dir(), so
+ * that the latest on-disk version is used. Call this only
+ * if you just changed the data on disk yourself.
+ *
+ * Due to threadsafety issues this may cause leaking of strings
+ * that were previously returned from g_get_user_special_dir()
+ * that can't be freed. We ensure to only leak the data for
+ * the directories that actually changed value though.
+ *
+ * Since: 2.22
+ */
+void
+g_reload_user_special_dirs_cache (void)
+{
+  int i;
+
+  G_LOCK (g_utils_global);
+
+  if (g_user_special_dirs != NULL)
+    {
+      /* save a copy of the pointer, to check if some memory can be preserved */
+      char **old_g_user_special_dirs = g_user_special_dirs;
+      char *old_val;
+
+      /* recreate and reload our cache */
+      g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES);
+      load_user_special_dirs ();
+
+      /* only leak changed directories */
+      for (i = 0; i < G_USER_N_DIRECTORIES; i++)
+        {
+         old_val = old_g_user_special_dirs[i];
+         if (g_strcmp0 (old_val, g_user_special_dirs[i]) == 0)
+            {
+             /* don't leak */
+             g_free (g_user_special_dirs[i]);
+             g_user_special_dirs[i] = old_val;
+            }
+         else
+            g_free (old_val);
+        }
+
+      /* free the old array */
+      g_free (old_g_user_special_dirs);
+    }
+
+  G_UNLOCK (g_utils_global);
+}
+
+/**
+ * g_get_user_special_dir:
+ * @directory: the logical id of special directory
+ *
+ * Returns the full path of a special directory using its logical id.
+ *
+ * On Unix this is done using the XDG special user directories.
+ * For compatibility with existing practise, %G_USER_DIRECTORY_DESKTOP
+ * falls back to <filename>$HOME/Desktop</filename> when XDG special
+ * user directories have not been set up. 
+ *
+ * Depending on the platform, the user might be able to change the path
+ * of the special directory without requiring the session to restart; GLib
+ * will not reflect any change once the special directories are loaded.
+ *
+ * Return value: the path to the specified special directory, or %NULL
+ *   if the logical id was not found. The returned string is owned by
+ *   GLib and should not be modified or freed.
+ *
+ * Since: 2.14
+ */
+G_CONST_RETURN gchar *
+g_get_user_special_dir (GUserDirectory directory)
+{
+  g_return_val_if_fail (directory >= G_USER_DIRECTORY_DESKTOP &&
+                        directory < G_USER_N_DIRECTORIES, NULL);
+
+  G_LOCK (g_utils_global);
+
+  if (G_UNLIKELY (g_user_special_dirs == NULL))
+    {
+      g_user_special_dirs = g_new0 (gchar *, G_USER_N_DIRECTORIES);
+
+      load_user_special_dirs ();
+
+      /* Special-case desktop for historical compatibility */
+      if (g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] == NULL)
+        {
+          g_get_any_init ();
+
+          g_user_special_dirs[G_USER_DIRECTORY_DESKTOP] =
+            g_build_filename (g_home_dir, "Desktop", NULL);
+        }
+    }
+
+  G_UNLOCK (g_utils_global);
+
+  return g_user_special_dirs[directory];
+}
+
+#ifdef G_OS_WIN32
+
+#undef g_get_system_data_dirs
+
+static HMODULE
+get_module_for_address (gconstpointer address)
+{
+  /* Holds the g_utils_global lock */
+
+  static gboolean beenhere = FALSE;
+  typedef BOOL (WINAPI *t_GetModuleHandleExA) (DWORD, LPCTSTR, HMODULE *);
+  static t_GetModuleHandleExA p_GetModuleHandleExA = NULL;
+  HMODULE hmodule = NULL;
+
+  if (!address)
+    return NULL;
+
+  if (!beenhere)
+    {
+      p_GetModuleHandleExA =
+       (t_GetModuleHandleExA) GetProcAddress (GetModuleHandle ("kernel32.dll"),
+                                              "GetModuleHandleExA");
+      beenhere = TRUE;
+    }
+
+  if (p_GetModuleHandleExA == NULL ||
+      !(*p_GetModuleHandleExA) (GET_MODULE_HANDLE_EX_FLAG_UNCHANGED_REFCOUNT |
+                               GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS,
+                               address, &hmodule))
+    {
+      MEMORY_BASIC_INFORMATION mbi;
+      VirtualQuery (address, &mbi, sizeof (mbi));
+      hmodule = (HMODULE) mbi.AllocationBase;
+    }
+
+  return hmodule;
+}
+
+static gchar *
+get_module_share_dir (gconstpointer address)
+{
+  HMODULE hmodule;
+  gchar *filename;
+  gchar *retval;
+
+  hmodule = get_module_for_address (address);
+  if (hmodule == NULL)
+    return NULL;
+
+  filename = g_win32_get_package_installation_directory_of_module (hmodule);
+  retval = g_build_filename (filename, "share", NULL);
+  g_free (filename);
+
+  return retval;
+}
+
+G_CONST_RETURN gchar * G_CONST_RETURN *
+g_win32_get_system_data_dirs_for_module (void (*address_of_function)())
+{
+  GArray *data_dirs;
+  HMODULE hmodule;
+  static GHashTable *per_module_data_dirs = NULL;
+  gchar **retval;
+  gchar *p;
+  gchar *exe_root;
+      
+  if (address_of_function)
+    {
+      G_LOCK (g_utils_global);
+      hmodule = get_module_for_address (address_of_function);
+      if (hmodule != NULL)
+       {
+         if (per_module_data_dirs == NULL)
+           per_module_data_dirs = g_hash_table_new (NULL, NULL);
+         else
+           {
+             retval = g_hash_table_lookup (per_module_data_dirs, hmodule);
+             
+             if (retval != NULL)
+               {
+                 G_UNLOCK (g_utils_global);
+                 return (G_CONST_RETURN gchar * G_CONST_RETURN *) retval;
+               }
+           }
+       }
+    }
+
+  data_dirs = g_array_new (TRUE, TRUE, sizeof (char *));
+
+  /* Documents and Settings\All Users\Application Data */
+  p = get_special_folder (CSIDL_COMMON_APPDATA);
+  if (p)
+    g_array_append_val (data_dirs, p);
+  
+  /* Documents and Settings\All Users\Documents */
+  p = get_special_folder (CSIDL_COMMON_DOCUMENTS);
+  if (p)
+    g_array_append_val (data_dirs, p);
+       
+  /* Using the above subfolders of Documents and Settings perhaps
+   * makes sense from a Windows perspective.
+   *
+   * But looking at the actual use cases of this function in GTK+
+   * and GNOME software, what we really want is the "share"
+   * subdirectory of the installation directory for the package
+   * our caller is a part of.
+   *
+   * The address_of_function parameter, if non-NULL, points to a
+   * function in the calling module. Use that to determine that
+   * module's installation folder, and use its "share" subfolder.
+   *
+   * Additionally, also use the "share" subfolder of the installation
+   * locations of GLib and the .exe file being run.
+   *
+   * To guard against none of the above being what is really wanted,
+   * callers of this function should have Win32-specific code to look
+   * up their installation folder themselves, and handle a subfolder
+   * "share" of it in the same way as the folders returned from this
+   * function.
+   */
+
+  p = get_module_share_dir (address_of_function);
+  if (p)
+    g_array_append_val (data_dirs, p);
+    
+  if (glib_dll != NULL)
+    {
+      gchar *glib_root = g_win32_get_package_installation_directory_of_module (glib_dll);
+      p = g_build_filename (glib_root, "share", NULL);
+      if (p)
+       g_array_append_val (data_dirs, p);
+      g_free (glib_root);
+    }
+  
+  exe_root = g_win32_get_package_installation_directory_of_module (NULL);
+  p = g_build_filename (exe_root, "share", NULL);
+  if (p)
+    g_array_append_val (data_dirs, p);
+  g_free (exe_root);
+
+  retval = (gchar **) g_array_free (data_dirs, FALSE);
+
+  if (address_of_function)
+    {
+      if (hmodule != NULL)
+       g_hash_table_insert (per_module_data_dirs, hmodule, retval);
+      G_UNLOCK (g_utils_global);
+    }
+
+  return (G_CONST_RETURN gchar * G_CONST_RETURN *) retval;
+}
+
+#endif
+
+/**
+ * g_get_system_data_dirs:
+ * 
+ * Returns an ordered list of base directories in which to access 
+ * system-wide application data.
+ *
+ * On UNIX platforms this is determined using the mechanisms described in
+ * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
+ * XDG Base Directory Specification</ulink>
+ * In this case the list of directories retrieved will be XDG_DATA_DIRS.
+ *
+ * On Windows the first elements in the list are the Application Data
+ * and Documents folders for All Users. (These can be determined only
+ * on Windows 2000 or later and are not present in the list on other
+ * Windows versions.) See documentation for CSIDL_COMMON_APPDATA and
+ * CSIDL_COMMON_DOCUMENTS.
+ *
+ * Then follows the "share" subfolder in the installation folder for
+ * the package containing the DLL that calls this function, if it can
+ * be determined.
+ * 
+ * Finally the list contains the "share" subfolder in the installation
+ * folder for GLib, and in the installation folder for the package the
+ * application's .exe file belongs to.
+ *
+ * The installation folders above are determined by looking up the
+ * folder where the module (DLL or EXE) in question is located. If the
+ * folder's name is "bin", its parent is used, otherwise the folder
+ * itself.
+ *
+ * Note that on Windows the returned list can vary depending on where
+ * this function is called.
+ *
+ * Return value: a %NULL-terminated array of strings owned by GLib that must 
+ *               not be modified or freed.
+ * Since: 2.6
+ **/
+G_CONST_RETURN gchar * G_CONST_RETURN * 
+g_get_system_data_dirs (void)
+{
+  gchar **data_dir_vector;
+
+  G_LOCK (g_utils_global);
+
+  if (!g_system_data_dirs)
+    {
+#ifdef G_OS_WIN32
+      data_dir_vector = (gchar **) g_win32_get_system_data_dirs_for_module (NULL);
+#else
+      gchar *data_dirs = (gchar *) g_getenv ("XDG_DATA_DIRS");
+
+      if (!data_dirs || !data_dirs[0])
+          data_dirs = "/usr/local/share/:/usr/share/";
+
+      data_dir_vector = g_strsplit (data_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
+#endif
+
+      g_system_data_dirs = data_dir_vector;
+    }
+  else
+    data_dir_vector = g_system_data_dirs;
+
+  G_UNLOCK (g_utils_global);
+
+  return (G_CONST_RETURN gchar * G_CONST_RETURN *) data_dir_vector;
+}
+
+/**
+ * g_get_system_config_dirs:
+ * 
+ * Returns an ordered list of base directories in which to access 
+ * system-wide configuration information.
+ *
+ * On UNIX platforms this is determined using the mechanisms described in
+ * the <ulink url="http://www.freedesktop.org/Standards/basedir-spec">
+ * XDG Base Directory Specification</ulink>.
+ * In this case the list of directories retrieved will be XDG_CONFIG_DIRS.
+ *
+ * On Windows is the directory that contains application data for all users.
+ * A typical path is C:\Documents and Settings\All Users\Application Data.
+ * This folder is used for application data that is not user specific.
+ * For example, an application can store a spell-check dictionary, a database
+ * of clip art, or a log file in the CSIDL_COMMON_APPDATA folder.
+ * This information will not roam and is available to anyone using the computer.
+ *
+ * Return value: a %NULL-terminated array of strings owned by GLib that must 
+ *               not be modified or freed.
+ * Since: 2.6
+ **/
+G_CONST_RETURN gchar * G_CONST_RETURN *
+g_get_system_config_dirs (void)
+{
+  gchar *conf_dirs, **conf_dir_vector;
+
+  G_LOCK (g_utils_global);
+
+  if (!g_system_config_dirs)
+    {
+#ifdef G_OS_WIN32
+      conf_dirs = get_special_folder (CSIDL_COMMON_APPDATA);
+      if (conf_dirs)
+       {
+         conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
+         g_free (conf_dirs);
+       }
+      else
+       {
+         /* Return empty list */
+         conf_dir_vector = g_strsplit ("", G_SEARCHPATH_SEPARATOR_S, 0);
+       }
+#else
+      conf_dirs = (gchar *) g_getenv ("XDG_CONFIG_DIRS");
+
+      if (!conf_dirs || !conf_dirs[0])
+          conf_dirs = "/etc/xdg";
+
+      conf_dir_vector = g_strsplit (conf_dirs, G_SEARCHPATH_SEPARATOR_S, 0);
+#endif
+
+      g_system_config_dirs = conf_dir_vector;
+    }
+  else
+    conf_dir_vector = g_system_config_dirs;
+  G_UNLOCK (g_utils_global);
+
+  return (G_CONST_RETURN gchar * G_CONST_RETURN *) conf_dir_vector;
+}
+
+#ifndef G_OS_WIN32
+
+static GHashTable *alias_table = NULL;
+
+/* read an alias file for the locales */
+static void
+read_aliases (gchar *file)
+{
+  FILE *fp;
+  char buf[256];
+  
+  if (!alias_table)
+    alias_table = g_hash_table_new (g_str_hash, g_str_equal);
+  fp = fopen (file,"r");
+  if (!fp)
+    return;
+  while (fgets (buf, 256, fp))
+    {
+      char *p, *q;
+
+      g_strstrip (buf);
+
+      /* Line is a comment */
+      if ((buf[0] == '#') || (buf[0] == '\0'))
+       continue;
+
+      /* Reads first column */
+      for (p = buf, q = NULL; *p; p++) {
+       if ((*p == '\t') || (*p == ' ') || (*p == ':')) {
+         *p = '\0';
+         q = p+1;
+         while ((*q == '\t') || (*q == ' ')) {
+           q++;
+         }
+         break;
+       }
+      }
+      /* The line only had one column */
+      if (!q || *q == '\0')
+       continue;
+      
+      /* Read second column */
+      for (p = q; *p; p++) {
+       if ((*p == '\t') || (*p == ' ')) {
+         *p = '\0';
+         break;
+       }
+      }
+
+      /* Add to alias table if necessary */
+      if (!g_hash_table_lookup (alias_table, buf)) {
+       g_hash_table_insert (alias_table, g_strdup (buf), g_strdup (q));
+      }
+    }
+  fclose (fp);
+}
+
+#endif
+
+static char *
+unalias_lang (char *lang)
+{
+#ifndef G_OS_WIN32
+  char *p;
+  int i;
+
+  if (!alias_table)
+    read_aliases ("/usr/share/locale/locale.alias");
+
+  i = 0;
+  while ((p = g_hash_table_lookup (alias_table, lang)) && (strcmp (p, lang) != 0))
+    {
+      lang = p;
+      if (i++ == 30)
+        {
+          static gboolean said_before = FALSE;
+         if (!said_before)
+            g_warning ("Too many alias levels for a locale, "
+                      "may indicate a loop");
+         said_before = TRUE;
+         return lang;
+       }
+    }
+#endif
+  return lang;
+}
+
+/* Mask for components of locale spec. The ordering here is from
+ * least significant to most significant
+ */
+enum
+{
+  COMPONENT_CODESET =   1 << 0,
+  COMPONENT_TERRITORY = 1 << 1,
+  COMPONENT_MODIFIER =  1 << 2
+};
+
+/* Break an X/Open style locale specification into components
+ */
+static guint
+explode_locale (const gchar *locale,
+               gchar      **language, 
+               gchar      **territory, 
+               gchar      **codeset, 
+               gchar      **modifier)
+{
+  const gchar *uscore_pos;
+  const gchar *at_pos;
+  const gchar *dot_pos;
+
+  guint mask = 0;
+
+  uscore_pos = strchr (locale, '_');
+  dot_pos = strchr (uscore_pos ? uscore_pos : locale, '.');
+  at_pos = strchr (dot_pos ? dot_pos : (uscore_pos ? uscore_pos : locale), '@');
+
+  if (at_pos)
+    {
+      mask |= COMPONENT_MODIFIER;
+      *modifier = g_strdup (at_pos);
+    }
+  else
+    at_pos = locale + strlen (locale);
+
+  if (dot_pos)
+    {
+      mask |= COMPONENT_CODESET;
+      *codeset = g_strndup (dot_pos, at_pos - dot_pos);
+    }
+  else
+    dot_pos = at_pos;
+
+  if (uscore_pos)
+    {
+      mask |= COMPONENT_TERRITORY;
+      *territory = g_strndup (uscore_pos, dot_pos - uscore_pos);
+    }
+  else
+    uscore_pos = dot_pos;
+
+  *language = g_strndup (locale, uscore_pos - locale);
+
+  return mask;
+}
+
+/*
+ * Compute all interesting variants for a given locale name -
+ * by stripping off different components of the value.
+ *
+ * For simplicity, we assume that the locale is in
+ * X/Open format: language[_territory][.codeset][@modifier]
+ *
+ * TODO: Extend this to handle the CEN format (see the GNUlibc docs)
+ *       as well. We could just copy the code from glibc wholesale
+ *       but it is big, ugly, and complicated, so I'm reluctant
+ *       to do so when this should handle 99% of the time...
+ */
+GSList *
+_g_compute_locale_variants (const gchar *locale)
+{
+  GSList *retval = NULL;
+
+  gchar *language = NULL;
+  gchar *territory = NULL;
+  gchar *codeset = NULL;
+  gchar *modifier = NULL;
+
+  guint mask;
+  guint i;
+
+  g_return_val_if_fail (locale != NULL, NULL);
+
+  mask = explode_locale (locale, &language, &territory, &codeset, &modifier);
+
+  /* Iterate through all possible combinations, from least attractive
+   * to most attractive.
+   */
+  for (i = 0; i <= mask; i++)
+    if ((i & ~mask) == 0)
+      {
+       gchar *val = g_strconcat (language,
+                                 (i & COMPONENT_TERRITORY) ? territory : "",
+                                 (i & COMPONENT_CODESET) ? codeset : "",
+                                 (i & COMPONENT_MODIFIER) ? modifier : "",
+                                 NULL);
+       retval = g_slist_prepend (retval, val);
+      }
+
+  g_free (language);
+  if (mask & COMPONENT_CODESET)
+    g_free (codeset);
+  if (mask & COMPONENT_TERRITORY)
+    g_free (territory);
+  if (mask & COMPONENT_MODIFIER)
+    g_free (modifier);
+
+  return retval;
+}
+
+/* The following is (partly) taken from the gettext package.
+   Copyright (C) 1995, 1996, 1997, 1998 Free Software Foundation, Inc.  */
+
+static const gchar *
+guess_category_value (const gchar *category_name)
+{
+  const gchar *retval;
+
+  /* The highest priority value is the `LANGUAGE' environment
+     variable.  This is a GNU extension.  */
+  retval = g_getenv ("LANGUAGE");
+  if ((retval != NULL) && (retval[0] != '\0'))
+    return retval;
+
+  /* `LANGUAGE' is not set.  So we have to proceed with the POSIX
+     methods of looking to `LC_ALL', `LC_xxx', and `LANG'.  On some
+     systems this can be done by the `setlocale' function itself.  */
+
+  /* Setting of LC_ALL overwrites all other.  */
+  retval = g_getenv ("LC_ALL");  
+  if ((retval != NULL) && (retval[0] != '\0'))
+    return retval;
+
+  /* Next comes the name of the desired category.  */
+  retval = g_getenv (category_name);
+  if ((retval != NULL) && (retval[0] != '\0'))
+    return retval;
+
+  /* Last possibility is the LANG environment variable.  */
+  retval = g_getenv ("LANG");
+  if ((retval != NULL) && (retval[0] != '\0'))
+    return retval;
+
+#ifdef G_PLATFORM_WIN32
+  /* g_win32_getlocale() first checks for LC_ALL, LC_MESSAGES and
+   * LANG, which we already did above. Oh well. The main point of
+   * calling g_win32_getlocale() is to get the thread's locale as used
+   * by Windows and the Microsoft C runtime (in the "English_United
+   * States" format) translated into the Unixish format.
+   */
+  {
+    char *locale = g_win32_getlocale ();
+    retval = g_intern_string (locale);
+    g_free (locale);
+    return retval;
+  }
+#endif  
+
+  return NULL;
+}
+
+typedef struct _GLanguageNamesCache GLanguageNamesCache;
+
+struct _GLanguageNamesCache {
+  gchar *languages;
+  gchar **language_names;
+};
+
+static void
+language_names_cache_free (gpointer data)
+{
+  GLanguageNamesCache *cache = data;
+  g_free (cache->languages);
+  g_strfreev (cache->language_names);
+  g_free (cache);
+}
+
+/**
+ * g_get_language_names:
+ * 
+ * Computes a list of applicable locale names, which can be used to 
+ * e.g. construct locale-dependent filenames or search paths. The returned 
+ * list is sorted from most desirable to least desirable and always contains 
+ * the default locale "C".
+ *
+ * For example, if LANGUAGE=de:en_US, then the returned list is
+ * "de", "en_US", "en", "C".
+ *
+ * This function consults the environment variables <envar>LANGUAGE</envar>, 
+ * <envar>LC_ALL</envar>, <envar>LC_MESSAGES</envar> and <envar>LANG</envar> 
+ * to find the list of locales specified by the user.
+ * 
+ * Return value: a %NULL-terminated array of strings owned by GLib 
+ *    that must not be modified or freed.
+ *
+ * Since: 2.6
+ **/
+G_CONST_RETURN gchar * G_CONST_RETURN * 
+g_get_language_names (void)
+{
+  static GStaticPrivate cache_private = G_STATIC_PRIVATE_INIT;
+  GLanguageNamesCache *cache = g_static_private_get (&cache_private);
+  const gchar *value;
+
+  if (!cache)
+    {
+      cache = g_new0 (GLanguageNamesCache, 1);
+      g_static_private_set (&cache_private, cache, language_names_cache_free);
+    }
+
+  value = guess_category_value ("LC_MESSAGES");
+  if (!value)
+    value = "C";
+
+  if (!(cache->languages && strcmp (cache->languages, value) == 0))
+    {
+      gchar **languages;
+      gchar **alist, **a;
+      GSList *list, *l;
+      gint i;
+
+      g_free (cache->languages);
+      g_strfreev (cache->language_names);
+      cache->languages = g_strdup (value);
+
+      alist = g_strsplit (value, ":", 0);
+      list = NULL;
+      for (a = alist; *a; a++)
+       {
+         gchar *b = unalias_lang (*a);
+         list = g_slist_concat (list, _g_compute_locale_variants (b));
+       }
+      g_strfreev (alist);
+      list = g_slist_append (list, g_strdup ("C"));
+
+      cache->language_names = languages = g_new (gchar *, g_slist_length (list) + 1);
+      for (l = list, i = 0; l; l = l->next, i++)
+       languages[i] = l->data;
+      languages[i] = NULL;
+
+      g_slist_free (list);
+    }
+
+  return (G_CONST_RETURN gchar * G_CONST_RETURN *) cache->language_names;
+}
+
+/**
+ * g_direct_hash:
+ * @v: a #gpointer key
+ *
+ * Converts a gpointer to a hash value.
+ * It can be passed to g_hash_table_new() as the @hash_func parameter, 
+ * when using pointers as keys in a #GHashTable.
+ *
+ * Returns: a hash value corresponding to the key.
+ */
+guint
+g_direct_hash (gconstpointer v)
+{
+  return GPOINTER_TO_UINT (v);
+}
+
+/**
+ * g_direct_equal:
+ * @v1: a key.
+ * @v2: a key to compare with @v1.
+ *
+ * Compares two #gpointer arguments and returns %TRUE if they are equal.
+ * It can be passed to g_hash_table_new() as the @key_equal_func
+ * parameter, when using pointers as keys in a #GHashTable.
+ * 
+ * Returns: %TRUE if the two keys match.
+ */
+gboolean
+g_direct_equal (gconstpointer v1,
+               gconstpointer v2)
+{
+  return v1 == v2;
+}
+
+/**
+ * g_int_equal:
+ * @v1: a pointer to a #gint key.
+ * @v2: a pointer to a #gint key to compare with @v1.
+ *
+ * Compares the two #gint values being pointed to and returns 
+ * %TRUE if they are equal.
+ * It can be passed to g_hash_table_new() as the @key_equal_func
+ * parameter, when using pointers to integers as keys in a #GHashTable.
+ * 
+ * Returns: %TRUE if the two keys match.
+ */
+gboolean
+g_int_equal (gconstpointer v1,
+            gconstpointer v2)
+{
+  return *((const gint*) v1) == *((const gint*) v2);
+}
+
+/**
+ * g_int_hash:
+ * @v: a pointer to a #gint key
+ *
+ * Converts a pointer to a #gint to a hash value.
+ * It can be passed to g_hash_table_new() as the @hash_func parameter, 
+ * when using pointers to integers values as keys in a #GHashTable.
+ *
+ * Returns: a hash value corresponding to the key.
+ */
+guint
+g_int_hash (gconstpointer v)
+{
+  return *(const gint*) v;
+}
+
+/**
+ * g_int64_equal:
+ * @v1: a pointer to a #gint64 key.
+ * @v2: a pointer to a #gint64 key to compare with @v1.
+ *
+ * Compares the two #gint64 values being pointed to and returns 
+ * %TRUE if they are equal.
+ * It can be passed to g_hash_table_new() as the @key_equal_func
+ * parameter, when using pointers to 64-bit integers as keys in a #GHashTable.
+ * 
+ * Returns: %TRUE if the two keys match.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_int64_equal (gconstpointer v1,
+               gconstpointer v2)
+{
+  return *((const gint64*) v1) == *((const gint64*) v2);
+}
+
+/**
+ * g_int64_hash:
+ * @v: a pointer to a #gint64 key
+ *
+ * Converts a pointer to a #gint64 to a hash value.
+ * It can be passed to g_hash_table_new() as the @hash_func parameter, 
+ * when using pointers to 64-bit integers values as keys in a #GHashTable.
+ *
+ * Returns: a hash value corresponding to the key.
+ *
+ * Since: 2.22
+ */
+guint
+g_int64_hash (gconstpointer v)
+{
+  return (guint) *(const gint64*) v;
+}
+
+/**
+ * g_double_equal:
+ * @v1: a pointer to a #gdouble key.
+ * @v2: a pointer to a #gdouble key to compare with @v1.
+ *
+ * Compares the two #gdouble values being pointed to and returns 
+ * %TRUE if they are equal.
+ * It can be passed to g_hash_table_new() as the @key_equal_func
+ * parameter, when using pointers to doubles as keys in a #GHashTable.
+ * 
+ * Returns: %TRUE if the two keys match.
+ *
+ * Since: 2.22
+ */
+gboolean
+g_double_equal (gconstpointer v1,
+                gconstpointer v2)
+{
+  return *((const gdouble*) v1) == *((const gdouble*) v2);
+}
+
+/**
+ * g_double_hash:
+ * @v: a pointer to a #gdouble key
+ *
+ * Converts a pointer to a #gdouble to a hash value.
+ * It can be passed to g_hash_table_new() as the @hash_func parameter, 
+ * when using pointers to doubles as keys in a #GHashTable.
+ *
+ * Returns: a hash value corresponding to the key.
+ *
+ * Since: 2.22
+ */
+guint
+g_double_hash (gconstpointer v)
+{
+  return (guint) *(const gdouble*) v;
+}
+
+/**
+ * g_nullify_pointer:
+ * @nullify_location: the memory address of the pointer.
+ * 
+ * Set the pointer at the specified location to %NULL.
+ **/
+void
+g_nullify_pointer (gpointer *nullify_location)
+{
+  g_return_if_fail (nullify_location != NULL);
+
+  *nullify_location = NULL;
+}
+
+/**
+ * g_get_codeset:
+ * 
+ * Get the codeset for the current locale.
+ * 
+ * Return value: a newly allocated string containing the name
+ * of the codeset. This string must be freed with g_free().
+ **/
+gchar *
+g_get_codeset (void)
+{
+  const gchar *charset;
+
+  g_get_charset (&charset);
+
+  return g_strdup (charset);
+}
+
+/* This is called from g_thread_init(). It's used to
+ * initialize some static data in a threadsafe way.
+ */
+void
+_g_utils_thread_init (void)
+{
+  g_get_language_names ();
+}
+
+#ifdef G_OS_WIN32
+
+/**
+ * _glib_get_locale_dir:
+ *
+ * Return the path to the share\locale or lib\locale subfolder of the
+ * GLib installation folder. The path is in the system codepage. We
+ * have to use system codepage as bindtextdomain() doesn't have a
+ * UTF-8 interface.
+ */
+static gchar *
+_glib_get_locale_dir (void)
+{
+  gchar *install_dir = NULL, *locale_dir;
+  gchar *retval = NULL;
+
+  if (glib_dll != NULL)
+    install_dir = g_win32_get_package_installation_directory_of_module (glib_dll);
+
+  if (install_dir)
+    {
+      /*
+       * Append "/share/locale" or "/lib/locale" depending on whether
+       * autoconfigury detected GNU gettext or not.
+       */
+      const char *p = GLIB_LOCALE_DIR + strlen (GLIB_LOCALE_DIR);
+      while (*--p != '/')
+       ;
+      while (*--p != '/')
+       ;
+
+      locale_dir = g_build_filename (install_dir, p, NULL);
+
+      retval = g_win32_locale_filename_from_utf8 (locale_dir);
+
+      g_free (install_dir);
+      g_free (locale_dir);
+    }
+
+  if (retval)
+    return retval;
+  else
+    return g_strdup ("");
+}
+
+#undef GLIB_LOCALE_DIR
+
+#endif /* G_OS_WIN32 */
+
+/**
+ * glib_gettext:
+ * @str: The string to be translated
+ *
+ * Returns the translated string from the glib translations.
+ * This is an internal function and should only be used by
+ * the internals of glib (such as libgio).
+ *
+ * Returns: the transation of @str to the current locale
+ */
+G_CONST_RETURN gchar *
+glib_gettext (const gchar *str)
+{
+  static gboolean _glib_gettext_initialized = FALSE;
+
+  if (!_glib_gettext_initialized)
+    {
+#ifdef G_OS_WIN32
+      gchar *tmp = _glib_get_locale_dir ();
+      bindtextdomain (GETTEXT_PACKAGE, tmp);
+      g_free (tmp);
+#else
+      bindtextdomain (GETTEXT_PACKAGE, GLIB_LOCALE_DIR);
+#endif
+#    ifdef HAVE_BIND_TEXTDOMAIN_CODESET
+      bind_textdomain_codeset (GETTEXT_PACKAGE, "UTF-8");
+#    endif
+      _glib_gettext_initialized = TRUE;
+    }
+  
+  return g_dgettext (GETTEXT_PACKAGE, str);
+}
+
+#if defined (G_OS_WIN32) && !defined (_WIN64)
+
+/* Binary compatibility versions. Not for newly compiled code. */
+
+#undef g_find_program_in_path
+
+gchar*
+g_find_program_in_path (const gchar *program)
+{
+  gchar *utf8_program = g_locale_to_utf8 (program, -1, NULL, NULL, NULL);
+  gchar *utf8_retval = g_find_program_in_path_utf8 (utf8_program);
+  gchar *retval;
+
+  g_free (utf8_program);
+  if (utf8_retval == NULL)
+    return NULL;
+  retval = g_locale_from_utf8 (utf8_retval, -1, NULL, NULL, NULL);
+  g_free (utf8_retval);
+
+  return retval;
+}
+
+#undef g_get_current_dir
+
+gchar*
+g_get_current_dir (void)
+{
+  gchar *utf8_dir = g_get_current_dir_utf8 ();
+  gchar *dir = g_locale_from_utf8 (utf8_dir, -1, NULL, NULL, NULL);
+  g_free (utf8_dir);
+  return dir;
+}
+
+#undef g_getenv
+
+G_CONST_RETURN gchar*
+g_getenv (const gchar *variable)
+{
+  gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL);
+  const gchar *utf8_value = g_getenv_utf8 (utf8_variable);
+  gchar *value;
+  GQuark quark;
+
+  g_free (utf8_variable);
+  if (!utf8_value)
+    return NULL;
+  value = g_locale_from_utf8 (utf8_value, -1, NULL, NULL, NULL);
+  quark = g_quark_from_string (value);
+  g_free (value);
+
+  return g_quark_to_string (quark);
+}
+
+#undef g_setenv
+
+gboolean
+g_setenv (const gchar *variable, 
+         const gchar *value, 
+         gboolean     overwrite)
+{
+  gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL);
+  gchar *utf8_value = g_locale_to_utf8 (value, -1, NULL, NULL, NULL);
+  gboolean retval = g_setenv_utf8 (utf8_variable, utf8_value, overwrite);
+
+  g_free (utf8_variable);
+  g_free (utf8_value);
+
+  return retval;
+}
+
+#undef g_unsetenv
+
+void
+g_unsetenv (const gchar *variable)
+{
+  gchar *utf8_variable = g_locale_to_utf8 (variable, -1, NULL, NULL, NULL);
+
+  g_unsetenv_utf8 (utf8_variable);
+
+  g_free (utf8_variable);
+}
+
+#undef g_get_user_name
+
+G_CONST_RETURN gchar*
+g_get_user_name (void)
+{
+  g_get_any_init_locked ();
+  return g_user_name_cp;
+}
+
+#undef g_get_real_name
+
+G_CONST_RETURN gchar*
+g_get_real_name (void)
+{
+  g_get_any_init_locked ();
+  return g_real_name_cp;
+}
+
+#undef g_get_home_dir
+
+G_CONST_RETURN gchar*
+g_get_home_dir (void)
+{
+  g_get_any_init_locked ();
+  return g_home_dir_cp;
+}
+
+#undef g_get_tmp_dir
+
+G_CONST_RETURN gchar*
+g_get_tmp_dir (void)
+{
+  g_get_any_init_locked ();
+  return g_tmp_dir_cp;
+}
+
+#endif
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gutils.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gutils.h
new file mode 100644 (file)
index 0000000..9028157
--- /dev/null
@@ -0,0 +1,490 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_UTILS_H__
+#define __G_UTILS_H__
+
+#include <glib/gtypes.h>
+#include <stdarg.h>
+
+G_BEGIN_DECLS
+
+#ifdef G_OS_WIN32
+
+/* On Win32, the canonical directory separator is the backslash, and
+ * the search path separator is the semicolon. Note that also the
+ * (forward) slash works as directory separator.
+ */
+#define G_DIR_SEPARATOR '\\'
+#define G_DIR_SEPARATOR_S "\\"
+#define G_IS_DIR_SEPARATOR(c) ((c) == G_DIR_SEPARATOR || (c) == '/')
+#define G_SEARCHPATH_SEPARATOR ';'
+#define G_SEARCHPATH_SEPARATOR_S ";"
+
+#else  /* !G_OS_WIN32 */
+
+/* Unix */
+
+#define G_DIR_SEPARATOR '/'
+#define G_DIR_SEPARATOR_S "/"
+#define G_IS_DIR_SEPARATOR(c) ((c) == G_DIR_SEPARATOR)
+#define G_SEARCHPATH_SEPARATOR ':'
+#define G_SEARCHPATH_SEPARATOR_S ":"
+
+#endif /* !G_OS_WIN32 */
+
+/* Define G_VA_COPY() to do the right thing for copying va_list variables.
+ * glibconfig.h may have already defined G_VA_COPY as va_copy or __va_copy.
+ */
+#if !defined (G_VA_COPY)
+#  if defined (__GNUC__) && defined (__PPC__) && (defined (_CALL_SYSV) || defined (_WIN32))
+#    define G_VA_COPY(ap1, ap2)          (*(ap1) = *(ap2))
+#  elif defined (G_VA_COPY_AS_ARRAY)
+#    define G_VA_COPY(ap1, ap2)          g_memmove ((ap1), (ap2), sizeof (va_list))
+#  else /* va_list is a pointer */
+#    define G_VA_COPY(ap1, ap2)          ((ap1) = (ap2))
+#  endif /* va_list is a pointer */
+#endif /* !G_VA_COPY */
+
+/* inlining hassle. for compilers that don't allow the `inline' keyword,
+ * mostly because of strict ANSI C compliance or dumbness, we try to fall
+ * back to either `__inline__' or `__inline'.
+ * G_CAN_INLINE is defined in glibconfig.h if the compiler seems to be 
+ * actually *capable* to do function inlining, in which case inline 
+ * function bodies do make sense. we also define G_INLINE_FUNC to properly 
+ * export the function prototypes if no inlining can be performed.
+ * inline function bodies have to be special cased with G_CAN_INLINE and a
+ * .c file specific macro to allow one compiled instance with extern linkage
+ * of the functions by defining G_IMPLEMENT_INLINES and the .c file macro.
+ */
+#if defined (G_HAVE_INLINE) && defined (__GNUC__) && defined (__STRICT_ANSI__)
+#  undef inline
+#  define inline __inline__
+#elif !defined (G_HAVE_INLINE)
+#  undef inline
+#  if defined (G_HAVE___INLINE__)
+#    define inline __inline__
+#  elif defined (G_HAVE___INLINE)
+#    define inline __inline
+#  else /* !inline && !__inline__ && !__inline */
+#    define inline  /* don't inline, then */
+#  endif
+#endif
+#ifdef G_IMPLEMENT_INLINES
+#  define G_INLINE_FUNC
+#  undef  G_CAN_INLINE
+#elif defined (__GNUC__) 
+#  define G_INLINE_FUNC static __inline __attribute__ ((unused))
+#elif defined (G_CAN_INLINE) 
+#  define G_INLINE_FUNC static inline
+#else /* can't inline */
+#  define G_INLINE_FUNC
+#endif /* !G_INLINE_FUNC */
+
+/* Retrive static string info
+ */
+#ifdef G_OS_WIN32
+#define g_get_user_name g_get_user_name_utf8
+#define g_get_real_name g_get_real_name_utf8
+#define g_get_home_dir g_get_home_dir_utf8
+#define g_get_tmp_dir g_get_tmp_dir_utf8
+#endif
+
+G_CONST_RETURN gchar* g_get_user_name        (void);
+G_CONST_RETURN gchar* g_get_real_name        (void);
+G_CONST_RETURN gchar* g_get_home_dir         (void);
+G_CONST_RETURN gchar* g_get_tmp_dir          (void);
+G_CONST_RETURN gchar* g_get_host_name       (void);
+gchar*                g_get_prgname          (void);
+void                  g_set_prgname          (const gchar *prgname);
+G_CONST_RETURN gchar* g_get_application_name (void);
+void                  g_set_application_name (const gchar *application_name);
+
+void    g_reload_user_special_dirs_cache     (void);
+G_CONST_RETURN gchar*    g_get_user_data_dir      (void);
+G_CONST_RETURN gchar*    g_get_user_config_dir    (void);
+G_CONST_RETURN gchar*    g_get_user_cache_dir     (void);
+G_CONST_RETURN gchar* G_CONST_RETURN * g_get_system_data_dirs   (void);
+
+#ifdef G_OS_WIN32
+/* This functions is not part of the public GLib API */
+G_CONST_RETURN gchar* G_CONST_RETURN * g_win32_get_system_data_dirs_for_module (void (*address_of_function)(void));
+#endif
+
+#if defined (G_OS_WIN32) && defined (G_CAN_INLINE) && !defined (__cplusplus)
+/* This function is not part of the public GLib API either. Just call
+ * g_get_system_data_dirs() in your code, never mind that that is
+ * actually a macro and you will in fact call this inline function.
+ */
+static inline G_CONST_RETURN gchar * G_CONST_RETURN *
+_g_win32_get_system_data_dirs (void)
+{
+  return g_win32_get_system_data_dirs_for_module ((void (*)(void)) &_g_win32_get_system_data_dirs);
+}
+#define g_get_system_data_dirs _g_win32_get_system_data_dirs
+#endif
+
+G_CONST_RETURN gchar* G_CONST_RETURN * g_get_system_config_dirs (void);
+
+G_CONST_RETURN gchar* G_CONST_RETURN * g_get_language_names (void);
+
+/**
+ * GUserDirectory:
+ * @G_USER_DIRECTORY_DESKTOP: the user's Desktop directory
+ * @G_USER_DIRECTORY_DOCUMENTS: the user's Documents directory
+ * @G_USER_DIRECTORY_DOWNLOAD: the user's Downloads directory
+ * @G_USER_DIRECTORY_MUSIC: the user's Music directory
+ * @G_USER_DIRECTORY_PICTURES: the user's Pictures directory
+ * @G_USER_DIRECTORY_PUBLIC_SHARE: the user's shared directory
+ * @G_USER_DIRECTORY_TEMPLATES: the user's Templates directory
+ * @G_USER_DIRECTORY_VIDEOS: the user's Movies directory
+ * @G_USER_N_DIRECTORIES: the number of enum values
+ *
+ * These are logical ids for special directories which are defined
+ * depending on the platform used. You should use g_get_user_special_dir()
+ * to retrieve the full path associated to the logical id.
+ *
+ * The #GUserDirectory enumeration can be extended at later date. Not
+ * every platform has a directory for every logical id in this
+ * enumeration.
+ *
+ * Since: 2.14
+ */
+typedef enum {
+  G_USER_DIRECTORY_DESKTOP,
+  G_USER_DIRECTORY_DOCUMENTS,
+  G_USER_DIRECTORY_DOWNLOAD,
+  G_USER_DIRECTORY_MUSIC,
+  G_USER_DIRECTORY_PICTURES,
+  G_USER_DIRECTORY_PUBLIC_SHARE,
+  G_USER_DIRECTORY_TEMPLATES,
+  G_USER_DIRECTORY_VIDEOS,
+
+  G_USER_N_DIRECTORIES
+} GUserDirectory;
+
+G_CONST_RETURN gchar* g_get_user_special_dir (GUserDirectory directory);
+
+typedef struct _GDebugKey      GDebugKey;
+struct _GDebugKey
+{
+  const gchar *key;
+  guint               value;
+};
+
+/* Miscellaneous utility functions
+ */
+guint                 g_parse_debug_string (const gchar     *string,
+                                           const GDebugKey *keys,
+                                           guint            nkeys);
+
+gint                  g_snprintf           (gchar       *string,
+                                           gulong       n,
+                                           gchar const *format,
+                                           ...) G_GNUC_PRINTF (3, 4);
+gint                  g_vsnprintf          (gchar       *string,
+                                           gulong       n,
+                                           gchar const *format,
+                                           va_list      args);
+
+/* Check if a file name is an absolute path */
+gboolean              g_path_is_absolute   (const gchar *file_name);
+
+/* In case of absolute paths, skip the root part */
+G_CONST_RETURN gchar* g_path_skip_root     (const gchar *file_name);
+
+#ifndef G_DISABLE_DEPRECATED
+
+/* These two functions are deprecated and will be removed in the next
+ * major release of GLib. Use g_path_get_dirname/g_path_get_basename
+ * instead. Whatch out! The string returned by g_path_get_basename
+ * must be g_freed, while the string returned by g_basename must not.*/
+G_CONST_RETURN gchar* g_basename           (const gchar *file_name);
+#define g_dirname g_path_get_dirname
+
+#endif /* G_DISABLE_DEPRECATED */
+
+#ifdef G_OS_WIN32
+#define g_get_current_dir g_get_current_dir_utf8
+#endif
+
+/* The returned strings are newly allocated with g_malloc() */
+gchar*                g_get_current_dir    (void);
+gchar*                g_path_get_basename  (const gchar *file_name) G_GNUC_MALLOC;
+gchar*                g_path_get_dirname   (const gchar *file_name) G_GNUC_MALLOC;
+
+/* Set the pointer at the specified location to NULL */
+void                  g_nullify_pointer    (gpointer    *nullify_location);
+
+/* return the environment string for the variable. The returned memory
+ * must not be freed. */
+#ifdef G_OS_WIN32
+#define g_getenv g_getenv_utf8
+#define g_setenv g_setenv_utf8
+#define g_unsetenv g_unsetenv_utf8
+#define g_find_program_in_path g_find_program_in_path_utf8
+#endif
+
+G_CONST_RETURN gchar* g_getenv             (const gchar *variable);
+gboolean              g_setenv             (const gchar *variable,
+                                           const gchar *value,
+                                           gboolean     overwrite);
+void                  g_unsetenv           (const gchar *variable);
+gchar**               g_listenv            (void);
+
+/* private */
+const gchar*        _g_getenv_nomalloc    (const gchar *variable,
+                                           gchar        buffer[1024]);
+
+/* we try to provide a useful equivalent for ATEXIT if it is
+ * not defined, but use is actually abandoned. people should
+ * use g_atexit() instead.
+ */
+typedef        void            (*GVoidFunc)            (void);
+#ifndef ATEXIT
+# define ATEXIT(proc)  g_ATEXIT(proc)
+#else
+# define G_NATIVE_ATEXIT
+#endif /* ATEXIT */
+/* we use a GLib function as a replacement for ATEXIT, so
+ * the programmer is not required to check the return value
+ * (if there is any in the implementation) and doesn't encounter
+ * missing include files.
+ */
+void   g_atexit                (GVoidFunc    func);
+
+#ifdef G_OS_WIN32
+/* It's a bad idea to wrap atexit() on Windows. If the GLib DLL calls
+ * atexit(), the function will be called when the GLib DLL is detached
+ * from the program, which is not what the caller wants. The caller
+ * wants the function to be called when it *itself* exits (or is
+ * detached, in case the caller, too, is a DLL).
+ */
+#if (defined(__MINGW_H) && !defined(_STDLIB_H_)) || (defined(_MSC_VER) && !defined(_INC_STDLIB))
+int atexit (void (*)(void));
+#endif
+#define g_atexit(func) atexit(func)
+#endif
+
+/* Look for an executable in PATH, following execvp() rules */
+gchar*  g_find_program_in_path  (const gchar *program);
+
+/* Bit tests
+ */
+G_INLINE_FUNC gint     g_bit_nth_lsf (gulong  mask,
+                                      gint    nth_bit) G_GNUC_CONST;
+G_INLINE_FUNC gint     g_bit_nth_msf (gulong  mask,
+                                      gint    nth_bit) G_GNUC_CONST;
+G_INLINE_FUNC guint    g_bit_storage (gulong  number) G_GNUC_CONST;
+
+/* Trash Stacks
+ * elements need to be >= sizeof (gpointer)
+ */
+typedef struct _GTrashStack     GTrashStack;
+struct _GTrashStack
+{
+  GTrashStack *next;
+};
+
+G_INLINE_FUNC void     g_trash_stack_push      (GTrashStack **stack_p,
+                                                gpointer      data_p);
+G_INLINE_FUNC gpointer g_trash_stack_pop       (GTrashStack **stack_p);
+G_INLINE_FUNC gpointer g_trash_stack_peek      (GTrashStack **stack_p);
+G_INLINE_FUNC guint    g_trash_stack_height    (GTrashStack **stack_p);
+
+/* inline function implementations
+ */
+#if defined (G_CAN_INLINE) || defined (__G_UTILS_C__)
+G_INLINE_FUNC gint
+g_bit_nth_lsf (gulong mask,
+              gint   nth_bit)
+{
+  if (G_UNLIKELY (nth_bit < -1))
+    nth_bit = -1;
+  while (nth_bit < ((GLIB_SIZEOF_LONG * 8) - 1))
+    {
+      nth_bit++;
+      if (mask & (1UL << nth_bit))
+       return nth_bit;
+    }
+  return -1;
+}
+G_INLINE_FUNC gint
+g_bit_nth_msf (gulong mask,
+              gint   nth_bit)
+{
+  if (nth_bit < 0 || G_UNLIKELY (nth_bit > GLIB_SIZEOF_LONG * 8))
+    nth_bit = GLIB_SIZEOF_LONG * 8;
+  while (nth_bit > 0)
+    {
+      nth_bit--;
+      if (mask & (1UL << nth_bit))
+       return nth_bit;
+    }
+  return -1;
+}
+G_INLINE_FUNC guint
+g_bit_storage (gulong number)
+{
+#if defined(__GNUC__) && (__GNUC__ >= 4) && defined(__OPTIMIZE__)
+  return G_LIKELY (number) ?
+          ((GLIB_SIZEOF_LONG * 8U - 1) ^ __builtin_clzl(number)) + 1 : 1;
+#else
+  register guint n_bits = 0;
+  
+  do
+    {
+      n_bits++;
+      number >>= 1;
+    }
+  while (number);
+  return n_bits;
+#endif
+}
+G_INLINE_FUNC void
+g_trash_stack_push (GTrashStack **stack_p,
+                   gpointer      data_p)
+{
+  GTrashStack *data = (GTrashStack *) data_p;
+
+  data->next = *stack_p;
+  *stack_p = data;
+}
+G_INLINE_FUNC gpointer
+g_trash_stack_pop (GTrashStack **stack_p)
+{
+  GTrashStack *data;
+
+  data = *stack_p;
+  if (data)
+    {
+      *stack_p = data->next;
+      /* NULLify private pointer here, most platforms store NULL as
+       * subsequent 0 bytes
+       */
+      data->next = NULL;
+    }
+
+  return data;
+}
+G_INLINE_FUNC gpointer
+g_trash_stack_peek (GTrashStack **stack_p)
+{
+  GTrashStack *data;
+
+  data = *stack_p;
+
+  return data;
+}
+G_INLINE_FUNC guint
+g_trash_stack_height (GTrashStack **stack_p)
+{
+  GTrashStack *data;
+  guint i = 0;
+
+  for (data = *stack_p; data; data = data->next)
+    i++;
+
+  return i;
+}
+#endif  /* G_CAN_INLINE || __G_UTILS_C__ */
+
+/* Glib version.
+ * we prefix variable declarations so they can
+ * properly get exported in windows dlls.
+ */
+GLIB_VAR const guint glib_major_version;
+GLIB_VAR const guint glib_minor_version;
+GLIB_VAR const guint glib_micro_version;
+GLIB_VAR const guint glib_interface_age;
+GLIB_VAR const guint glib_binary_age;
+
+const gchar * glib_check_version (guint required_major,
+                                  guint required_minor,
+                                  guint required_micro);
+
+#define GLIB_CHECK_VERSION(major,minor,micro)    \
+    (GLIB_MAJOR_VERSION > (major) || \
+     (GLIB_MAJOR_VERSION == (major) && GLIB_MINOR_VERSION > (minor)) || \
+     (GLIB_MAJOR_VERSION == (major) && GLIB_MINOR_VERSION == (minor) && \
+      GLIB_MICRO_VERSION >= (micro)))
+
+G_END_DECLS
+
+#ifndef G_DISABLE_DEPRECATED
+
+/*
+ * This macro is deprecated. This DllMain() is too complex. It is
+ * recommended to write an explicit minimal DLlMain() that just saves
+ * the handle to the DLL and then use that handle instead, for
+ * instance passing it to
+ * g_win32_get_package_installation_directory_of_module().
+ *
+ * On Windows, this macro defines a DllMain function that stores the
+ * actual DLL name that the code being compiled will be included in.
+ * STATIC should be empty or 'static'. DLL_NAME is the name of the
+ * (pointer to the) char array where the DLL name will be stored. If
+ * this is used, you must also include <windows.h>. If you need a more complex
+ * DLL entry point function, you cannot use this.
+ *
+ * On non-Windows platforms, expands to nothing.
+ */
+
+#ifndef G_PLATFORM_WIN32
+# define G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name)
+#else
+# define G_WIN32_DLLMAIN_FOR_DLL_NAME(static, dll_name)                        \
+static char *dll_name;                                                 \
+                                                                       \
+BOOL WINAPI                                                            \
+DllMain (HINSTANCE hinstDLL,                                           \
+        DWORD     fdwReason,                                           \
+        LPVOID    lpvReserved)                                         \
+{                                                                      \
+  wchar_t wcbfr[1000];                                                 \
+  char *tem;                                                           \
+  switch (fdwReason)                                                   \
+    {                                                                  \
+    case DLL_PROCESS_ATTACH:                                           \
+      GetModuleFileNameW ((HMODULE) hinstDLL, wcbfr, G_N_ELEMENTS (wcbfr)); \
+      tem = g_utf16_to_utf8 (wcbfr, -1, NULL, NULL, NULL);             \
+      dll_name = g_path_get_basename (tem);                            \
+      g_free (tem);                                                    \
+      break;                                                           \
+    }                                                                  \
+                                                                       \
+  return TRUE;                                                         \
+}
+
+#endif /* !G_DISABLE_DEPRECATED */
+
+#endif /* G_PLATFORM_WIN32 */
+
+#endif /* __G_UTILS_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-core.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-core.c
new file mode 100644 (file)
index 0000000..6f01930
--- /dev/null
@@ -0,0 +1,974 @@
+/*
+ * Copyright © 2007, 2008 Ryan Lortie
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#include <glib/gvariant-core.h>
+
+#include <glib/gvariant-serialiser.h>
+#include <glib/gtestutils.h>
+#include <glib/gbitlock.h>
+#include <glib/gatomic.h>
+#include <glib/gbuffer.h>
+#include <glib/gslice.h>
+#include <glib/gmem.h>
+#include <string.h>
+
+
+/*
+ * This file includes the structure definition for GVariant and a small
+ * set of functions that are allowed to access the structure directly.
+ *
+ * This minimises the amount of code that can possibly touch a GVariant
+ * structure directly to a few simple fundamental operations.  These few
+ * operations are written to be completely threadsafe with respect to
+ * all possible outside access.  This means that we only need to be
+ * concerned about thread safety issues in this one small file.
+ *
+ * Most GVariant API functions are in gvariant.c.
+ */
+
+/**
+ * GVariant:
+ *
+ * #GVariant is an opaque data structure and can only be accessed
+ * using the following functions.
+ *
+ * Since: 2.24
+ **/
+struct _GVariant
+/* see below for field member documentation */
+{
+  GVariantTypeInfo *type_info;
+  gsize size;
+
+  union
+  {
+    struct
+    {
+      GBuffer *buffer;
+      gconstpointer data;
+    } serialised;
+
+    struct
+    {
+      GVariant **children;
+      gsize n_children;
+    } tree;
+  } contents;
+
+  gint state;
+  gint ref_count;
+};
+
+/* struct GVariant:
+ *
+ * There are two primary forms of GVariant instances: "serialised form"
+ * and "tree form".
+ *
+ * "serialised form": A serialised GVariant instance stores its value in
+ *                    the GVariant serialisation format.  All
+ *                    basic-typed instances (ie: non-containers) are in
+ *                    serialised format, as are some containers.
+ *
+ * "tree form": Some containers are in "tree form".  In this case,
+ *              instead of containing the serialised data for the
+ *              container, the instance contains an array of pointers to
+ *              the child values of the container (thus forming a tree).
+ *
+ * It is possible for an instance to transition from tree form to
+ * serialised form.  This happens, implicitly, if the serialised data is
+ * requested (eg: via g_variant_get_data()).  Serialised form instances
+ * never transition into tree form.
+ *
+ *
+ * The fields of the structure are documented here:
+ *
+ * type_info: this is a reference to a GVariantTypeInfo describing the
+ *            type of the instance.  When the instance is freed, this
+ *            reference must be released with g_variant_type_info_unref().
+ *
+ *            The type_info field never changes during the life of the
+ *            instance, so it can be accessed without a lock.
+ *
+ * size: this is the size of the serialised form for the instance, if it
+ *       is known.  If the instance is in serialised form then it is, by
+ *       definition, known.  If the instance is in tree form then it may
+ *       be unknown (in which case it is -1).  It is possible for the
+ *       size to be known when in tree form if, for example, the user
+ *       has called g_variant_get_size() without calling
+ *       g_variant_get_data().  Additionally, even when the user calls
+ *       g_variant_get_data() the size of the data must first be
+ *       determined so that a large enough buffer can be allocated for
+ *       the data.
+ *
+ *       Once the size is known, it can never become unknown again.
+ *       g_variant_ensure_size() is used to ensure that the size is in
+ *       the known state -- it calculates the size if needed.  After
+ *       that, the size field can be accessed without a lock.
+ *
+ * contents: a union containing either the information associated with
+ *           holding a value in serialised form or holding a value in
+ *           tree form.
+ *
+ *   .serialised: Only valid when the instance is in serialised form.
+ *
+ *                Since an instance can never transition away from
+ *                serialised form, once these fields are set, they will
+ *                never be changed.  It is therefore valid to access
+ *                them without holding a lock.
+ *
+ *     .buffer: the #GBuffer that contains the memory pointed to by
+ *              .data, or %NULL if .data is %NULL.  In the event that
+ *              the instance was deserialised from another instance,
+ *              then the buffer will be shared by both of them.  When
+ *              the instance is freed, this reference must be released
+ *              with g_buffer_unref().
+ *
+ *     .data: the serialised data (of size 'size') of the instance.
+ *            This pointer should not be freed or modified in any way.
+ *            #GBuffer is responsible for memory management.
+ *
+ *            This pointer may be %NULL in two cases:
+ *
+ *              - if the serialised size of the instance is 0
+ *
+ *              - if the instance is of a fixed-sized type and was
+ *                deserialised out of a corrupted container such that
+ *                the container contains too few bytes to point to the
+ *                entire proper fixed-size of this instance.  In this
+ *                case, 'size' will still be equal to the proper fixed
+ *                size, but this pointer will be %NULL.  This is exactly
+ *                the reason that g_variant_get_data() sometimes returns
+ *                %NULL.  For all other calls, the effect should be as
+ *                if .data pointed to the appropriate number of nul
+ *                bytes.
+ *
+ *   .tree: Only valid when the instance is in tree form.
+ *
+ *          Note that accesses from other threads could result in
+ *          conversion of the instance from tree form to serialised form
+ *          at any time.  For this reason, the instance lock must always
+ *          be held while performing any operations on 'contents.tree'.
+ *
+ *     .children: the array of the child instances of this instance.
+ *                When the instance is freed (or converted to serialised
+ *                form) then each child must have g_variant_unref()
+ *                called on it and the array must be freed using
+ *                g_free().
+ *
+ *     .n_children: the number of items in the .children array.
+ *
+ * state: a bitfield describing the state of the instance.  It is a
+ *        bitwise-or of the following STATE_* constants:
+ *
+ *    STATE_LOCKED: the instance lock is held.  This is the bit used by
+ *                  g_bit_lock().
+ *
+ *    STATE_SERIALISED: the instance is in serialised form.  If this
+ *                      flag is not set then the instance is in tree
+ *                      form.
+ *
+ *    STATE_TRUSTED: for serialised form instances, this means that the
+ *                   serialised data is known to be in normal form (ie:
+ *                   not corrupted).
+ *
+ *                   For tree form instances, this means that all of the
+ *                   child instances in the contents.tree.children array
+ *                   are trusted.  This means that if the container is
+ *                   serialised then the resulting data will be in
+ *                   normal form.
+ *
+ *                   If this flag is unset it does not imply that the
+ *                   data is corrupted.  It merely means that we're not
+ *                   sure that it's valid.  See g_variant_is_trusted().
+ *
+ *    STATE_FLOATING: if this flag is set then the object has a floating
+ *                    reference.  See g_variant_ref_sink().
+ *
+ * ref_count: the reference count of the instance
+ */
+#define STATE_LOCKED     1
+#define STATE_SERIALISED 2
+#define STATE_TRUSTED    4
+#define STATE_FLOATING   8
+
+/* -- private -- */
+/* < private >
+ * g_variant_lock:
+ * @value: a #GVariant
+ *
+ * Locks @value for performing sensitive operations.
+ */
+static void
+g_variant_lock (GVariant *value)
+{
+  g_bit_lock (&value->state, 0);
+}
+
+/* < private >
+ * g_variant_unlock:
+ * @value: a #GVariant
+ *
+ * Unlocks @value after performing sensitive operations.
+ */
+static void
+g_variant_unlock (GVariant *value)
+{
+  g_bit_unlock (&value->state, 0);
+}
+
+/* < private >
+ * g_variant_release_children:
+ * @value: a #GVariant
+ *
+ * Releases the reference held on each child in the 'children' array of
+ * @value and frees the array itself.  @value must be in tree form.
+ *
+ * This is done when freeing a tree-form instance or converting it to
+ * serialised form.
+ *
+ * The current thread must hold the lock on @value.
+ */
+static void
+g_variant_release_children (GVariant *value)
+{
+  gsize i;
+
+  g_assert (value->state & STATE_LOCKED);
+  g_assert (~value->state & STATE_SERIALISED);
+
+  for (i = 0; i < value->contents.tree.n_children; i++)
+    g_variant_unref (value->contents.tree.children[i]);
+
+  g_free (value->contents.tree.children);
+}
+
+/* This begins the main body of the recursive serialiser.
+ *
+ * There are 3 functions here that work as a team with the serialiser to
+ * get things done.  g_variant_store() has a trivial role, but as a
+ * public API function, it has its definition elsewhere.
+ *
+ * Note that "serialisation" of an instance does not mean that the
+ * instance is converted to serialised form -- it means that the
+ * serialised form of an instance is written to an external buffer.
+ * g_variant_ensure_serialised() (which is not part of this set of
+ * functions) is the function that is responsible for converting an
+ * instance to serialised form.
+ *
+ * We are only concerned here with container types since non-container
+ * instances are always in serialised form.  For these instances,
+ * storing their serialised form merely involves a memcpy().
+ *
+ * Serialisation is a two-step process.  First, the size of the
+ * serialised data must be calculated so that an appropriately-sized
+ * buffer can be allocated.  Second, the data is written into the
+ * buffer.
+ *
+ * Determining the size:
+ *   The process of determining the size is triggered by a call to
+ *   g_variant_ensure_size() on a container.  This invokes the
+ *   serialiser code to determine the size.  The serialiser is passed
+ *   g_variant_fill_gvs() as a callback.
+ *
+ *   g_variant_fill_gvs() is called by the serialiser on each child of
+ *   the container which, in turn, calls g_variant_ensure_size() on
+ *   itself and fills in the result of its own size calculation.
+ *
+ *   The serialiser uses the size information from the children to
+ *   calculate the size needed for the entire container.
+ *
+ * Writing the data:
+ *   After the buffer has been allocated, g_variant_serialise() is
+ *   called on the container.  This invokes the serialiser code to write
+ *   the bytes to the container.  The serialiser is, again, passed
+ *   g_variant_fill_gvs() as a callback.
+ *
+ *   This time, when g_variant_fill_gvs() is called for each child, the
+ *   child is given a pointer to a sub-region of the allocated buffer
+ *   where it should write its data.  This is done by calling
+ *   g_variant_store().  In the event that the instance is in serialised
+ *   form this means a memcpy() of the serialised data into the
+ *   allocated buffer.  In the event that the instance is in tree form
+ *   this means a recursive call back into g_variant_serialise().
+ *
+ *
+ * The forward declaration here allows corecursion via callback:
+ */
+static void g_variant_fill_gvs (GVariantSerialised *, gpointer);
+
+/* < private >
+ * g_variant_ensure_size:
+ * @value: a #GVariant
+ *
+ * Ensures that the ->size field of @value is filled in properly.  This
+ * must be done as a precursor to any serialisation of the value in
+ * order to know how large of a buffer is needed to store the data.
+ *
+ * The current thread must hold the lock on @value.
+ */
+static void
+g_variant_ensure_size (GVariant *value)
+{
+  g_assert (value->state & STATE_LOCKED);
+
+  if (value->size == (gssize) -1)
+    {
+      gpointer *children;
+      gsize n_children;
+
+      children = (gpointer *) value->contents.tree.children;
+      n_children = value->contents.tree.n_children;
+      value->size = g_variant_serialiser_needed_size (value->type_info,
+                                                      g_variant_fill_gvs,
+                                                      children, n_children);
+    }
+}
+
+/* < private >
+ * g_variant_serialise:
+ * @value: a #GVariant
+ * @data: an appropriately-sized buffer
+ *
+ * Serialises @value into @data.  @value must be in tree form.
+ *
+ * No change is made to @value.
+ *
+ * The current thread must hold the lock on @value.
+ */
+static void
+g_variant_serialise (GVariant *value,
+                     gpointer  data)
+{
+  GVariantSerialised serialised = { 0, };
+  gpointer *children;
+  gsize n_children;
+
+  g_assert (~value->state & STATE_SERIALISED);
+  g_assert (value->state & STATE_LOCKED);
+
+  serialised.type_info = value->type_info;
+  serialised.size = value->size;
+  serialised.data = data;
+
+  children = (gpointer *) value->contents.tree.children;
+  n_children = value->contents.tree.n_children;
+
+  g_variant_serialiser_serialise (serialised, g_variant_fill_gvs,
+                                  children, n_children);
+}
+
+/* < private >
+ * g_variant_fill_gvs:
+ * @serialised: a pointer to a #GVariantSerialised
+ * @data: a #GVariant instance
+ *
+ * This is the callback that is passed by a tree-form container instance
+ * to the serialiser.  This callback gets called on each child of the
+ * container.  Each child is responsible for performing the following
+ * actions:
+ *
+ *  - reporting its type
+ *
+ *  - reporting its serialised size (requires knowing the size first)
+ *
+ *  - possibly storing its serialised form into the provided buffer
+ */
+static void
+g_variant_fill_gvs (GVariantSerialised *serialised,
+                    gpointer            data)
+{
+  GVariant *value = data;
+
+  g_variant_lock (value);
+  g_variant_ensure_size (value);
+  g_variant_unlock (value);
+
+  if (serialised->type_info == NULL)
+    serialised->type_info = value->type_info;
+  g_assert (serialised->type_info == value->type_info);
+
+  if (serialised->size == 0)
+    serialised->size = value->size;
+  g_assert (serialised->size == value->size);
+
+  if (serialised->data)
+    /* g_variant_store() is a public API, so it
+     * it will reacquire the lock if it needs to.
+     */
+    g_variant_store (value, serialised->data);
+}
+
+/* this ends the main body of the recursive serialiser */
+
+/* < private >
+ * g_variant_ensure_serialised:
+ * @value: a #GVariant
+ *
+ * Ensures that @value is in serialised form.
+ *
+ * If @value is in tree form then this function ensures that the
+ * serialised size is known and then allocates a buffer of that size and
+ * serialises the instance into the buffer.  The 'children' array is
+ * then released and the instance is set to serialised form based on the
+ * contents of the buffer.
+ *
+ * The current thread must hold the lock on @value.
+ */
+static void
+g_variant_ensure_serialised (GVariant *value)
+{
+  g_assert (value->state & STATE_LOCKED);
+
+  if (~value->state & STATE_SERIALISED)
+    {
+      GBuffer *buffer;
+      gpointer data;
+
+      g_variant_ensure_size (value);
+      data = g_malloc (value->size);
+      g_variant_serialise (value, data);
+
+      g_variant_release_children (value);
+
+      buffer = g_buffer_new_take_data (data, value->size);
+      value->contents.serialised.data = buffer->data;
+      value->contents.serialised.buffer = buffer;
+      value->state |= STATE_SERIALISED;
+    }
+}
+
+/* < private >
+ * g_variant_alloc:
+ * @type: the type of the new instance
+ * @serialised: if the instance will be in serialised form
+ * @trusted: if the instance will be trusted
+ * @returns: a new #GVariant with a floating reference
+ *
+ * Allocates a #GVariant instance and does some common work (such as
+ * looking up and filling in the type info), setting the state field,
+ * and setting the ref_count to 1.
+ */
+static GVariant *
+g_variant_alloc (const GVariantType *type,
+                 gboolean            serialised,
+                 gboolean            trusted)
+{
+  GVariant *value;
+
+  value = g_slice_new (GVariant);
+  value->type_info = g_variant_type_info_get (type);
+  value->state = (serialised ? STATE_SERIALISED : 0) |
+                 (trusted ? STATE_TRUSTED : 0) |
+                 STATE_FLOATING;
+  value->size = (gssize) -1;
+  value->ref_count = 1;
+
+  return value;
+}
+
+/* -- internal -- */
+/* < internal >
+ * g_variant_new_from_buffer:
+ * @type: a #GVariantType
+ * @buffer: a #GBuffer
+ * @trusted: if the contents of @buffer are trusted
+ * @returns: a new #GVariant with a floating reference
+ *
+ * Constructs a new serialised-mode #GVariant instance.  This is the
+ * inner interface for creation of new serialised values that gets
+ * called from various functions in gvariant.c.
+ *
+ * A reference is taken on @buffer.
+ */
+GVariant *
+g_variant_new_from_buffer (const GVariantType *type,
+                           GBuffer            *buffer,
+                           gboolean            trusted)
+{
+  GVariant *value;
+  guint alignment;
+  gsize size;
+
+  value = g_variant_alloc (type, TRUE, trusted);
+
+  value->contents.serialised.buffer = g_buffer_ref (buffer);
+
+  g_variant_type_info_query (value->type_info,
+                             &alignment, &size);
+
+  if (size && buffer->size != size)
+    {
+      /* Creating a fixed-sized GVariant with a buffer of the wrong
+       * size.
+       *
+       * We should do the equivalent of pulling a fixed-sized child out
+       * of a brozen container (ie: data is NULL size is equal to the correct
+       * fixed size).
+       */
+      value->contents.serialised.data = NULL;
+      value->size = size;
+    }
+  else
+    {
+      value->contents.serialised.data = buffer->data;
+      value->size = buffer->size;
+    }
+
+  return value;
+}
+
+/* < internal >
+ * g_variant_new_from_children:
+ * @type: a #GVariantType
+ * @children: an array of #GVariant pointers.  Consumed.
+ * @n_children: the length of @children
+ * @trusted: %TRUE if every child in @children in trusted
+ * @returns: a new #GVariant with a floating reference
+ *
+ * Constructs a new tree-mode #GVariant instance.  This is the inner
+ * interface for creation of new serialised values that gets called from
+ * various functions in gvariant.c.
+ *
+ * @children is consumed by this function.  g_free() will be called on
+ * it some time later.
+ */
+GVariant *
+g_variant_new_from_children (const GVariantType  *type,
+                             GVariant           **children,
+                             gsize                n_children,
+                             gboolean             trusted)
+{
+  GVariant *value;
+
+  value = g_variant_alloc (type, FALSE, trusted);
+  value->contents.tree.children = children;
+  value->contents.tree.n_children = n_children;
+
+  return value;
+}
+
+/* < internal >
+ * g_variant_get_type_info:
+ * @value: a #GVariant
+ * @returns: the #GVariantTypeInfo for @value
+ *
+ * Returns the #GVariantTypeInfo corresponding to the type of @value.  A
+ * reference is not added, so the return value is only good for the
+ * duration of the life of @value.
+ */
+GVariantTypeInfo *
+g_variant_get_type_info (GVariant *value)
+{
+  return value->type_info;
+}
+
+/* < internal >
+ * g_variant_is_trusted:
+ * @value: a #GVariant
+ * @returns: if @value is trusted
+ *
+ * Determines if @value is trusted by #GVariant to contain only
+ * fully-valid data.  All values constructed solely via #GVariant APIs
+ * are trusted, but values containing data read in from other sources
+ * are usually not trusted.
+ *
+ * The main advantage of trusted data is that certain checks can be
+ * skipped.  For example, we don't need to check that a string is
+ * properly nul-terminated or that an object path is actually a
+ * properly-formatted object path.
+ */
+gboolean
+g_variant_is_trusted (GVariant *value)
+{
+  return (value->state & STATE_TRUSTED) != 0;
+}
+
+/* -- public -- */
+
+/**
+ * g_variant_unref:
+ * @value: a #GVariant
+ *
+ * Decreases the reference count of @value.  When its reference count
+ * drops to 0, the memory used by the variant is freed.
+ *
+ * Since: 2.24
+ **/
+void
+g_variant_unref (GVariant *value)
+{
+  if (g_atomic_int_dec_and_test (&value->ref_count))
+    {
+      if G_UNLIKELY (value->state & STATE_LOCKED)
+        g_critical ("attempting to free a locked GVariant instance.  "
+                    "This should never happen.");
+
+      value->state |= STATE_LOCKED;
+
+      g_variant_type_info_unref (value->type_info);
+
+      if (value->state & STATE_SERIALISED)
+        g_buffer_unref (value->contents.serialised.buffer);
+      else
+        g_variant_release_children (value);
+
+      g_slice_free (GVariant, value);
+    }
+}
+
+/**
+ * g_variant_ref:
+ * @value: a #GVariant
+ * @returns: the same @value
+ *
+ * Increases the reference count of @value.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_ref (GVariant *value)
+{
+  g_atomic_int_inc (&value->ref_count);
+
+  return value;
+}
+
+/**
+ * g_variant_ref_sink:
+ * @value: a #GVariant
+ * @returns: the same @value
+ *
+ * #GVariant uses a floating reference count system.  All functions with
+ * names starting with <literal>g_variant_new_</literal> return floating
+ * references.
+ *
+ * Calling g_variant_ref_sink() on a #GVariant with a floating reference
+ * will convert the floating reference into a full reference.  Calling
+ * g_variant_ref_sink() on a non-floating #GVariant results in an
+ * additional normal reference being added.
+ *
+ * In other words, if the @value is floating, then this call "assumes
+ * ownership" of the floating reference, converting it to a normal
+ * reference.  If the @value is not floating, then this call adds a
+ * new normal reference increasing the reference count by one.
+ *
+ * All calls that result in a #GVariant instance being inserted into a
+ * container will call g_variant_ref_sink() on the instance.  This means
+ * that if the value was just created (and has only its floating
+ * reference) then the container will assume sole ownership of the value
+ * at that point and the caller will not need to unreference it.  This
+ * makes certain common styles of programming much easier while still
+ * maintaining normal refcounting semantics in situations where values
+ * are not floating.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_ref_sink (GVariant *value)
+{
+  g_variant_lock (value);
+
+  if (~value->state & STATE_FLOATING)
+    g_variant_ref (value);
+  else
+    value->state &= ~STATE_FLOATING;
+
+  g_variant_unlock (value);
+
+  return value;
+}
+
+/**
+ * g_variant_is_floating:
+ * @value: a #GVariant
+ * @returns: whether @value is floating
+ *
+ * Checks whether @value has a floating reference count.
+ *
+ * This function should only ever be used to assert that a given variant
+ * is or is not floating, or for debug purposes. To acquire a reference
+ * to a variant that might be floating, always use g_variant_ref_sink().
+ *
+ * See g_variant_ref_sink() for more information about floating reference
+ * counts.
+ *
+ * Since: 2.26
+ **/
+gboolean
+g_variant_is_floating (GVariant *value)
+{
+  g_return_val_if_fail (value != NULL, FALSE);
+
+  return (value->state & STATE_FLOATING) != 0;
+}
+
+/**
+ * g_variant_get_size:
+ * @value: a #GVariant instance
+ * @returns: the serialised size of @value
+ *
+ * Determines the number of bytes that would be required to store @value
+ * with g_variant_store().
+ *
+ * If @value has a fixed-sized type then this function always returned
+ * that fixed size.
+ *
+ * In the case that @value is already in serialised form or the size has
+ * already been calculated (ie: this function has been called before)
+ * then this function is O(1).  Otherwise, the size is calculated, an
+ * operation which is approximately O(n) in the number of values
+ * involved.
+ *
+ * Since: 2.24
+ **/
+gsize
+g_variant_get_size (GVariant *value)
+{
+  g_variant_lock (value);
+  g_variant_ensure_size (value);
+  g_variant_unlock (value);
+
+  return value->size;
+}
+
+/**
+ * g_variant_get_data:
+ * @value: a #GVariant instance
+ * @returns: the serialised form of @value, or %NULL
+ *
+ * Returns a pointer to the serialised form of a #GVariant instance.
+ * The returned data may not be in fully-normalised form if read from an
+ * untrusted source.  The returned data must not be freed; it remains
+ * valid for as long as @value exists.
+ *
+ * If @value is a fixed-sized value that was deserialised from a
+ * corrupted serialised container then %NULL may be returned.  In this
+ * case, the proper thing to do is typically to use the appropriate
+ * number of nul bytes in place of @value.  If @value is not fixed-sized
+ * then %NULL is never returned.
+ *
+ * In the case that @value is already in serialised form, this function
+ * is O(1).  If the value is not already in serialised form,
+ * serialisation occurs implicitly and is approximately O(n) in the size
+ * of the result.
+ *
+ * Since: 2.24
+ **/
+gconstpointer
+g_variant_get_data (GVariant *value)
+{
+  g_variant_lock (value);
+  g_variant_ensure_serialised (value);
+  g_variant_unlock (value);
+
+  return value->contents.serialised.data;
+}
+
+/**
+ * g_variant_n_children:
+ * @value: a container #GVariant
+ * @returns: the number of children in the container
+ *
+ * Determines the number of children in a container #GVariant instance.
+ * This includes variants, maybes, arrays, tuples and dictionary
+ * entries.  It is an error to call this function on any other type of
+ * #GVariant.
+ *
+ * For variants, the return value is always 1.  For values with maybe
+ * types, it is always zero or one.  For arrays, it is the length of the
+ * array.  For tuples it is the number of tuple items (which depends
+ * only on the type).  For dictionary entries, it is always 2
+ *
+ * This function is O(1).
+ *
+ * Since: 2.24
+ **/
+gsize
+g_variant_n_children (GVariant *value)
+{
+  gsize n_children;
+
+  g_variant_lock (value);
+
+  if (value->state & STATE_SERIALISED)
+    {
+      GVariantSerialised serialised = {
+        value->type_info,
+        (gpointer) value->contents.serialised.data,
+        value->size
+      };
+
+      n_children = g_variant_serialised_n_children (serialised);
+    }
+  else
+    n_children = value->contents.tree.n_children;
+
+  g_variant_unlock (value);
+
+  return n_children;
+}
+
+/**
+ * g_variant_get_child_value:
+ * @value: a container #GVariant
+ * @index_: the index of the child to fetch
+ * @returns: the child at the specified index
+ *
+ * Reads a child item out of a container #GVariant instance.  This
+ * includes variants, maybes, arrays, tuples and dictionary
+ * entries.  It is an error to call this function on any other type of
+ * #GVariant.
+ *
+ * It is an error if @index_ is greater than the number of child items
+ * in the container.  See g_variant_n_children().
+ *
+ * This function is O(1).
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_get_child_value (GVariant *value,
+                           gsize     index_)
+{
+  GVariant *child = NULL;
+
+  g_variant_lock (value);
+
+  if (value->state & STATE_SERIALISED)
+    {
+      GVariantSerialised serialised = {
+        value->type_info,
+        (gpointer) value->contents.serialised.data,
+        value->size
+      };
+      GVariantSerialised s_child;
+
+      /* get the serialiser to extract the serialised data for the child
+       * from the serialised data for the container
+       */
+      s_child = g_variant_serialised_get_child (serialised, index_);
+
+      /* create a new serialised instance out of it */
+      child = g_slice_new (GVariant);
+      child->type_info = s_child.type_info;
+      child->state = (value->state & STATE_TRUSTED) |
+                     STATE_SERIALISED;
+      child->size = s_child.size;
+      child->ref_count = 1;
+      child->contents.serialised.buffer =
+        g_buffer_ref (value->contents.serialised.buffer);
+      child->contents.serialised.data = s_child.data;
+     }
+  else
+    child = g_variant_ref (value->contents.tree.children[index_]);
+
+  g_variant_unlock (value);
+
+  return child;
+}
+
+/**
+ * g_variant_store:
+ * @value: the #GVariant to store
+ * @data: the location to store the serialised data at
+ *
+ * Stores the serialised form of @value at @data.  @data should be
+ * large enough.  See g_variant_get_size().
+ *
+ * The stored data is in machine native byte order but may not be in
+ * fully-normalised form if read from an untrusted source.  See
+ * g_variant_normalise() for a solution.
+ *
+ * This function is approximately O(n) in the size of @data.
+ *
+ * Since: 2.24
+ **/
+void
+g_variant_store (GVariant *value,
+                 gpointer  data)
+{
+  g_variant_lock (value);
+
+  if (value->state & STATE_SERIALISED)
+    {
+      if (value->contents.serialised.data != NULL)
+        memcpy (data, value->contents.serialised.data, value->size);
+      else
+        memset (data, 0, value->size);
+    }
+  else
+    g_variant_serialise (value, data);
+
+  g_variant_unlock (value);
+}
+
+/**
+ * g_variant_is_normal_form:
+ * @value: a #GVariant instance
+ * @returns: %TRUE if @value is in normal form
+ *
+ * Checks if @value is in normal form.
+ *
+ * The main reason to do this is to detect if a given chunk of
+ * serialised data is in normal form: load the data into a #GVariant
+ * using g_variant_create_from_data() and then use this function to
+ * check.
+ *
+ * If @value is found to be in normal form then it will be marked as
+ * being trusted.  If the value was already marked as being trusted then
+ * this function will immediately return %TRUE.
+ *
+ * Since: 2.24
+ **/
+gboolean
+g_variant_is_normal_form (GVariant *value)
+{
+  if (value->state & STATE_TRUSTED)
+    return TRUE;
+
+  g_variant_lock (value);
+
+  if (value->state & STATE_SERIALISED)
+    {
+      GVariantSerialised serialised = {
+        value->type_info,
+        (gpointer) value->contents.serialised.data,
+        value->size
+      };
+
+      if (g_variant_serialised_is_normal (serialised))
+        value->state |= STATE_TRUSTED;
+    }
+  else
+    {
+      gboolean normal = TRUE;
+      gsize i;
+
+      for (i = 0; i < value->contents.tree.n_children; i++)
+        normal &= g_variant_is_normal_form (value->contents.tree.children[i]);
+
+      if (normal)
+        value->state |= STATE_TRUSTED;
+    }
+
+  g_variant_unlock (value);
+
+  return (value->state & STATE_TRUSTED) != 0;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-core.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-core.h
new file mode 100644 (file)
index 0000000..33c0ef3
--- /dev/null
@@ -0,0 +1,46 @@
+/*
+ * Copyright © 2007, 2008 Ryan Lortie
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+#ifndef __G_VARIANT_CORE_H__
+#define __G_VARIANT_CORE_H__
+
+#include <glib/gvarianttypeinfo.h>
+#include <glib/gvariant.h>
+#include <glib/gbuffer.h>
+
+/* gvariant-core.c */
+G_GNUC_INTERNAL
+GVariant *              g_variant_new_from_buffer                       (const GVariantType *type,
+                                                                         GBuffer            *buffer,
+                                                                         gboolean            trusted);
+
+G_GNUC_INTERNAL
+GVariant *              g_variant_new_from_children                     (const GVariantType  *type,
+                                                                         GVariant           **children,
+                                                                         gsize                n_children,
+                                                                         gboolean             trusted);
+
+G_GNUC_INTERNAL
+gboolean                g_variant_is_trusted                            (GVariant            *value);
+
+G_GNUC_INTERNAL
+GVariantTypeInfo *      g_variant_get_type_info                         (GVariant            *value);
+
+#endif /* __G_VARIANT_CORE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-internal.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-internal.h
new file mode 100644 (file)
index 0000000..66a080a
--- /dev/null
@@ -0,0 +1,49 @@
+/*
+ * Copyright © 2007, 2008 Ryan Lortie
+ * Copyright © 2009, 2010 Codethink Limited
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+
+/* The purpose of this header is to allow certain internal symbols of
+ * GVariant to be put under test cases.
+ */
+
+#ifndef __G_VARIANT_INTERNAL_H__
+#define __G_VARIANT_INTERNAL_H__
+
+#ifndef GLIB_COMPILATION
+#define GLIB_COMPILATION
+#endif
+
+#include <glib/gvarianttype.h>
+#include <glib/gtypes.h>
+
+#include "gvariant-serialiser.h"
+#include "gvarianttypeinfo.h"
+
+gboolean                        g_variant_format_string_scan            (const gchar          *string,
+                                                                         const gchar          *limit,
+                                                                         const gchar         **endptr);
+
+GVariantType *                  g_variant_format_string_scan_type       (const gchar          *string,
+                                                                         const gchar          *limit,
+                                                                         const gchar         **endptr);
+
+#endif /* __G_VARIANT_INTERNAL_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-parser.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-parser.c
new file mode 100644 (file)
index 0000000..c38732d
--- /dev/null
@@ -0,0 +1,2466 @@
+/*
+ * Copyright © 2009, 2010 Codethink Limited
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#include "gerror.h"
+#include "gquark.h"
+#include "gstring.h"
+#include "gstrfuncs.h"
+#include "gtestutils.h"
+#include "gvariant.h"
+#include "gvarianttype.h"
+
+/*
+ * two-pass algorithm
+ * designed by ryan lortie and william hua
+ * designed in itb-229 and at ghazi's, 2009.
+ */
+
+/**
+ * G_VARIANT_PARSE_ERROR:
+ *
+ * Error domain for GVariant text format parsing.  Specific error codes
+ * are not currently defined for this domain.  See #GError for
+ * information on error domains.
+ **/
+/**
+ * GVariantParseError:
+ * @G_VARIANT_PARSE_ERROR_FAILED: generic error
+ *
+ * Error codes returned by parsing text-format GVariants.  Currently the
+ * parser makes no distinction between different types of error.
+ **/
+GQuark
+g_variant_parser_get_error_quark (void)
+{
+  static GQuark the_quark;
+
+  if (the_quark == 0)
+    the_quark = g_quark_from_static_string ("g-variant-parse-error-quark");
+
+  return the_quark;
+}
+
+typedef struct
+{
+  gint start, end;
+} SourceRef;
+
+static void
+parser_set_error_va (GError      **error,
+                     SourceRef    *location,
+                     SourceRef    *other,
+                     const gchar  *format,
+                     va_list       ap)
+{
+  GString *msg = g_string_new (NULL);
+
+  if (location->start == location->end)
+    g_string_append_printf (msg, "%d", location->start);
+  else
+    g_string_append_printf (msg, "%d-%d", location->start, location->end);
+
+  if (other != NULL)
+    {
+      g_assert (other->start != other->end);
+      g_string_append_printf (msg, ",%d-%d", other->start, other->end);
+    }
+  g_string_append_c (msg, ':');
+
+  g_string_append_vprintf (msg, format, ap);
+  g_set_error_literal (error, G_VARIANT_PARSE_ERROR, 0, msg->str);
+  g_string_free (msg, TRUE);
+}
+
+static void
+parser_set_error (GError      **error,
+                  SourceRef    *location,
+                  SourceRef    *other,
+                  const gchar  *format,
+                  ...)
+{
+  va_list ap;
+
+  va_start (ap, format);
+  parser_set_error_va (error, location, other, format, ap);
+  va_end (ap);
+}
+
+typedef struct
+{
+  const gchar *start;
+  const gchar *stream;
+  const gchar *end;
+
+  const gchar *this;
+} TokenStream;
+
+
+static void
+token_stream_set_error (TokenStream  *stream,
+                        GError      **error,
+                        gboolean      this_token,
+                        const gchar  *format,
+                        ...)
+{
+  SourceRef ref;
+  va_list ap;
+
+  ref.start = stream->this - stream->start;
+
+  if (this_token)
+    ref.end = stream->stream - stream->start;
+  else
+    ref.end = ref.start;
+
+  va_start (ap, format);
+  parser_set_error_va (error, &ref, NULL, format, ap);
+  va_end (ap);
+}
+
+static void
+token_stream_prepare (TokenStream *stream)
+{
+  gint brackets = 0;
+  const gchar *end;
+
+  if (stream->this != NULL)
+    return;
+
+  while (stream->stream != stream->end && g_ascii_isspace (*stream->stream))
+    stream->stream++;
+
+  if (stream->stream == stream->end || *stream->stream == '\0')
+    {
+      stream->this = stream->stream;
+      return;
+    }
+
+  switch (stream->stream[0])
+    {
+    case '-': case '+': case '.': case '0': case '1': case '2':
+    case '3': case '4': case '5': case '6': case '7': case '8':
+    case '9':
+      for (end = stream->stream; end != stream->end; end++)
+        if (!g_ascii_isalnum (*end) &&
+            *end != '-' && *end != '+' && *end != '.')
+          break;
+      break;
+
+    case 'b':
+      if (stream->stream[1] == '\'' || stream->stream[1] == '"')
+        {
+          for (end = stream->stream + 2; end != stream->end; end++)
+            if (*end == stream->stream[1] || *end == '\0' ||
+                (*end == '\\' && (++end == stream->end || *end == '\0')))
+              break;
+
+          if (end != stream->end && *end)
+            end++;
+          break;
+        }
+
+      else    /* ↓↓↓ */;
+
+    case 'a': /* 'b' */ case 'c': case 'd': case 'e': case 'f':
+    case 'g': case 'h': case 'i': case 'j': case 'k': case 'l':
+    case 'm': case 'n': case 'o': case 'p': case 'q': case 'r':
+    case 's': case 't': case 'u': case 'v': case 'w': case 'x':
+    case 'y': case 'z':
+      for (end = stream->stream; end != stream->end; end++)
+        if (!g_ascii_isalnum (*end))
+          break;
+      break;
+
+    case '\'': case '"':
+      for (end = stream->stream + 1; end != stream->end; end++)
+        if (*end == stream->stream[0] || *end == '\0' ||
+            (*end == '\\' && (++end == stream->end || *end == '\0')))
+          break;
+
+      if (end != stream->end && *end)
+        end++;
+      break;
+
+    case '@': case '%':
+      /* stop at the first space, comma, colon or unmatched bracket.
+       * deals nicely with cases like (%i, %i) or {%i: %i}.
+       */
+      for (end = stream->stream + 1;
+           end != stream->end && *end != ',' &&
+           *end != ':' && *end != '>' && !g_ascii_isspace (*end);
+           end++)
+
+        if (*end == '(' || *end == '{')
+          brackets++;
+
+        else if ((*end == ')' || *end == '}') && !brackets--)
+          break;
+
+      break;
+
+    default:
+      end = stream->stream + 1;
+      break;
+    }
+
+  stream->this = stream->stream;
+  stream->stream = end;
+}
+
+static void
+token_stream_next (TokenStream *stream)
+{
+  stream->this = NULL;
+}
+
+static gboolean
+token_stream_peek (TokenStream *stream,
+                   gchar        first_char)
+{
+  token_stream_prepare (stream);
+
+  return stream->this[0] == first_char;
+}
+
+static gboolean
+token_stream_peek2 (TokenStream *stream,
+                    gchar        first_char,
+                    gchar        second_char)
+{
+  token_stream_prepare (stream);
+
+  return stream->this[0] == first_char &&
+         stream->this[1] == second_char;
+}
+
+static gboolean
+token_stream_is_keyword (TokenStream *stream)
+{
+  token_stream_prepare (stream);
+
+  return g_ascii_isalpha (stream->this[0]) &&
+         g_ascii_isalpha (stream->this[1]);
+}
+
+static gboolean
+token_stream_is_numeric (TokenStream *stream)
+{
+  token_stream_prepare (stream);
+
+  return (g_ascii_isdigit (stream->this[0]) ||
+          stream->this[0] == '-' ||
+          stream->this[0] == '+' ||
+          stream->this[0] == '.');
+}
+
+static gboolean
+token_stream_consume (TokenStream *stream,
+                      const gchar *token)
+{
+  gint length = strlen (token);
+
+  token_stream_prepare (stream);
+
+  if (stream->stream - stream->this == length &&
+      memcmp (stream->this, token, length) == 0)
+    {
+      token_stream_next (stream);
+      return TRUE;
+    }
+
+  return FALSE;
+}
+
+static gboolean
+token_stream_require (TokenStream  *stream,
+                      const gchar  *token,
+                      const gchar  *purpose,
+                      GError      **error)
+{
+
+  if (!token_stream_consume (stream, token))
+    {
+      token_stream_set_error (stream, error, FALSE,
+                              "expected `%s'%s", token, purpose);
+      return FALSE;
+    }
+
+  return TRUE;
+}
+
+static void
+token_stream_assert (TokenStream *stream,
+                     const gchar *token)
+{
+  gboolean correct_token;
+
+  correct_token = token_stream_consume (stream, token);
+  g_assert (correct_token);
+}
+
+static gchar *
+token_stream_get (TokenStream *stream)
+{
+  gchar *result;
+
+  token_stream_prepare (stream);
+
+  result = g_strndup (stream->this, stream->stream - stream->this);
+
+  return result;
+}
+
+static void
+token_stream_start_ref (TokenStream *stream,
+                        SourceRef   *ref)
+{
+  token_stream_prepare (stream);
+  ref->start = stream->this - stream->start;
+}
+
+static void
+token_stream_end_ref (TokenStream *stream,
+                      SourceRef   *ref)
+{
+  ref->end = stream->stream - stream->start;
+}
+
+void
+pattern_copy (gchar       **out,
+              const gchar **in)
+{
+  gint brackets = 0;
+
+  while (**in == 'a' || **in == 'm' || **in == 'M')
+    *(*out)++ = *(*in)++;
+
+  do
+    {
+      if (**in == '(' || **in == '{')
+        brackets++;
+
+      else if (**in == ')' || **in == '}')
+        brackets--;
+
+      *(*out)++ = *(*in)++;
+    }
+  while (brackets);
+}
+
+static gchar *
+pattern_coalesce (const gchar *left,
+                  const gchar *right)
+{
+  gchar *result;
+  gchar *out;
+
+  /* the length of the output is loosely bound by the sum of the input
+   * lengths, not simply the greater of the two lengths.
+   *
+   *   (*(iii)) + ((iii)*) ((iii)(iii))
+   *
+   *      8     +    8    =  12
+   */
+  out = result = g_malloc (strlen (left) + strlen (right));
+
+  while (*left && *right)
+    {
+      if (*left == *right)
+        {
+          *out++ = *left++;
+          right++;
+        }
+
+      else
+        {
+          const gchar **one = &left, **the_other = &right;
+
+         again:
+          if (**one == '*' && **the_other != ')')
+            {
+              pattern_copy (&out, the_other);
+              (*one)++;
+            }
+
+          else if (**one == 'M' && **the_other == 'm')
+            {
+              *out++ = *(*the_other)++;
+            }
+
+          else if (**one == 'M' && **the_other != 'm')
+            {
+              (*one)++;
+            }
+
+          else if (**one == 'N' && strchr ("ynqiuxthd", **the_other))
+            {
+              *out++ = *(*the_other)++;
+              (*one)++;
+            }
+
+          else if (**one == 'S' && strchr ("sog", **the_other))
+            {
+              *out++ = *(*the_other)++;
+              (*one)++;
+            }
+
+          else if (one == &left)
+            {
+              one = &right, the_other = &left;
+              goto again;
+            }
+
+          else
+            break;
+        }
+    }
+
+  if (*left || *right)
+    {
+      g_free (result);
+      result = NULL;
+    }
+  else
+    *out++ = '\0';
+
+  return result;
+}
+
+typedef struct _AST AST;
+typedef gchar *    (*get_pattern_func)    (AST                 *ast,
+                                           GError             **error);
+typedef GVariant * (*get_value_func)      (AST                 *ast,
+                                           const GVariantType  *type,
+                                           GError             **error);
+typedef GVariant * (*get_base_value_func) (AST                 *ast,
+                                           const GVariantType  *type,
+                                           GError             **error);
+typedef void       (*free_func)           (AST                 *ast);
+
+typedef struct
+{
+  gchar *    (* get_pattern)    (AST                 *ast,
+                                 GError             **error);
+  GVariant * (* get_value)      (AST                 *ast,
+                                 const GVariantType  *type,
+                                 GError             **error);
+  GVariant * (* get_base_value) (AST                 *ast,
+                                 const GVariantType  *type,
+                                 GError             **error);
+  void       (* free)           (AST                 *ast);
+} ASTClass;
+
+struct _AST
+{
+  const ASTClass *class;
+  SourceRef source_ref;
+};
+
+static gchar *
+ast_get_pattern (AST     *ast,
+                 GError **error)
+{
+  return ast->class->get_pattern (ast, error);
+}
+
+static GVariant *
+ast_get_value (AST                 *ast,
+               const GVariantType  *type,
+               GError             **error)
+{
+  return ast->class->get_value (ast, type, error);
+}
+
+static void
+ast_free (AST *ast)
+{
+  ast->class->free (ast);
+}
+
+static void
+ast_set_error (AST          *ast,
+               GError      **error,
+               AST          *other_ast,
+               const gchar  *format,
+               ...)
+{
+  va_list ap;
+
+  va_start (ap, format);
+  parser_set_error_va (error, &ast->source_ref,
+                       other_ast ? & other_ast->source_ref : NULL,
+                       format, ap);
+  va_end (ap);
+}
+
+static GVariant *
+ast_type_error (AST                 *ast,
+                const GVariantType  *type,
+                GError             **error)
+{
+  gchar *typestr;
+
+  typestr = g_variant_type_dup_string (type);
+  ast_set_error (ast, error, NULL,
+                 "can not parse as value of type `%s'",
+                 typestr);
+  g_free (typestr);
+
+  return NULL;
+}
+
+static GVariant *
+ast_resolve (AST     *ast,
+             GError **error)
+{
+  GVariant *value;
+  gchar *pattern;
+  gint i, j = 0;
+
+  pattern = ast_get_pattern (ast, error);
+
+  if (pattern == NULL)
+    return NULL;
+
+  /* choose reasonable defaults
+   *
+   *   1) favour non-maybe values where possible
+   *   2) default type for strings is 's'
+   *   3) default type for integers is 'i'
+   */
+  for (i = 0; pattern[i]; i++)
+    switch (pattern[i])
+      {
+      case '*':
+        ast_set_error (ast, error, NULL, "unable to infer type");
+        g_free (pattern);
+        return NULL;
+
+      case 'M':
+        break;
+
+      case 'S':
+        pattern[j++] = 's';
+        break;
+
+      case 'N':
+        pattern[j++] = 'i';
+        break;
+
+      default:
+        pattern[j++] = pattern[i];
+        break;
+      }
+  pattern[j++] = '\0';
+
+  value = ast_get_value (ast, G_VARIANT_TYPE (pattern), error);
+  g_free (pattern);
+
+  return value;
+}
+
+
+static AST *parse (TokenStream  *stream,
+                   va_list      *app,
+                   GError      **error);
+
+static void
+ast_array_append (AST  ***array,
+                  gint   *n_items,
+                  AST    *ast)
+{
+  if ((*n_items & (*n_items - 1)) == 0)
+    *array = g_renew (AST *, *array, *n_items ? 2 ** n_items : 1);
+
+  (*array)[(*n_items)++] = ast;
+}
+
+static void
+ast_array_free (AST  **array,
+                gint   n_items)
+{
+  gint i;
+
+  for (i = 0; i < n_items; i++)
+    ast_free (array[i]);
+  g_free (array);
+}
+
+static gchar *
+ast_array_get_pattern (AST    **array,
+                       gint     n_items,
+                       GError **error)
+{
+  gchar *pattern;
+  gint i;
+
+  pattern = ast_get_pattern (array[0], error);
+
+  if (pattern == NULL)
+    return NULL;
+
+  for (i = 1; i < n_items; i++)
+    {
+      gchar *tmp, *merged;
+
+      tmp = ast_get_pattern (array[i], error);
+
+      if (tmp == NULL)
+        {
+          g_free (pattern);
+          return NULL;
+        }
+
+      merged = pattern_coalesce (pattern, tmp);
+      g_free (pattern);
+      pattern = merged;
+
+      if (merged == NULL)
+        /* set coalescence implies pairwise coalescence (i think).
+         * we should therefore be able to trace the failure to a single
+         * pair of values.
+         */
+        {
+          int j = 0;
+
+          while (TRUE)
+            {
+              gchar *tmp2;
+              gchar *m;
+
+              /* if 'j' reaches 'i' then we failed to find the pair */
+              g_assert (j < i);
+
+              tmp2 = ast_get_pattern (array[j], NULL);
+              g_assert (tmp2 != NULL);
+
+              m = pattern_coalesce (tmp, tmp2);
+              g_free (tmp2);
+              g_free (m);
+
+              if (m == NULL)
+                {
+                  /* we found a conflict between 'i' and 'j'.
+                   *
+                   * report the error.  note: 'j' is first.
+                   */
+                  ast_set_error (array[j], error, array[i],
+                                 "unable to find a common type");
+                  g_free (tmp);
+                  return NULL;
+                }
+
+              j++;
+            }
+
+        }
+
+      g_free (tmp);
+    }
+
+  return pattern;
+}
+
+typedef struct
+{
+  AST ast;
+
+  AST *child;
+} Maybe;
+
+static gchar *
+maybe_get_pattern (AST     *ast,
+                   GError **error)
+{
+  Maybe *maybe = (Maybe *) ast;
+
+  if (maybe->child != NULL)
+    {
+      gchar *child_pattern;
+      gchar *pattern;
+
+      child_pattern = ast_get_pattern (maybe->child, error);
+
+      if (child_pattern == NULL)
+        return NULL;
+
+      pattern = g_strdup_printf ("m%s", child_pattern);
+      g_free (child_pattern);
+
+      return pattern;
+    }
+
+  return g_strdup ("m*");
+}
+
+static GVariant *
+maybe_get_value (AST                 *ast,
+                 const GVariantType  *type,
+                 GError             **error)
+{
+  Maybe *maybe = (Maybe *) ast;
+  GVariant *value;
+
+  if (!g_variant_type_is_maybe (type))
+    return ast_type_error (ast, type, error);
+
+  type = g_variant_type_element (type);
+
+  if (maybe->child)
+    {
+      value = ast_get_value (maybe->child, type, error);
+
+      if (value == NULL)
+        return NULL;
+    }
+  else
+    value = NULL;
+
+  return g_variant_new_maybe (type, value);
+}
+
+static void
+maybe_free (AST *ast)
+{
+  Maybe *maybe = (Maybe *) ast;
+
+  if (maybe->child != NULL)
+    ast_free (maybe->child);
+
+  g_slice_free (Maybe, maybe);
+}
+
+static AST *
+maybe_parse (TokenStream  *stream,
+             va_list      *app,
+             GError      **error)
+{
+  static const ASTClass maybe_class = {
+    maybe_get_pattern,
+    maybe_get_value, NULL,
+    maybe_free
+  };
+  AST *child = NULL;
+  Maybe *maybe;
+
+  if (token_stream_consume (stream, "just"))
+    {
+      child = parse (stream, app, error);
+      if (child == NULL)
+        return NULL;
+    }
+
+  else if (!token_stream_consume (stream, "nothing"))
+    {
+      token_stream_set_error (stream, error, TRUE, "unknown keyword");
+      return NULL;
+    }
+
+  maybe = g_slice_new (Maybe);
+  maybe->ast.class = &maybe_class;
+  maybe->child = child;
+
+  return (AST *) maybe;
+}
+
+static GVariant *
+maybe_wrapper (AST                 *ast,
+               const GVariantType  *type,
+               GError             **error)
+{
+  const GVariantType *t;
+  GVariant *value;
+  int depth;
+
+  for (depth = 0, t = type;
+       g_variant_type_is_maybe (t);
+       depth++, t = g_variant_type_element (t));
+
+  value = ast->class->get_base_value (ast, t, error);
+
+  if (value == NULL)
+    return NULL;
+
+  while (depth--)
+    value = g_variant_new_maybe (NULL, value);
+
+  return value;
+}
+
+typedef struct
+{
+  AST ast;
+
+  AST **children;
+  gint n_children;
+} Array;
+
+static gchar *
+array_get_pattern (AST     *ast,
+                   GError **error)
+{
+  Array *array = (Array *) ast;
+  gchar *pattern;
+  gchar *result;
+
+  if (array->n_children == 0)
+    return g_strdup ("Ma*");
+
+  pattern = ast_array_get_pattern (array->children, array->n_children, error);
+
+  if (pattern == NULL)
+    return NULL;
+
+  result = g_strdup_printf ("Ma%s", pattern);
+  g_free (pattern);
+
+  return result;
+}
+
+static GVariant *
+array_get_value (AST                 *ast,
+                 const GVariantType  *type,
+                 GError             **error)
+{
+  Array *array = (Array *) ast;
+  const GVariantType *childtype;
+  GVariantBuilder builder;
+  gint i;
+
+  if (!g_variant_type_is_array (type))
+    return ast_type_error (ast, type, error);
+
+  g_variant_builder_init (&builder, type);
+  childtype = g_variant_type_element (type);
+
+  for (i = 0; i < array->n_children; i++)
+    {
+      GVariant *child;
+
+      if (!(child = ast_get_value (array->children[i], childtype, error)))
+        {
+          g_variant_builder_clear (&builder);
+          return NULL;
+        }
+
+      g_variant_builder_add_value (&builder, child);
+    }
+
+  return g_variant_builder_end (&builder);
+}
+
+static void
+array_free (AST *ast)
+{
+  Array *array = (Array *) ast;
+
+  ast_array_free (array->children, array->n_children);
+  g_slice_free (Array, array);
+}
+
+static AST *
+array_parse (TokenStream  *stream,
+             va_list      *app,
+             GError      **error)
+{
+  static const ASTClass array_class = {
+    array_get_pattern,
+    maybe_wrapper, array_get_value,
+    array_free
+  };
+  gboolean need_comma = FALSE;
+  Array *array;
+
+  array = g_slice_new (Array);
+  array->ast.class = &array_class;
+  array->children = NULL;
+  array->n_children = 0;
+
+  token_stream_assert (stream, "[");
+  while (!token_stream_consume (stream, "]"))
+    {
+      AST *child;
+
+      if (need_comma &&
+          !token_stream_require (stream, ",",
+                                 " or `]' to follow array element",
+                                 error))
+        goto error;
+
+      child = parse (stream, app, error);
+
+      if (!child)
+        goto error;
+
+      ast_array_append (&array->children, &array->n_children, child);
+      need_comma = TRUE;
+    }
+
+  return (AST *) array;
+
+ error:
+  ast_array_free (array->children, array->n_children);
+  g_slice_free (Array, array);
+
+  return NULL;
+}
+
+typedef struct
+{
+  AST ast;
+
+  AST **children;
+  gint n_children;
+} Tuple;
+
+static gchar *
+tuple_get_pattern (AST     *ast,
+                   GError **error)
+{
+  Tuple *tuple = (Tuple *) ast;
+  gchar *result = NULL;
+  gchar **parts;
+  gint i;
+
+  parts = g_new (gchar *, tuple->n_children + 4);
+  parts[tuple->n_children + 1] = (gchar *) ")";
+  parts[tuple->n_children + 2] = NULL;
+  parts[0] = (gchar *) "M(";
+
+  for (i = 0; i < tuple->n_children; i++)
+    if (!(parts[i + 1] = ast_get_pattern (tuple->children[i], error)))
+      break;
+
+  if (i == tuple->n_children)
+    result = g_strjoinv ("", parts);
+
+  /* parts[0] should not be freed */
+  while (i)
+    g_free (parts[i--]);
+  g_free (parts);
+
+  return result;
+}
+
+static GVariant *
+tuple_get_value (AST                 *ast,
+                 const GVariantType  *type,
+                 GError             **error)
+{
+  Tuple *tuple = (Tuple *) ast;
+  const GVariantType *childtype;
+  GVariantBuilder builder;
+  gint i;
+
+  if (!g_variant_type_is_tuple (type))
+    return ast_type_error (ast, type, error);
+
+  g_variant_builder_init (&builder, type);
+  childtype = g_variant_type_first (type);
+
+  for (i = 0; i < tuple->n_children; i++)
+    {
+      GVariant *child;
+
+      if (!(child = ast_get_value (tuple->children[i], childtype, error)))
+        {
+          g_variant_builder_clear (&builder);
+          return FALSE;
+        }
+
+      g_variant_builder_add_value (&builder, child);
+      childtype = g_variant_type_next (childtype);
+    }
+
+  return g_variant_builder_end (&builder);
+}
+
+static void
+tuple_free (AST *ast)
+{
+  Tuple *tuple = (Tuple *) ast;
+
+  ast_array_free (tuple->children, tuple->n_children);
+  g_slice_free (Tuple, tuple);
+}
+
+static AST *
+tuple_parse (TokenStream  *stream,
+             va_list      *app,
+             GError      **error)
+{
+  static const ASTClass tuple_class = {
+    tuple_get_pattern,
+    maybe_wrapper, tuple_get_value,
+    tuple_free
+  };
+  gboolean need_comma = FALSE;
+  gboolean first = TRUE;
+  Tuple *tuple;
+
+  tuple = g_slice_new (Tuple);
+  tuple->ast.class = &tuple_class;
+  tuple->children = NULL;
+  tuple->n_children = 0;
+
+  token_stream_assert (stream, "(");
+  while (!token_stream_consume (stream, ")"))
+    {
+      AST *child;
+
+      if (need_comma &&
+          !token_stream_require (stream, ",",
+                                 " or `)' to follow tuple element",
+                                 error))
+        goto error;
+
+      child = parse (stream, app, error);
+
+      if (!child)
+        goto error;
+
+      ast_array_append (&tuple->children, &tuple->n_children, child);
+
+      /* the first time, we absolutely require a comma, so grab it here
+       * and leave need_comma = FALSE so that the code above doesn't
+       * require a second comma.
+       *
+       * the second and remaining times, we set need_comma = TRUE.
+       */
+      if (first)
+        {
+          if (!token_stream_require (stream, ",",
+                                     " after first tuple element", error))
+            goto error;
+
+          first = FALSE;
+        }
+      else
+        need_comma = TRUE;
+    }
+
+  return (AST *) tuple;
+
+ error:
+  ast_array_free (tuple->children, tuple->n_children);
+  g_slice_free (Tuple, tuple);
+
+  return NULL;
+}
+
+typedef struct
+{
+  AST ast;
+
+  AST *value;
+} Variant;
+
+static gchar *
+variant_get_pattern (AST     *ast,
+                     GError **error)
+{
+  return g_strdup ("Mv");
+}
+
+static GVariant *
+variant_get_value (AST                 *ast,
+                   const GVariantType  *type,
+                   GError             **error)
+{
+  Variant *variant = (Variant *) ast;
+  GVariant *child;
+
+  g_assert (g_variant_type_equal (type, G_VARIANT_TYPE_VARIANT));
+  child = ast_resolve (variant->value, error);
+
+  if (child == NULL)
+    return NULL;
+
+  return g_variant_new_variant (child);
+}
+
+static void
+variant_free (AST *ast)
+{
+  Variant *variant = (Variant *) ast;
+
+  ast_free (variant->value);
+  g_slice_free (Variant, variant);
+}
+
+static AST *
+variant_parse (TokenStream  *stream,
+               va_list      *app,
+               GError      **error)
+{
+  static const ASTClass variant_class = {
+    variant_get_pattern,
+    maybe_wrapper, variant_get_value,
+    variant_free
+  };
+  Variant *variant;
+  AST *value;
+
+  token_stream_assert (stream, "<");
+  value = parse (stream, app, error);
+
+  if (!value)
+    return NULL;
+
+  if (!token_stream_require (stream, ">", " to follow variant value", error))
+    {
+      ast_free (value);
+      return NULL;
+    }
+
+  variant = g_slice_new (Variant);
+  variant->ast.class = &variant_class;
+  variant->value = value;
+
+  return (AST *) variant;
+}
+
+typedef struct
+{
+  AST ast;
+
+  AST **keys;
+  AST **values;
+  gint n_children;
+} Dictionary;
+
+static gchar *
+dictionary_get_pattern (AST     *ast,
+                        GError **error)
+{
+  Dictionary *dict = (Dictionary *) ast;
+  gchar *value_pattern;
+  gchar *key_pattern;
+  gchar key_char;
+  gchar *result;
+
+  if (dict->n_children == 0)
+    return g_strdup ("Ma{**}");
+
+  key_pattern = ast_array_get_pattern (dict->keys,
+                                       abs (dict->n_children),
+                                       error);
+
+  if (key_pattern == NULL)
+    return NULL;
+
+  /* we can not have maybe keys */
+  if (key_pattern[0] == 'M')
+    key_char = key_pattern[1];
+  else
+    key_char = key_pattern[0];
+
+  g_free (key_pattern);
+
+  /* the basic types,
+   * plus undetermined number type and undetermined string type.
+   */
+  if (!strchr ("bynqiuxthdsogNS", key_char))
+    {
+      ast_set_error (ast, error, NULL,
+                     "dictionary keys must have basic types");
+      return NULL;
+    }
+
+  value_pattern = ast_get_pattern (dict->values[0], error);
+
+  if (value_pattern == NULL)
+    return NULL;
+
+  result = g_strdup_printf ("M%s{%c%s}",
+                            dict->n_children > 0 ? "a" : "",
+                            key_char, value_pattern);
+  g_free (value_pattern);
+
+  return result;
+}
+
+static GVariant *
+dictionary_get_value (AST                 *ast,
+                      const GVariantType  *type,
+                      GError             **error)
+{
+  Dictionary *dict = (Dictionary *) ast;
+
+  if (dict->n_children == -1)
+    {
+      const GVariantType *subtype;
+      GVariantBuilder builder;
+      GVariant *subvalue;
+
+      if (!g_variant_type_is_dict_entry (type))
+        return ast_type_error (ast, type, error);
+
+      g_variant_builder_init (&builder, type);
+
+      subtype = g_variant_type_key (type);
+      if (!(subvalue = ast_get_value (dict->keys[0], subtype, error)))
+        {
+          g_variant_builder_clear (&builder);
+          return NULL;
+        }
+      g_variant_builder_add_value (&builder, subvalue);
+
+      subtype = g_variant_type_value (type);
+      if (!(subvalue = ast_get_value (dict->values[0], subtype, error)))
+        {
+          g_variant_builder_clear (&builder);
+          return NULL;
+        }
+      g_variant_builder_add_value (&builder, subvalue);
+
+      return g_variant_builder_end (&builder);
+    }
+  else
+    {
+      const GVariantType *entry, *key, *val;
+      GVariantBuilder builder;
+      gint i;
+
+      if (!g_variant_type_is_subtype_of (type, G_VARIANT_TYPE_DICTIONARY))
+        return ast_type_error (ast, type, error);
+
+      entry = g_variant_type_element (type);
+      key = g_variant_type_key (entry);
+      val = g_variant_type_value (entry);
+
+      g_variant_builder_init (&builder, type);
+
+      for (i = 0; i < dict->n_children; i++)
+        {
+          GVariant *subvalue;
+
+          g_variant_builder_open (&builder, entry);
+
+          if (!(subvalue = ast_get_value (dict->keys[i], key, error)))
+            {
+              g_variant_builder_clear (&builder);
+              return NULL;
+            }
+          g_variant_builder_add_value (&builder, subvalue);
+
+          if (!(subvalue = ast_get_value (dict->values[i], val, error)))
+            {
+              g_variant_builder_clear (&builder);
+              return NULL;
+            }
+          g_variant_builder_add_value (&builder, subvalue);
+          g_variant_builder_close (&builder);
+        }
+
+      return g_variant_builder_end (&builder);
+    }
+}
+
+static void
+dictionary_free (AST *ast)
+{
+  Dictionary *dict = (Dictionary *) ast;
+  gint n_children;
+
+  if (dict->n_children > -1)
+    n_children = dict->n_children;
+  else
+    n_children = 1;
+
+  ast_array_free (dict->keys, n_children);
+  ast_array_free (dict->values, n_children);
+  g_slice_free (Dictionary, dict);
+}
+
+static AST *
+dictionary_parse (TokenStream  *stream,
+                  va_list      *app,
+                  GError      **error)
+{
+  static const ASTClass dictionary_class = {
+    dictionary_get_pattern,
+    maybe_wrapper, dictionary_get_value,
+    dictionary_free
+  };
+  gint n_keys, n_values;
+  gboolean only_one;
+  Dictionary *dict;
+  AST *first;
+
+  dict = g_slice_new (Dictionary);
+  dict->ast.class = &dictionary_class;
+  dict->keys = NULL;
+  dict->values = NULL;
+  n_keys = n_values = 0;
+
+  token_stream_assert (stream, "{");
+
+  if (token_stream_consume (stream, "}"))
+    {
+      dict->n_children = 0;
+      return (AST *) dict;
+    }
+
+  if ((first = parse (stream, app, error)) == NULL)
+    goto error;
+
+  ast_array_append (&dict->keys, &n_keys, first);
+
+  only_one = token_stream_consume (stream, ",");
+  if (!only_one &&
+      !token_stream_require (stream, ":",
+                             " or `,' to follow dictionary entry key",
+                             error))
+    goto error;
+
+  if ((first = parse (stream, app, error)) == NULL)
+    goto error;
+
+  ast_array_append (&dict->values, &n_values, first);
+
+  if (only_one)
+    {
+      if (!token_stream_require (stream, "}", " at end of dictionary entry",
+                                 error))
+        goto error;
+
+      g_assert (n_keys == 1 && n_values == 1);
+      dict->n_children = -1;
+
+      return (AST *) dict;
+    }
+
+  while (!token_stream_consume (stream, "}"))
+    {
+      AST *child;
+
+      if (!token_stream_require (stream, ",",
+                                 " or `}' to follow dictionary entry", error))
+        goto error;
+
+      child = parse (stream, app, error);
+
+      if (!child)
+        goto error;
+
+      ast_array_append (&dict->keys, &n_keys, child);
+
+      if (!token_stream_require (stream, ":",
+                                 " to follow dictionary entry key", error))
+        goto error;
+
+      child = parse (stream, app, error);
+
+      if (!child)
+        goto error;
+
+      ast_array_append (&dict->values, &n_values, child);
+    }
+
+  g_assert (n_keys == n_values);
+  dict->n_children = n_keys;
+
+  return (AST *) dict;
+
+ error:
+  ast_array_free (dict->keys, n_keys);
+  ast_array_free (dict->values, n_values);
+  g_slice_free (Dictionary, dict);
+
+  return NULL;
+}
+
+typedef struct
+{
+  AST ast;
+  gchar *string;
+} String;
+
+static gchar *
+string_get_pattern (AST     *ast,
+                    GError **error)
+{
+  return g_strdup ("MS");
+}
+
+static GVariant *
+string_get_value (AST                 *ast,
+                  const GVariantType  *type,
+                  GError             **error)
+{
+  String *string = (String *) ast;
+
+  if (g_variant_type_equal (type, G_VARIANT_TYPE_STRING))
+    return g_variant_new_string (string->string);
+
+  else if (g_variant_type_equal (type, G_VARIANT_TYPE_OBJECT_PATH))
+    {
+      if (!g_variant_is_object_path (string->string))
+        {
+          ast_set_error (ast, error, NULL, "not a valid object path");
+          return NULL;
+        }
+
+      return g_variant_new_object_path (string->string);
+    }
+
+  else if (g_variant_type_equal (type, G_VARIANT_TYPE_SIGNATURE))
+    {
+      if (!g_variant_is_signature (string->string))
+        {
+          ast_set_error (ast, error, NULL, "not a valid signature");
+          return NULL;
+        }
+
+      return g_variant_new_signature (string->string);
+    }
+
+  else
+    return ast_type_error (ast, type, error);
+}
+
+static void
+string_free (AST *ast)
+{
+  String *string = (String *) ast;
+
+  g_free (string->string);
+  g_slice_free (String, string);
+}
+
+static gboolean
+unicode_unescape (const gchar  *src,
+                  gint         *src_ofs,
+                  gchar        *dest,
+                  gint         *dest_ofs,
+                  gint          length,
+                  SourceRef    *ref,
+                  GError      **error)
+{
+  gchar buffer[9];
+  guint64 value;
+  gchar *end;
+
+  (*src_ofs)++;
+
+  g_assert (length < sizeof (buffer));
+  strncpy (buffer, src + *src_ofs, length);
+  buffer[length] = '\0';
+
+  value = g_ascii_strtoull (buffer, &end, 0x10);
+
+  if (value == 0 || end != buffer + length)
+    {
+      parser_set_error (error, ref, NULL,
+                        "invalid %d-character unicode escape", length);
+      return FALSE;
+    }
+
+  g_assert (value <= G_MAXUINT32);
+
+  *dest_ofs += g_unichar_to_utf8 (value, dest + *dest_ofs);
+  *src_ofs += length;
+
+  return TRUE;
+}
+
+static AST *
+string_parse (TokenStream  *stream,
+              va_list      *app,
+              GError      **error)
+{
+  static const ASTClass string_class = {
+    string_get_pattern,
+    maybe_wrapper, string_get_value,
+    string_free
+  };
+  String *string;
+  SourceRef ref;
+  gchar *token;
+  gsize length;
+  gchar quote;
+  gchar *str;
+  gint i, j;
+
+  token_stream_start_ref (stream, &ref);
+  token = token_stream_get (stream);
+  token_stream_end_ref (stream, &ref);
+  length = strlen (token);
+  quote = token[0];
+
+  str = g_malloc (length);
+  g_assert (quote == '"' || quote == '\'');
+  j = 0;
+  i = 1;
+  while (token[i] != quote)
+    switch (token[i])
+      {
+      case '\0':
+        parser_set_error (error, &ref, NULL,
+                          "unterminated string constant");
+        g_free (token);
+        g_free (str);
+        return NULL;
+
+      case '\\':
+        switch (token[++i])
+          {
+          case '\0':
+            parser_set_error (error, &ref, NULL,
+                              "unterminated string constant");
+            g_free (token);
+            g_free (str);
+            return NULL;
+
+          case 'u':
+            if (!unicode_unescape (token, &i, str, &j, 4, &ref, error))
+              {
+                g_free (token);
+                g_free (str);
+                return NULL;
+              }
+            continue;
+
+          case 'U':
+            if (!unicode_unescape (token, &i, str, &j, 8, &ref, error))
+              {
+                g_free (token);
+                g_free (str);
+                return NULL;
+              }
+            continue;
+
+          case 'a': str[j++] = '\a'; i++; continue;
+          case 'b': str[j++] = '\b'; i++; continue;
+          case 'f': str[j++] = '\f'; i++; continue;
+          case 'n': str[j++] = '\n'; i++; continue;
+          case 'r': str[j++] = '\r'; i++; continue;
+          case 't': str[j++] = '\t'; i++; continue;
+          case 'v': str[j++] = '\v'; i++; continue;
+          case '\n': i++; continue;
+          }
+
+      default:
+        str[j++] = token[i++];
+      }
+  str[j++] = '\0';
+  g_free (token);
+
+  string = g_slice_new (String);
+  string->ast.class = &string_class;
+  string->string = str;
+
+  token_stream_next (stream);
+
+  return (AST *) string;
+}
+
+typedef struct
+{
+  AST ast;
+  gchar *string;
+} ByteString;
+
+static gchar *
+bytestring_get_pattern (AST     *ast,
+                        GError **error)
+{
+  return g_strdup ("May");
+}
+
+static GVariant *
+bytestring_get_value (AST                 *ast,
+                      const GVariantType  *type,
+                      GError             **error)
+{
+  ByteString *string = (ByteString *) ast;
+
+  g_assert (g_variant_type_equal (type, G_VARIANT_TYPE_BYTESTRING));
+
+  return g_variant_new_bytestring (string->string);
+}
+
+static void
+bytestring_free (AST *ast)
+{
+  ByteString *string = (ByteString *) ast;
+
+  g_free (string->string);
+  g_slice_free (ByteString, string);
+}
+
+static AST *
+bytestring_parse (TokenStream  *stream,
+                  va_list      *app,
+                  GError      **error)
+{
+  static const ASTClass bytestring_class = {
+    bytestring_get_pattern,
+    maybe_wrapper, bytestring_get_value,
+    bytestring_free
+  };
+  ByteString *string;
+  SourceRef ref;
+  gchar *token;
+  gsize length;
+  gchar quote;
+  gchar *str;
+  gint i, j;
+
+  token_stream_start_ref (stream, &ref);
+  token = token_stream_get (stream);
+  token_stream_end_ref (stream, &ref);
+  g_assert (token[0] == 'b');
+  length = strlen (token);
+  quote = token[1];
+
+  str = g_malloc (length);
+  g_assert (quote == '"' || quote == '\'');
+  j = 0;
+  i = 2;
+  while (token[i] != quote)
+    switch (token[i])
+      {
+      case '\0':
+        parser_set_error (error, &ref, NULL,
+                          "unterminated string constant");
+        g_free (token);
+        return NULL;
+
+      case '\\':
+        switch (token[++i])
+          {
+          case '\0':
+            parser_set_error (error, &ref, NULL,
+                              "unterminated string constant");
+            g_free (token);
+            return NULL;
+
+          case '0': case '1': case '2': case '3':
+          case '4': case '5': case '6': case '7':
+            {
+              /* up to 3 characters */
+              guchar val = token[i++] - '0';
+
+              if ('0' <= token[i] && token[i] < '8')
+                val = (val << 3) | (token[i++] - '0');
+
+              if ('0' <= token[i] && token[i] < '8')
+                val = (val << 3) | (token[i++] - '0');
+
+              str[j++] = val;
+            }
+            continue;
+
+          case 'a': str[j++] = '\a'; i++; continue;
+          case 'b': str[j++] = '\b'; i++; continue;
+          case 'f': str[j++] = '\f'; i++; continue;
+          case 'n': str[j++] = '\n'; i++; continue;
+          case 'r': str[j++] = '\r'; i++; continue;
+          case 't': str[j++] = '\t'; i++; continue;
+          case 'v': str[j++] = '\v'; i++; continue;
+          case '\n': i++; continue;
+          }
+
+      default:
+        str[j++] = token[i++];
+      }
+  str[j++] = '\0';
+  g_free (token);
+
+  string = g_slice_new (ByteString);
+  string->ast.class = &bytestring_class;
+  string->string = str;
+
+  token_stream_next (stream);
+
+  return (AST *) string;
+}
+
+typedef struct
+{
+  AST ast;
+
+  gchar *token;
+} Number;
+
+static gchar *
+number_get_pattern (AST     *ast,
+                    GError **error)
+{
+  Number *number = (Number *) ast;
+
+  if (strchr (number->token, '.') ||
+      (!g_str_has_prefix (number->token, "0x") &&
+       strchr (number->token, 'e')))
+    return g_strdup ("Md");
+
+  return g_strdup ("MN");
+}
+
+static GVariant *
+number_overflow (AST                 *ast,
+                 const GVariantType  *type,
+                 GError             **error)
+{
+  ast_set_error (ast, error, NULL, "number out of range for type `%c'",
+                 g_variant_type_peek_string (type)[0]);
+  return NULL;
+}
+
+static GVariant *
+number_get_value (AST                 *ast,
+                  const GVariantType  *type,
+                  GError             **error)
+{
+  Number *number = (Number *) ast;
+  const gchar *token;
+  gboolean negative;
+  gboolean floating;
+  guint64 abs_val;
+  gdouble dbl_val;
+  gchar *end;
+
+  token = number->token;
+
+  if (g_variant_type_equal (type, G_VARIANT_TYPE_DOUBLE))
+    {
+      floating = TRUE;
+
+      errno = 0;
+      dbl_val = g_ascii_strtod (token, &end);
+      if (dbl_val != 0.0 && errno == ERANGE)
+        {
+          ast_set_error (ast, error, NULL, "number too big for any type");
+          return NULL;
+        }
+
+      /* silence uninitialised warnings... */
+      negative = FALSE;
+      abs_val = 0;
+    }
+  else
+    {
+      floating = FALSE;
+      negative = token[0] == '-';
+      if (token[0] == '-')
+        token++;
+
+      errno = 0;
+      abs_val = g_ascii_strtoull (token, &end, 0);
+      if (abs_val == G_MAXUINT64 && errno == ERANGE)
+        {
+          ast_set_error (ast, error, NULL, "integer too big for any type");
+          return NULL;
+        }
+
+      if (abs_val == 0)
+        negative = FALSE;
+
+      /* silence uninitialised warning... */
+      dbl_val = 0.0;
+    }
+
+  if (*end != '\0')
+    {
+      SourceRef ref;
+
+      ref = ast->source_ref;
+      ref.start += end - number->token;
+      ref.end = ref.start + 1;
+
+      parser_set_error (error, &ref, NULL,
+                        "invalid character in number");
+      return NULL;
+     }
+
+  if (floating)
+    return g_variant_new_double (dbl_val);
+
+  switch (*g_variant_type_peek_string (type))
+    {
+    case 'y':
+      if (negative || abs_val > G_MAXUINT8)
+        return number_overflow (ast, type, error);
+      return g_variant_new_byte (abs_val);
+
+    case 'n':
+      if (abs_val - negative > G_MAXINT16)
+        return number_overflow (ast, type, error);
+      return g_variant_new_int16 (negative ? -abs_val : abs_val);
+
+    case 'q':
+      if (negative || abs_val > G_MAXUINT16)
+        return number_overflow (ast, type, error);
+      return g_variant_new_uint16 (negative ? -abs_val : abs_val);
+
+    case 'i':
+      if (abs_val - negative > G_MAXINT32)
+        return number_overflow (ast, type, error);
+      return g_variant_new_int32 (negative ? -abs_val : abs_val);
+
+    case 'u':
+      if (negative || abs_val > G_MAXUINT32)
+        return number_overflow (ast, type, error);
+      return g_variant_new_uint32 (negative ? -abs_val : abs_val);
+
+    case 'x':
+      if (abs_val - negative > G_MAXINT64)
+        return number_overflow (ast, type, error);
+      return g_variant_new_int64 (negative ? -abs_val : abs_val);
+
+    case 't':
+      if (negative)
+        return number_overflow (ast, type, error);
+      return g_variant_new_uint64 (negative ? -abs_val : abs_val);
+
+    case 'h':
+      if (abs_val - negative > G_MAXINT32)
+        return number_overflow (ast, type, error);
+      return g_variant_new_handle (negative ? -abs_val : abs_val);
+
+    default:
+      return ast_type_error (ast, type, error);
+    }
+}
+
+static void
+number_free (AST *ast)
+{
+  Number *number = (Number *) ast;
+
+  g_free (number->token);
+  g_slice_free (Number, number);
+}
+
+static AST *
+number_parse (TokenStream  *stream,
+              va_list      *app,
+              GError      **error)
+{
+  static const ASTClass number_class = {
+    number_get_pattern,
+    maybe_wrapper, number_get_value,
+    number_free
+  };
+  Number *number;
+
+  number = g_slice_new (Number);
+  number->ast.class = &number_class;
+  number->token = token_stream_get (stream);
+  token_stream_next (stream);
+
+  return (AST *) number;
+}
+
+typedef struct
+{
+  AST ast;
+  gboolean value;
+} Boolean;
+
+static gchar *
+boolean_get_pattern (AST     *ast,
+                     GError **error)
+{
+  return g_strdup ("Mb");
+}
+
+static GVariant *
+boolean_get_value (AST                 *ast,
+                   const GVariantType  *type,
+                   GError             **error)
+{
+  Boolean *boolean = (Boolean *) ast;
+
+  if (!g_variant_type_equal (type, G_VARIANT_TYPE_BOOLEAN))
+    return ast_type_error (ast, type, error);
+
+  return g_variant_new_boolean (boolean->value);
+}
+
+static void
+boolean_free (AST *ast)
+{
+  Boolean *boolean = (Boolean *) ast;
+
+  g_slice_free (Boolean, boolean);
+}
+
+static AST *
+boolean_new (gboolean value)
+{
+  static const ASTClass boolean_class = {
+    boolean_get_pattern,
+    maybe_wrapper, boolean_get_value,
+    boolean_free
+  };
+  Boolean *boolean;
+
+  boolean = g_slice_new (Boolean);
+  boolean->ast.class = &boolean_class;
+  boolean->value = value;
+
+  return (AST *) boolean;
+}
+
+typedef struct
+{
+  AST ast;
+
+  GVariant *value;
+} Positional;
+
+static gchar *
+positional_get_pattern (AST     *ast,
+                        GError **error)
+{
+  Positional *positional = (Positional *) ast;
+
+  return g_strdup (g_variant_get_type_string (positional->value));
+}
+
+static GVariant *
+positional_get_value (AST                 *ast,
+                      const GVariantType  *type,
+                      GError             **error)
+{
+  Positional *positional = (Positional *) ast;
+  GVariant *value;
+
+  g_assert (positional->value != NULL);
+
+  if G_UNLIKELY (!g_variant_is_of_type (positional->value, type))
+    return ast_type_error (ast, type, error);
+
+  /* NOTE: if _get is called more than once then
+   * things get messed up with respect to floating refs.
+   *
+   * fortunately, this function should only ever get called once.
+   */
+  g_assert (positional->value != NULL);
+  value = positional->value;
+  positional->value = NULL;
+
+  return value;
+}
+
+static void
+positional_free (AST *ast)
+{
+  Positional *positional = (Positional *) ast;
+
+  /* if positional->value is set, just leave it.
+   * memory management doesn't matter in case of programmer error.
+   */
+  g_slice_free (Positional, positional);
+}
+
+static AST *
+positional_parse (TokenStream  *stream,
+                  va_list      *app,
+                  GError      **error)
+{
+  static const ASTClass positional_class = {
+    positional_get_pattern,
+    positional_get_value, NULL,
+    positional_free
+  };
+  Positional *positional;
+  const gchar *endptr;
+  gchar *token;
+
+  token = token_stream_get (stream);
+  g_assert (token[0] == '%');
+
+  positional = g_slice_new (Positional);
+  positional->ast.class = &positional_class;
+  positional->value = g_variant_new_va (token + 1, &endptr, app);
+
+  if (*endptr || positional->value == NULL)
+    {
+      token_stream_set_error (stream, error, TRUE,
+                              "invalid GVariant format string");
+      /* memory management doesn't matter in case of programmer error. */
+      return NULL;
+    }
+
+  token_stream_next (stream);
+  g_free (token);
+
+  return (AST *) positional;
+}
+
+typedef struct
+{
+  AST ast;
+
+  GVariantType *type;
+  AST *child;
+} TypeDecl;
+
+static gchar *
+typedecl_get_pattern (AST     *ast,
+                      GError **error)
+{
+  TypeDecl *decl = (TypeDecl *) ast;
+
+  return g_variant_type_dup_string (decl->type);
+}
+
+static GVariant *
+typedecl_get_value (AST                 *ast,
+                    const GVariantType  *type,
+                    GError             **error)
+{
+  TypeDecl *decl = (TypeDecl *) ast;
+
+  return ast_get_value (decl->child, type, error);
+}
+
+static void
+typedecl_free (AST *ast)
+{
+  TypeDecl *decl = (TypeDecl *) ast;
+
+  ast_free (decl->child);
+  g_variant_type_free (decl->type);
+  g_slice_free (TypeDecl, decl);
+}
+
+static AST *
+typedecl_parse (TokenStream  *stream,
+                va_list      *app,
+                GError      **error)
+{
+  static const ASTClass typedecl_class = {
+    typedecl_get_pattern,
+    typedecl_get_value, NULL,
+    typedecl_free
+  };
+  GVariantType *type;
+  TypeDecl *decl;
+  AST *child;
+
+  if (token_stream_peek (stream, '@'))
+    {
+      gchar *token;
+
+      token = token_stream_get (stream);
+
+      if (!g_variant_type_string_is_valid (token + 1))
+        {
+          token_stream_set_error (stream, error, TRUE,
+                                  "invalid type declaration");
+          g_free (token);
+
+          return NULL;
+        }
+
+      type = g_variant_type_new (token + 1);
+
+      if (!g_variant_type_is_definite (type))
+        {
+          token_stream_set_error (stream, error, TRUE,
+                                  "type declarations must be definite");
+          g_variant_type_free (type);
+          g_free (token);
+
+          return NULL;
+        }
+
+      token_stream_next (stream);
+      g_free (token);
+    }
+  else
+    {
+      if (token_stream_consume (stream, "boolean"))
+        type = g_variant_type_copy (G_VARIANT_TYPE_BOOLEAN);
+
+      else if (token_stream_consume (stream, "byte"))
+        type = g_variant_type_copy (G_VARIANT_TYPE_BYTE);
+
+      else if (token_stream_consume (stream, "int16"))
+        type = g_variant_type_copy (G_VARIANT_TYPE_INT16);
+
+      else if (token_stream_consume (stream, "uint16"))
+        type = g_variant_type_copy (G_VARIANT_TYPE_UINT16);
+
+      else if (token_stream_consume (stream, "int32"))
+        type = g_variant_type_copy (G_VARIANT_TYPE_INT32);
+
+      else if (token_stream_consume (stream, "handle"))
+        type = g_variant_type_copy (G_VARIANT_TYPE_HANDLE);
+
+      else if (token_stream_consume (stream, "uint32"))
+        type = g_variant_type_copy (G_VARIANT_TYPE_UINT32);
+
+      else if (token_stream_consume (stream, "int64"))
+        type = g_variant_type_copy (G_VARIANT_TYPE_INT64);
+
+      else if (token_stream_consume (stream, "uint64"))
+        type = g_variant_type_copy (G_VARIANT_TYPE_UINT64);
+
+      else if (token_stream_consume (stream, "double"))
+        type = g_variant_type_copy (G_VARIANT_TYPE_DOUBLE);
+
+      else if (token_stream_consume (stream, "string"))
+        type = g_variant_type_copy (G_VARIANT_TYPE_STRING);
+
+      else if (token_stream_consume (stream, "objectpath"))
+        type = g_variant_type_copy (G_VARIANT_TYPE_OBJECT_PATH);
+
+      else if (token_stream_consume (stream, "signature"))
+        type = g_variant_type_copy (G_VARIANT_TYPE_SIGNATURE);
+
+      else
+        {
+          token_stream_set_error (stream, error, TRUE, "unknown keyword");
+          return NULL;
+        }
+    }
+
+  if ((child = parse (stream, app, error)) == NULL)
+    {
+      g_variant_type_free (type);
+      return NULL;
+    }
+
+  decl = g_slice_new (TypeDecl);
+  decl->ast.class = &typedecl_class;
+  decl->type = type;
+  decl->child = child;
+
+  return (AST *) decl;
+}
+
+static AST *
+parse (TokenStream  *stream,
+       va_list      *app,
+       GError      **error)
+{
+  SourceRef source_ref;
+  AST *result;
+
+  token_stream_prepare (stream);
+  token_stream_start_ref (stream, &source_ref);
+
+  if (token_stream_peek (stream, '['))
+    result = array_parse (stream, app, error);
+
+  else if (token_stream_peek (stream, '('))
+    result = tuple_parse (stream, app, error);
+
+  else if (token_stream_peek (stream, '<'))
+    result = variant_parse (stream, app, error);
+
+  else if (token_stream_peek (stream, '{'))
+    result = dictionary_parse (stream, app, error);
+
+  else if (app && token_stream_peek (stream, '%'))
+    result = positional_parse (stream, app, error);
+
+  else if (token_stream_consume (stream, "true"))
+    result = boolean_new (TRUE);
+
+  else if (token_stream_consume (stream, "false"))
+    result = boolean_new (FALSE);
+
+  else if (token_stream_peek (stream, 'n') ||
+           token_stream_peek (stream, 'j'))
+    result = maybe_parse (stream, app, error);
+
+  else if (token_stream_peek (stream, '@') ||
+           token_stream_is_keyword (stream))
+    result = typedecl_parse (stream, app, error);
+
+  else if (token_stream_is_numeric (stream))
+    result = number_parse (stream, app, error);
+
+  else if (token_stream_peek (stream, '\'') ||
+           token_stream_peek (stream, '"'))
+    result = string_parse (stream, app, error);
+
+  else if (token_stream_peek2 (stream, 'b', '\'') ||
+           token_stream_peek2 (stream, 'b', '"'))
+    result = bytestring_parse (stream, app, error);
+
+  else
+    {
+      token_stream_set_error (stream, error, FALSE, "expected value");
+      return NULL;
+    }
+
+  if (result != NULL)
+    {
+      token_stream_end_ref (stream, &source_ref);
+      result->source_ref = source_ref;
+    }
+
+  return result;
+}
+
+/**
+ * g_variant_parse:
+ * @type: a #GVariantType, or %NULL
+ * @text: a string containing a GVariant in text form
+ * @limit: a pointer to the end of @text, or %NULL
+ * @endptr: a location to store the end pointer, or %NULL
+ * @error: a pointer to a %NULL #GError pointer, or %NULL
+ * @Returns: a reference to a #GVariant, or %NULL
+ *
+ * Parses a #GVariant from a text representation.
+ *
+ * A single #GVariant is parsed from the content of @text.
+ *
+ * The memory at @limit will never be accessed and the parser behaves as
+ * if the character at @limit is the nul terminator.  This has the
+ * effect of bounding @text.
+ *
+ * If @endptr is non-%NULL then @text is permitted to contain data
+ * following the value that this function parses and @endptr will be
+ * updated to point to the first character past the end of the text
+ * parsed by this function.  If @endptr is %NULL and there is extra data
+ * then an error is returned.
+ *
+ * If @type is non-%NULL then the value will be parsed to have that
+ * type.  This may result in additional parse errors (in the case that
+ * the parsed value doesn't fit the type) but may also result in fewer
+ * errors (in the case that the type would have been ambiguous, such as
+ * with empty arrays).
+ *
+ * In the event that the parsing is successful, the resulting #GVariant
+ * is returned.
+ *
+ * In case of any error, %NULL will be returned.  If @error is non-%NULL
+ * then it will be set to reflect the error that occured.
+ *
+ * Officially, the language understood by the parser is "any string
+ * produced by g_variant_print()".
+ **/
+GVariant *
+g_variant_parse (const GVariantType  *type,
+                 const gchar         *text,
+                 const gchar         *limit,
+                 const gchar        **endptr,
+                 GError             **error)
+{
+  TokenStream stream = { 0, };
+  GVariant *result = NULL;
+  AST *ast;
+
+  g_return_val_if_fail (text != NULL, NULL);
+  g_return_val_if_fail (text == limit || text != NULL, NULL);
+
+  stream.start = text;
+  stream.stream = text;
+  stream.end = limit;
+
+  if ((ast = parse (&stream, NULL, error)))
+    {
+      if (type == NULL)
+        result = ast_resolve (ast, error);
+      else
+        result = ast_get_value (ast, type, error);
+
+      if (result != NULL)
+        {
+          g_variant_ref_sink (result);
+
+          if (endptr == NULL)
+            {
+              while (stream.stream != limit &&
+                     g_ascii_isspace (*stream.stream))
+                stream.stream++;
+
+              if (stream.stream != limit && *stream.stream != '\0')
+                {
+                  SourceRef ref = { stream.stream - text,
+                                    stream.stream - text };
+
+                  parser_set_error (error, &ref, NULL,
+                                    "expected end of input");
+                  g_variant_unref (result);
+
+                  result = NULL;
+                }
+            }
+          else
+            *endptr = stream.stream;
+        }
+
+      ast_free (ast);
+    }
+
+  return result;
+}
+
+/**
+ * g_variant_new_parsed_va:
+ * @format: a text format #GVariant
+ * @app: a pointer to a #va_list
+ * @returns: a new, usually floating, #GVariant
+ *
+ * Parses @format and returns the result.
+ *
+ * This is the version of g_variant_new_parsed() intended to be used
+ * from libraries.
+ *
+ * The return value will be floating if it was a newly created GVariant
+ * instance.  In the case that @format simply specified the collection
+ * of a #GVariant pointer (eg: @format was "%*") then the collected
+ * #GVariant pointer will be returned unmodified, without adding any
+ * additional references.
+ *
+ * In order to behave correctly in all cases it is necessary for the
+ * calling function to g_variant_ref_sink() the return result before
+ * returning control to the user that originally provided the pointer.
+ * At this point, the caller will have their own full reference to the
+ * result.  This can also be done by adding the result to a container,
+ * or by passing it to another g_variant_new() call.
+ **/
+GVariant *
+g_variant_new_parsed_va (const gchar *format,
+                         va_list     *app)
+{
+  TokenStream stream = { 0, };
+  GVariant *result = NULL;
+  GError *error = NULL;
+  AST *ast;
+
+  g_return_val_if_fail (format != NULL, NULL);
+  g_return_val_if_fail (app != NULL, NULL);
+
+  stream.start = format;
+  stream.stream = format;
+  stream.end = NULL;
+
+  if ((ast = parse (&stream, app, &error)))
+    {
+      result = ast_resolve (ast, &error);
+      ast_free (ast);
+    }
+
+  if (result == NULL)
+    g_error ("g_variant_new_parsed: %s", error->message);
+
+  if (*stream.stream)
+    g_error ("g_variant_new_parsed: trailing text after value");
+
+  return result;
+}
+
+/**
+ * g_variant_new_parsed:
+ * @format: a text format #GVariant
+ * @...: arguments as per @format
+ * @returns: a new floating #GVariant instance
+ *
+ * Parses @format and returns the result.
+ *
+ * @format must be a text format #GVariant with one extension: at any
+ * point that a value may appear in the text, a '%' character followed
+ * by a GVariant format string (as per g_variant_new()) may appear.  In
+ * that case, the same arguments are collected from the argument list as
+ * g_variant_new() would have collected.
+ *
+ * Consider this simple example:
+ *
+ * <informalexample><programlisting>
+ *  g_variant_new_parsed ("[('one', 1), ('two', %i), (%s, 3)]", 2, "three");
+ * </programlisting></informalexample>
+ *
+ * In the example, the variable argument parameters are collected and
+ * filled in as if they were part of the original string to produce the
+ * result of <code>[('one', 1), ('two', 2), ('three', 3)]</code>.
+ *
+ * This function is intended only to be used with @format as a string
+ * literal.  Any parse error is fatal to the calling process.  If you
+ * want to parse data from untrusted sources, use g_variant_parse().
+ *
+ * You may not use this function to return, unmodified, a single
+ * #GVariant pointer from the argument list.  ie: @format may not solely
+ * be anything along the lines of "%*", "%?", "%r", or anything starting
+ * with "%@".
+ **/
+GVariant *
+g_variant_new_parsed (const gchar *format,
+                      ...)
+{
+  GVariant *result;
+  va_list ap;
+
+  va_start (ap, format);
+  result = g_variant_new_parsed_va (format, &ap);
+  va_end (ap);
+
+  return result;
+}
+
+/**
+ * g_variant_builder_add_parsed:
+ * @builder: a #GVariantBuilder
+ * @format: a text format #GVariant
+ * @...: arguments as per @format
+ *
+ * Adds to a #GVariantBuilder.
+ *
+ * This call is a convenience wrapper that is exactly equivalent to
+ * calling g_variant_new_parsed() followed by
+ * g_variant_builder_add_value().
+ *
+ * This function might be used as follows:
+ *
+ * <programlisting>
+ * GVariant *
+ * make_pointless_dictionary (void)
+ * {
+ *   GVariantBuilder *builder;
+ *   int i;
+ *
+ *   builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
+ *   g_variant_builder_add_parsed (builder, "{'width', <%i>}", 600);
+ *   g_variant_builder_add_parsed (builder, "{'title', <%s>}", "foo");
+ *   g_variant_builder_add_parsed (builder, "{'transparency', <0.5>}");
+ *   return g_variant_builder_end (builder);
+ * }
+ * </programlisting>
+ *
+ * Since: 2.26
+ **/
+void
+g_variant_builder_add_parsed (GVariantBuilder *builder,
+                              const gchar     *format,
+                              ...)
+{
+  va_list ap;
+
+  va_start (ap, format);
+  g_variant_builder_add_value (builder, g_variant_new_parsed_va (format, &ap));
+  va_end (ap);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-serialiser.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-serialiser.c
new file mode 100644 (file)
index 0000000..68128e2
--- /dev/null
@@ -0,0 +1,1687 @@
+/*
+ * Copyright © 2007, 2008 Ryan Lortie
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+/* Prologue {{{1 */
+#include "config.h"
+
+#include "gvariant-serialiser.h"
+
+#include <glib/gtestutils.h>
+#include <glib/gstrfuncs.h>
+#include <glib/gtypes.h>
+
+#include <string.h>
+
+
+/* GVariantSerialiser
+ *
+ * After this prologue section, this file has roughly 2 parts.
+ *
+ * The first part is split up into sections according to various
+ * container types.  Maybe, Array, Tuple, Variant.  The Maybe and Array
+ * sections are subdivided for element types being fixed or
+ * variable-sized types.
+ *
+ * Each section documents the format of that particular type of
+ * container and implements 5 functions for dealing with it:
+ *
+ *  n_children:
+ *    - determines (according to serialised data) how many child values
+ *      are inside a particular container value.
+ *
+ *  get_child:
+ *    - gets the type of and the serialised data corresponding to a
+ *      given child value within the container value.
+ *
+ *  needed_size:
+ *    - determines how much space would be required to serialise a
+ *      container of this type, containing the given children so that
+ *      buffers can be preallocated before serialising.
+ *
+ *  serialise:
+ *    - write the serialised data for a container of this type,
+ *      containing the given children, to a buffer.
+ *
+ *  is_normal:
+ *    - check the given data to ensure that it is in normal form.  For a
+ *      given set of child values, there is exactly one normal form for
+ *      the serialised data of a container.  Other forms are possible
+ *      while maintaining the same children (for example, by inserting
+ *      something other than zero bytes as padding) but only one form is
+ *      the normal form.
+ *
+ * The second part contains the main entry point for each of the above 5
+ * functions and logic to dispatch it to the handler for the appropriate
+ * container type code.
+ *
+ * The second part also contains a routine to byteswap serialised
+ * values.  This code makes use of the n_children() and get_child()
+ * functions above to do its work so no extra support is needed on a
+ * per-container-type basis.
+ *
+ * There is also additional code for checking for normal form.  All
+ * numeric types are always in normal form since the full range of
+ * values is permitted (eg: 0 to 255 is a valid byte).  Special checks
+ * need to be performed for booleans (only 0 or 1 allowed), strings
+ * (properly nul-terminated) and object paths and signature strings
+ * (meeting the DBus specification requirements).
+ */
+
+/* < private >
+ * GVariantSerialised:
+ * @type_info: the #GVariantTypeInfo of this value
+ * @data: the serialised data of this value, or %NULL
+ * @size: the size of this value
+ *
+ * A structure representing a GVariant in serialised form.  This
+ * structure is used with #GVariantSerialisedFiller functions and as the
+ * primary interface to the serialiser.  See #GVariantSerialisedFiller
+ * for a description of its use there.
+ *
+ * When used with the serialiser API functions, the following invariants
+ * apply to all #GVariantTypeSerialised structures passed to and
+ * returned from the serialiser.
+ *
+ * @type_info must be non-%NULL.
+ *
+ * @data must be properly aligned for the type described by @type_info.
+ *
+ * If @type_info describes a fixed-sized type then @size must always be
+ * equal to the fixed size of that type.
+ *
+ * For fixed-sized types (and only fixed-sized types), @data may be
+ * %NULL even if @size is non-zero.  This happens when a framing error
+ * occurs while attempting to extract a fixed-sized value out of a
+ * variable-sized container.  There is no data to return for the
+ * fixed-sized type, yet @size must be non-zero.  The effect of this
+ * combination should be as if @data were a pointer to an
+ * appropriately-sized zero-filled region.
+ */
+
+/* < private >
+ * g_variant_serialised_check:
+ * @serialised: a #GVariantSerialised struct
+ *
+ * Checks @serialised for validity according to the invariants described
+ * above.
+ */
+static void
+g_variant_serialised_check (GVariantSerialised serialised)
+{
+  gsize fixed_size;
+  guint alignment;
+
+  g_assert (serialised.type_info != NULL);
+  g_variant_type_info_query (serialised.type_info, &alignment, &fixed_size);
+
+  if (fixed_size)
+    g_assert_cmpint (serialised.size, ==, fixed_size);
+  else
+    g_assert (serialised.size == 0 || serialised.data != NULL);
+
+  /* Depending on the native alignment requirements of the machine, the
+   * compiler will insert either 3 or 7 padding bytes after the char.
+   * This will result in the sizeof() the struct being 12 or 16.
+   * Subtract 9 to get 3 or 7 which is a nice bitmask to apply to get
+   * the alignment bits that we "care about" being zero: in the
+   * 4-aligned case, we care about 2 bits, and in the 8-aligned case, we
+   * care about 3 bits.
+   */
+  alignment &= sizeof (struct {
+                         char a;
+                         union {
+                           guint64 x;
+                           void *y;
+                           gdouble z;
+                         } b;
+                       }
+                      ) - 9;
+
+  /* Some OSes (FreeBSD is a known example) have a malloc() that returns
+   * unaligned memory if you request small sizes.  'malloc (1);', for
+   * example, has been seen to return pointers aligned to 6 mod 16.
+   *
+   * Check if this is a small allocation and return without enforcing
+   * the alignment assertion if this is the case.
+   */
+  if (serialised.size <= alignment)
+    return;
+
+  g_assert_cmpint (alignment & (gsize) serialised.data, ==, 0);
+}
+
+/* < private >
+ * GVariantSerialisedFiller:
+ * @serialised: a #GVariantSerialised instance to fill
+ * @data: data from the children array
+ *
+ * This function is called back from g_variant_serialiser_needed_size()
+ * and g_variant_serialiser_serialise().  It fills in missing details
+ * from a partially-complete #GVariantSerialised.
+ *
+ * The @data parameter passed back to the function is one of the items
+ * that was passed to the serialiser in the @children array.  It
+ * represents a single child item of the container that is being
+ * serialised.  The information filled in to @serialised is the
+ * information for this child.
+ *
+ * If the @type_info field of @serialised is %NULL then the callback
+ * function must set it to the type information corresponding to the
+ * type of the child.  No reference should be added.  If it is non-%NULL
+ * then the callback should assert that it is equal to the actual type
+ * of the child.
+ *
+ * If the @size field is zero then the callback must fill it in with the
+ * required amount of space to store the serialised form of the child.
+ * If it is non-zero then the callback should assert that it is equal to
+ * the needed size of the child.
+ *
+ * If @data is non-%NULL then it points to a space that is properly
+ * aligned for and large enough to store the serialised data of the
+ * child.  The callback must store the serialised form of the child at
+ * @data.
+ *
+ * If the child value is another container then the callback will likely
+ * recurse back into the serialiser by calling
+ * g_variant_serialiser_needed_size() to determine @size and
+ * g_variant_serialiser_serialise() to write to @data.
+ */
+
+/* PART 1: Container types {{{1
+ *
+ * This section contains the serialiser implementation functions for
+ * each container type.
+ */
+
+/* Maybe {{{2
+ *
+ * Maybe types are handled depending on if the element type of the maybe
+ * type is a fixed-sized or variable-sized type.  Although all maybe
+ * types themselves are variable-sized types, herein, a maybe value with
+ * a fixed-sized element type is called a "fixed-sized maybe" for
+ * convenience and a maybe value with a variable-sized element type is
+ * called a "variable-sized maybe".
+ */
+
+/* Fixed-sized Maybe {{{3
+ *
+ * The size of a maybe value with a fixed-sized element type is either 0
+ * or equal to the fixed size of its element type.  The case where the
+ * size of the maybe value is zero corresponds to the "Nothing" case and
+ * the case where the size of the maybe value is equal to the fixed size
+ * of the element type corresponds to the "Just" case; in that case, the
+ * serialised data of the child value forms the entire serialised data
+ * of the maybe value.
+ *
+ * In the event that a fixed-sized maybe value is presented with a size
+ * that is not equal to the fixed size of the element type then the
+ * value must be taken to be "Nothing".
+ */
+
+static gsize
+gvs_fixed_sized_maybe_n_children (GVariantSerialised value)
+{
+  gsize element_fixed_size;
+
+  g_variant_type_info_query_element (value.type_info, NULL,
+                                     &element_fixed_size);
+
+  return (element_fixed_size == value.size) ? 1 : 0;
+}
+
+static GVariantSerialised
+gvs_fixed_sized_maybe_get_child (GVariantSerialised value,
+                                 gsize              index_)
+{
+  /* the child has the same bounds as the
+   * container, so just update the type.
+   */
+  value.type_info = g_variant_type_info_element (value.type_info);
+  g_variant_type_info_ref (value.type_info);
+
+  return value;
+}
+
+static gsize
+gvs_fixed_sized_maybe_needed_size (GVariantTypeInfo         *type_info,
+                                   GVariantSerialisedFiller  gvs_filler,
+                                   const gpointer           *children,
+                                   gsize                     n_children)
+{
+  if (n_children)
+    {
+      gsize element_fixed_size;
+
+      g_variant_type_info_query_element (type_info, NULL,
+                                         &element_fixed_size);
+
+      return element_fixed_size;
+    }
+  else
+    return 0;
+}
+
+static void
+gvs_fixed_sized_maybe_serialise (GVariantSerialised        value,
+                                 GVariantSerialisedFiller  gvs_filler,
+                                 const gpointer           *children,
+                                 gsize                     n_children)
+{
+  if (n_children)
+    {
+      GVariantSerialised child = { NULL, value.data, value.size };
+
+      gvs_filler (&child, children[0]);
+    }
+}
+
+static gboolean
+gvs_fixed_sized_maybe_is_normal (GVariantSerialised value)
+{
+  if (value.size > 0)
+    {
+      gsize element_fixed_size;
+
+      g_variant_type_info_query_element (value.type_info,
+                                         NULL, &element_fixed_size);
+
+      if (value.size != element_fixed_size)
+        return FALSE;
+
+      /* proper element size: "Just".  recurse to the child. */
+      value.type_info = g_variant_type_info_element (value.type_info);
+
+      return g_variant_serialised_is_normal (value);
+    }
+
+  /* size of 0: "Nothing" */
+  return TRUE;
+}
+
+/* Variable-sized Maybe
+ *
+ * The size of a maybe value with a variable-sized element type is
+ * either 0 or strictly greater than 0.  The case where the size of the
+ * maybe value is zero corresponds to the "Nothing" case and the case
+ * where the size of the maybe value is greater than zero corresponds to
+ * the "Just" case; in that case, the serialised data of the child value
+ * forms the first part of the serialised data of the maybe value and is
+ * followed by a single zero byte.  This zero byte is always appended,
+ * regardless of any zero bytes that may already be at the end of the
+ * serialised ata of the child value.
+ */
+
+static gsize
+gvs_variable_sized_maybe_n_children (GVariantSerialised value)
+{
+  return (value.size > 0) ? 1 : 0;
+}
+
+static GVariantSerialised
+gvs_variable_sized_maybe_get_child (GVariantSerialised value,
+                                    gsize              index_)
+{
+  /* remove the padding byte and update the type. */
+  value.type_info = g_variant_type_info_element (value.type_info);
+  g_variant_type_info_ref (value.type_info);
+  value.size--;
+
+  /* if it's zero-sized then it may as well be NULL */
+  if (value.size == 0)
+    value.data = NULL;
+
+  return value;
+}
+
+static gsize
+gvs_variable_sized_maybe_needed_size (GVariantTypeInfo         *type_info,
+                                      GVariantSerialisedFiller  gvs_filler,
+                                      const gpointer           *children,
+                                      gsize                     n_children)
+{
+  if (n_children)
+    {
+      GVariantSerialised child = { 0, };
+
+      gvs_filler (&child, children[0]);
+
+      return child.size + 1;
+    }
+  else
+    return 0;
+}
+
+static void
+gvs_variable_sized_maybe_serialise (GVariantSerialised        value,
+                                    GVariantSerialisedFiller  gvs_filler,
+                                    const gpointer           *children,
+                                    gsize                     n_children)
+{
+  if (n_children)
+    {
+      GVariantSerialised child = { NULL, value.data, value.size - 1 };
+
+      /* write the data for the child.  */
+      gvs_filler (&child, children[0]);
+      value.data[child.size] = '\0';
+    }
+}
+
+static gboolean
+gvs_variable_sized_maybe_is_normal (GVariantSerialised value)
+{
+  if (value.size == 0)
+    return TRUE;
+
+  if (value.data[value.size - 1] != '\0')
+    return FALSE;
+
+  value.type_info = g_variant_type_info_element (value.type_info);
+  value.size--;
+
+  return g_variant_serialised_is_normal (value);
+}
+
+/* Arrays {{{2
+ *
+ * Just as with maybe types, array types are handled depending on if the
+ * element type of the array type is a fixed-sized or variable-sized
+ * type.  Similar to maybe types, for convenience, an array value with a
+ * fixed-sized element type is called a "fixed-sized array" and an array
+ * value with a variable-sized element type is called a "variable sized
+ * array".
+ */
+
+/* Fixed-sized Array {{{3
+ *
+ * For fixed sized arrays, the serialised data is simply a concatenation
+ * of the serialised data of each element, in order.  Since fixed-sized
+ * values always have a fixed size that is a multiple of their alignment
+ * requirement no extra padding is required.
+ *
+ * In the event that a fixed-sized array is presented with a size that
+ * is not an integer multiple of the element size then the value of the
+ * array must be taken as being empty.
+ */
+
+static gsize
+gvs_fixed_sized_array_n_children (GVariantSerialised value)
+{
+  gsize element_fixed_size;
+
+  g_variant_type_info_query_element (value.type_info, NULL,
+                                     &element_fixed_size);
+
+  if (value.size % element_fixed_size == 0)
+    return value.size / element_fixed_size;
+
+  return 0;
+}
+
+static GVariantSerialised
+gvs_fixed_sized_array_get_child (GVariantSerialised value,
+                                 gsize              index_)
+{
+  GVariantSerialised child = { 0, };
+
+  child.type_info = g_variant_type_info_element (value.type_info);
+  g_variant_type_info_query (child.type_info, NULL, &child.size);
+  child.data = value.data + (child.size * index_);
+  g_variant_type_info_ref (child.type_info);
+
+  return child;
+}
+
+static gsize
+gvs_fixed_sized_array_needed_size (GVariantTypeInfo         *type_info,
+                                   GVariantSerialisedFiller  gvs_filler,
+                                   const gpointer           *children,
+                                   gsize                     n_children)
+{
+  gsize element_fixed_size;
+
+  g_variant_type_info_query_element (type_info, NULL, &element_fixed_size);
+
+  return element_fixed_size * n_children;
+}
+
+static void
+gvs_fixed_sized_array_serialise (GVariantSerialised        value,
+                                 GVariantSerialisedFiller  gvs_filler,
+                                 const gpointer           *children,
+                                 gsize                     n_children)
+{
+  GVariantSerialised child = { 0, };
+  gsize i;
+
+  child.type_info = g_variant_type_info_element (value.type_info);
+  g_variant_type_info_query (child.type_info, NULL, &child.size);
+  child.data = value.data;
+
+  for (i = 0; i < n_children; i++)
+    {
+      gvs_filler (&child, children[i]);
+      child.data += child.size;
+    }
+}
+
+static gboolean
+gvs_fixed_sized_array_is_normal (GVariantSerialised value)
+{
+  GVariantSerialised child = { 0, };
+
+  child.type_info = g_variant_type_info_element (value.type_info);
+  g_variant_type_info_query (child.type_info, NULL, &child.size);
+
+  if (value.size % child.size != 0)
+    return FALSE;
+
+  for (child.data = value.data;
+       child.data < value.data + value.size;
+       child.data += child.size)
+    {
+      if (!g_variant_serialised_is_normal (child))
+        return FALSE;
+    }
+
+  return TRUE;
+}
+
+/* Variable-sized Array {{{3
+ *
+ * Variable sized arrays, containing variable-sized elements, must be
+ * able to determine the boundaries between the elements.  The items
+ * cannot simply be concatenated.  Additionally, we are faced with the
+ * fact that non-fixed-sized values do not neccessarily have a size that
+ * is a multiple of their alignment requirement, so we may need to
+ * insert zero-filled padding.
+ *
+ * While it is possible to find the start of an item by starting from
+ * the end of the item before it and padding for alignment, it is not
+ * generally possible to do the reverse operation.  For this reason, we
+ * record the end point of each element in the array.
+ *
+ * GVariant works in terms of "offsets".  An offset is a pointer to a
+ * boundary between two bytes.  In 4 bytes of serialised data, there
+ * would be 5 possible offsets: one at the start ('0'), one between each
+ * pair of adjacent bytes ('1', '2', '3') and one at the end ('4').
+ *
+ * The numeric value of an offset is an unsigned integer given relative
+ * to the start of the serialised data of the array.  Offsets are always
+ * stored in little endian byte order and are always only as big as they
+ * need to be.  For example, in 255 bytes of serialised data, there are
+ * 256 offsets.  All possibilities can be stored in an 8 bit unsigned
+ * integer.  In 256 bytes of serialised data, however, there are 257
+ * possible offsets so 16 bit integers must be used.  The size of an
+ * offset is always a power of 2.
+ *
+ * The offsets are stored at the end of the serialised data of the
+ * array.  They are simply concatenated on without any particular
+ * alignment.  The size of the offsets is included in the size of the
+ * serialised data for purposes of determining the size of the offsets.
+ * This presents a possibly ambiguity; in certain cases, a particular
+ * value of array could have two different serialised forms.
+ *
+ * Imagine an array containing a single string of 253 bytes in length
+ * (so, 254 bytes including the nul terminator).  Now the offset must be
+ * written.  If an 8 bit offset is written, it will bring the size of
+ * the array's serialised data to 255 -- which means that the use of an
+ * 8 bit offset was valid.  If a 16 bit offset is used then the total
+ * size of the array will be 256 -- which means that the use of a 16 bit
+ * offset was valid.  Although both of these will be accepted by the
+ * deserialiser, only the smaller of the two is considered to be in
+ * normal form and that is the one that the serialiser must produce.
+ */
+
+static inline gsize
+gvs_read_unaligned_le (guchar *bytes,
+                       guint   size)
+{
+  union
+  {
+    guchar bytes[GLIB_SIZEOF_SIZE_T];
+    gsize integer;
+  } tmpvalue;
+
+  tmpvalue.integer = 0;
+  memcpy (&tmpvalue.bytes, bytes, size);
+
+  return GSIZE_FROM_LE (tmpvalue.integer);
+}
+
+static inline void
+gvs_write_unaligned_le (guchar *bytes,
+                        gsize   value,
+                        guint   size)
+{
+  union
+  {
+    guchar bytes[GLIB_SIZEOF_SIZE_T];
+    gsize integer;
+  } tmpvalue;
+
+  tmpvalue.integer = GSIZE_TO_LE (value);
+  memcpy (bytes, &tmpvalue.bytes, size);
+}
+
+static guint
+gvs_get_offset_size (gsize size)
+{
+  if (size > G_MAXUINT32)
+    return 8;
+
+  else if (size > G_MAXUINT16)
+    return 4;
+
+  else if (size > G_MAXUINT8)
+    return 2;
+
+  else if (size > 0)
+    return 1;
+
+  return 0;
+}
+
+static gsize
+gvs_calculate_total_size (gsize body_size,
+                          gsize offsets)
+{
+  if (body_size + 1 * offsets <= G_MAXUINT8)
+    return body_size + 1 * offsets;
+
+  if (body_size + 2 * offsets <= G_MAXUINT16)
+    return body_size + 2 * offsets;
+
+  if (body_size + 4 * offsets <= G_MAXUINT32)
+    return body_size + 4 * offsets;
+
+  return body_size + 8 * offsets;
+}
+
+static gsize
+gvs_variable_sized_array_n_children (GVariantSerialised value)
+{
+  gsize offsets_array_size;
+  gsize offset_size;
+  gsize last_end;
+
+  if (value.size == 0)
+    return 0;
+
+  offset_size = gvs_get_offset_size (value.size);
+
+  last_end = gvs_read_unaligned_le (value.data + value.size -
+                                    offset_size, offset_size);
+
+  if (last_end > value.size)
+    return 0;
+
+  offsets_array_size = value.size - last_end;
+
+  if (offsets_array_size % offset_size)
+    return 0;
+
+  return offsets_array_size / offset_size;
+}
+
+static GVariantSerialised
+gvs_variable_sized_array_get_child (GVariantSerialised value,
+                                    gsize              index_)
+{
+  GVariantSerialised child = { 0, };
+  gsize offset_size;
+  gsize last_end;
+  gsize start;
+  gsize end;
+
+  child.type_info = g_variant_type_info_element (value.type_info);
+  g_variant_type_info_ref (child.type_info);
+
+  offset_size = gvs_get_offset_size (value.size);
+
+  last_end = gvs_read_unaligned_le (value.data + value.size -
+                                    offset_size, offset_size);
+
+  if (index_ > 0)
+    {
+      guint alignment;
+
+      start = gvs_read_unaligned_le (value.data + last_end +
+                                     (offset_size * (index_ - 1)),
+                                     offset_size);
+
+      g_variant_type_info_query (child.type_info, &alignment, NULL);
+      start += (-start) & alignment;
+    }
+  else
+    start = 0;
+
+  end = gvs_read_unaligned_le (value.data + last_end +
+                               (offset_size * index_),
+                               offset_size);
+
+  if (start < end && end <= value.size)
+    {
+      child.data = value.data + start;
+      child.size = end - start;
+    }
+
+  return child;
+}
+
+static gsize
+gvs_variable_sized_array_needed_size (GVariantTypeInfo         *type_info,
+                                      GVariantSerialisedFiller  gvs_filler,
+                                      const gpointer           *children,
+                                      gsize                     n_children)
+{
+  guint alignment;
+  gsize offset;
+  gsize i;
+
+  g_variant_type_info_query (type_info, &alignment, NULL);
+  offset = 0;
+
+  for (i = 0; i < n_children; i++)
+    {
+      GVariantSerialised child = { 0, };
+
+      offset += (-offset) & alignment;
+      gvs_filler (&child, children[i]);
+      offset += child.size;
+    }
+
+  return gvs_calculate_total_size (offset, n_children);
+}
+
+static void
+gvs_variable_sized_array_serialise (GVariantSerialised        value,
+                                    GVariantSerialisedFiller  gvs_filler,
+                                    const gpointer           *children,
+                                    gsize                     n_children)
+{
+  guchar *offset_ptr;
+  gsize offset_size;
+  guint alignment;
+  gsize offset;
+  gsize i;
+
+  g_variant_type_info_query (value.type_info, &alignment, NULL);
+  offset_size = gvs_get_offset_size (value.size);
+  offset = 0;
+
+  offset_ptr = value.data + value.size - offset_size * n_children;
+
+  for (i = 0; i < n_children; i++)
+    {
+      GVariantSerialised child = { 0, };
+
+      while (offset & alignment)
+        value.data[offset++] = '\0';
+
+      child.data = value.data + offset;
+      gvs_filler (&child, children[i]);
+      offset += child.size;
+
+      gvs_write_unaligned_le (offset_ptr, offset, offset_size);
+      offset_ptr += offset_size;
+    }
+}
+
+static gboolean
+gvs_variable_sized_array_is_normal (GVariantSerialised value)
+{
+  GVariantSerialised child = { 0, };
+  gsize offsets_array_size;
+  guchar *offsets_array;
+  guint offset_size;
+  guint alignment;
+  gsize last_end;
+  gsize length;
+  gsize offset;
+  gsize i;
+
+  if (value.size == 0)
+    return TRUE;
+
+  offset_size = gvs_get_offset_size (value.size);
+  last_end = gvs_read_unaligned_le (value.data + value.size -
+                                    offset_size, offset_size);
+
+  if (last_end > value.size)
+    return FALSE;
+
+  offsets_array_size = value.size - last_end;
+
+  if (offsets_array_size % offset_size)
+    return FALSE;
+
+  offsets_array = value.data + value.size - offsets_array_size;
+  length = offsets_array_size / offset_size;
+
+  if (length == 0)
+    return FALSE;
+
+  child.type_info = g_variant_type_info_element (value.type_info);
+  g_variant_type_info_query (child.type_info, &alignment, NULL);
+  offset = 0;
+
+  for (i = 0; i < length; i++)
+    {
+      gsize this_end;
+
+      this_end = gvs_read_unaligned_le (offsets_array + offset_size * i,
+                                        offset_size);
+
+      if (this_end < offset || this_end > last_end)
+        return FALSE;
+
+      while (offset & alignment)
+        {
+          if (!(offset < this_end && value.data[offset] == '\0'))
+            return FALSE;
+          offset++;
+        }
+
+      child.data = value.data + offset;
+      child.size = this_end - offset;
+
+      if (child.size == 0)
+        child.data = NULL;
+
+      if (!g_variant_serialised_is_normal (child))
+        return FALSE;
+
+      offset = this_end;
+    }
+
+  g_assert (offset == last_end);
+
+  return TRUE;
+}
+
+/* Tuples {{{2
+ *
+ * Since tuples can contain a mix of variable- and fixed-sized items,
+ * they are, in terms of serialisation, a hybrid of variable-sized and
+ * fixed-sized arrays.
+ *
+ * Offsets are only stored for variable-sized items.  Also, since the
+ * number of items in a tuple is known from its type, we are able to
+ * know exactly how many offsets to expect in the serialised data (and
+ * therefore how much space is taken up by the offset array).  This
+ * means that we know where the end of the serialised data for the last
+ * item is -- we can just subtract the size of the offset array from the
+ * total size of the tuple.  For this reason, the last item in the tuple
+ * doesn't need an offset stored.
+ *
+ * Tuple offsets are stored in reverse.  This design choice allows
+ * iterator-based deserialisers to be more efficient.
+ *
+ * Most of the "heavy lifting" here is handled by the GVariantTypeInfo
+ * for the tuple.  See the notes in gvarianttypeinfo.h.
+ */
+
+static gsize
+gvs_tuple_n_children (GVariantSerialised value)
+{
+  return g_variant_type_info_n_members (value.type_info);
+}
+
+static GVariantSerialised
+gvs_tuple_get_child (GVariantSerialised value,
+                     gsize              index_)
+{
+  const GVariantMemberInfo *member_info;
+  GVariantSerialised child = { 0, };
+  gsize offset_size;
+  gsize start, end;
+
+  member_info = g_variant_type_info_member_info (value.type_info, index_);
+  child.type_info = g_variant_type_info_ref (member_info->type_info);
+  offset_size = gvs_get_offset_size (value.size);
+
+  /* tuples are the only (potentially) fixed-sized containers, so the
+   * only ones that have to deal with the possibility of having %NULL
+   * data with a non-zero %size if errors occured elsewhere.
+   */
+  if G_UNLIKELY (value.data == NULL && value.size != 0)
+    {
+      g_variant_type_info_query (child.type_info, NULL, &child.size);
+
+      /* this can only happen in fixed-sized tuples,
+       * so the child must also be fixed sized.
+       */
+      g_assert (child.size != 0);
+      child.data = NULL;
+
+      return child;
+    }
+
+  if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_OFFSET)
+    {
+      if (offset_size * (member_info->i + 2) > value.size)
+        return child;
+    }
+  else
+    {
+      if (offset_size * (member_info->i + 1) > value.size)
+        {
+          /* if the child is fixed size, return its size.
+           * if child is not fixed-sized, return size = 0.
+           */
+          g_variant_type_info_query (child.type_info, NULL, &child.size);
+
+          return child;
+        }
+    }
+
+  if (member_info->i + 1)
+    start = gvs_read_unaligned_le (value.data + value.size -
+                                   offset_size * (member_info->i + 1),
+                                   offset_size);
+  else
+    start = 0;
+
+  start += member_info->a;
+  start &= member_info->b;
+  start |= member_info->c;
+
+  if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_LAST)
+    end = value.size - offset_size * (member_info->i + 1);
+
+  else if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_FIXED)
+    {
+      gsize fixed_size;
+
+      g_variant_type_info_query (child.type_info, NULL, &fixed_size);
+      end = start + fixed_size;
+      child.size = fixed_size;
+    }
+
+  else /* G_VARIANT_MEMEBER_ENDING_OFFSET */
+    end = gvs_read_unaligned_le (value.data + value.size -
+                                 offset_size * (member_info->i + 2),
+                                 offset_size);
+
+  if (start < end && end <= value.size)
+    {
+      child.data = value.data + start;
+      child.size = end - start;
+    }
+
+  return child;
+}
+
+static gsize
+gvs_tuple_needed_size (GVariantTypeInfo         *type_info,
+                       GVariantSerialisedFiller  gvs_filler,
+                       const gpointer           *children,
+                       gsize                     n_children)
+{
+  const GVariantMemberInfo *member_info = NULL;
+  gsize fixed_size;
+  gsize offset;
+  gsize i;
+
+  g_variant_type_info_query (type_info, NULL, &fixed_size);
+
+  if (fixed_size)
+    return fixed_size;
+
+  offset = 0;
+
+  for (i = 0; i < n_children; i++)
+    {
+      guint alignment;
+
+      member_info = g_variant_type_info_member_info (type_info, i);
+      g_variant_type_info_query (member_info->type_info,
+                                 &alignment, &fixed_size);
+      offset += (-offset) & alignment;
+
+      if (fixed_size)
+        offset += fixed_size;
+      else
+        {
+          GVariantSerialised child = { 0, };
+
+          gvs_filler (&child, children[i]);
+          offset += child.size;
+        }
+    }
+
+  return gvs_calculate_total_size (offset, member_info->i + 1);
+}
+
+static void
+gvs_tuple_serialise (GVariantSerialised        value,
+                     GVariantSerialisedFiller  gvs_filler,
+                     const gpointer           *children,
+                     gsize                     n_children)
+{
+  gsize offset_size;
+  gsize offset;
+  gsize i;
+
+  offset_size = gvs_get_offset_size (value.size);
+  offset = 0;
+
+  for (i = 0; i < n_children; i++)
+    {
+      const GVariantMemberInfo *member_info;
+      GVariantSerialised child = { 0, };
+      guint alignment;
+
+      member_info = g_variant_type_info_member_info (value.type_info, i);
+      g_variant_type_info_query (member_info->type_info, &alignment, NULL);
+
+      while (offset & alignment)
+        value.data[offset++] = '\0';
+
+      child.data = value.data + offset;
+      gvs_filler (&child, children[i]);
+      offset += child.size;
+
+      if (member_info->ending_type == G_VARIANT_MEMBER_ENDING_OFFSET)
+        {
+          value.size -= offset_size;
+          gvs_write_unaligned_le (value.data + value.size,
+                                  offset, offset_size);
+        }
+    }
+
+  while (offset < value.size)
+    value.data[offset++] = '\0';
+}
+
+static gboolean
+gvs_tuple_is_normal (GVariantSerialised value)
+{
+  guint offset_size;
+  gsize offset_ptr;
+  gsize length;
+  gsize offset;
+  gsize i;
+
+  offset_size = gvs_get_offset_size (value.size);
+  length = g_variant_type_info_n_members (value.type_info);
+  offset_ptr = value.size;
+  offset = 0;
+
+  for (i = 0; i < length; i++)
+    {
+      const GVariantMemberInfo *member_info;
+      GVariantSerialised child;
+      gsize fixed_size;
+      guint alignment;
+      gsize end;
+
+      member_info = g_variant_type_info_member_info (value.type_info, i);
+      child.type_info = member_info->type_info;
+
+      g_variant_type_info_query (child.type_info, &alignment, &fixed_size);
+
+      while (offset & alignment)
+        {
+          if (offset > value.size || value.data[offset] != '\0')
+            return FALSE;
+          offset++;
+        }
+
+      child.data = value.data + offset;
+
+      switch (member_info->ending_type)
+        {
+        case G_VARIANT_MEMBER_ENDING_FIXED:
+          end = offset + fixed_size;
+          break;
+
+        case G_VARIANT_MEMBER_ENDING_LAST:
+          end = offset_ptr;
+          break;
+
+        case G_VARIANT_MEMBER_ENDING_OFFSET:
+          offset_ptr -= offset_size;
+
+          if (offset_ptr < offset)
+            return FALSE;
+
+          end = gvs_read_unaligned_le (value.data + offset_ptr, offset_size);
+          break;
+
+        default:
+          g_assert_not_reached ();
+        }
+
+      if (end < offset || end > offset_ptr)
+        return FALSE;
+
+      child.size = end - offset;
+
+      if (child.size == 0)
+        child.data = NULL;
+
+      if (!g_variant_serialised_is_normal (child))
+        return FALSE;
+
+      offset = end;
+    }
+
+  {
+    gsize fixed_size;
+    guint alignment;
+
+    g_variant_type_info_query (value.type_info, &alignment, &fixed_size);
+
+    if (fixed_size)
+      {
+        g_assert (fixed_size == value.size);
+        g_assert (offset_ptr == value.size);
+
+        if (i == 0)
+          {
+            if (value.data[offset++] != '\0')
+              return FALSE;
+          }
+        else
+          {
+            while (offset & alignment)
+              if (value.data[offset++] != '\0')
+                return FALSE;
+          }
+
+        g_assert (offset == value.size);
+      }
+  }
+
+  return offset_ptr == offset;
+}
+
+/* Variants {{{2
+ *
+ * Variants are stored by storing the serialised data of the child,
+ * followed by a '\0' character, followed by the type string of the
+ * child.
+ *
+ * In the case that a value is presented that contains no '\0'
+ * character, or doesn't have a single well-formed definite type string
+ * following that character, the variant must be taken as containing the
+ * unit tuple: ().
+ */
+
+static inline gsize
+gvs_variant_n_children (GVariantSerialised value)
+{
+  return 1;
+}
+
+static inline GVariantSerialised
+gvs_variant_get_child (GVariantSerialised value,
+                       gsize              index_)
+{
+  GVariantSerialised child = { 0, };
+
+  /* NOTE: not O(1) and impossible for it to be... */
+  if (value.size)
+    {
+      /* find '\0' character */
+      for (child.size = value.size - 1; child.size; child.size--)
+        if (value.data[child.size] == '\0')
+          break;
+
+      /* ensure we didn't just hit the start of the string */
+      if (value.data[child.size] == '\0')
+        {
+          const gchar *type_string = (gchar *) &value.data[child.size + 1];
+          const gchar *limit = (gchar *) &value.data[value.size];
+          const gchar *end;
+
+          if (g_variant_type_string_scan (type_string, limit, &end) &&
+              end == limit)
+            {
+              const GVariantType *type = (GVariantType *) type_string;
+
+              if (g_variant_type_is_definite (type))
+                {
+                  gsize fixed_size;
+
+                  child.type_info = g_variant_type_info_get (type);
+
+                  if (child.size != 0)
+                    /* only set to non-%NULL if size > 0 */
+                    child.data = value.data;
+
+                  g_variant_type_info_query (child.type_info,
+                                             NULL, &fixed_size);
+
+                  if (!fixed_size || fixed_size == child.size)
+                    return child;
+
+                  g_variant_type_info_unref (child.type_info);
+                }
+            }
+        }
+    }
+
+  child.type_info = g_variant_type_info_get (G_VARIANT_TYPE_UNIT);
+  child.data = NULL;
+  child.size = 1;
+
+  return child;
+}
+
+static inline gsize
+gvs_variant_needed_size (GVariantTypeInfo         *type_info,
+                         GVariantSerialisedFiller  gvs_filler,
+                         const gpointer           *children,
+                         gsize                     n_children)
+{
+  GVariantSerialised child = { 0, };
+  const gchar *type_string;
+
+  gvs_filler (&child, children[0]);
+  type_string = g_variant_type_info_get_type_string (child.type_info);
+
+  return child.size + 1 + strlen (type_string);
+}
+
+static inline void
+gvs_variant_serialise (GVariantSerialised        value,
+                       GVariantSerialisedFiller  gvs_filler,
+                       const gpointer           *children,
+                       gsize                     n_children)
+{
+  GVariantSerialised child = { 0, };
+  const gchar *type_string;
+
+  child.data = value.data;
+
+  gvs_filler (&child, children[0]);
+  type_string = g_variant_type_info_get_type_string (child.type_info);
+  value.data[child.size] = '\0';
+  memcpy (value.data + child.size + 1, type_string, strlen (type_string));
+}
+
+static inline gboolean
+gvs_variant_is_normal (GVariantSerialised value)
+{
+  GVariantSerialised child;
+  gboolean normal;
+
+  child = gvs_variant_get_child (value, 0);
+
+  normal = (child.data != NULL || child.size == 0) &&
+           g_variant_serialised_is_normal (child);
+
+  g_variant_type_info_unref (child.type_info);
+
+  return normal;
+}
+
+
+
+/* PART 2: Serialiser API {{{1
+ *
+ * This is the implementation of the API of the serialiser as advertised
+ * in gvariant-serialiser.h.
+ */
+
+/* Dispatch Utilities {{{2
+ *
+ * These macros allow a given function (for example,
+ * g_variant_serialiser_serialise) to be dispatched to the appropriate
+ * type-specific function above (fixed/variable-sized maybe,
+ * fixed/variable-sized array, tuple or variant).
+ */
+#define DISPATCH_FIXED(type_info, before, after) \
+  {                                                     \
+    gsize fixed_size;                                   \
+                                                        \
+    g_variant_type_info_query_element (type_info, NULL, \
+                                       &fixed_size);    \
+                                                        \
+    if (fixed_size)                                     \
+      {                                                 \
+        before ## fixed_sized ## after                  \
+      }                                                 \
+    else                                                \
+      {                                                 \
+        before ## variable_sized ## after               \
+      }                                                 \
+  }
+
+#define DISPATCH_CASES(type_info, before, after) \
+  switch (g_variant_type_info_get_type_char (type_info))        \
+    {                                                           \
+      case G_VARIANT_TYPE_INFO_CHAR_MAYBE:                      \
+        DISPATCH_FIXED (type_info, before, _maybe ## after)     \
+                                                                \
+      case G_VARIANT_TYPE_INFO_CHAR_ARRAY:                      \
+        DISPATCH_FIXED (type_info, before, _array ## after)     \
+                                                                \
+      case G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY:                 \
+      case G_VARIANT_TYPE_INFO_CHAR_TUPLE:                      \
+        {                                                       \
+          before ## tuple ## after                              \
+        }                                                       \
+                                                                \
+      case G_VARIANT_TYPE_INFO_CHAR_VARIANT:                    \
+        {                                                       \
+          before ## variant ## after                            \
+        }                                                       \
+    }
+
+/* Serialiser entry points {{{2
+ *
+ * These are the functions that are called in order for the serialiser
+ * to do its thing.
+ */
+
+/* < private >
+ * g_variant_serialised_n_children:
+ * @serialised: a #GVariantSerialised
+ * @returns: the number of children
+ *
+ * For serialised data that represents a container value (maybes,
+ * tuples, arrays, variants), determine how many child items are inside
+ * that container.
+ */
+gsize
+g_variant_serialised_n_children (GVariantSerialised serialised)
+{
+  g_variant_serialised_check (serialised);
+
+  DISPATCH_CASES (serialised.type_info,
+
+                  return gvs_/**/,/**/_n_children (serialised);
+
+                 )
+  g_assert_not_reached ();
+}
+
+/* < private >
+ * g_variant_serialised_get_child:
+ * @serialised: a #GVariantSerialised
+ * @index_: the index of the child to fetch
+ * @returns: a #GVariantSerialised for the child
+ *
+ * Extracts a child from a serialised data representing a container
+ * value.
+ *
+ * It is an error to call this function with an index out of bounds.
+ *
+ * If the result .data == %NULL and .size > 0 then there has been an
+ * error extracting the requested fixed-sized value.  This number of
+ * zero bytes needs to be allocated instead.
+ *
+ * In the case that .data == %NULL and .size == 0 then a zero-sized
+ * item of a variable-sized type is being returned.
+ *
+ * .data is never non-%NULL if size is 0.
+ */
+GVariantSerialised
+g_variant_serialised_get_child (GVariantSerialised serialised,
+                                gsize              index_)
+{
+  GVariantSerialised child;
+
+  g_variant_serialised_check (serialised);
+
+  if G_LIKELY (index_ < g_variant_serialised_n_children (serialised))
+    {
+      DISPATCH_CASES (serialised.type_info,
+
+                      child = gvs_/**/,/**/_get_child (serialised, index_);
+                      g_assert (child.size || child.data == NULL);
+                      g_variant_serialised_check (child);
+                      return child;
+
+                     )
+      g_assert_not_reached ();
+    }
+
+  g_error ("Attempt to access item %"G_GSIZE_FORMAT
+           " in a container with only %"G_GSIZE_FORMAT" items",
+           index_, g_variant_serialised_n_children (serialised));
+}
+
+/* < private >
+ * g_variant_serialiser_serialise:
+ * @serialised: a #GVariantSerialised, properly set up
+ * @gvs_filler: the filler function
+ * @children: an array of child items
+ * @n_children: the size of @children
+ *
+ * Writes data in serialised form.
+ *
+ * The type_info field of @serialised must be filled in to type info for
+ * the type that we are serialising.
+ *
+ * The size field of @serialised must be filled in with the value
+ * returned by a previous call to g_variant_serialiser_needed_size().
+ *
+ * The data field of @serialised must be a pointer to a properly-aligned
+ * memory region large enough to serialise into (ie: at least as big as
+ * the size field).
+ *
+ * This function is only resonsible for serialising the top-level
+ * container.  @gvs_filler is called on each child of the container in
+ * order for all of the data of that child to be filled in.
+ */
+void
+g_variant_serialiser_serialise (GVariantSerialised        serialised,
+                                GVariantSerialisedFiller  gvs_filler,
+                                const gpointer           *children,
+                                gsize                     n_children)
+{
+  g_variant_serialised_check (serialised);
+
+  DISPATCH_CASES (serialised.type_info,
+
+                  gvs_/**/,/**/_serialise (serialised, gvs_filler,
+                                           children, n_children);
+                  return;
+
+                 )
+  g_assert_not_reached ();
+}
+
+/* < private >
+ * g_variant_serialiser_needed_size:
+ * @type_info: the type to serialise for
+ * @gvs_filler: the filler function
+ * @children: an array of child items
+ * @n_children: the size of @children
+ *
+ * Determines how much memory would be needed to serialise this value.
+ *
+ * This function is only resonsible for performing calculations for the
+ * top-level container.  @gvs_filler is called on each child of the
+ * container in order to determine its size.
+ */
+gsize
+g_variant_serialiser_needed_size (GVariantTypeInfo         *type_info,
+                                  GVariantSerialisedFiller  gvs_filler,
+                                  const gpointer           *children,
+                                  gsize                     n_children)
+{
+  DISPATCH_CASES (type_info,
+
+                  return gvs_/**/,/**/_needed_size (type_info, gvs_filler,
+                                                    children, n_children);
+
+                 )
+  g_assert_not_reached ();
+}
+
+/* Byteswapping {{{2 */
+
+/* < private >
+ * g_variant_serialised_byteswap:
+ * @value: a #GVariantSerialised
+ *
+ * Byte-swap serialised data.  The result of this function is only
+ * well-defined if the data is in normal form.
+ */
+void
+g_variant_serialised_byteswap (GVariantSerialised serialised)
+{
+  gsize fixed_size;
+  guint alignment;
+
+  g_variant_serialised_check (serialised);
+
+  if (!serialised.data)
+    return;
+
+  /* the types we potentially need to byteswap are
+   * exactly those with alignment requirements.
+   */
+  g_variant_type_info_query (serialised.type_info, &alignment, &fixed_size);
+  if (!alignment)
+    return;
+
+  /* if fixed size and alignment are equal then we are down
+   * to the base integer type and we should swap it.  the
+   * only exception to this is if we have a tuple with a
+   * single item, and then swapping it will be OK anyway.
+   */
+  if (alignment + 1 == fixed_size)
+    {
+      switch (fixed_size)
+      {
+        case 2:
+          {
+            guint16 *ptr = (guint16 *) serialised.data;
+
+            g_assert_cmpint (serialised.size, ==, 2);
+            *ptr = GUINT16_SWAP_LE_BE (*ptr);
+          }
+          return;
+
+        case 4:
+          {
+            guint32 *ptr = (guint32 *) serialised.data;
+
+            g_assert_cmpint (serialised.size, ==, 4);
+            *ptr = GUINT32_SWAP_LE_BE (*ptr);
+          }
+          return;
+
+        case 8:
+          {
+            guint64 *ptr = (guint64 *) serialised.data;
+
+            g_assert_cmpint (serialised.size, ==, 8);
+            *ptr = GUINT64_SWAP_LE_BE (*ptr);
+          }
+          return;
+
+        default:
+          g_assert_not_reached ();
+      }
+    }
+
+  /* else, we have a container that potentially contains
+   * some children that need to be byteswapped.
+   */
+  else
+    {
+      gsize children, i;
+
+      children = g_variant_serialised_n_children (serialised);
+      for (i = 0; i < children; i++)
+        {
+          GVariantSerialised child;
+
+          child = g_variant_serialised_get_child (serialised, i);
+          g_variant_serialised_byteswap (child);
+          g_variant_type_info_unref (child.type_info);
+        }
+    }
+}
+
+/* Normal form checking {{{2 */
+
+/* < private >
+ * g_variant_serialised_is_normal:
+ * @serialised: a #GVariantSerialised
+ *
+ * Determines, recursively if @serialised is in normal form.  There is
+ * precisely one normal form of serialised data for each possible value.
+ *
+ * It is possible that multiple byte sequences form the serialised data
+ * for a given value if, for example, the padding bytes are filled in
+ * with something other than zeros, but only one form is the normal
+ * form.
+ */
+gboolean
+g_variant_serialised_is_normal (GVariantSerialised serialised)
+{
+  DISPATCH_CASES (serialised.type_info,
+
+                  return gvs_/**/,/**/_is_normal (serialised);
+
+                 )
+
+  if (serialised.data == NULL)
+    return FALSE;
+
+  /* some hard-coded terminal cases */
+  switch (g_variant_type_info_get_type_char (serialised.type_info))
+    {
+    case 'b': /* boolean */
+      return serialised.data[0] < 2;
+
+    case 's': /* string */
+      return g_variant_serialiser_is_string (serialised.data,
+                                             serialised.size);
+
+    case 'o':
+      return g_variant_serialiser_is_object_path (serialised.data,
+                                                  serialised.size);
+
+    case 'g':
+      return g_variant_serialiser_is_signature (serialised.data,
+                                                serialised.size);
+
+    default:
+      /* all of the other types are fixed-sized numerical types for
+       * which all possible values are valid (including various NaN
+       * representations for floating point values).
+       */
+      return TRUE;
+    }
+}
+
+/* Validity-checking functions {{{2
+ *
+ * Checks if strings, object paths and signature strings are valid.
+ */
+
+/* < private >
+ * g_variant_serialiser_is_string:
+ * @data: a possible string
+ * @size: the size of @data
+ *
+ * Ensures that @data is a valid string with a nul terminator at the end
+ * and no nul bytes embedded.
+ */
+gboolean
+g_variant_serialiser_is_string (gconstpointer data,
+                                gsize         size)
+{
+  const gchar *end;
+
+  g_utf8_validate (data, size, &end);
+
+  return data == end - (size - 1);
+}
+
+/* < private >
+ * g_variant_serialiser_is_object_path:
+ * @data: a possible DBus object path
+ * @size: the size of @data
+ *
+ * Performs the checks for being a valid string.
+ *
+ * Also, ensures that @data is a valid DBus object path, as per the DBus
+ * specification.
+ */
+gboolean
+g_variant_serialiser_is_object_path (gconstpointer data,
+                                     gsize         size)
+{
+  const gchar *string = data;
+  gsize i;
+
+  if (!g_variant_serialiser_is_string (data, size))
+    return FALSE;
+
+  /* The path must begin with an ASCII '/' (integer 47) character */
+  if (string[0] != '/')
+    return FALSE;
+
+  for (i = 1; string[i]; i++)
+    /* Each element must only contain the ASCII characters
+     * "[A-Z][a-z][0-9]_"
+     */
+    if (g_ascii_isalnum (string[i]) || string[i] == '_')
+      ;
+
+    /* must consist of elements separated by slash characters. */
+    else if (string[i] == '/')
+      {
+        /* No element may be the empty string. */
+        /* Multiple '/' characters cannot occur in sequence. */
+        if (string[i - 1] == '/')
+          return FALSE;
+      }
+
+    else
+      return FALSE;
+
+  /* A trailing '/' character is not allowed unless the path is the
+   * root path (a single '/' character).
+   */
+  if (i > 1 && string[i - 1] == '/')
+    return FALSE;
+
+  return TRUE;
+}
+
+/* < private >
+ * g_variant_serialiser_is_signature:
+ * @data: a possible DBus signature
+ * @size: the size of @data
+ *
+ * Performs the checks for being a valid string.
+ *
+ * Also, ensures that @data is a valid DBus type signature, as per the
+ * DBus specification.
+ */
+gboolean
+g_variant_serialiser_is_signature (gconstpointer data,
+                                   gsize         size)
+{
+  const gchar *string = data;
+  gsize first_invalid;
+
+  if (!g_variant_serialiser_is_string (data, size))
+    return FALSE;
+
+  /* make sure no non-definite characters appear */
+  first_invalid = strspn (string, "ybnqiuxthdvasog(){}");
+  if (string[first_invalid])
+    return FALSE;
+
+  /* make sure each type string is well-formed */
+  while (*string)
+    if (!g_variant_type_string_scan (string, NULL, &string))
+      return FALSE;
+
+  return TRUE;
+}
+
+/* Epilogue {{{1 */
+/* vim:set foldmethod=marker: */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-serialiser.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant-serialiser.h
new file mode 100644 (file)
index 0000000..f26b118
--- /dev/null
@@ -0,0 +1,66 @@
+/*
+ * Copyright © 2007, 2008 Ryan Lortie
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __G_VARIANT_SERIALISER_H__
+#define __G_VARIANT_SERIALISER_H__
+
+#include "gvarianttypeinfo.h"
+
+typedef struct
+{
+  GVariantTypeInfo *type_info;
+  guchar           *data;
+  gsize             size;
+} GVariantSerialised;
+
+/* deserialisation */
+gsize                           g_variant_serialised_n_children         (GVariantSerialised        container);
+GVariantSerialised              g_variant_serialised_get_child          (GVariantSerialised        container,
+                                                                         gsize                     index);
+
+/* serialisation */
+typedef void                  (*GVariantSerialisedFiller)               (GVariantSerialised       *serialised,
+                                                                         gpointer                  data);
+
+gsize                           g_variant_serialiser_needed_size        (GVariantTypeInfo         *info,
+                                                                         GVariantSerialisedFiller  gsv_filler,
+                                                                         const gpointer           *children,
+                                                                         gsize                     n_children);
+
+void                            g_variant_serialiser_serialise          (GVariantSerialised        container,
+                                                                         GVariantSerialisedFiller  gsv_filler,
+                                                                         const gpointer           *children,
+                                                                         gsize                     n_children);
+
+/* misc */
+gboolean                        g_variant_serialised_is_normal          (GVariantSerialised        value);
+void                            g_variant_serialised_byteswap           (GVariantSerialised        value);
+
+/* validation of strings */
+gboolean                        g_variant_serialiser_is_string          (gconstpointer             data,
+                                                                         gsize                     size);
+gboolean                        g_variant_serialiser_is_object_path     (gconstpointer             data,
+                                                                         gsize                     size);
+gboolean                        g_variant_serialiser_is_signature       (gconstpointer             data,
+                                                                         gsize                     size);
+
+#endif /* __G_VARIANT_SERIALISER_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant.c
new file mode 100644 (file)
index 0000000..f9eb851
--- /dev/null
@@ -0,0 +1,4649 @@
+/*
+ * Copyright © 2007, 2008 Ryan Lortie
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+/* Prologue {{{1 */
+
+#include "config.h"
+
+#include <glib/gvariant-serialiser.h>
+#include "gvariant-internal.h"
+#include <glib/gvariant-core.h>
+#include <glib/gtestutils.h>
+#include <glib/gstrfuncs.h>
+#include <glib/ghash.h>
+#include <glib/gmem.h>
+
+#include <string.h>
+
+
+/**
+ * SECTION: gvariant
+ * @title: GVariant
+ * @short_description: strongly typed value datatype
+ * @see_also: GVariantType
+ *
+ * #GVariant is a variant datatype; it stores a value along with
+ * information about the type of that value.  The range of possible
+ * values is determined by the type.  The type system used by #GVariant
+ * is #GVariantType.
+ *
+ * #GVariant instances always have a type and a value (which are given
+ * at construction time).  The type and value of a #GVariant instance
+ * can never change other than by the #GVariant itself being
+ * destroyed.  A #GVariant can not contain a pointer.
+ *
+ * #GVariant is reference counted using g_variant_ref() and
+ * g_variant_unref().  #GVariant also has floating reference counts --
+ * see g_variant_ref_sink().
+ *
+ * #GVariant is completely threadsafe.  A #GVariant instance can be
+ * concurrently accessed in any way from any number of threads without
+ * problems.
+ *
+ * #GVariant is heavily optimised for dealing with data in serialised
+ * form.  It works particularly well with data located in memory-mapped
+ * files.  It can perform nearly all deserialisation operations in a
+ * small constant time, usually touching only a single memory page.
+ * Serialised #GVariant data can also be sent over the network.
+ *
+ * #GVariant is largely compatible with DBus.  Almost all types of
+ * #GVariant instances can be sent over DBus.  See #GVariantType for
+ * exceptions.
+ *
+ * For convenience to C programmers, #GVariant features powerful
+ * varargs-based value construction and destruction.  This feature is
+ * designed to be embedded in other libraries.
+ *
+ * There is a Python-inspired text language for describing #GVariant
+ * values.  #GVariant includes a printer for this language and a parser
+ * with type inferencing.
+ *
+ * <refsect2>
+ *  <title>Memory Use</title>
+ *  <para>
+ *   #GVariant tries to be quite efficient with respect to memory use.
+ *   This section gives a rough idea of how much memory is used by the
+ *   current implementation.  The information here is subject to change
+ *   in the future.
+ *  </para>
+ *  <para>
+ *   The memory allocated by #GVariant can be grouped into 4 broad
+ *   purposes: memory for serialised data, memory for the type
+ *   information cache, buffer management memory and memory for the
+ *   #GVariant structure itself.
+ *  </para>
+ *  <refsect3>
+ *   <title>Serialised Data Memory</title>
+ *   <para>
+ *    This is the memory that is used for storing GVariant data in
+ *    serialised form.  This is what would be sent over the network or
+ *    what would end up on disk.
+ *   </para>
+ *   <para>
+ *    The amount of memory required to store a boolean is 1 byte.  16,
+ *    32 and 64 bit integers and double precision floating point numbers
+ *    use their "natural" size.  Strings (including object path and
+ *    signature strings) are stored with a nul terminator, and as such
+ *    use the length of the string plus 1 byte.
+ *   </para>
+ *   <para>
+ *    Maybe types use no space at all to represent the null value and
+ *    use the same amount of space (sometimes plus one byte) as the
+ *    equivalent non-maybe-typed value to represent the non-null case.
+ *   </para>
+ *   <para>
+ *    Arrays use the amount of space required to store each of their
+ *    members, concatenated.  Additionally, if the items stored in an
+ *    array are not of a fixed-size (ie: strings, other arrays, etc)
+ *    then an additional framing offset is stored for each item.  The
+ *    size of this offset is either 1, 2 or 4 bytes depending on the
+ *    overall size of the container.  Additionally, extra padding bytes
+ *    are added as required for alignment of child values.
+ *   </para>
+ *   <para>
+ *    Tuples (including dictionary entries) use the amount of space
+ *    required to store each of their members, concatenated, plus one
+ *    framing offset (as per arrays) for each non-fixed-sized item in
+ *    the tuple, except for the last one.  Additionally, extra padding
+ *    bytes are added as required for alignment of child values.
+ *   </para>
+ *   <para>
+ *    Variants use the same amount of space as the item inside of the
+ *    variant, plus 1 byte, plus the length of the type string for the
+ *    item inside the variant.
+ *   </para>
+ *   <para>
+ *    As an example, consider a dictionary mapping strings to variants.
+ *    In the case that the dictionary is empty, 0 bytes are required for
+ *    the serialisation.
+ *   </para>
+ *   <para>
+ *    If we add an item "width" that maps to the int32 value of 500 then
+ *    we will use 4 byte to store the int32 (so 6 for the variant
+ *    containing it) and 6 bytes for the string.  The variant must be
+ *    aligned to 8 after the 6 bytes of the string, so that's 2 extra
+ *    bytes.  6 (string) + 2 (padding) + 6 (variant) is 14 bytes used
+ *    for the dictionary entry.  An additional 1 byte is added to the
+ *    array as a framing offset making a total of 15 bytes.
+ *   </para>
+ *   <para>
+ *    If we add another entry, "title" that maps to a nullable string
+ *    that happens to have a value of null, then we use 0 bytes for the
+ *    null value (and 3 bytes for the variant to contain it along with
+ *    its type string) plus 6 bytes for the string.  Again, we need 2
+ *    padding bytes.  That makes a total of 6 + 2 + 3 = 11 bytes.
+ *   </para>
+ *   <para>
+ *    We now require extra padding between the two items in the array.
+ *    After the 14 bytes of the first item, that's 2 bytes required.  We
+ *    now require 2 framing offsets for an extra two bytes.  14 + 2 + 11
+ *    + 2 = 29 bytes to encode the entire two-item dictionary.
+ *   </para>
+ *  </refsect3>
+ *  <refsect3>
+ *   <title>Type Information Cache</title>
+ *   <para>
+ *    For each GVariant type that currently exists in the program a type
+ *    information structure is kept in the type information cache.  The
+ *    type information structure is required for rapid deserialisation.
+ *   </para>
+ *   <para>
+ *    Continuing with the above example, if a #GVariant exists with the
+ *    type "a{sv}" then a type information struct will exist for
+ *    "a{sv}", "{sv}", "s", and "v".  Multiple uses of the same type
+ *    will share the same type information.  Additionally, all
+ *    single-digit types are stored in read-only static memory and do
+ *    not contribute to the writable memory footprint of a program using
+ *    #GVariant.
+ *   </para>
+ *   <para>
+ *    Aside from the type information structures stored in read-only
+ *    memory, there are two forms of type information.  One is used for
+ *    container types where there is a single element type: arrays and
+ *    maybe types.  The other is used for container types where there
+ *    are multiple element types: tuples and dictionary entries.
+ *   </para>
+ *   <para>
+ *    Array type info structures are 6 * sizeof (void *), plus the
+ *    memory required to store the type string itself.  This means that
+ *    on 32bit systems, the cache entry for "a{sv}" would require 30
+ *    bytes of memory (plus malloc overhead).
+ *   </para>
+ *   <para>
+ *    Tuple type info structures are 6 * sizeof (void *), plus 4 *
+ *    sizeof (void *) for each item in the tuple, plus the memory
+ *    required to store the type string itself.  A 2-item tuple, for
+ *    example, would have a type information structure that consumed
+ *    writable memory in the size of 14 * sizeof (void *) (plus type
+ *    string)  This means that on 32bit systems, the cache entry for
+ *    "{sv}" would require 61 bytes of memory (plus malloc overhead).
+ *   </para>
+ *   <para>
+ *    This means that in total, for our "a{sv}" example, 91 bytes of
+ *    type information would be allocated.
+ *   </para>
+ *   <para>
+ *    The type information cache, additionally, uses a #GHashTable to
+ *    store and lookup the cached items and stores a pointer to this
+ *    hash table in static storage.  The hash table is freed when there
+ *    are zero items in the type cache.
+ *   </para>
+ *   <para>
+ *    Although these sizes may seem large it is important to remember
+ *    that a program will probably only have a very small number of
+ *    different types of values in it and that only one type information
+ *    structure is required for many different values of the same type.
+ *   </para>
+ *  </refsect3>
+ *  <refsect3>
+ *   <title>Buffer Management Memory</title>
+ *   <para>
+ *    #GVariant uses an internal buffer management structure to deal
+ *    with the various different possible sources of serialised data
+ *    that it uses.  The buffer is responsible for ensuring that the
+ *    correct call is made when the data is no longer in use by
+ *    #GVariant.  This may involve a g_free() or a g_slice_free() or
+ *    even g_mapped_file_unref().
+ *   </para>
+ *   <para>
+ *    One buffer management structure is used for each chunk of
+ *    serialised data.  The size of the buffer management structure is 4
+ *    * (void *).  On 32bit systems, that's 16 bytes.
+ *   </para>
+ *  </refsect3>
+ *  <refsect3>
+ *   <title>GVariant structure</title>
+ *   <para>
+ *    The size of a #GVariant structure is 6 * (void *).  On 32 bit
+ *    systems, that's 24 bytes.
+ *   </para>
+ *   <para>
+ *    #GVariant structures only exist if they are explicitly created
+ *    with API calls.  For example, if a #GVariant is constructed out of
+ *    serialised data for the example given above (with the dictionary)
+ *    then although there are 9 individual values that comprise the
+ *    entire dictionary (two keys, two values, two variants containing
+ *    the values, two dictionary entries, plus the dictionary itself),
+ *    only 1 #GVariant instance exists -- the one refering to the
+ *    dictionary.
+ *   </para>
+ *   <para>
+ *    If calls are made to start accessing the other values then
+ *    #GVariant instances will exist for those values only for as long
+ *    as they are in use (ie: until you call g_variant_unref()).  The
+ *    type information is shared.  The serialised data and the buffer
+ *    management structure for that serialised data is shared by the
+ *    child.
+ *   </para>
+ *  </refsect3>
+ *  <refsect3>
+ *   <title>Summary</title>
+ *   <para>
+ *    To put the entire example together, for our dictionary mapping
+ *    strings to variants (with two entries, as given above), we are
+ *    using 91 bytes of memory for type information, 29 byes of memory
+ *    for the serialised data, 16 bytes for buffer management and 24
+ *    bytes for the #GVariant instance, or a total of 160 bytes, plus
+ *    malloc overhead.  If we were to use g_variant_get_child_value() to
+ *    access the two dictionary entries, we would use an additional 48
+ *    bytes.  If we were to have other dictionaries of the same type, we
+ *    would use more memory for the serialised data and buffer
+ *    management for those dictionaries, but the type information would
+ *    be shared.
+ *   </para>
+ *  </refsect3>
+ * </refsect2>
+ */
+
+/* definition of GVariant structure is in gvariant-core.c */
+
+/* this is a g_return_val_if_fail() for making
+ * sure a (GVariant *) has the required type.
+ */
+#define TYPE_CHECK(value, TYPE, val) \
+  if G_UNLIKELY (!g_variant_is_of_type (value, TYPE)) {           \
+    g_return_if_fail_warning (G_LOG_DOMAIN, G_STRFUNC,            \
+                              "g_variant_is_of_type (" #value     \
+                              ", " #TYPE ")");                    \
+    return val;                                                   \
+  }
+
+/* Numeric Type Constructor/Getters {{{1 */
+/* < private >
+ * g_variant_new_from_trusted:
+ * @type: the #GVariantType
+ * @data: the data to use
+ * @size: the size of @data
+ * @returns: a new floating #GVariant
+ *
+ * Constructs a new trusted #GVariant instance from the provided data.
+ * This is used to implement g_variant_new_* for all the basic types.
+ */
+static GVariant *
+g_variant_new_from_trusted (const GVariantType *type,
+                            gconstpointer       data,
+                            gsize               size)
+{
+  GVariant *value;
+  GBuffer *buffer;
+
+  buffer = g_buffer_new_from_data (data, size);
+  value = g_variant_new_from_buffer (type, buffer, TRUE);
+  g_buffer_unref (buffer);
+
+  return value;
+}
+
+/**
+ * g_variant_new_boolean:
+ * @boolean: a #gboolean value
+ * @returns: a floating reference to a new boolean #GVariant instance
+ *
+ * Creates a new boolean #GVariant instance -- either %TRUE or %FALSE.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_new_boolean (gboolean value)
+{
+  guchar v = value;
+
+  return g_variant_new_from_trusted (G_VARIANT_TYPE_BOOLEAN, &v, 1);
+}
+
+/**
+ * g_variant_get_boolean:
+ * @value: a boolean #GVariant instance
+ * @returns: %TRUE or %FALSE
+ *
+ * Returns the boolean value of @value.
+ *
+ * It is an error to call this function with a @value of any type
+ * other than %G_VARIANT_TYPE_BOOLEAN.
+ *
+ * Since: 2.24
+ **/
+gboolean
+g_variant_get_boolean (GVariant *value)
+{
+  const guchar *data;
+
+  TYPE_CHECK (value, G_VARIANT_TYPE_BOOLEAN, FALSE);
+
+  data = g_variant_get_data (value);
+
+  return data != NULL ? *data != 0 : FALSE;
+}
+
+/* the constructors and accessors for byte, int{16,32,64}, handles and
+ * doubles all look pretty much exactly the same, so we reduce
+ * copy/pasting here.
+ */
+#define NUMERIC_TYPE(TYPE, type, ctype) \
+  GVariant *g_variant_new_##type (ctype value) {                \
+    return g_variant_new_from_trusted (G_VARIANT_TYPE_##TYPE,   \
+                                       &value, sizeof value);   \
+  }                                                             \
+  ctype g_variant_get_##type (GVariant *value) {                \
+    const ctype *data;                                          \
+    TYPE_CHECK (value, G_VARIANT_TYPE_ ## TYPE, 0);             \
+    data = g_variant_get_data (value);                          \
+    return data != NULL ? *data : 0;                            \
+  }
+
+
+/**
+ * g_variant_new_byte:
+ * @byte: a #guint8 value
+ * @returns: a floating reference to a new byte #GVariant instance
+ *
+ * Creates a new byte #GVariant instance.
+ *
+ * Since: 2.24
+ **/
+/**
+ * g_variant_get_byte:
+ * @value: a byte #GVariant instance
+ * @returns: a #guchar
+ *
+ * Returns the byte value of @value.
+ *
+ * It is an error to call this function with a @value of any type
+ * other than %G_VARIANT_TYPE_BYTE.
+ *
+ * Since: 2.24
+ **/
+NUMERIC_TYPE (BYTE, byte, guchar)
+
+/**
+ * g_variant_new_int16:
+ * @int16: a #gint16 value
+ * @returns: a floating reference to a new int16 #GVariant instance
+ *
+ * Creates a new int16 #GVariant instance.
+ *
+ * Since: 2.24
+ **/
+/**
+ * g_variant_get_int16:
+ * @value: a int16 #GVariant instance
+ * @returns: a #gint16
+ *
+ * Returns the 16-bit signed integer value of @value.
+ *
+ * It is an error to call this function with a @value of any type
+ * other than %G_VARIANT_TYPE_INT16.
+ *
+ * Since: 2.24
+ **/
+NUMERIC_TYPE (INT16, int16, gint16)
+
+/**
+ * g_variant_new_uint16:
+ * @uint16: a #guint16 value
+ * @returns: a floating reference to a new uint16 #GVariant instance
+ *
+ * Creates a new uint16 #GVariant instance.
+ *
+ * Since: 2.24
+ **/
+/**
+ * g_variant_get_uint16:
+ * @value: a uint16 #GVariant instance
+ * @returns: a #guint16
+ *
+ * Returns the 16-bit unsigned integer value of @value.
+ *
+ * It is an error to call this function with a @value of any type
+ * other than %G_VARIANT_TYPE_UINT16.
+ *
+ * Since: 2.24
+ **/
+NUMERIC_TYPE (UINT16, uint16, guint16)
+
+/**
+ * g_variant_new_int32:
+ * @int32: a #gint32 value
+ * @returns: a floating reference to a new int32 #GVariant instance
+ *
+ * Creates a new int32 #GVariant instance.
+ *
+ * Since: 2.24
+ **/
+/**
+ * g_variant_get_int32:
+ * @value: a int32 #GVariant instance
+ * @returns: a #gint32
+ *
+ * Returns the 32-bit signed integer value of @value.
+ *
+ * It is an error to call this function with a @value of any type
+ * other than %G_VARIANT_TYPE_INT32.
+ *
+ * Since: 2.24
+ **/
+NUMERIC_TYPE (INT32, int32, gint32)
+
+/**
+ * g_variant_new_uint32:
+ * @uint32: a #guint32 value
+ * @returns: a floating reference to a new uint32 #GVariant instance
+ *
+ * Creates a new uint32 #GVariant instance.
+ *
+ * Since: 2.24
+ **/
+/**
+ * g_variant_get_uint32:
+ * @value: a uint32 #GVariant instance
+ * @returns: a #guint32
+ *
+ * Returns the 32-bit unsigned integer value of @value.
+ *
+ * It is an error to call this function with a @value of any type
+ * other than %G_VARIANT_TYPE_UINT32.
+ *
+ * Since: 2.24
+ **/
+NUMERIC_TYPE (UINT32, uint32, guint32)
+
+/**
+ * g_variant_new_int64:
+ * @int64: a #gint64 value
+ * @returns: a floating reference to a new int64 #GVariant instance
+ *
+ * Creates a new int64 #GVariant instance.
+ *
+ * Since: 2.24
+ **/
+/**
+ * g_variant_get_int64:
+ * @value: a int64 #GVariant instance
+ * @returns: a #gint64
+ *
+ * Returns the 64-bit signed integer value of @value.
+ *
+ * It is an error to call this function with a @value of any type
+ * other than %G_VARIANT_TYPE_INT64.
+ *
+ * Since: 2.24
+ **/
+NUMERIC_TYPE (INT64, int64, gint64)
+
+/**
+ * g_variant_new_uint64:
+ * @uint64: a #guint64 value
+ * @returns: a floating reference to a new uint64 #GVariant instance
+ *
+ * Creates a new uint64 #GVariant instance.
+ *
+ * Since: 2.24
+ **/
+/**
+ * g_variant_get_uint64:
+ * @value: a uint64 #GVariant instance
+ * @returns: a #guint64
+ *
+ * Returns the 64-bit unsigned integer value of @value.
+ *
+ * It is an error to call this function with a @value of any type
+ * other than %G_VARIANT_TYPE_UINT64.
+ *
+ * Since: 2.24
+ **/
+NUMERIC_TYPE (UINT64, uint64, guint64)
+
+/**
+ * g_variant_new_handle:
+ * @handle: a #gint32 value
+ * @returns: a floating reference to a new handle #GVariant instance
+ *
+ * Creates a new handle #GVariant instance.
+ *
+ * By convention, handles are indexes into an array of file descriptors
+ * that are sent alongside a DBus message.  If you're not interacting
+ * with DBus, you probably don't need them.
+ *
+ * Since: 2.24
+ **/
+/**
+ * g_variant_get_handle:
+ * @value: a handle #GVariant instance
+ * @returns: a #gint32
+ *
+ * Returns the 32-bit signed integer value of @value.
+ *
+ * It is an error to call this function with a @value of any type other
+ * than %G_VARIANT_TYPE_HANDLE.
+ *
+ * By convention, handles are indexes into an array of file descriptors
+ * that are sent alongside a DBus message.  If you're not interacting
+ * with DBus, you probably don't need them.
+ *
+ * Since: 2.24
+ **/
+NUMERIC_TYPE (HANDLE, handle, gint32)
+
+/**
+ * g_variant_new_double:
+ * @floating: a #gdouble floating point value
+ * @returns: a floating reference to a new double #GVariant instance
+ *
+ * Creates a new double #GVariant instance.
+ *
+ * Since: 2.24
+ **/
+/**
+ * g_variant_get_double:
+ * @value: a double #GVariant instance
+ * @returns: a #gdouble
+ *
+ * Returns the double precision floating point value of @value.
+ *
+ * It is an error to call this function with a @value of any type
+ * other than %G_VARIANT_TYPE_DOUBLE.
+ *
+ * Since: 2.24
+ **/
+NUMERIC_TYPE (DOUBLE, double, gdouble)
+
+/* Container type Constructor / Deconstructors {{{1 */
+/**
+ * g_variant_new_maybe:
+ * @child_type: (allow-none): the #GVariantType of the child, or %NULL
+ * @child: (allow-none): the child value, or %NULL
+ * @returns: a floating reference to a new #GVariant maybe instance
+ *
+ * Depending on if @child is %NULL, either wraps @child inside of a
+ * maybe container or creates a Nothing instance for the given @type.
+ *
+ * At least one of @child_type and @child must be non-%NULL.
+ * If @child_type is non-%NULL then it must be a definite type.
+ * If they are both non-%NULL then @child_type must be the type
+ * of @child.
+ *
+ * If @child is a floating reference (see g_variant_ref_sink()), the new
+ * instance takes ownership of @child.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_new_maybe (const GVariantType *child_type,
+                     GVariant           *child)
+{
+  GVariantType *maybe_type;
+  GVariant *value;
+
+  g_return_val_if_fail (child_type == NULL || g_variant_type_is_definite
+                        (child_type), 0);
+  g_return_val_if_fail (child_type != NULL || child != NULL, NULL);
+  g_return_val_if_fail (child_type == NULL || child == NULL ||
+                        g_variant_is_of_type (child, child_type),
+                        NULL);
+
+  if (child_type == NULL)
+    child_type = g_variant_get_type (child);
+
+  maybe_type = g_variant_type_new_maybe (child_type);
+
+  if (child != NULL)
+    {
+      GVariant **children;
+      gboolean trusted;
+
+      children = g_new (GVariant *, 1);
+      children[0] = g_variant_ref_sink (child);
+      trusted = g_variant_is_trusted (children[0]);
+
+      value = g_variant_new_from_children (maybe_type, children, 1, trusted);
+    }
+  else
+    value = g_variant_new_from_children (maybe_type, NULL, 0, TRUE);
+
+  g_variant_type_free (maybe_type);
+
+  return value;
+}
+
+/**
+ * g_variant_get_maybe:
+ * @value: a maybe-typed value
+ * @returns: (allow-none): the contents of @value, or %NULL
+ *
+ * Given a maybe-typed #GVariant instance, extract its value.  If the
+ * value is Nothing, then this function returns %NULL.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_get_maybe (GVariant *value)
+{
+  TYPE_CHECK (value, G_VARIANT_TYPE_MAYBE, NULL);
+
+  if (g_variant_n_children (value))
+    return g_variant_get_child_value (value, 0);
+
+  return NULL;
+}
+
+/**
+ * g_variant_new_variant:
+ * @value: a #GVariance instance
+ * @returns: a floating reference to a new variant #GVariant instance
+ *
+ * Boxes @value.  The result is a #GVariant instance representing a
+ * variant containing the original value.
+ *
+ * If @child is a floating reference (see g_variant_ref_sink()), the new
+ * instance takes ownership of @child.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_new_variant (GVariant *value)
+{
+  g_return_val_if_fail (value != NULL, NULL);
+
+  g_variant_ref_sink (value);
+
+  return g_variant_new_from_children (G_VARIANT_TYPE_VARIANT,
+                                      g_memdup (&value, sizeof value),
+                                      1, g_variant_is_trusted (value));
+}
+
+/**
+ * g_variant_get_variant:
+ * @value: a variant #GVariance instance
+ * @returns: the item contained in the variant
+ *
+ * Unboxes @value.  The result is the #GVariant instance that was
+ * contained in @value.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_get_variant (GVariant *value)
+{
+  TYPE_CHECK (value, G_VARIANT_TYPE_VARIANT, NULL);
+
+  return g_variant_get_child_value (value, 0);
+}
+
+/**
+ * g_variant_new_array:
+ * @child_type: (allow-none): the element type of the new array
+ * @children: (allow-none) (array length=n_children): an array of
+ *            #GVariant pointers, the children
+ * @n_children: the length of @children
+ * @returns: a floating reference to a new #GVariant array
+ *
+ * Creates a new #GVariant array from @children.
+ *
+ * @child_type must be non-%NULL if @n_children is zero.  Otherwise, the
+ * child type is determined by inspecting the first element of the
+ * @children array.  If @child_type is non-%NULL then it must be a
+ * definite type.
+ *
+ * The items of the array are taken from the @children array.  No entry
+ * in the @children array may be %NULL.
+ *
+ * All items in the array must have the same type, which must be the
+ * same as @child_type, if given.
+ *
+ * If the @children are floating references (see g_variant_ref_sink()), the
+ * new instance takes ownership of them as if via g_variant_ref_sink().
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_new_array (const GVariantType *child_type,
+                     GVariant * const   *children,
+                     gsize               n_children)
+{
+  GVariantType *array_type;
+  GVariant **my_children;
+  gboolean trusted;
+  GVariant *value;
+  gsize i;
+
+  g_return_val_if_fail (n_children > 0 || child_type != NULL, NULL);
+  g_return_val_if_fail (n_children == 0 || children != NULL, NULL);
+  g_return_val_if_fail (child_type == NULL ||
+                        g_variant_type_is_definite (child_type), NULL);
+
+  my_children = g_new (GVariant *, n_children);
+  trusted = TRUE;
+
+  if (child_type == NULL)
+    child_type = g_variant_get_type (children[0]);
+  array_type = g_variant_type_new_array (child_type);
+
+  for (i = 0; i < n_children; i++)
+    {
+      TYPE_CHECK (children[i], child_type, NULL);
+      my_children[i] = g_variant_ref_sink (children[i]);
+      trusted &= g_variant_is_trusted (children[i]);
+    }
+
+  value = g_variant_new_from_children (array_type, my_children,
+                                       n_children, trusted);
+  g_variant_type_free (array_type);
+
+  return value;
+}
+
+/*< private >
+ * g_variant_make_tuple_type:
+ * @children: (array length=n_children): an array of GVariant *
+ * @n_children: the length of @children
+ *
+ * Return the type of a tuple containing @children as its items.
+ **/
+static GVariantType *
+g_variant_make_tuple_type (GVariant * const *children,
+                           gsize             n_children)
+{
+  const GVariantType **types;
+  GVariantType *type;
+  gsize i;
+
+  types = g_new (const GVariantType *, n_children);
+
+  for (i = 0; i < n_children; i++)
+    types[i] = g_variant_get_type (children[i]);
+
+  type = g_variant_type_new_tuple (types, n_children);
+  g_free (types);
+
+  return type;
+}
+
+/**
+ * g_variant_new_tuple:
+ * @children: (array length=n_children): the items to make the tuple out of
+ * @n_children: the length of @children
+ * @returns: a floating reference to a new #GVariant tuple
+ *
+ * Creates a new tuple #GVariant out of the items in @children.  The
+ * type is determined from the types of @children.  No entry in the
+ * @children array may be %NULL.
+ *
+ * If @n_children is 0 then the unit tuple is constructed.
+ *
+ * If the @children are floating references (see g_variant_ref_sink()), the
+ * new instance takes ownership of them as if via g_variant_ref_sink().
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_new_tuple (GVariant * const *children,
+                     gsize             n_children)
+{
+  GVariantType *tuple_type;
+  GVariant **my_children;
+  gboolean trusted;
+  GVariant *value;
+  gsize i;
+
+  g_return_val_if_fail (n_children == 0 || children != NULL, NULL);
+
+  my_children = g_new (GVariant *, n_children);
+  trusted = TRUE;
+
+  for (i = 0; i < n_children; i++)
+    {
+      my_children[i] = g_variant_ref_sink (children[i]);
+      trusted &= g_variant_is_trusted (children[i]);
+    }
+
+  tuple_type = g_variant_make_tuple_type (children, n_children);
+  value = g_variant_new_from_children (tuple_type, my_children,
+                                       n_children, trusted);
+  g_variant_type_free (tuple_type);
+
+  return value;
+}
+
+/*< private >
+ * g_variant_make_dict_entry_type:
+ * @key: a #GVariant, the key
+ * @val: a #GVariant, the value
+ *
+ * Return the type of a dictionary entry containing @key and @val as its
+ * children.
+ **/
+static GVariantType *
+g_variant_make_dict_entry_type (GVariant *key,
+                                GVariant *val)
+{
+  return g_variant_type_new_dict_entry (g_variant_get_type (key),
+                                        g_variant_get_type (val));
+}
+
+/**
+ * g_variant_new_dict_entry:
+ * @key: a basic #GVariant, the key
+ * @value: a #GVariant, the value
+ * @returns: a floating reference to a new dictionary entry #GVariant
+ *
+ * Creates a new dictionary entry #GVariant.  @key and @value must be
+ * non-%NULL.
+ *
+ * @key must be a value of a basic type (ie: not a container).
+ *
+ * If the @key or @value are floating references (see g_variant_ref_sink()),
+ * the new instance takes ownership of them as if via g_variant_ref_sink().
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_new_dict_entry (GVariant *key,
+                          GVariant *value)
+{
+  GVariantType *dict_type;
+  GVariant **children;
+  gboolean trusted;
+
+  g_return_val_if_fail (key != NULL && value != NULL, NULL);
+  g_return_val_if_fail (!g_variant_is_container (key), NULL);
+
+  children = g_new (GVariant *, 2);
+  children[0] = g_variant_ref_sink (key);
+  children[1] = g_variant_ref_sink (value);
+  trusted = g_variant_is_trusted (key) && g_variant_is_trusted (value);
+
+  dict_type = g_variant_make_dict_entry_type (key, value);
+  value = g_variant_new_from_children (dict_type, children, 2, trusted);
+  g_variant_type_free (dict_type);
+
+  return value;
+}
+
+/**
+ * g_variant_get_fixed_array:
+ * @value: a #GVariant array with fixed-sized elements
+ * @n_elements: a pointer to the location to store the number of items
+ * @element_size: the size of each element
+ * @returns: (array length=n_elements): a pointer to the fixed array
+ *
+ * Provides access to the serialised data for an array of fixed-sized
+ * items.
+ *
+ * @value must be an array with fixed-sized elements.  Numeric types are
+ * fixed-size as are tuples containing only other fixed-sized types.
+ *
+ * @element_size must be the size of a single element in the array.  For
+ * example, if calling this function for an array of 32 bit integers,
+ * you might say <code>sizeof (gint32)</code>.  This value isn't used
+ * except for the purpose of a double-check that the form of the
+ * seralised data matches the caller's expectation.
+ *
+ * @n_elements, which must be non-%NULL is set equal to the number of
+ * items in the array.
+ *
+ * Since: 2.24
+ **/
+gconstpointer
+g_variant_get_fixed_array (GVariant *value,
+                           gsize    *n_elements,
+                           gsize     element_size)
+{
+  GVariantTypeInfo *array_info;
+  gsize array_element_size;
+  gconstpointer data;
+  gsize size;
+
+  TYPE_CHECK (value, G_VARIANT_TYPE_ARRAY, NULL);
+
+  g_return_val_if_fail (n_elements != NULL, NULL);
+  g_return_val_if_fail (element_size > 0, NULL);
+
+  array_info = g_variant_get_type_info (value);
+  g_variant_type_info_query_element (array_info, NULL, &array_element_size);
+
+  g_return_val_if_fail (array_element_size, NULL);
+
+  if G_UNLIKELY (array_element_size != element_size)
+    {
+      if (array_element_size)
+        g_critical ("g_variant_get_fixed_array: assertion "
+                    "`g_variant_array_has_fixed_size (value, element_size)' "
+                    "failed: array size %"G_GSIZE_FORMAT" does not match "
+                    "given element_size %"G_GSIZE_FORMAT".",
+                    array_element_size, element_size);
+      else
+        g_critical ("g_variant_get_fixed_array: assertion "
+                    "`g_variant_array_has_fixed_size (value, element_size)' "
+                    "failed: array does not have fixed size.");
+    }
+
+  data = g_variant_get_data (value);
+  size = g_variant_get_size (value);
+
+  if (size % element_size)
+    *n_elements = 0;
+  else
+    *n_elements = size / element_size;
+
+  if (*n_elements)
+    return data;
+
+  return NULL;
+}
+
+/* String type constructor/getters/validation {{{1 */
+/**
+ * g_variant_new_string:
+ * @string: a normal utf8 nul-terminated string
+ * @returns: a floating reference to a new string #GVariant instance
+ *
+ * Creates a string #GVariant with the contents of @string.
+ *
+ * @string must be valid utf8.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_new_string (const gchar *string)
+{
+  g_return_val_if_fail (string != NULL, NULL);
+  g_return_val_if_fail (g_utf8_validate (string, -1, NULL), NULL);
+
+  return g_variant_new_from_trusted (G_VARIANT_TYPE_STRING,
+                                     string, strlen (string) + 1);
+}
+
+/**
+ * g_variant_new_object_path:
+ * @object_path: a normal C nul-terminated string
+ * @returns: a floating reference to a new object path #GVariant instance
+ *
+ * Creates a DBus object path #GVariant with the contents of @string.
+ * @string must be a valid DBus object path.  Use
+ * g_variant_is_object_path() if you're not sure.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_new_object_path (const gchar *object_path)
+{
+  g_return_val_if_fail (g_variant_is_object_path (object_path), NULL);
+
+  return g_variant_new_from_trusted (G_VARIANT_TYPE_OBJECT_PATH,
+                                     object_path, strlen (object_path) + 1);
+}
+
+/**
+ * g_variant_is_object_path:
+ * @string: a normal C nul-terminated string
+ * @returns: %TRUE if @string is a DBus object path
+ *
+ * Determines if a given string is a valid DBus object path.  You
+ * should ensure that a string is a valid DBus object path before
+ * passing it to g_variant_new_object_path().
+ *
+ * A valid object path starts with '/' followed by zero or more
+ * sequences of characters separated by '/' characters.  Each sequence
+ * must contain only the characters "[A-Z][a-z][0-9]_".  No sequence
+ * (including the one following the final '/' character) may be empty.
+ *
+ * Since: 2.24
+ **/
+gboolean
+g_variant_is_object_path (const gchar *string)
+{
+  g_return_val_if_fail (string != NULL, FALSE);
+
+  return g_variant_serialiser_is_object_path (string, strlen (string) + 1);
+}
+
+/**
+ * g_variant_new_signature:
+ * @signature: a normal C nul-terminated string
+ * @returns: a floating reference to a new signature #GVariant instance
+ *
+ * Creates a DBus type signature #GVariant with the contents of
+ * @string.  @string must be a valid DBus type signature.  Use
+ * g_variant_is_signature() if you're not sure.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_new_signature (const gchar *signature)
+{
+  g_return_val_if_fail (g_variant_is_signature (signature), NULL);
+
+  return g_variant_new_from_trusted (G_VARIANT_TYPE_SIGNATURE,
+                                     signature, strlen (signature) + 1);
+}
+
+/**
+ * g_variant_is_signature:
+ * @string: a normal C nul-terminated string
+ * @returns: %TRUE if @string is a DBus type signature
+ *
+ * Determines if a given string is a valid DBus type signature.  You
+ * should ensure that a string is a valid DBus type signature before
+ * passing it to g_variant_new_signature().
+ *
+ * DBus type signatures consist of zero or more definite #GVariantType
+ * strings in sequence.
+ *
+ * Since: 2.24
+ **/
+gboolean
+g_variant_is_signature (const gchar *string)
+{
+  g_return_val_if_fail (string != NULL, FALSE);
+
+  return g_variant_serialiser_is_signature (string, strlen (string) + 1);
+}
+
+/**
+ * g_variant_get_string:
+ * @value: a string #GVariant instance
+ * @length: (allow-none) (default NULL) (out): a pointer to a #gsize,
+ *          to store the length
+ * @returns: the constant string, utf8 encoded
+ *
+ * Returns the string value of a #GVariant instance with a string
+ * type.  This includes the types %G_VARIANT_TYPE_STRING,
+ * %G_VARIANT_TYPE_OBJECT_PATH and %G_VARIANT_TYPE_SIGNATURE.
+ *
+ * The string will always be utf8 encoded.
+ *
+ * If @length is non-%NULL then the length of the string (in bytes) is
+ * returned there.  For trusted values, this information is already
+ * known.  For untrusted values, a strlen() will be performed.
+ *
+ * It is an error to call this function with a @value of any type
+ * other than those three.
+ *
+ * The return value remains valid as long as @value exists.
+ *
+ * Since: 2.24
+ **/
+const gchar *
+g_variant_get_string (GVariant *value,
+                      gsize    *length)
+{
+  gconstpointer data;
+  gsize size;
+
+  g_return_val_if_fail (value != NULL, NULL);
+  g_return_val_if_fail (
+    g_variant_is_of_type (value, G_VARIANT_TYPE_STRING) ||
+    g_variant_is_of_type (value, G_VARIANT_TYPE_OBJECT_PATH) ||
+    g_variant_is_of_type (value, G_VARIANT_TYPE_SIGNATURE), NULL);
+
+  data = g_variant_get_data (value);
+  size = g_variant_get_size (value);
+
+  if (!g_variant_is_trusted (value))
+    {
+      switch (g_variant_classify (value))
+        {
+        case G_VARIANT_CLASS_STRING:
+          if (g_variant_serialiser_is_string (data, size))
+            break;
+
+          data = "";
+          size = 1;
+          break;
+
+        case G_VARIANT_CLASS_OBJECT_PATH:
+          if (g_variant_serialiser_is_object_path (data, size))
+            break;
+
+          data = "/";
+          size = 2;
+          break;
+
+        case G_VARIANT_CLASS_SIGNATURE:
+          if (g_variant_serialiser_is_signature (data, size))
+            break;
+
+          data = "";
+          size = 1;
+          break;
+
+        default:
+          g_assert_not_reached ();
+        }
+    }
+
+  if (length)
+    *length = size - 1;
+
+  return data;
+}
+
+/**
+ * g_variant_dup_string:
+ * @value: a string #GVariant instance
+ * @length: a pointer to a #gsize, to store the length
+ * @returns: a newly allocated string, utf8 encoded
+ *
+ * Similar to g_variant_get_string() except that instead of returning
+ * a constant string, the string is duplicated.
+ *
+ * The string will always be utf8 encoded.
+ *
+ * The return value must be freed using g_free().
+ *
+ * Since: 2.24
+ **/
+gchar *
+g_variant_dup_string (GVariant *value,
+                      gsize    *length)
+{
+  return g_strdup (g_variant_get_string (value, length));
+}
+
+/**
+ * g_variant_new_strv:
+ * @strv: (array length=length) (element-type utf8): an array of strings
+ * @length: the length of @strv, or -1
+ * @returns: a new floating #GVariant instance
+ *
+ * Constructs an array of strings #GVariant from the given array of
+ * strings.
+ *
+ * If @length is -1 then @strv is %NULL-terminated.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_new_strv (const gchar * const *strv,
+                    gssize               length)
+{
+  GVariant **strings;
+  gsize i;
+
+  g_return_val_if_fail (length == 0 || strv != NULL, NULL);
+
+  if (length < 0)
+    length = g_strv_length ((gchar **) strv);
+
+  strings = g_new (GVariant *, length);
+  for (i = 0; i < length; i++)
+    strings[i] = g_variant_ref_sink (g_variant_new_string (strv[i]));
+
+  return g_variant_new_from_children (G_VARIANT_TYPE_STRING_ARRAY,
+                                      strings, length, TRUE);
+}
+
+/**
+ * g_variant_get_strv:
+ * @value: an array of strings #GVariant
+ * @length: (allow-none): the length of the result, or %NULL
+ * @returns: (array length=length) (transfer container): an array of constant
+ * strings
+ *
+ * Gets the contents of an array of strings #GVariant.  This call
+ * makes a shallow copy; the return result should be released with
+ * g_free(), but the individual strings must not be modified.
+ *
+ * If @length is non-%NULL then the number of elements in the result
+ * is stored there.  In any case, the resulting array will be
+ * %NULL-terminated.
+ *
+ * For an empty array, @length will be set to 0 and a pointer to a
+ * %NULL pointer will be returned.
+ *
+ * Since: 2.24
+ **/
+const gchar **
+g_variant_get_strv (GVariant *value,
+                    gsize    *length)
+{
+  const gchar **strv;
+  gsize n;
+  gsize i;
+
+  TYPE_CHECK (value, G_VARIANT_TYPE_STRING_ARRAY, NULL);
+
+  g_variant_get_data (value);
+  n = g_variant_n_children (value);
+  strv = g_new (const gchar *, n + 1);
+
+  for (i = 0; i < n; i++)
+    {
+      GVariant *string;
+
+      string = g_variant_get_child_value (value, i);
+      strv[i] = g_variant_get_string (string, NULL);
+      g_variant_unref (string);
+    }
+  strv[i] = NULL;
+
+  if (length)
+    *length = n;
+
+  return strv;
+}
+
+/**
+ * g_variant_dup_strv:
+ * @value: an array of strings #GVariant
+ * @length: (allow-none): the length of the result, or %NULL
+ * @returns: (array length=length): an array of strings
+ *
+ * Gets the contents of an array of strings #GVariant.  This call
+ * makes a deep copy; the return result should be released with
+ * g_strfreev().
+ *
+ * If @length is non-%NULL then the number of elements in the result
+ * is stored there.  In any case, the resulting array will be
+ * %NULL-terminated.
+ *
+ * For an empty array, @length will be set to 0 and a pointer to a
+ * %NULL pointer will be returned.
+ *
+ * Since: 2.24
+ **/
+gchar **
+g_variant_dup_strv (GVariant *value,
+                    gsize    *length)
+{
+  gchar **strv;
+  gsize n;
+  gsize i;
+
+  TYPE_CHECK (value, G_VARIANT_TYPE_STRING_ARRAY, NULL);
+
+  n = g_variant_n_children (value);
+  strv = g_new (gchar *, n + 1);
+
+  for (i = 0; i < n; i++)
+    {
+      GVariant *string;
+
+      string = g_variant_get_child_value (value, i);
+      strv[i] = g_variant_dup_string (string, NULL);
+      g_variant_unref (string);
+    }
+  strv[i] = NULL;
+
+  if (length)
+    *length = n;
+
+  return strv;
+}
+
+/**
+ * g_variant_new_bytestring:
+ * @string: a normal nul-terminated string in no particular encoding
+ * @returns: a floating reference to a new bytestring #GVariant instance
+ *
+ * Creates an array-of-bytes #GVariant with the contents of @string.
+ * This function is just like g_variant_new_string() except that the
+ * string need not be valid utf8.
+ *
+ * The nul terminator character at the end of the string is stored in
+ * the array.
+ *
+ * Since: 2.26
+ **/
+GVariant *
+g_variant_new_bytestring (const gchar *string)
+{
+  g_return_val_if_fail (string != NULL, NULL);
+
+  return g_variant_new_from_trusted (G_VARIANT_TYPE_BYTESTRING,
+                                     string, strlen (string) + 1);
+}
+
+/**
+ * g_variant_get_bytestring:
+ * @value: an array-of-bytes #GVariant instance
+ * @returns: the constant string
+ *
+ * Returns the string value of a #GVariant instance with an
+ * array-of-bytes type.  The string has no particular encoding.
+ *
+ * If the array does not end with a nul terminator character, the empty
+ * string is returned.  For this reason, you can always trust that a
+ * non-%NULL nul-terminated string will be returned by this function.
+ *
+ * If the array contains a nul terminator character somewhere other than
+ * the last byte then the returned string is the string, up to the first
+ * such nul character.
+ *
+ * It is an error to call this function with a @value that is not an
+ * array of bytes.
+ *
+ * The return value remains valid as long as @value exists.
+ *
+ * Since: 2.26
+ **/
+const gchar *
+g_variant_get_bytestring (GVariant *value)
+{
+  const gchar *string;
+  gsize size;
+
+  TYPE_CHECK (value, G_VARIANT_TYPE_BYTESTRING, NULL);
+
+  /* Won't be NULL since this is an array type */
+  string = g_variant_get_data (value);
+  size = g_variant_get_size (value);
+
+  if (size && string[size - 1] == '\0')
+    return string;
+  else
+    return "";
+}
+
+/**
+ * g_variant_dup_bytestring:
+ * @value: an array-of-bytes #GVariant instance
+ * @length: (allow-none) (default NULL): a pointer to a #gsize, to store
+ *          the length (not including the nul terminator)
+ * @returns: a newly allocated string
+ *
+ * Similar to g_variant_get_bytestring() except that instead of
+ * returning a constant string, the string is duplicated.
+ *
+ * The return value must be freed using g_free().
+ *
+ * Since: 2.26
+ **/
+gchar *
+g_variant_dup_bytestring (GVariant *value,
+                          gsize    *length)
+{
+  const gchar *original = g_variant_get_bytestring (value);
+  gsize size;
+
+  /* don't crash in case get_bytestring() had an assert failure */
+  if (original == NULL)
+    return NULL;
+
+  size = strlen (original);
+
+  if (length)
+    *length = size;
+
+  return g_memdup (original, size + 1);
+}
+
+/**
+ * g_variant_new_bytestring_array:
+ * @strv: (array length=length): an array of strings
+ * @length: the length of @strv, or -1
+ * @returns: a new floating #GVariant instance
+ *
+ * Constructs an array of bytestring #GVariant from the given array of
+ * strings.
+ *
+ * If @length is -1 then @strv is %NULL-terminated.
+ *
+ * Since: 2.26
+ **/
+GVariant *
+g_variant_new_bytestring_array (const gchar * const *strv,
+                                gssize               length)
+{
+  GVariant **strings;
+  gsize i;
+
+  g_return_val_if_fail (length == 0 || strv != NULL, NULL);
+
+  if (length < 0)
+    length = g_strv_length ((gchar **) strv);
+
+  strings = g_new (GVariant *, length);
+  for (i = 0; i < length; i++)
+    strings[i] = g_variant_ref_sink (g_variant_new_bytestring (strv[i]));
+
+  return g_variant_new_from_children (G_VARIANT_TYPE_BYTESTRING_ARRAY,
+                                      strings, length, TRUE);
+}
+
+/**
+ * g_variant_get_bytestring_array:
+ * @value: an array of array of bytes #GVariant ('aay')
+ * @length: (allow-none): the length of the result, or %NULL
+ * @returns: (array length=length): an array of constant strings
+ *
+ * Gets the contents of an array of array of bytes #GVariant.  This call
+ * makes a shallow copy; the return result should be released with
+ * g_free(), but the individual strings must not be modified.
+ *
+ * If @length is non-%NULL then the number of elements in the result is
+ * stored there.  In any case, the resulting array will be
+ * %NULL-terminated.
+ *
+ * For an empty array, @length will be set to 0 and a pointer to a
+ * %NULL pointer will be returned.
+ *
+ * Since: 2.26
+ **/
+const gchar **
+g_variant_get_bytestring_array (GVariant *value,
+                                gsize    *length)
+{
+  const gchar **strv;
+  gsize n;
+  gsize i;
+
+  TYPE_CHECK (value, G_VARIANT_TYPE_BYTESTRING_ARRAY, NULL);
+
+  g_variant_get_data (value);
+  n = g_variant_n_children (value);
+  strv = g_new (const gchar *, n + 1);
+
+  for (i = 0; i < n; i++)
+    {
+      GVariant *string;
+
+      string = g_variant_get_child_value (value, i);
+      strv[i] = g_variant_get_bytestring (string);
+      g_variant_unref (string);
+    }
+  strv[i] = NULL;
+
+  if (length)
+    *length = n;
+
+  return strv;
+}
+
+/**
+ * g_variant_dup_bytestring_array:
+ * @value: an array of array of bytes #GVariant ('aay')
+ * @length: (allow-none): the length of the result, or %NULL
+ * @returns: (array length=length): an array of strings
+ *
+ * Gets the contents of an array of array of bytes #GVariant.  This call
+ * makes a deep copy; the return result should be released with
+ * g_strfreev().
+ *
+ * If @length is non-%NULL then the number of elements in the result is
+ * stored there.  In any case, the resulting array will be
+ * %NULL-terminated.
+ *
+ * For an empty array, @length will be set to 0 and a pointer to a
+ * %NULL pointer will be returned.
+ *
+ * Since: 2.26
+ **/
+gchar **
+g_variant_dup_bytestring_array (GVariant *value,
+                                gsize    *length)
+{
+  gchar **strv;
+  gsize n;
+  gsize i;
+
+  TYPE_CHECK (value, G_VARIANT_TYPE_BYTESTRING_ARRAY, NULL);
+
+  g_variant_get_data (value);
+  n = g_variant_n_children (value);
+  strv = g_new (gchar *, n + 1);
+
+  for (i = 0; i < n; i++)
+    {
+      GVariant *string;
+
+      string = g_variant_get_child_value (value, i);
+      strv[i] = g_variant_dup_bytestring (string, NULL);
+      g_variant_unref (string);
+    }
+  strv[i] = NULL;
+
+  if (length)
+    *length = n;
+
+  return strv;
+}
+
+/* Type checking and querying {{{1 */
+/**
+ * g_variant_get_type:
+ * @value: a #GVariant
+ * @returns: a #GVariantType
+ *
+ * Determines the type of @value.
+ *
+ * The return value is valid for the lifetime of @value and must not
+ * be freed.
+ *
+ * Since: 2.24
+ **/
+const GVariantType *
+g_variant_get_type (GVariant *value)
+{
+  GVariantTypeInfo *type_info;
+
+  g_return_val_if_fail (value != NULL, NULL);
+
+  type_info = g_variant_get_type_info (value);
+
+  return (GVariantType *) g_variant_type_info_get_type_string (type_info);
+}
+
+/**
+ * g_variant_get_type_string:
+ * @value: a #GVariant
+ * @returns: the type string for the type of @value
+ *
+ * Returns the type string of @value.  Unlike the result of calling
+ * g_variant_type_peek_string(), this string is nul-terminated.  This
+ * string belongs to #GVariant and must not be freed.
+ *
+ * Since: 2.24
+ **/
+const gchar *
+g_variant_get_type_string (GVariant *value)
+{
+  GVariantTypeInfo *type_info;
+
+  g_return_val_if_fail (value != NULL, NULL);
+
+  type_info = g_variant_get_type_info (value);
+
+  return g_variant_type_info_get_type_string (type_info);
+}
+
+/**
+ * g_variant_is_of_type:
+ * @value: a #GVariant instance
+ * @type: a #GVariantType
+ * @returns: %TRUE if the type of @value matches @type
+ *
+ * Checks if a value has a type matching the provided type.
+ *
+ * Since: 2.24
+ **/
+gboolean
+g_variant_is_of_type (GVariant           *value,
+                      const GVariantType *type)
+{
+  return g_variant_type_is_subtype_of (g_variant_get_type (value), type);
+}
+
+/**
+ * g_variant_is_container:
+ * @value: a #GVariant instance
+ * @returns: %TRUE if @value is a container
+ *
+ * Checks if @value is a container.
+ */
+gboolean
+g_variant_is_container (GVariant *value)
+{
+  return g_variant_type_is_container (g_variant_get_type (value));
+}
+
+
+/**
+ * g_variant_classify:
+ * @value: a #GVariant
+ * @returns: the #GVariantClass of @value
+ *
+ * Classifies @value according to its top-level type.
+ *
+ * Since: 2.24
+ **/
+/**
+ * GVariantClass:
+ * @G_VARIANT_CLASS_BOOLEAN: The #GVariant is a boolean.
+ * @G_VARIANT_CLASS_BYTE: The #GVariant is a byte.
+ * @G_VARIANT_CLASS_INT16: The #GVariant is a signed 16 bit integer.
+ * @G_VARIANT_CLASS_UINT16: The #GVariant is an unsigned 16 bit integer.
+ * @G_VARIANT_CLASS_INT32: The #GVariant is a signed 32 bit integer.
+ * @G_VARIANT_CLASS_UINT32: The #GVariant is an unsigned 32 bit integer.
+ * @G_VARIANT_CLASS_INT64: The #GVariant is a signed 64 bit integer.
+ * @G_VARIANT_CLASS_UINT64: The #GVariant is an unsigned 64 bit integer.
+ * @G_VARIANT_CLASS_HANDLE: The #GVariant is a file handle index.
+ * @G_VARIANT_CLASS_DOUBLE: The #GVariant is a double precision floating 
+ *                          point value.
+ * @G_VARIANT_CLASS_STRING: The #GVariant is a normal string.
+ * @G_VARIANT_CLASS_OBJECT_PATH: The #GVariant is a DBus object path 
+ *                               string.
+ * @G_VARIANT_CLASS_SIGNATURE: The #GVariant is a DBus signature string.
+ * @G_VARIANT_CLASS_VARIANT: The #GVariant is a variant.
+ * @G_VARIANT_CLASS_MAYBE: The #GVariant is a maybe-typed value.
+ * @G_VARIANT_CLASS_ARRAY: The #GVariant is an array.
+ * @G_VARIANT_CLASS_TUPLE: The #GVariant is a tuple.
+ * @G_VARIANT_CLASS_DICT_ENTRY: The #GVariant is a dictionary entry.
+ *
+ * The range of possible top-level types of #GVariant instances.
+ *
+ * Since: 2.24
+ **/
+GVariantClass
+g_variant_classify (GVariant *value)
+{
+  g_return_val_if_fail (value != NULL, 0);
+
+  return *g_variant_get_type_string (value);
+}
+
+/* Pretty printer {{{1 */
+/**
+ * g_variant_print_string:
+ * @value: a #GVariant
+ * @string: (allow-none) (default NULL): a #GString, or %NULL
+ * @type_annotate: %TRUE if type information should be included in
+ *                 the output
+ * @returns: a #GString containing the string
+ *
+ * Behaves as g_variant_print(), but operates on a #GString.
+ *
+ * If @string is non-%NULL then it is appended to and returned.  Else,
+ * a new empty #GString is allocated and it is returned.
+ *
+ * Since: 2.24
+ **/
+GString *
+g_variant_print_string (GVariant *value,
+                        GString  *string,
+                        gboolean  type_annotate)
+{
+  if G_UNLIKELY (string == NULL)
+    string = g_string_new (NULL);
+
+  switch (g_variant_classify (value))
+    {
+    case G_VARIANT_CLASS_MAYBE:
+      if (type_annotate)
+        g_string_append_printf (string, "@%s ",
+                                g_variant_get_type_string (value));
+
+      if (g_variant_n_children (value))
+        {
+          gchar *printed_child;
+          GVariant *element;
+
+          /* Nested maybes:
+           *
+           * Consider the case of the type "mmi".  In this case we could
+           * write "just just 4", but "4" alone is totally unambiguous,
+           * so we try to drop "just" where possible.
+           *
+           * We have to be careful not to always drop "just", though,
+           * since "nothing" needs to be distinguishable from "just
+           * nothing".  The case where we need to ensure we keep the
+           * "just" is actually exactly the case where we have a nested
+           * Nothing.
+           *
+           * Instead of searching for that nested Nothing, we just print
+           * the contained value into a separate string and see if we
+           * end up with "nothing" at the end of it.  If so, we need to
+           * add "just" at our level.
+           */
+          element = g_variant_get_child_value (value, 0);
+          printed_child = g_variant_print (element, FALSE);
+          g_variant_unref (element);
+
+          if (g_str_has_suffix (printed_child, "nothing"))
+            g_string_append (string, "just ");
+          g_string_append (string, printed_child);
+          g_free (printed_child);
+        }
+      else
+        g_string_append (string, "nothing");
+
+      break;
+
+    case G_VARIANT_CLASS_ARRAY:
+      /* it's an array so the first character of the type string is 'a'
+       *
+       * if the first two characters are 'ay' then it's a bytestring.
+       * under certain conditions we print those as strings.
+       */
+      if (g_variant_get_type_string (value)[1] == 'y')
+        {
+          const gchar *str;
+          gsize size;
+          gsize i;
+
+          /* first determine if it is a byte string.
+           * that's when there's a single nul character: at the end.
+           */
+          str = g_variant_get_data (value);
+          size = g_variant_get_size (value);
+
+          for (i = 0; i < size; i++)
+            if (str[i] == '\0')
+              break;
+
+          /* first nul byte is the last byte -> it's a byte string. */
+          if (i == size - 1)
+            {
+              gchar *escaped = g_strescape (str, NULL);
+
+              /* use double quotes only if a ' is in the string */
+              if (strchr (str, '\''))
+                g_string_append_printf (string, "b\"%s\"", escaped);
+              else
+                g_string_append_printf (string, "b'%s'", escaped);
+
+              g_free (escaped);
+              break;
+            }
+
+          else
+            /* fall through and handle normally... */;
+        }
+
+      /*
+       * if the first two characters are 'a{' then it's an array of
+       * dictionary entries (ie: a dictionary) so we print that
+       * differently.
+       */
+      if (g_variant_get_type_string (value)[1] == '{')
+        /* dictionary */
+        {
+          const gchar *comma = "";
+          gsize n, i;
+
+          if ((n = g_variant_n_children (value)) == 0)
+            {
+              if (type_annotate)
+                g_string_append_printf (string, "@%s ",
+                                        g_variant_get_type_string (value));
+              g_string_append (string, "{}");
+              break;
+            }
+
+          g_string_append_c (string, '{');
+          for (i = 0; i < n; i++)
+            {
+              GVariant *entry, *key, *val;
+
+              g_string_append (string, comma);
+              comma = ", ";
+
+              entry = g_variant_get_child_value (value, i);
+              key = g_variant_get_child_value (entry, 0);
+              val = g_variant_get_child_value (entry, 1);
+              g_variant_unref (entry);
+
+              g_variant_print_string (key, string, type_annotate);
+              g_variant_unref (key);
+              g_string_append (string, ": ");
+              g_variant_print_string (val, string, type_annotate);
+              g_variant_unref (val);
+              type_annotate = FALSE;
+            }
+          g_string_append_c (string, '}');
+        }
+      else
+        /* normal (non-dictionary) array */
+        {
+          const gchar *comma = "";
+          gsize n, i;
+
+          if ((n = g_variant_n_children (value)) == 0)
+            {
+              if (type_annotate)
+                g_string_append_printf (string, "@%s ",
+                                        g_variant_get_type_string (value));
+              g_string_append (string, "[]");
+              break;
+            }
+
+          g_string_append_c (string, '[');
+          for (i = 0; i < n; i++)
+            {
+              GVariant *element;
+
+              g_string_append (string, comma);
+              comma = ", ";
+
+              element = g_variant_get_child_value (value, i);
+
+              g_variant_print_string (element, string, type_annotate);
+              g_variant_unref (element);
+              type_annotate = FALSE;
+            }
+          g_string_append_c (string, ']');
+        }
+
+      break;
+
+    case G_VARIANT_CLASS_TUPLE:
+      {
+        gsize n, i;
+
+        n = g_variant_n_children (value);
+
+        g_string_append_c (string, '(');
+        for (i = 0; i < n; i++)
+          {
+            GVariant *element;
+
+            element = g_variant_get_child_value (value, i);
+            g_variant_print_string (element, string, type_annotate);
+            g_string_append (string, ", ");
+            g_variant_unref (element);
+          }
+
+        /* for >1 item:  remove final ", "
+         * for 1 item:   remove final " ", but leave the ","
+         * for 0 items:  there is only "(", so remove nothing
+         */
+        g_string_truncate (string, string->len - (n > 0) - (n > 1));
+        g_string_append_c (string, ')');
+      }
+      break;
+
+    case G_VARIANT_CLASS_DICT_ENTRY:
+      {
+        GVariant *element;
+
+        g_string_append_c (string, '{');
+
+        element = g_variant_get_child_value (value, 0);
+        g_variant_print_string (element, string, type_annotate);
+        g_variant_unref (element);
+
+        g_string_append (string, ", ");
+
+        element = g_variant_get_child_value (value, 1);
+        g_variant_print_string (element, string, type_annotate);
+        g_variant_unref (element);
+
+        g_string_append_c (string, '}');
+      }
+      break;
+
+    case G_VARIANT_CLASS_VARIANT:
+      {
+        GVariant *child = g_variant_get_variant (value);
+
+        /* Always annotate types in nested variants, because they are
+         * (by nature) of variable type.
+         */
+        g_string_append_c (string, '<');
+        g_variant_print_string (child, string, TRUE);
+        g_string_append_c (string, '>');
+
+        g_variant_unref (child);
+      }
+      break;
+
+    case G_VARIANT_CLASS_BOOLEAN:
+      if (g_variant_get_boolean (value))
+        g_string_append (string, "true");
+      else
+        g_string_append (string, "false");
+      break;
+
+    case G_VARIANT_CLASS_STRING:
+      {
+        const gchar *str = g_variant_get_string (value, NULL);
+        gunichar quote = strchr (str, '\'') ? '"' : '\'';
+
+        g_string_append_c (string, quote);
+
+        while (*str)
+          {
+            gunichar c = g_utf8_get_char (str);
+
+            if (c == quote || c == '\\')
+              g_string_append_c (string, '\\');
+
+            if (g_unichar_isprint (c))
+              g_string_append_unichar (string, c);
+
+            else
+              {
+                g_string_append_c (string, '\\');
+                if (c < 0x10000)
+                  switch (c)
+                    {
+                    case '\a':
+                      g_string_append_c (string, 'a');
+                      break;
+
+                    case '\b':
+                      g_string_append_c (string, 'b');
+                      break;
+
+                    case '\f':
+                      g_string_append_c (string, 'f');
+                      break;
+
+                    case '\n':
+                      g_string_append_c (string, 'n');
+                      break;
+
+                    case '\r':
+                      g_string_append_c (string, 'r');
+                      break;
+
+                    case '\t':
+                      g_string_append_c (string, 't');
+                      break;
+
+                    case '\v':
+                      g_string_append_c (string, 'v');
+                      break;
+
+                    default:
+                      g_string_append_printf (string, "u%04x", c);
+                      break;
+                    }
+                 else
+                   g_string_append_printf (string, "U%08x", c);
+              }
+
+            str = g_utf8_next_char (str);
+          }
+
+        g_string_append_c (string, quote);
+      }
+      break;
+
+    case G_VARIANT_CLASS_BYTE:
+      if (type_annotate)
+        g_string_append (string, "byte ");
+      g_string_append_printf (string, "0x%02x",
+                              g_variant_get_byte (value));
+      break;
+
+    case G_VARIANT_CLASS_INT16:
+      if (type_annotate)
+        g_string_append (string, "int16 ");
+      g_string_append_printf (string, "%"G_GINT16_FORMAT,
+                              g_variant_get_int16 (value));
+      break;
+
+    case G_VARIANT_CLASS_UINT16:
+      if (type_annotate)
+        g_string_append (string, "uint16 ");
+      g_string_append_printf (string, "%"G_GUINT16_FORMAT,
+                              g_variant_get_uint16 (value));
+      break;
+
+    case G_VARIANT_CLASS_INT32:
+      /* Never annotate this type because it is the default for numbers
+       * (and this is a *pretty* printer)
+       */
+      g_string_append_printf (string, "%"G_GINT32_FORMAT,
+                              g_variant_get_int32 (value));
+      break;
+
+    case G_VARIANT_CLASS_HANDLE:
+      if (type_annotate)
+        g_string_append (string, "handle ");
+      g_string_append_printf (string, "%"G_GINT32_FORMAT,
+                              g_variant_get_handle (value));
+      break;
+
+    case G_VARIANT_CLASS_UINT32:
+      if (type_annotate)
+        g_string_append (string, "uint32 ");
+      g_string_append_printf (string, "%"G_GUINT32_FORMAT,
+                              g_variant_get_uint32 (value));
+      break;
+
+    case G_VARIANT_CLASS_INT64:
+      if (type_annotate)
+        g_string_append (string, "int64 ");
+      g_string_append_printf (string, "%"G_GINT64_FORMAT,
+                              g_variant_get_int64 (value));
+      break;
+
+    case G_VARIANT_CLASS_UINT64:
+      if (type_annotate)
+        g_string_append (string, "uint64 ");
+      g_string_append_printf (string, "%"G_GUINT64_FORMAT,
+                              g_variant_get_uint64 (value));
+      break;
+
+    case G_VARIANT_CLASS_DOUBLE:
+      {
+        gchar buffer[100];
+        gint i;
+
+        g_ascii_dtostr (buffer, sizeof buffer, g_variant_get_double (value));
+
+        for (i = 0; buffer[i]; i++)
+          if (buffer[i] == '.' || buffer[i] == 'e' ||
+              buffer[i] == 'n' || buffer[i] == 'N')
+            break;
+
+        /* if there is no '.' or 'e' in the float then add one */
+        if (buffer[i] == '\0')
+          {
+            buffer[i++] = '.';
+            buffer[i++] = '0';
+            buffer[i++] = '\0';
+          }
+
+        g_string_append (string, buffer);
+      }
+      break;
+
+    case G_VARIANT_CLASS_OBJECT_PATH:
+      if (type_annotate)
+        g_string_append (string, "objectpath ");
+      g_string_append_printf (string, "\'%s\'",
+                              g_variant_get_string (value, NULL));
+      break;
+
+    case G_VARIANT_CLASS_SIGNATURE:
+      if (type_annotate)
+        g_string_append (string, "signature ");
+      g_string_append_printf (string, "\'%s\'",
+                              g_variant_get_string (value, NULL));
+      break;
+
+    default:
+      g_assert_not_reached ();
+  }
+
+  return string;
+}
+
+/**
+ * g_variant_print:
+ * @value: a #GVariant
+ * @type_annotate: %TRUE if type information should be included in
+ *                 the output
+ * @returns: a newly-allocated string holding the result.
+ *
+ * Pretty-prints @value in the format understood by g_variant_parse().
+ *
+ * If @type_annotate is %TRUE, then type information is included in
+ * the output.
+ */
+gchar *
+g_variant_print (GVariant *value,
+                 gboolean  type_annotate)
+{
+  return g_string_free (g_variant_print_string (value, NULL, type_annotate),
+                        FALSE);
+};
+
+/* Hash, Equal, Compare {{{1 */
+/**
+ * g_variant_hash:
+ * @value: (type GVariant): a basic #GVariant value as a #gconstpointer
+ * @returns: a hash value corresponding to @value
+ *
+ * Generates a hash value for a #GVariant instance.
+ *
+ * The output of this function is guaranteed to be the same for a given
+ * value only per-process.  It may change between different processor
+ * architectures or even different versions of GLib.  Do not use this
+ * function as a basis for building protocols or file formats.
+ *
+ * The type of @value is #gconstpointer only to allow use of this
+ * function with #GHashTable.  @value must be a #GVariant.
+ *
+ * Since: 2.24
+ **/
+guint
+g_variant_hash (gconstpointer value_)
+{
+  GVariant *value = (GVariant *) value_;
+
+  switch (g_variant_classify (value))
+    {
+    case G_VARIANT_CLASS_STRING:
+    case G_VARIANT_CLASS_OBJECT_PATH:
+    case G_VARIANT_CLASS_SIGNATURE:
+      return g_str_hash (g_variant_get_string (value, NULL));
+
+    case G_VARIANT_CLASS_BOOLEAN:
+      /* this is a very odd thing to hash... */
+      return g_variant_get_boolean (value);
+
+    case G_VARIANT_CLASS_BYTE:
+      return g_variant_get_byte (value);
+
+    case G_VARIANT_CLASS_INT16:
+    case G_VARIANT_CLASS_UINT16:
+      {
+        const guint16 *ptr;
+
+        ptr = g_variant_get_data (value);
+
+        if (ptr)
+          return *ptr;
+        else
+          return 0;
+      }
+
+    case G_VARIANT_CLASS_INT32:
+    case G_VARIANT_CLASS_UINT32:
+    case G_VARIANT_CLASS_HANDLE:
+      {
+        const guint *ptr;
+
+        ptr = g_variant_get_data (value);
+
+        if (ptr)
+          return *ptr;
+        else
+          return 0;
+      }
+
+    case G_VARIANT_CLASS_INT64:
+    case G_VARIANT_CLASS_UINT64:
+    case G_VARIANT_CLASS_DOUBLE:
+      /* need a separate case for these guys because otherwise
+       * performance could be quite bad on big endian systems
+       */
+      {
+        const guint *ptr;
+
+        ptr = g_variant_get_data (value);
+
+        if (ptr)
+          return ptr[0] + ptr[1];
+        else
+          return 0;
+      }
+
+    default:
+      g_return_val_if_fail (!g_variant_is_container (value), 0);
+      g_assert_not_reached ();
+    }
+}
+
+/**
+ * g_variant_equal:
+ * @one: (type GVariant): a #GVariant instance
+ * @two: (type GVariant): a #GVariant instance
+ * @returns: %TRUE if @one and @two are equal
+ *
+ * Checks if @one and @two have the same type and value.
+ *
+ * The types of @one and @two are #gconstpointer only to allow use of
+ * this function with #GHashTable.  They must each be a #GVariant.
+ *
+ * Since: 2.24
+ **/
+gboolean
+g_variant_equal (gconstpointer one,
+                 gconstpointer two)
+{
+  gboolean equal;
+
+  g_return_val_if_fail (one != NULL && two != NULL, FALSE);
+
+  if (g_variant_get_type_info ((GVariant *) one) !=
+      g_variant_get_type_info ((GVariant *) two))
+    return FALSE;
+
+  /* if both values are trusted to be in their canonical serialised form
+   * then a simple memcmp() of their serialised data will answer the
+   * question.
+   *
+   * if not, then this might generate a false negative (since it is
+   * possible for two different byte sequences to represent the same
+   * value).  for now we solve this by pretty-printing both values and
+   * comparing the result.
+   */
+  if (g_variant_is_trusted ((GVariant *) one) &&
+      g_variant_is_trusted ((GVariant *) two))
+    {
+      gconstpointer data_one, data_two;
+      gsize size_one, size_two;
+
+      size_one = g_variant_get_size ((GVariant *) one);
+      size_two = g_variant_get_size ((GVariant *) two);
+
+      if (size_one != size_two)
+        return FALSE;
+
+      data_one = g_variant_get_data ((GVariant *) one);
+      data_two = g_variant_get_data ((GVariant *) two);
+
+      equal = memcmp (data_one, data_two, size_one) == 0;
+    }
+  else
+    {
+      gchar *strone, *strtwo;
+
+      strone = g_variant_print ((GVariant *) one, FALSE);
+      strtwo = g_variant_print ((GVariant *) two, FALSE);
+      equal = strcmp (strone, strtwo) == 0;
+      g_free (strone);
+      g_free (strtwo);
+    }
+
+  return equal;
+}
+
+/**
+ * g_variant_compare:
+ * @one: (type GVariant): a basic-typed #GVariant instance
+ * @two: (type GVariant): a #GVariant instance of the same type
+ * @returns: negative value if a &lt; b;
+ *           zero if a = b;
+ *           positive value if a &gt; b.
+ *
+ * Compares @one and @two.
+ *
+ * The types of @one and @two are #gconstpointer only to allow use of
+ * this function with #GTree, #GPtrArray, etc.  They must each be a
+ * #GVariant.
+ *
+ * Comparison is only defined for basic types (ie: booleans, numbers,
+ * strings).  For booleans, %FALSE is less than %TRUE.  Numbers are
+ * ordered in the usual way.  Strings are in ASCII lexographical order.
+ *
+ * It is a programmer error to attempt to compare container values or
+ * two values that have types that are not exactly equal.  For example,
+ * you can not compare a 32-bit signed integer with a 32-bit unsigned
+ * integer.  Also note that this function is not particularly
+ * well-behaved when it comes to comparison of doubles; in particular,
+ * the handling of incomparable values (ie: NaN) is undefined.
+ *
+ * If you only require an equality comparison, g_variant_equal() is more
+ * general.
+ *
+ * Since: 2.26
+ **/
+gint
+g_variant_compare (gconstpointer one,
+                   gconstpointer two)
+{
+  GVariant *a = (GVariant *) one;
+  GVariant *b = (GVariant *) two;
+
+  g_return_val_if_fail (g_variant_classify (a) == g_variant_classify (b), 0);
+
+  switch (g_variant_classify (a))
+    {
+    case G_VARIANT_CLASS_BYTE:
+      return ((gint) g_variant_get_byte (a)) -
+             ((gint) g_variant_get_byte (b));
+
+    case G_VARIANT_CLASS_INT16:
+      return ((gint) g_variant_get_int16 (a)) -
+             ((gint) g_variant_get_int16 (b));
+
+    case G_VARIANT_CLASS_UINT16:
+      return ((gint) g_variant_get_uint16 (a)) -
+             ((gint) g_variant_get_uint16 (b));
+
+    case G_VARIANT_CLASS_INT32:
+      {
+        gint32 a_val = g_variant_get_int32 (a);
+        gint32 b_val = g_variant_get_int32 (b);
+
+        return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1;
+      }
+
+    case G_VARIANT_CLASS_UINT32:
+      {
+        guint32 a_val = g_variant_get_uint32 (a);
+        guint32 b_val = g_variant_get_uint32 (b);
+
+        return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1;
+      }
+
+    case G_VARIANT_CLASS_INT64:
+      {
+        gint64 a_val = g_variant_get_int64 (a);
+        gint64 b_val = g_variant_get_int64 (b);
+
+        return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1;
+      }
+
+    case G_VARIANT_CLASS_UINT64:
+      {
+        guint64 a_val = g_variant_get_int32 (a);
+        guint64 b_val = g_variant_get_int32 (b);
+
+        return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1;
+      }
+
+    case G_VARIANT_CLASS_DOUBLE:
+      {
+        gdouble a_val = g_variant_get_double (a);
+        gdouble b_val = g_variant_get_double (b);
+
+        return (a_val == b_val) ? 0 : (a_val > b_val) ? 1 : -1;
+      }
+
+    case G_VARIANT_CLASS_STRING:
+    case G_VARIANT_CLASS_OBJECT_PATH:
+    case G_VARIANT_CLASS_SIGNATURE:
+      return strcmp (g_variant_get_string (a, NULL),
+                     g_variant_get_string (b, NULL));
+
+    default:
+      g_return_val_if_fail (!g_variant_is_container (a), 0);
+      g_assert_not_reached ();
+    }
+}
+
+/* GVariantIter {{{1 */
+/**
+ * GVariantIter:
+ *
+ * #GVariantIter is an opaque data structure and can only be accessed
+ * using the following functions.
+ **/
+struct stack_iter
+{
+  GVariant *value;
+  gssize n, i;
+
+  const gchar *loop_format;
+
+  gsize padding[3];
+  gsize magic;
+};
+
+G_STATIC_ASSERT (sizeof (struct stack_iter) <= sizeof (GVariantIter));
+
+struct heap_iter
+{
+  struct stack_iter iter;
+
+  GVariant *value_ref;
+  gsize magic;
+};
+
+#define GVSI(i)                 ((struct stack_iter *) (i))
+#define GVHI(i)                 ((struct heap_iter *) (i))
+#define GVSI_MAGIC              ((gsize) 3579507750u)
+#define GVHI_MAGIC              ((gsize) 1450270775u)
+#define is_valid_iter(i)        (i != NULL && \
+                                 GVSI(i)->magic == GVSI_MAGIC)
+#define is_valid_heap_iter(i)   (GVHI(i)->magic == GVHI_MAGIC && \
+                                 is_valid_iter(i))
+
+/**
+ * g_variant_iter_new:
+ * @value: a container #GVariant
+ * @returns: a new heap-allocated #GVariantIter
+ *
+ * Creates a heap-allocated #GVariantIter for iterating over the items
+ * in @value.
+ *
+ * Use g_variant_iter_free() to free the return value when you no longer
+ * need it.
+ *
+ * A reference is taken to @value and will be released only when
+ * g_variant_iter_free() is called.
+ *
+ * Since: 2.24
+ **/
+GVariantIter *
+g_variant_iter_new (GVariant *value)
+{
+  GVariantIter *iter;
+
+  iter = (GVariantIter *) g_slice_new (struct heap_iter);
+  GVHI(iter)->value_ref = g_variant_ref (value);
+  GVHI(iter)->magic = GVHI_MAGIC;
+
+  g_variant_iter_init (iter, value);
+
+  return iter;
+}
+
+/**
+ * g_variant_iter_init:
+ * @iter: a pointer to a #GVariantIter
+ * @value: a container #GVariant
+ * @returns: the number of items in @value
+ *
+ * Initialises (without allocating) a #GVariantIter.  @iter may be
+ * completely uninitialised prior to this call; its old value is
+ * ignored.
+ *
+ * The iterator remains valid for as long as @value exists, and need not
+ * be freed in any way.
+ *
+ * Since: 2.24
+ **/
+gsize
+g_variant_iter_init (GVariantIter *iter,
+                     GVariant     *value)
+{
+  GVSI(iter)->magic = GVSI_MAGIC;
+  GVSI(iter)->value = value;
+  GVSI(iter)->n = g_variant_n_children (value);
+  GVSI(iter)->i = -1;
+  GVSI(iter)->loop_format = NULL;
+
+  return GVSI(iter)->n;
+}
+
+/**
+ * g_variant_iter_copy:
+ * @iter: a #GVariantIter
+ * @returns: a new heap-allocated #GVariantIter
+ *
+ * Creates a new heap-allocated #GVariantIter to iterate over the
+ * container that was being iterated over by @iter.  Iteration begins on
+ * the new iterator from the current position of the old iterator but
+ * the two copies are independent past that point.
+ *
+ * Use g_variant_iter_free() to free the return value when you no longer
+ * need it.
+ *
+ * A reference is taken to the container that @iter is iterating over
+ * and will be releated only when g_variant_iter_free() is called.
+ *
+ * Since: 2.24
+ **/
+GVariantIter *
+g_variant_iter_copy (GVariantIter *iter)
+{
+  GVariantIter *copy;
+
+  g_return_val_if_fail (is_valid_iter (iter), 0);
+
+  copy = g_variant_iter_new (GVSI(iter)->value);
+  GVSI(copy)->i = GVSI(iter)->i;
+
+  return copy;
+}
+
+/**
+ * g_variant_iter_n_children:
+ * @iter: a #GVariantIter
+ * @returns: the number of children in the container
+ *
+ * Queries the number of child items in the container that we are
+ * iterating over.  This is the total number of items -- not the number
+ * of items remaining.
+ *
+ * This function might be useful for preallocation of arrays.
+ *
+ * Since: 2.24
+ **/
+gsize
+g_variant_iter_n_children (GVariantIter *iter)
+{
+  g_return_val_if_fail (is_valid_iter (iter), 0);
+
+  return GVSI(iter)->n;
+}
+
+/**
+ * g_variant_iter_free:
+ * @iter: a heap-allocated #GVariantIter
+ *
+ * Frees a heap-allocated #GVariantIter.  Only call this function on
+ * iterators that were returned by g_variant_iter_new() or
+ * g_variant_iter_copy().
+ *
+ * Since: 2.24
+ **/
+void
+g_variant_iter_free (GVariantIter *iter)
+{
+  g_return_if_fail (is_valid_heap_iter (iter));
+
+  g_variant_unref (GVHI(iter)->value_ref);
+  GVHI(iter)->magic = 0;
+
+  g_slice_free (struct heap_iter, GVHI(iter));
+}
+
+/**
+ * g_variant_iter_next_value:
+ * @iter: a #GVariantIter
+ * @returns: (allow-none): a #GVariant, or %NULL
+ *
+ * Gets the next item in the container.  If no more items remain then
+ * %NULL is returned.
+ *
+ * Use g_variant_unref() to drop your reference on the return value when
+ * you no longer need it.
+ *
+ * <example>
+ *  <title>Iterating with g_variant_iter_next_value()</title>
+ *  <programlisting>
+ *   /<!-- -->* recursively iterate a container *<!-- -->/
+ *   void
+ *   iterate_container_recursive (GVariant *container)
+ *   {
+ *     GVariantIter iter;
+ *     GVariant *child;
+ *
+ *     g_variant_iter_init (&iter, dictionary);
+ *     while ((child = g_variant_iter_next_value (&iter)))
+ *       {
+ *         g_print ("type '%s'\n", g_variant_get_type_string (child));
+ *
+ *         if (g_variant_is_container (child))
+ *           iterate_container_recursive (child);
+ *
+ *         g_variant_unref (child);
+ *       }
+ *   }
+ * </programlisting>
+ * </example>
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_iter_next_value (GVariantIter *iter)
+{
+  g_return_val_if_fail (is_valid_iter (iter), FALSE);
+
+  if G_UNLIKELY (GVSI(iter)->i >= GVSI(iter)->n)
+    {
+      g_critical ("g_variant_iter_next_value: must not be called again "
+                  "after NULL has already been returned.");
+      return NULL;
+    }
+
+  GVSI(iter)->i++;
+
+  if (GVSI(iter)->i < GVSI(iter)->n)
+    return g_variant_get_child_value (GVSI(iter)->value, GVSI(iter)->i);
+
+  return NULL;
+}
+
+/* GVariantBuilder {{{1 */
+/**
+ * GVariantBuilder:
+ *
+ * A utility type for constructing container-type #GVariant instances.
+ *
+ * This is an opaque structure and may only be accessed using the
+ * following functions.
+ *
+ * #GVariantBuilder is not threadsafe in any way.  Do not attempt to
+ * access it from more than one thread.
+ **/
+
+struct stack_builder
+{
+  GVariantBuilder *parent;
+  GVariantType *type;
+
+  /* type constraint explicitly specified by 'type'.
+   * for tuple types, this moves along as we add more items.
+   */
+  const GVariantType *expected_type;
+
+  /* type constraint implied by previous array item.
+   */
+  const GVariantType *prev_item_type;
+
+  /* constraints on the number of children.  max = -1 for unlimited. */
+  gsize min_items;
+  gsize max_items;
+
+  /* dynamically-growing pointer array */
+  GVariant **children;
+  gsize allocated_children;
+  gsize offset;
+
+  /* set to '1' if all items in the container will have the same type
+   * (ie: maybe, array, variant) '0' if not (ie: tuple, dict entry)
+   */
+  guint uniform_item_types : 1;
+
+  /* set to '1' initially and changed to '0' if an untrusted value is
+   * added
+   */
+  guint trusted : 1;
+
+  gsize magic;
+};
+
+G_STATIC_ASSERT (sizeof (struct stack_builder) <= sizeof (GVariantBuilder));
+
+struct heap_builder
+{
+  GVariantBuilder builder;
+  gsize magic;
+
+  gint ref_count;
+};
+
+#define GVSB(b)                  ((struct stack_builder *) (b))
+#define GVHB(b)                  ((struct heap_builder *) (b))
+#define GVSB_MAGIC               ((gsize) 1033660112u)
+#define GVHB_MAGIC               ((gsize) 3087242682u)
+#define is_valid_builder(b)      (b != NULL && \
+                                  GVSB(b)->magic == GVSB_MAGIC)
+#define is_valid_heap_builder(b) (GVHB(b)->magic == GVHB_MAGIC)
+
+/**
+ * g_variant_builder_new:
+ * @type: a container type
+ * @returns: a #GVariantBuilder
+ *
+ * Allocates and initialises a new #GVariantBuilder.
+ *
+ * You should call g_variant_builder_unref() on the return value when it
+ * is no longer needed.  The memory will not be automatically freed by
+ * any other call.
+ *
+ * In most cases it is easier to place a #GVariantBuilder directly on
+ * the stack of the calling function and initialise it with
+ * g_variant_builder_init().
+ *
+ * Since: 2.24
+ **/
+GVariantBuilder *
+g_variant_builder_new (const GVariantType *type)
+{
+  GVariantBuilder *builder;
+
+  builder = (GVariantBuilder *) g_slice_new (struct heap_builder);
+  g_variant_builder_init (builder, type);
+  GVHB(builder)->magic = GVHB_MAGIC;
+  GVHB(builder)->ref_count = 1;
+
+  return builder;
+}
+
+/**
+ * g_variant_builder_unref:
+ * @builder: a #GVariantBuilder allocated by g_variant_builder_new()
+ *
+ * Decreases the reference count on @builder.
+ *
+ * In the event that there are no more references, releases all memory
+ * associated with the #GVariantBuilder.
+ *
+ * Don't call this on stack-allocated #GVariantBuilder instances or bad
+ * things will happen.
+ *
+ * Since: 2.24
+ **/
+void
+g_variant_builder_unref (GVariantBuilder *builder)
+{
+  g_return_if_fail (is_valid_heap_builder (builder));
+
+  if (--GVHB(builder)->ref_count)
+    return;
+
+  g_variant_builder_clear (builder);
+  GVHB(builder)->magic = 0;
+
+  g_slice_free (struct heap_builder, GVHB(builder));
+}
+
+/**
+ * g_variant_builder_ref:
+ * @builder: a #GVariantBuilder allocated by g_variant_builder_new()
+ * @returns: a new reference to @builder
+ *
+ * Increases the reference count on @builder.
+ *
+ * Don't call this on stack-allocated #GVariantBuilder instances or bad
+ * things will happen.
+ *
+ * Since: 2.24
+ **/
+GVariantBuilder *
+g_variant_builder_ref (GVariantBuilder *builder)
+{
+  g_return_val_if_fail (is_valid_heap_builder (builder), NULL);
+
+  GVHB(builder)->ref_count++;
+
+  return builder;
+}
+
+/**
+ * g_variant_builder_clear:
+ * @builder: a #GVariantBuilder
+ *
+ * Releases all memory associated with a #GVariantBuilder without
+ * freeing the #GVariantBuilder structure itself.
+ *
+ * It typically only makes sense to do this on a stack-allocated
+ * #GVariantBuilder if you want to abort building the value part-way
+ * through.  This function need not be called if you call
+ * g_variant_builder_end() and it also doesn't need to be called on
+ * builders allocated with g_variant_builder_new (see
+ * g_variant_builder_free() for that).
+ *
+ * This function leaves the #GVariantBuilder structure set to all-zeros.
+ * It is valid to call this function on either an initialised
+ * #GVariantBuilder or one that is set to all-zeros but it is not valid
+ * to call this function on uninitialised memory.
+ *
+ * Since: 2.24
+ **/
+void
+g_variant_builder_clear (GVariantBuilder *builder)
+{
+  gsize i;
+
+  if (GVSB(builder)->magic == 0)
+    /* all-zeros case */
+    return;
+
+  g_return_if_fail (is_valid_builder (builder));
+
+  g_variant_type_free (GVSB(builder)->type);
+
+  for (i = 0; i < GVSB(builder)->offset; i++)
+    g_variant_unref (GVSB(builder)->children[i]);
+
+  g_free (GVSB(builder)->children);
+
+  if (GVSB(builder)->parent)
+    {
+      g_variant_builder_clear (GVSB(builder)->parent);
+      g_slice_free (GVariantBuilder, GVSB(builder)->parent);
+    }
+
+  memset (builder, 0, sizeof (GVariantBuilder));
+}
+
+/**
+ * g_variant_builder_init:
+ * @builder: a #GVariantBuilder
+ * @type: a container type
+ *
+ * Initialises a #GVariantBuilder structure.
+ *
+ * @type must be non-%NULL.  It specifies the type of container to
+ * construct.  It can be an indefinite type such as
+ * %G_VARIANT_TYPE_ARRAY or a definite type such as "as" or "(ii)".
+ * Maybe, array, tuple, dictionary entry and variant-typed values may be
+ * constructed.
+ *
+ * After the builder is initialised, values are added using
+ * g_variant_builder_add_value() or g_variant_builder_add().
+ *
+ * After all the child values are added, g_variant_builder_end() frees
+ * the memory associated with the builder and returns the #GVariant that
+ * was created.
+ *
+ * This function completely ignores the previous contents of @builder.
+ * On one hand this means that it is valid to pass in completely
+ * uninitialised memory.  On the other hand, this means that if you are
+ * initialising over top of an existing #GVariantBuilder you need to
+ * first call g_variant_builder_clear() in order to avoid leaking
+ * memory.
+ *
+ * You must not call g_variant_builder_ref() or
+ * g_variant_builder_unref() on a #GVariantBuilder that was initialised
+ * with this function.  If you ever pass a reference to a
+ * #GVariantBuilder outside of the control of your own code then you
+ * should assume that the person receiving that reference may try to use
+ * reference counting; you should use g_variant_builder_new() instead of
+ * this function.
+ *
+ * Since: 2.24
+ **/
+void
+g_variant_builder_init (GVariantBuilder    *builder,
+                        const GVariantType *type)
+{
+  g_return_if_fail (type != NULL);
+  g_return_if_fail (g_variant_type_is_container (type));
+
+  memset (builder, 0, sizeof (GVariantBuilder));
+
+  GVSB(builder)->type = g_variant_type_copy (type);
+  GVSB(builder)->magic = GVSB_MAGIC;
+  GVSB(builder)->trusted = TRUE;
+
+  switch (*(const gchar *) type)
+    {
+    case G_VARIANT_CLASS_VARIANT:
+      GVSB(builder)->uniform_item_types = TRUE;
+      GVSB(builder)->allocated_children = 1;
+      GVSB(builder)->expected_type = NULL;
+      GVSB(builder)->min_items = 1;
+      GVSB(builder)->max_items = 1;
+      break;
+
+    case G_VARIANT_CLASS_ARRAY:
+      GVSB(builder)->uniform_item_types = TRUE;
+      GVSB(builder)->allocated_children = 8;
+      GVSB(builder)->expected_type =
+        g_variant_type_element (GVSB(builder)->type);
+      GVSB(builder)->min_items = 0;
+      GVSB(builder)->max_items = -1;
+      break;
+
+    case G_VARIANT_CLASS_MAYBE:
+      GVSB(builder)->uniform_item_types = TRUE;
+      GVSB(builder)->allocated_children = 1;
+      GVSB(builder)->expected_type =
+        g_variant_type_element (GVSB(builder)->type);
+      GVSB(builder)->min_items = 0;
+      GVSB(builder)->max_items = 1;
+      break;
+
+    case G_VARIANT_CLASS_DICT_ENTRY:
+      GVSB(builder)->uniform_item_types = FALSE;
+      GVSB(builder)->allocated_children = 2;
+      GVSB(builder)->expected_type =
+        g_variant_type_key (GVSB(builder)->type);
+      GVSB(builder)->min_items = 2;
+      GVSB(builder)->max_items = 2;
+      break;
+
+    case 'r': /* G_VARIANT_TYPE_TUPLE was given */
+      GVSB(builder)->uniform_item_types = FALSE;
+      GVSB(builder)->allocated_children = 8;
+      GVSB(builder)->expected_type = NULL;
+      GVSB(builder)->min_items = 0;
+      GVSB(builder)->max_items = -1;
+      break;
+
+    case G_VARIANT_CLASS_TUPLE: /* a definite tuple type was given */
+      GVSB(builder)->allocated_children = g_variant_type_n_items (type);
+      GVSB(builder)->expected_type =
+        g_variant_type_first (GVSB(builder)->type);
+      GVSB(builder)->min_items = GVSB(builder)->allocated_children;
+      GVSB(builder)->max_items = GVSB(builder)->allocated_children;
+      GVSB(builder)->uniform_item_types = FALSE;
+      break;
+
+    default:
+      g_assert_not_reached ();
+   }
+
+  GVSB(builder)->children = g_new (GVariant *,
+                                   GVSB(builder)->allocated_children);
+}
+
+static void
+g_variant_builder_make_room (struct stack_builder *builder)
+{
+  if (builder->offset == builder->allocated_children)
+    {
+      builder->allocated_children *= 2;
+      builder->children = g_renew (GVariant *, builder->children,
+                                   builder->allocated_children);
+    }
+}
+
+/**
+ * g_variant_builder_add_value:
+ * @builder: a #GVariantBuilder
+ * @value: a #GVariant
+ *
+ * Adds @value to @builder.
+ *
+ * It is an error to call this function in any way that would create an
+ * inconsistent value to be constructed.  Some examples of this are
+ * putting different types of items into an array, putting the wrong
+ * types or number of items in a tuple, putting more than one value into
+ * a variant, etc.
+ *
+ * Since: 2.24
+ **/
+void
+g_variant_builder_add_value (GVariantBuilder *builder,
+                             GVariant        *value)
+{
+  g_return_if_fail (is_valid_builder (builder));
+  g_return_if_fail (GVSB(builder)->offset < GVSB(builder)->max_items);
+  g_return_if_fail (!GVSB(builder)->expected_type ||
+                    g_variant_is_of_type (value,
+                                          GVSB(builder)->expected_type));
+  g_return_if_fail (!GVSB(builder)->prev_item_type ||
+                    g_variant_is_of_type (value,
+                                          GVSB(builder)->prev_item_type));
+
+  GVSB(builder)->trusted &= g_variant_is_trusted (value);
+
+  if (!GVSB(builder)->uniform_item_types)
+    {
+      /* advance our expected type pointers */
+      if (GVSB(builder)->expected_type)
+        GVSB(builder)->expected_type =
+          g_variant_type_next (GVSB(builder)->expected_type);
+
+      if (GVSB(builder)->prev_item_type)
+        GVSB(builder)->prev_item_type =
+          g_variant_type_next (GVSB(builder)->prev_item_type);
+    }
+  else
+    GVSB(builder)->prev_item_type = g_variant_get_type (value);
+
+  g_variant_builder_make_room (GVSB(builder));
+
+  GVSB(builder)->children[GVSB(builder)->offset++] =
+    g_variant_ref_sink (value);
+}
+
+/**
+ * g_variant_builder_open:
+ * @builder: a #GVariantBuilder
+ * @type: a #GVariantType
+ *
+ * Opens a subcontainer inside the given @builder.  When done adding
+ * items to the subcontainer, g_variant_builder_close() must be called.
+ *
+ * It is an error to call this function in any way that would cause an
+ * inconsistent value to be constructed (ie: adding too many values or
+ * a value of an incorrect type).
+ *
+ * Since: 2.24
+ **/
+void
+g_variant_builder_open (GVariantBuilder    *builder,
+                        const GVariantType *type)
+{
+  GVariantBuilder *parent;
+
+  g_return_if_fail (is_valid_builder (builder));
+  g_return_if_fail (GVSB(builder)->offset < GVSB(builder)->max_items);
+  g_return_if_fail (!GVSB(builder)->expected_type ||
+                    g_variant_type_is_subtype_of (type,
+                                                  GVSB(builder)->expected_type));
+  g_return_if_fail (!GVSB(builder)->prev_item_type ||
+                    g_variant_type_is_subtype_of (GVSB(builder)->prev_item_type,
+                                                  type));
+
+  parent = g_slice_dup (GVariantBuilder, builder);
+  g_variant_builder_init (builder, type);
+  GVSB(builder)->parent = parent;
+
+  /* push the prev_item_type down into the subcontainer */
+  if (GVSB(parent)->prev_item_type)
+    {
+      if (!GVSB(builder)->uniform_item_types)
+        /* tuples and dict entries */
+        GVSB(builder)->prev_item_type =
+          g_variant_type_first (GVSB(parent)->prev_item_type);
+
+      else if (!g_variant_type_is_variant (GVSB(builder)->type))
+        /* maybes and arrays */
+        GVSB(builder)->prev_item_type =
+          g_variant_type_element (GVSB(parent)->prev_item_type);
+    }
+}
+
+/**
+ * g_variant_builder_close:
+ * @builder: a #GVariantBuilder
+ *
+ * Closes the subcontainer inside the given @builder that was opened by
+ * the most recent call to g_variant_builder_open().
+ *
+ * It is an error to call this function in any way that would create an
+ * inconsistent value to be constructed (ie: too few values added to the
+ * subcontainer).
+ *
+ * Since: 2.24
+ **/
+void
+g_variant_builder_close (GVariantBuilder *builder)
+{
+  GVariantBuilder *parent;
+
+  g_return_if_fail (is_valid_builder (builder));
+  g_return_if_fail (GVSB(builder)->parent != NULL);
+
+  parent = GVSB(builder)->parent;
+  GVSB(builder)->parent = NULL;
+
+  g_variant_builder_add_value (parent, g_variant_builder_end (builder));
+  *builder = *parent;
+
+  g_slice_free (GVariantBuilder, parent);
+}
+
+/*< private >
+ * g_variant_make_maybe_type:
+ * @element: a #GVariant
+ *
+ * Return the type of a maybe containing @element.
+ */
+static GVariantType *
+g_variant_make_maybe_type (GVariant *element)
+{
+  return g_variant_type_new_maybe (g_variant_get_type (element));
+}
+
+/*< private >
+ * g_variant_make_array_type:
+ * @element: a #GVariant
+ *
+ * Return the type of an array containing @element.
+ */
+static GVariantType *
+g_variant_make_array_type (GVariant *element)
+{
+  return g_variant_type_new_array (g_variant_get_type (element));
+}
+
+/**
+ * g_variant_builder_end:
+ * @builder: a #GVariantBuilder
+ * @returns: (transfer none): a new, floating, #GVariant
+ *
+ * Ends the builder process and returns the constructed value.
+ *
+ * It is not permissible to use @builder in any way after this call
+ * except for reference counting operations (in the case of a
+ * heap-allocated #GVariantBuilder) or by reinitialising it with
+ * g_variant_builder_init() (in the case of stack-allocated).
+ *
+ * It is an error to call this function in any way that would create an
+ * inconsistent value to be constructed (ie: insufficient number of
+ * items added to a container with a specific number of children
+ * required).  It is also an error to call this function if the builder
+ * was created with an indefinite array or maybe type and no children
+ * have been added; in this case it is impossible to infer the type of
+ * the empty array.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_builder_end (GVariantBuilder *builder)
+{
+  GVariantType *my_type;
+  GVariant *value;
+
+  g_return_val_if_fail (is_valid_builder (builder), NULL);
+  g_return_val_if_fail (GVSB(builder)->offset >= GVSB(builder)->min_items,
+                        NULL);
+  g_return_val_if_fail (!GVSB(builder)->uniform_item_types ||
+                        GVSB(builder)->prev_item_type != NULL ||
+                        g_variant_type_is_definite (GVSB(builder)->type),
+                        NULL);
+
+  if (g_variant_type_is_definite (GVSB(builder)->type))
+    my_type = g_variant_type_copy (GVSB(builder)->type);
+
+  else if (g_variant_type_is_maybe (GVSB(builder)->type))
+    my_type = g_variant_make_maybe_type (GVSB(builder)->children[0]);
+
+  else if (g_variant_type_is_array (GVSB(builder)->type))
+    my_type = g_variant_make_array_type (GVSB(builder)->children[0]);
+
+  else if (g_variant_type_is_tuple (GVSB(builder)->type))
+    my_type = g_variant_make_tuple_type (GVSB(builder)->children,
+                                         GVSB(builder)->offset);
+
+  else if (g_variant_type_is_dict_entry (GVSB(builder)->type))
+    my_type = g_variant_make_dict_entry_type (GVSB(builder)->children[0],
+                                              GVSB(builder)->children[1]);
+  else
+    g_assert_not_reached ();
+
+  value = g_variant_new_from_children (my_type,
+                                       g_renew (GVariant *,
+                                                GVSB(builder)->children,
+                                                GVSB(builder)->offset),
+                                       GVSB(builder)->offset,
+                                       GVSB(builder)->trusted);
+  GVSB(builder)->children = NULL;
+  GVSB(builder)->offset = 0;
+
+  g_variant_builder_clear (builder);
+  g_variant_type_free (my_type);
+
+  return value;
+}
+
+/* Format strings {{{1 */
+/*< private >
+ * g_variant_format_string_scan:
+ * @string: a string that may be prefixed with a format string
+ * @limit: (allow-none) (default NULL): a pointer to the end of @string,
+ *         or %NULL
+ * @endptr: (allow-none) (default NULL): location to store the end pointer,
+ *          or %NULL
+ * @returns: %TRUE if there was a valid format string
+ *
+ * Checks the string pointed to by @string for starting with a properly
+ * formed #GVariant varargs format string.  If no valid format string is
+ * found then %FALSE is returned.
+ *
+ * If @string does start with a valid format string then %TRUE is
+ * returned.  If @endptr is non-%NULL then it is updated to point to the
+ * first character after the format string.
+ *
+ * If @limit is non-%NULL then @limit (and any charater after it) will
+ * not be accessed and the effect is otherwise equivalent to if the
+ * character at @limit were nul.
+ *
+ * See the section on <link linkend='gvariant-format-strings'>GVariant
+ * Format Strings</link>.
+ *
+ * Since: 2.24
+ */
+gboolean
+g_variant_format_string_scan (const gchar  *string,
+                              const gchar  *limit,
+                              const gchar **endptr)
+{
+#define next_char() (string == limit ? '\0' : *string++)
+#define peek_char() (string == limit ? '\0' : *string)
+  char c;
+
+  switch (next_char())
+    {
+    case 'b': case 'y': case 'n': case 'q': case 'i': case 'u':
+    case 'x': case 't': case 'h': case 'd': case 's': case 'o':
+    case 'g': case 'v': case '*': case '?': case 'r':
+      break;
+
+    case 'm':
+      return g_variant_format_string_scan (string, limit, endptr);
+
+    case 'a':
+    case '@':
+      return g_variant_type_string_scan (string, limit, endptr);
+
+    case '(':
+      while (peek_char() != ')')
+        if (!g_variant_format_string_scan (string, limit, &string))
+          return FALSE;
+
+      next_char(); /* consume ')' */
+      break;
+
+    case '{':
+      c = next_char();
+
+      if (c == '&')
+        {
+          c = next_char ();
+
+          if (c != 's' && c != 'o' && c != 'g')
+            return FALSE;
+        }
+      else
+        {
+          if (c == '@')
+            c = next_char ();
+
+          /* ISO/IEC 9899:1999 (C99) §7.21.5.2:
+           *    The terminating null character is considered to be
+           *    part of the string.
+           */
+          if (c != '\0' && strchr ("bynqiuxthdsog?", c) == NULL)
+            return FALSE;
+        }
+
+      if (!g_variant_format_string_scan (string, limit, &string))
+        return FALSE;
+
+      if (next_char() != '}')
+        return FALSE;
+
+      break;
+
+    case '^':
+      if ((c = next_char()) == 'a')
+        {
+          if ((c = next_char()) == '&')
+            {
+              if ((c = next_char()) == 'a')
+                {
+                  if ((c = next_char()) == 'y')
+                    break;      /* '^a&ay' */
+                }
+
+              else if (c == 's')
+                break;          /* '^a&s' */
+            }
+
+          else if (c == 'a')
+            {
+              if ((c = next_char()) == 'y')
+                break;          /* '^aay' */
+            }
+
+          else if (c == 's')
+            break;              /* '^as' */
+
+          else if (c == 'y')
+            break;              /* '^ay' */
+        }
+      else if (c == '&')
+        {
+          if ((c = next_char()) == 'a')
+            {
+              if ((c = next_char()) == 'y')
+                break;          /* '^&ay' */
+            }
+        }
+
+      return FALSE;
+
+    case '&':
+      c = next_char();
+
+      if (c != 's' && c != 'o' && c != 'g')
+        return FALSE;
+
+      break;
+
+    default:
+      return FALSE;
+    }
+
+  if (endptr != NULL)
+    *endptr = string;
+
+#undef next_char
+#undef peek_char
+
+  return TRUE;
+}
+
+/*< private >
+ * g_variant_format_string_scan_type:
+ * @string: a string that may be prefixed with a format string
+ * @limit: (allow-none) (default NULL): a pointer to the end of @string,
+ *         or %NULL
+ * @endptr: (allow-none) (default NULL): location to store the end pointer,
+ *          or %NULL
+ * @returns: (allow-none): a #GVariantType if there was a valid format string
+ *
+ * If @string starts with a valid format string then this function will
+ * return the type that the format string corresponds to.  Otherwise
+ * this function returns %NULL.
+ *
+ * Use g_variant_type_free() to free the return value when you no longer
+ * need it.
+ *
+ * This function is otherwise exactly like
+ * g_variant_format_string_scan().
+ *
+ * Since: 2.24
+ */
+GVariantType *
+g_variant_format_string_scan_type (const gchar  *string,
+                                   const gchar  *limit,
+                                   const gchar **endptr)
+{
+  const gchar *my_end;
+  gchar *dest;
+  gchar *new;
+
+  if (endptr == NULL)
+    endptr = &my_end;
+
+  if (!g_variant_format_string_scan (string, limit, endptr))
+    return NULL;
+
+  dest = new = g_malloc (*endptr - string + 1);
+  while (string != *endptr)
+    {
+      if (*string != '@' && *string != '&' && *string != '^')
+        *dest++ = *string;
+      string++;
+    }
+  *dest = '\0';
+
+  return (GVariantType *) G_VARIANT_TYPE (new);
+}
+
+static gboolean
+valid_format_string (const gchar *format_string,
+                     gboolean     single,
+                     GVariant    *value)
+{
+  const gchar *endptr;
+  GVariantType *type;
+
+  type = g_variant_format_string_scan_type (format_string, NULL, &endptr);
+
+  if G_UNLIKELY (type == NULL || (single && *endptr != '\0'))
+    {
+      if (single)
+        g_critical ("`%s' is not a valid GVariant format string",
+                    format_string);
+      else
+        g_critical ("`%s' does not have a valid GVariant format "
+                    "string as a prefix", format_string);
+
+      if (type != NULL)
+        g_variant_type_free (type);
+
+      return FALSE;
+    }
+
+  if G_UNLIKELY (value && !g_variant_is_of_type (value, type))
+    {
+      gchar *fragment;
+      gchar *typestr;
+
+      fragment = g_strndup (format_string, endptr - format_string);
+      typestr = g_variant_type_dup_string (type);
+
+      g_critical ("the GVariant format string `%s' has a type of "
+                  "`%s' but the given value has a type of `%s'",
+                  fragment, typestr, g_variant_get_type_string (value));
+
+      g_variant_type_free (type);
+
+      return FALSE;
+    }
+
+  g_variant_type_free (type);
+
+  return TRUE;
+}
+
+/* Variable Arguments {{{1 */
+/* We consider 2 main classes of format strings:
+ *
+ *   - recursive format strings
+ *      these are ones that result in recursion and the collection of
+ *      possibly more than one argument.  Maybe types, tuples,
+ *      dictionary entries.
+ *
+ *   - leaf format string
+ *      these result in the collection of a single argument.
+ *
+ * Leaf format strings are further subdivided into two categories:
+ *
+ *   - single non-null pointer ("nnp")
+ *      these either collect or return a single non-null pointer.
+ *
+ *   - other
+ *      these collect or return something else (bool, number, etc).
+ *
+ * Based on the above, the varargs handling code is split into 4 main parts:
+ *
+ *   - nnp handling code
+ *   - leaf handling code (which may invoke nnp code)
+ *   - generic handling code (may be recursive, may invoke leaf code)
+ *   - user-facing API (which invokes the generic code)
+ *
+ * Each section implements some of the following functions:
+ *
+ *   - skip:
+ *      collect the arguments for the format string as if
+ *      g_variant_new() had been called, but do nothing with them.  used
+ *      for skipping over arguments when constructing a Nothing maybe
+ *      type.
+ *
+ *   - new:
+ *      create a GVariant *
+ *
+ *   - get:
+ *      unpack a GVariant *
+ *
+ *   - free (nnp only):
+ *      free a previously allocated item
+ */
+
+static gboolean
+g_variant_format_string_is_leaf (const gchar *str)
+{
+  return str[0] != 'm' && str[0] != '(' && str[0] != '{';
+}
+
+static gboolean
+g_variant_format_string_is_nnp (const gchar *str)
+{
+  return str[0] == 'a' || str[0] == 's' || str[0] == 'o' || str[0] == 'g' ||
+         str[0] == '^' || str[0] == '@' || str[0] == '*' || str[0] == '?' ||
+         str[0] == 'r' || str[0] == 'v' || str[0] == '&';
+}
+
+/* Single non-null pointer ("nnp") {{{2 */
+static void
+g_variant_valist_free_nnp (const gchar *str,
+                           gpointer     ptr)
+{
+  switch (*str)
+    {
+    case 'a':
+      g_variant_iter_free (ptr);
+      break;
+
+    case '^':
+      if (str[2] != '&')        /* '^as' */
+        g_strfreev (ptr);
+      else                      /* '^a&s' */
+        g_free (ptr);
+      break;
+
+    case 's':
+    case 'o':
+    case 'g':
+      g_free (ptr);
+      break;
+
+    case '@':
+    case '*':
+    case '?':
+    case 'v':
+      g_variant_unref (ptr);
+      break;
+
+    case '&':
+      break;
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static gchar
+g_variant_scan_convenience (const gchar **str,
+                            gboolean     *constant,
+                            guint        *arrays)
+{
+  *constant = FALSE;
+  *arrays = 0;
+
+  for (;;)
+    {
+      char c = *(*str)++;
+
+      if (c == '&')
+        *constant = TRUE;
+
+      else if (c == 'a')
+        (*arrays)++;
+
+      else
+        return c;
+    }
+}
+
+static GVariant *
+g_variant_valist_new_nnp (const gchar **str,
+                          gpointer      ptr)
+{
+  if (**str == '&')
+    (*str)++;
+
+  switch (*(*str)++)
+    {
+    case 'a':
+      {
+        const GVariantType *type;
+        GVariant *value;
+
+        value = g_variant_builder_end (ptr);
+        type = g_variant_get_type (value);
+
+        if G_UNLIKELY (!g_variant_type_is_array (type))
+          g_error ("g_variant_new: expected array GVariantBuilder but "
+                   "the built value has type `%s'",
+                   g_variant_get_type_string (value));
+
+        type = g_variant_type_element (type);
+
+        if G_UNLIKELY (!g_variant_type_is_subtype_of (type, (GVariantType *) *str))
+          g_error ("g_variant_new: expected GVariantBuilder array element "
+                   "type `%s' but the built value has element type `%s'",
+                   g_variant_type_dup_string ((GVariantType *) *str),
+                   g_variant_get_type_string (value) + 1);
+
+        g_variant_type_string_scan (*str, NULL, str);
+
+        return value;
+      }
+
+    case 's':
+      return g_variant_new_string (ptr);
+
+    case 'o':
+      return g_variant_new_object_path (ptr);
+
+    case 'g':
+      return g_variant_new_signature (ptr);
+
+    case '^':
+      {
+        gboolean constant;
+        guint arrays;
+
+        if (g_variant_scan_convenience (str, &constant, &arrays) == 's')
+          return g_variant_new_strv (ptr, -1);
+
+        if (arrays > 1)
+          return g_variant_new_bytestring_array (ptr, -1);
+
+        return g_variant_new_bytestring (ptr);
+      }
+
+    case '@':
+      if G_UNLIKELY (!g_variant_is_of_type (ptr, (GVariantType *) *str))
+        g_error ("g_variant_new: expected GVariant of type `%s' but "
+                 "received value has type `%s'",
+                 g_variant_type_dup_string ((GVariantType *) *str),
+                 g_variant_get_type_string (ptr));
+
+      g_variant_type_string_scan (*str, NULL, str);
+
+      return ptr;
+
+    case '*':
+      return ptr;
+
+    case '?':
+      if G_UNLIKELY (!g_variant_type_is_basic (g_variant_get_type (ptr)))
+        g_error ("g_variant_new: format string `?' expects basic-typed "
+                 "GVariant, but received value has type `%s'",
+                 g_variant_get_type_string (ptr));
+
+      return ptr;
+
+    case 'r':
+      if G_UNLIKELY (!g_variant_type_is_tuple (g_variant_get_type (ptr)))
+        g_error ("g_variant_new: format string `r` expects tuple-typed "
+                 "GVariant, but received value has type `%s'",
+                 g_variant_get_type_string (ptr));
+
+      return ptr;
+
+    case 'v':
+      return g_variant_new_variant (ptr);
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static gpointer
+g_variant_valist_get_nnp (const gchar **str,
+                          GVariant     *value)
+{
+  switch (*(*str)++)
+    {
+    case 'a':
+      g_variant_type_string_scan (*str, NULL, str);
+      return g_variant_iter_new (value);
+
+    case '&':
+      (*str)++;
+      return (gchar *) g_variant_get_string (value, NULL);
+
+    case 's':
+    case 'o':
+    case 'g':
+      return g_variant_dup_string (value, NULL);
+
+    case '^':
+      {
+        gboolean constant;
+        guint arrays;
+
+        if (g_variant_scan_convenience (str, &constant, &arrays) == 's')
+          {
+            if (constant)
+              return g_variant_get_strv (value, NULL);
+            else
+              return g_variant_dup_strv (value, NULL);
+          }
+
+        else if (arrays > 1)
+          {
+            if (constant)
+              return g_variant_get_bytestring_array (value, NULL);
+            else
+              return g_variant_dup_bytestring_array (value, NULL);
+          }
+
+        else
+          {
+            if (constant)
+              return (gchar *) g_variant_get_bytestring (value);
+            else
+              return g_variant_dup_bytestring (value, NULL);
+          }
+      }
+
+    case '@':
+      g_variant_type_string_scan (*str, NULL, str);
+      /* fall through */
+
+    case '*':
+    case '?':
+    case 'r':
+      return g_variant_ref (value);
+
+    case 'v':
+      return g_variant_get_variant (value);
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+/* Leaves {{{2 */
+static void
+g_variant_valist_skip_leaf (const gchar **str,
+                            va_list      *app)
+{
+  if (g_variant_format_string_is_nnp (*str))
+    {
+      g_variant_format_string_scan (*str, NULL, str);
+      va_arg (*app, gpointer);
+      return;
+    }
+
+  switch (*(*str)++)
+    {
+    case 'b':
+    case 'y':
+    case 'n':
+    case 'q':
+    case 'i':
+    case 'u':
+    case 'h':
+      va_arg (*app, int);
+      return;
+
+    case 'x':
+    case 't':
+      va_arg (*app, guint64);
+      return;
+
+    case 'd':
+      va_arg (*app, gdouble);
+      return;
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+static GVariant *
+g_variant_valist_new_leaf (const gchar **str,
+                           va_list      *app)
+{
+  if (g_variant_format_string_is_nnp (*str))
+    return g_variant_valist_new_nnp (str, va_arg (*app, gpointer));
+
+  switch (*(*str)++)
+    {
+    case 'b':
+      return g_variant_new_boolean (va_arg (*app, gboolean));
+
+    case 'y':
+      return g_variant_new_byte (va_arg (*app, guint));
+
+    case 'n':
+      return g_variant_new_int16 (va_arg (*app, gint));
+
+    case 'q':
+      return g_variant_new_uint16 (va_arg (*app, guint));
+
+    case 'i':
+      return g_variant_new_int32 (va_arg (*app, gint));
+
+    case 'u':
+      return g_variant_new_uint32 (va_arg (*app, guint));
+
+    case 'x':
+      return g_variant_new_int64 (va_arg (*app, gint64));
+
+    case 't':
+      return g_variant_new_uint64 (va_arg (*app, guint64));
+
+    case 'h':
+      return g_variant_new_handle (va_arg (*app, gint));
+
+    case 'd':
+      return g_variant_new_double (va_arg (*app, gdouble));
+
+    default:
+      g_assert_not_reached ();
+    }
+}
+
+/* The code below assumes this */
+G_STATIC_ASSERT (sizeof (gboolean) == sizeof (guint32));
+G_STATIC_ASSERT (sizeof (gdouble) == sizeof (guint64));
+
+static void
+g_variant_valist_get_leaf (const gchar **str,
+                           GVariant     *value,
+                           gboolean      free,
+                           va_list      *app)
+{
+  gpointer ptr = va_arg (*app, gpointer);
+
+  if (ptr == NULL)
+    {
+      g_variant_format_string_scan (*str, NULL, str);
+      return;
+    }
+
+  if (g_variant_format_string_is_nnp (*str))
+    {
+      gpointer *nnp = (gpointer *) ptr;
+
+      if (free && *nnp != NULL)
+        g_variant_valist_free_nnp (*str, *nnp);
+
+      *nnp = NULL;
+
+      if (value != NULL)
+        *nnp = g_variant_valist_get_nnp (str, value);
+      else
+        g_variant_format_string_scan (*str, NULL, str);
+
+      return;
+    }
+
+  if (value != NULL)
+    {
+      switch (*(*str)++)
+        {
+        case 'b':
+          *(gboolean *) ptr = g_variant_get_boolean (value);
+          return;
+
+        case 'y':
+          *(guchar *) ptr = g_variant_get_byte (value);
+          return;
+
+        case 'n':
+          *(gint16 *) ptr = g_variant_get_int16 (value);
+          return;
+
+        case 'q':
+          *(guint16 *) ptr = g_variant_get_uint16 (value);
+          return;
+
+        case 'i':
+          *(gint32 *) ptr = g_variant_get_int32 (value);
+          return;
+
+        case 'u':
+          *(guint32 *) ptr = g_variant_get_uint32 (value);
+          return;
+
+        case 'x':
+          *(gint64 *) ptr = g_variant_get_int64 (value);
+          return;
+
+        case 't':
+          *(guint64 *) ptr = g_variant_get_uint64 (value);
+          return;
+
+        case 'h':
+          *(gint32 *) ptr = g_variant_get_handle (value);
+          return;
+
+        case 'd':
+          *(gdouble *) ptr = g_variant_get_double (value);
+          return;
+        }
+    }
+  else
+    {
+      switch (*(*str)++)
+        {
+        case 'y':
+          *(guchar *) ptr = 0;
+          return;
+
+        case 'n':
+        case 'q':
+          *(guint16 *) ptr = 0;
+          return;
+
+        case 'i':
+        case 'u':
+        case 'h':
+        case 'b':
+          *(guint32 *) ptr = 0;
+          return;
+
+        case 'x':
+        case 't':
+        case 'd':
+          *(guint64 *) ptr = 0;
+          return;
+        }
+    }
+
+  g_assert_not_reached ();
+}
+
+/* Generic (recursive) {{{2 */
+static void
+g_variant_valist_skip (const gchar **str,
+                       va_list      *app)
+{
+  if (g_variant_format_string_is_leaf (*str))
+    g_variant_valist_skip_leaf (str, app);
+
+  else if (**str == 'm') /* maybe */
+    {
+      (*str)++;
+
+      if (!g_variant_format_string_is_nnp (*str))
+        va_arg (*app, gboolean);
+
+      g_variant_valist_skip (str, app);
+    }
+  else /* tuple, dictionary entry */
+    {
+      g_assert (**str == '(' || **str == '{');
+      (*str)++;
+      while (**str != ')' && **str != '}')
+        g_variant_valist_skip (str, app);
+      (*str)++;
+    }
+}
+
+static GVariant *
+g_variant_valist_new (const gchar **str,
+                      va_list      *app)
+{
+  if (g_variant_format_string_is_leaf (*str))
+    return g_variant_valist_new_leaf (str, app);
+
+  if (**str == 'm') /* maybe */
+    {
+      GVariantType *type = NULL;
+      GVariant *value = NULL;
+
+      (*str)++;
+
+      if (g_variant_format_string_is_nnp (*str))
+        {
+          gpointer nnp = va_arg (*app, gpointer);
+
+          if (nnp != NULL)
+            value = g_variant_valist_new_nnp (str, nnp);
+          else
+            type = g_variant_format_string_scan_type (*str, NULL, str);
+        }
+      else
+        {
+          gboolean just = va_arg (*app, gboolean);
+
+          if (just)
+            value = g_variant_valist_new (str, app);
+          else
+            {
+              type = g_variant_format_string_scan_type (*str, NULL, NULL);
+              g_variant_valist_skip (str, app);
+            }
+        }
+
+      value = g_variant_new_maybe (type, value);
+
+      if (type != NULL)
+        g_variant_type_free (type);
+
+      return value;
+    }
+  else /* tuple, dictionary entry */
+    {
+      GVariantBuilder b;
+
+      if (**str == '(')
+        g_variant_builder_init (&b, G_VARIANT_TYPE_TUPLE);
+      else
+        {
+          g_assert (**str == '{');
+          g_variant_builder_init (&b, G_VARIANT_TYPE_DICT_ENTRY);
+        }
+
+      (*str)++; /* '(' */
+      while (**str != ')' && **str != '}')
+        g_variant_builder_add_value (&b, g_variant_valist_new (str, app));
+      (*str)++; /* ')' */
+
+      return g_variant_builder_end (&b);
+    }
+}
+
+static void
+g_variant_valist_get (const gchar **str,
+                      GVariant     *value,
+                      gboolean      free,
+                      va_list      *app)
+{
+  if (g_variant_format_string_is_leaf (*str))
+    g_variant_valist_get_leaf (str, value, free, app);
+
+  else if (**str == 'm')
+    {
+      (*str)++;
+
+      if (value != NULL)
+        value = g_variant_get_maybe (value);
+
+      if (!g_variant_format_string_is_nnp (*str))
+        {
+          gboolean *ptr = va_arg (*app, gboolean *);
+
+          if (ptr != NULL)
+            *ptr = value != NULL;
+        }
+
+      g_variant_valist_get (str, value, free, app);
+
+      if (value != NULL)
+        g_variant_unref (value);
+    }
+
+  else /* tuple, dictionary entry */
+    {
+      gint index = 0;
+
+      g_assert (**str == '(' || **str == '{');
+
+      (*str)++;
+      while (**str != ')' && **str != '}')
+        {
+          if (value != NULL)
+            {
+              GVariant *child = g_variant_get_child_value (value, index++);
+              g_variant_valist_get (str, child, free, app);
+              g_variant_unref (child);
+            }
+          else
+            g_variant_valist_get (str, NULL, free, app);
+        }
+      (*str)++;
+    }
+}
+
+/* User-facing API {{{2 */
+/**
+ * g_variant_new:
+ * @format_string: a #GVariant format string
+ * @...: arguments, as per @format_string
+ * @returns: a new floating #GVariant instance
+ *
+ * Creates a new #GVariant instance.
+ *
+ * Think of this function as an analogue to g_strdup_printf().
+ *
+ * The type of the created instance and the arguments that are
+ * expected by this function are determined by @format_string.  See the
+ * section on <link linkend='gvariant-format-strings'>GVariant Format
+ * Strings</link>.  Please note that the syntax of the format string is
+ * very likely to be extended in the future.
+ *
+ * The first character of the format string must not be '*' '?' '@' or
+ * 'r'; in essence, a new #GVariant must always be constructed by this
+ * function (and not merely passed through it unmodified).
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_new (const gchar *format_string,
+               ...)
+{
+  GVariant *value;
+  va_list ap;
+
+  g_return_val_if_fail (valid_format_string (format_string, TRUE, NULL) &&
+                        format_string[0] != '?' && format_string[0] != '@' &&
+                        format_string[0] != '*' && format_string[0] != 'r',
+                        NULL);
+
+  va_start (ap, format_string);
+  value = g_variant_new_va (format_string, NULL, &ap);
+  va_end (ap);
+
+  return value;
+}
+
+/**
+ * g_variant_new_va:
+ * @format_string: a string that is prefixed with a format string
+ * @endptr: (allow-none) (default NULL): location to store the end pointer,
+ *          or %NULL
+ * @app: a pointer to a #va_list
+ * @returns: a new, usually floating, #GVariant
+ *
+ * This function is intended to be used by libraries based on
+ * #GVariant that want to provide g_variant_new()-like functionality
+ * to their users.
+ *
+ * The API is more general than g_variant_new() to allow a wider range
+ * of possible uses.
+ *
+ * @format_string must still point to a valid format string, but it only
+ * needs to be nul-terminated if @endptr is %NULL.  If @endptr is
+ * non-%NULL then it is updated to point to the first character past the
+ * end of the format string.
+ *
+ * @app is a pointer to a #va_list.  The arguments, according to
+ * @format_string, are collected from this #va_list and the list is left
+ * pointing to the argument following the last.
+ *
+ * These two generalisations allow mixing of multiple calls to
+ * g_variant_new_va() and g_variant_get_va() within a single actual
+ * varargs call by the user.
+ *
+ * The return value will be floating if it was a newly created GVariant
+ * instance (for example, if the format string was "(ii)").  In the case
+ * that the format_string was '*', '?', 'r', or a format starting with
+ * '@' then the collected #GVariant pointer will be returned unmodified,
+ * without adding any additional references.
+ *
+ * In order to behave correctly in all cases it is necessary for the
+ * calling function to g_variant_ref_sink() the return result before
+ * returning control to the user that originally provided the pointer.
+ * At this point, the caller will have their own full reference to the
+ * result.  This can also be done by adding the result to a container,
+ * or by passing it to another g_variant_new() call.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_new_va (const gchar  *format_string,
+                  const gchar **endptr,
+                  va_list      *app)
+{
+  GVariant *value;
+
+  g_return_val_if_fail (valid_format_string (format_string, !endptr, NULL),
+                        NULL);
+  g_return_val_if_fail (app != NULL, NULL);
+
+  value = g_variant_valist_new (&format_string, app);
+
+  if (endptr != NULL)
+    *endptr = format_string;
+
+  return value;
+}
+
+/**
+ * g_variant_get:
+ * @value: a #GVariant instance
+ * @format_string: a #GVariant format string
+ * @...: arguments, as per @format_string
+ *
+ * Deconstructs a #GVariant instance.
+ *
+ * Think of this function as an analogue to scanf().
+ *
+ * The arguments that are expected by this function are entirely
+ * determined by @format_string.  @format_string also restricts the
+ * permissible types of @value.  It is an error to give a value with
+ * an incompatible type.  See the section on <link
+ * linkend='gvariant-format-strings'>GVariant Format Strings</link>.
+ * Please note that the syntax of the format string is very likely to be
+ * extended in the future.
+ *
+ * Since: 2.24
+ **/
+void
+g_variant_get (GVariant    *value,
+               const gchar *format_string,
+               ...)
+{
+  va_list ap;
+
+  g_return_if_fail (valid_format_string (format_string, TRUE, value));
+
+  /* if any direct-pointer-access formats are in use, flatten first */
+  if (strchr (format_string, '&'))
+    g_variant_get_data (value);
+
+  va_start (ap, format_string);
+  g_variant_get_va (value, format_string, NULL, &ap);
+  va_end (ap);
+}
+
+/**
+ * g_variant_get_va:
+ * @value: a #GVariant
+ * @format_string: a string that is prefixed with a format string
+ * @endptr: (allow-none) (default NULL): location to store the end pointer,
+ *          or %NULL
+ * @app: a pointer to a #va_list
+ *
+ * This function is intended to be used by libraries based on #GVariant
+ * that want to provide g_variant_get()-like functionality to their
+ * users.
+ *
+ * The API is more general than g_variant_get() to allow a wider range
+ * of possible uses.
+ *
+ * @format_string must still point to a valid format string, but it only
+ * need to be nul-terminated if @endptr is %NULL.  If @endptr is
+ * non-%NULL then it is updated to point to the first character past the
+ * end of the format string.
+ *
+ * @app is a pointer to a #va_list.  The arguments, according to
+ * @format_string, are collected from this #va_list and the list is left
+ * pointing to the argument following the last.
+ *
+ * These two generalisations allow mixing of multiple calls to
+ * g_variant_new_va() and g_variant_get_va() within a single actual
+ * varargs call by the user.
+ *
+ * Since: 2.24
+ **/
+void
+g_variant_get_va (GVariant     *value,
+                  const gchar  *format_string,
+                  const gchar **endptr,
+                  va_list      *app)
+{
+  g_return_if_fail (valid_format_string (format_string, !endptr, value));
+  g_return_if_fail (value != NULL);
+  g_return_if_fail (app != NULL);
+
+  /* if any direct-pointer-access formats are in use, flatten first */
+  if (strchr (format_string, '&'))
+    g_variant_get_data (value);
+
+  g_variant_valist_get (&format_string, value, FALSE, app);
+
+  if (endptr != NULL)
+    *endptr = format_string;
+}
+
+/* Varargs-enabled Utility Functions {{{1 */
+
+/**
+ * g_variant_builder_add:
+ * @builder: a #GVariantBuilder
+ * @format_string: a #GVariant varargs format string
+ * @...: arguments, as per @format_string
+ *
+ * Adds to a #GVariantBuilder.
+ *
+ * This call is a convenience wrapper that is exactly equivalent to
+ * calling g_variant_new() followed by g_variant_builder_add_value().
+ *
+ * This function might be used as follows:
+ *
+ * <programlisting>
+ * GVariant *
+ * make_pointless_dictionary (void)
+ * {
+ *   GVariantBuilder *builder;
+ *   int i;
+ *
+ *   builder = g_variant_builder_new (G_VARIANT_TYPE_ARRAY);
+ *   for (i = 0; i < 16; i++)
+ *     {
+ *       gchar buf[3];
+ *
+ *       sprintf (buf, "%d", i);
+ *       g_variant_builder_add (builder, "{is}", i, buf);
+ *     }
+ *
+ *   return g_variant_builder_end (builder);
+ * }
+ * </programlisting>
+ *
+ * Since: 2.24
+ **/
+void
+g_variant_builder_add (GVariantBuilder *builder,
+                       const gchar     *format_string,
+                       ...)
+{
+  GVariant *variant;
+  va_list ap;
+
+  va_start (ap, format_string);
+  variant = g_variant_new_va (format_string, NULL, &ap);
+  va_end (ap);
+
+  g_variant_builder_add_value (builder, variant);
+}
+
+/**
+ * g_variant_get_child:
+ * @value: a container #GVariant
+ * @index_: the index of the child to deconstruct
+ * @format_string: a #GVariant format string
+ * @...: arguments, as per @format_string
+ *
+ * Reads a child item out of a container #GVariant instance and
+ * deconstructs it according to @format_string.  This call is
+ * essentially a combination of g_variant_get_child_value() and
+ * g_variant_get().
+ *
+ * Since: 2.24
+ **/
+void
+g_variant_get_child (GVariant    *value,
+                     gsize        index_,
+                     const gchar *format_string,
+                     ...)
+{
+  GVariant *child;
+  va_list ap;
+
+  child = g_variant_get_child_value (value, index_);
+  g_return_if_fail (valid_format_string (format_string, TRUE, child));
+
+  va_start (ap, format_string);
+  g_variant_get_va (child, format_string, NULL, &ap);
+  va_end (ap);
+
+  g_variant_unref (child);
+}
+
+/**
+ * g_variant_iter_next:
+ * @iter: a #GVariantIter
+ * @format_string: a GVariant format string
+ * @...: the arguments to unpack the value into
+ * @returns: %TRUE if a value was unpacked, or %FALSE if there as no
+ *           value
+ *
+ * Gets the next item in the container and unpacks it into the variable
+ * argument list according to @format_string, returning %TRUE.
+ *
+ * If no more items remain then %FALSE is returned.
+ *
+ * All of the pointers given on the variable arguments list of this
+ * function are assumed to point at uninitialised memory.  It is the
+ * responsibility of the caller to free all of the values returned by
+ * the unpacking process.
+ *
+ * See the section on <link linkend='gvariant-format-strings'>GVariant
+ * Format Strings</link>.
+ *
+ * <example>
+ *  <title>Memory management with g_variant_iter_next()</title>
+ *  <programlisting>
+ *   /<!-- -->* Iterates a dictionary of type 'a{sv}' *<!-- -->/
+ *   void
+ *   iterate_dictionary (GVariant *dictionary)
+ *   {
+ *     GVariantIter iter;
+ *     GVariant *value;
+ *     gchar *key;
+ *
+ *     g_variant_iter_init (&iter, dictionary);
+ *     while (g_variant_iter_next (&iter, "{sv}", &key, &value))
+ *       {
+ *         g_print ("Item '%s' has type '%s'\n", key,
+ *                  g_variant_get_type_string (value));
+ *
+ *         /<!-- -->* must free data for ourselves *<!-- -->/
+ *         g_variant_unref (value);
+ *         g_free (key);
+ *       }
+ *   }
+ *  </programlisting>
+ * </example>
+ *
+ * For a solution that is likely to be more convenient to C programmers
+ * when dealing with loops, see g_variant_iter_loop().
+ *
+ * Since: 2.24
+ **/
+gboolean
+g_variant_iter_next (GVariantIter *iter,
+                     const gchar  *format_string,
+                     ...)
+{
+  GVariant *value;
+
+  value = g_variant_iter_next_value (iter);
+
+  g_return_val_if_fail (valid_format_string (format_string, TRUE, value),
+                        FALSE);
+
+  if (value != NULL)
+    {
+      va_list ap;
+
+      va_start (ap, format_string);
+      g_variant_valist_get (&format_string, value, FALSE, &ap);
+      va_end (ap);
+
+      g_variant_unref (value);
+    }
+
+  return value != NULL;
+}
+
+/**
+ * g_variant_iter_loop:
+ * @iter: a #GVariantIter
+ * @format_string: a GVariant format string
+ * @...: the arguments to unpack the value into
+ * @returns: %TRUE if a value was unpacked, or %FALSE if there as no
+ *           value
+ *
+ * Gets the next item in the container and unpacks it into the variable
+ * argument list according to @format_string, returning %TRUE.
+ *
+ * If no more items remain then %FALSE is returned.
+ *
+ * On the first call to this function, the pointers appearing on the
+ * variable argument list are assumed to point at uninitialised memory.
+ * On the second and later calls, it is assumed that the same pointers
+ * will be given and that they will point to the memory as set by the
+ * previous call to this function.  This allows the previous values to
+ * be freed, as appropriate.
+ *
+ * This function is intended to be used with a while loop as
+ * demonstrated in the following example.  This function can only be
+ * used when iterating over an array.  It is only valid to call this
+ * function with a string constant for the format string and the same
+ * string constant must be used each time.  Mixing calls to this
+ * function and g_variant_iter_next() or g_variant_iter_next_value() on
+ * the same iterator is not recommended.
+ *
+ * See the section on <link linkend='gvariant-format-strings'>GVariant
+ * Format Strings</link>.
+ *
+ * <example>
+ *  <title>Memory management with g_variant_iter_loop()</title>
+ *  <programlisting>
+ *   /<!-- -->* Iterates a dictionary of type 'a{sv}' *<!-- -->/
+ *   void
+ *   iterate_dictionary (GVariant *dictionary)
+ *   {
+ *     GVariantIter iter;
+ *     GVariant *value;
+ *     gchar *key;
+ *
+ *     g_variant_iter_init (&iter, dictionary);
+ *     while (g_variant_iter_loop (&iter, "{sv}", &key, &value))
+ *       {
+ *         g_print ("Item '%s' has type '%s'\n", key,
+ *                  g_variant_get_type_string (value));
+ *
+ *         /<!-- -->* no need to free 'key' and 'value' here *<!-- -->/
+ *       }
+ *   }
+ *  </programlisting>
+ * </example>
+ *
+ * If you want a slightly less magical alternative that requires more
+ * typing, see g_variant_iter_next().
+ *
+ * Since: 2.24
+ **/
+gboolean
+g_variant_iter_loop (GVariantIter *iter,
+                     const gchar  *format_string,
+                     ...)
+{
+  gboolean first_time = GVSI(iter)->loop_format == NULL;
+  GVariant *value;
+  va_list ap;
+
+  g_return_val_if_fail (first_time ||
+                        format_string == GVSI(iter)->loop_format,
+                        FALSE);
+
+  if (first_time)
+    {
+      TYPE_CHECK (GVSI(iter)->value, G_VARIANT_TYPE_ARRAY, FALSE);
+      GVSI(iter)->loop_format = format_string;
+
+      if (strchr (format_string, '&'))
+        g_variant_get_data (GVSI(iter)->value);
+    }
+
+  value = g_variant_iter_next_value (iter);
+
+  g_return_val_if_fail (!first_time ||
+                        valid_format_string (format_string, TRUE, value),
+                        FALSE);
+
+  va_start (ap, format_string);
+  g_variant_valist_get (&format_string, value, !first_time, &ap);
+  va_end (ap);
+
+  if (value != NULL)
+    g_variant_unref (value);
+
+  return value != NULL;
+}
+
+/* Serialised data {{{1 */
+static GVariant *
+g_variant_deep_copy (GVariant *value)
+{
+  switch (g_variant_classify (value))
+    {
+    case G_VARIANT_CLASS_MAYBE:
+    case G_VARIANT_CLASS_ARRAY:
+    case G_VARIANT_CLASS_TUPLE:
+    case G_VARIANT_CLASS_DICT_ENTRY:
+    case G_VARIANT_CLASS_VARIANT:
+      {
+        GVariantBuilder builder;
+        GVariantIter iter;
+        GVariant *child;
+
+        g_variant_builder_init (&builder, g_variant_get_type (value));
+        g_variant_iter_init (&iter, value);
+
+        while ((child = g_variant_iter_next_value (&iter)))
+          {
+            g_variant_builder_add_value (&builder, g_variant_deep_copy (child));
+            g_variant_unref (child);
+          }
+
+        return g_variant_builder_end (&builder);
+      }
+
+    case G_VARIANT_CLASS_BOOLEAN:
+      return g_variant_new_boolean (g_variant_get_boolean (value));
+
+    case G_VARIANT_CLASS_BYTE:
+      return g_variant_new_byte (g_variant_get_byte (value));
+
+    case G_VARIANT_CLASS_INT16:
+      return g_variant_new_int16 (g_variant_get_int16 (value));
+
+    case G_VARIANT_CLASS_UINT16:
+      return g_variant_new_uint16 (g_variant_get_uint16 (value));
+
+    case G_VARIANT_CLASS_INT32:
+      return g_variant_new_int32 (g_variant_get_int32 (value));
+
+    case G_VARIANT_CLASS_UINT32:
+      return g_variant_new_uint32 (g_variant_get_uint32 (value));
+
+    case G_VARIANT_CLASS_INT64:
+      return g_variant_new_int64 (g_variant_get_int64 (value));
+
+    case G_VARIANT_CLASS_UINT64:
+      return g_variant_new_uint64 (g_variant_get_uint64 (value));
+
+    case G_VARIANT_CLASS_HANDLE:
+      return g_variant_new_handle (g_variant_get_handle (value));
+
+    case G_VARIANT_CLASS_DOUBLE:
+      return g_variant_new_double (g_variant_get_double (value));
+
+    case G_VARIANT_CLASS_STRING:
+      return g_variant_new_string (g_variant_get_string (value, NULL));
+
+    case G_VARIANT_CLASS_OBJECT_PATH:
+      return g_variant_new_object_path (g_variant_get_string (value, NULL));
+
+    case G_VARIANT_CLASS_SIGNATURE:
+      return g_variant_new_signature (g_variant_get_string (value, NULL));
+    }
+
+  g_assert_not_reached ();
+}
+
+/**
+ * g_variant_get_normal_form:
+ * @value: a #GVariant
+ * @returns: a trusted #GVariant
+ *
+ * Gets a #GVariant instance that has the same value as @value and is
+ * trusted to be in normal form.
+ *
+ * If @value is already trusted to be in normal form then a new
+ * reference to @value is returned.
+ *
+ * If @value is not already trusted, then it is scanned to check if it
+ * is in normal form.  If it is found to be in normal form then it is
+ * marked as trusted and a new reference to it is returned.
+ *
+ * If @value is found not to be in normal form then a new trusted
+ * #GVariant is created with the same value as @value.
+ *
+ * It makes sense to call this function if you've received #GVariant
+ * data from untrusted sources and you want to ensure your serialised
+ * output is definitely in normal form.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_get_normal_form (GVariant *value)
+{
+  GVariant *trusted;
+
+  if (g_variant_is_normal_form (value))
+    return g_variant_ref (value);
+
+  trusted = g_variant_deep_copy (value);
+  g_assert (g_variant_is_trusted (trusted));
+
+  return g_variant_ref_sink (trusted);
+}
+
+/**
+ * g_variant_byteswap:
+ * @value: a #GVariant
+ * @returns: the byteswapped form of @value
+ *
+ * Performs a byteswapping operation on the contents of @value.  The
+ * result is that all multi-byte numeric data contained in @value is
+ * byteswapped.  That includes 16, 32, and 64bit signed and unsigned
+ * integers as well as file handles and double precision floating point
+ * values.
+ *
+ * This function is an identity mapping on any value that does not
+ * contain multi-byte numeric data.  That include strings, booleans,
+ * bytes and containers containing only these things (recursively).
+ *
+ * The returned value is always in normal form and is marked as trusted.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_byteswap (GVariant *value)
+{
+  GVariantSerialised serialised;
+  GVariant *trusted;
+  GBuffer *buffer;
+  GVariant *new;
+
+  trusted = g_variant_get_normal_form (value);
+  serialised.type_info = g_variant_get_type_info (trusted);
+  serialised.size = g_variant_get_size (trusted);
+  serialised.data = g_malloc (serialised.size);
+  g_variant_store (trusted, serialised.data);
+  g_variant_unref (trusted);
+
+  g_variant_serialised_byteswap (serialised);
+
+  buffer = g_buffer_new_take_data (serialised.data, serialised.size);
+  new = g_variant_new_from_buffer (g_variant_get_type (value), buffer, TRUE);
+  g_buffer_unref (buffer);
+
+  return g_variant_ref_sink (new);
+}
+
+/**
+ * g_variant_new_from_data:
+ * @type: a definite #GVariantType
+ * @data: the serialised data
+ * @size: the size of @data
+ * @trusted: %TRUE if @data is definitely in normal form
+ * @notify: function to call when @data is no longer needed
+ * @user_data: data for @notify
+ * @returns: a new floating #GVariant of type @type
+ *
+ * Creates a new #GVariant instance from serialised data.
+ *
+ * @type is the type of #GVariant instance that will be constructed.
+ * The interpretation of @data depends on knowing the type.
+ *
+ * @data is not modified by this function and must remain valid with an
+ * unchanging value until such a time as @notify is called with
+ * @user_data.  If the contents of @data change before that time then
+ * the result is undefined.
+ *
+ * If @data is trusted to be serialised data in normal form then
+ * @trusted should be %TRUE.  This applies to serialised data created
+ * within this process or read from a trusted location on the disk (such
+ * as a file installed in /usr/lib alongside your application).  You
+ * should set trusted to %FALSE if @data is read from the network, a
+ * file in the user's home directory, etc.
+ *
+ * @notify will be called with @user_data when @data is no longer
+ * needed.  The exact time of this call is unspecified and might even be
+ * before this function returns.
+ *
+ * Since: 2.24
+ **/
+GVariant *
+g_variant_new_from_data (const GVariantType *type,
+                         gconstpointer       data,
+                         gsize               size,
+                         gboolean            trusted,
+                         GDestroyNotify      notify,
+                         gpointer            user_data)
+{
+  GVariant *value;
+  GBuffer *buffer;
+
+  g_return_val_if_fail (g_variant_type_is_definite (type), NULL);
+  g_return_val_if_fail (data != NULL || size == 0, NULL);
+
+  if (notify)
+    buffer = g_buffer_new_from_pointer (data, size, notify, user_data);
+  else
+    buffer = g_buffer_new_from_static_data (data, size);
+
+  value = g_variant_new_from_buffer (type, buffer, trusted);
+  g_buffer_unref (buffer);
+
+  return value;
+}
+
+/* Epilogue {{{1 */
+/* vim:set foldmethod=marker: */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gvariant.h
new file mode 100644 (file)
index 0000000..528492b
--- /dev/null
@@ -0,0 +1,248 @@
+/*
+ * Copyright © 2007, 2008 Ryan Lortie
+ * Copyright © 2009, 2010 Codethink Limited
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_VARIANT_H__
+#define __G_VARIANT_H__
+
+#include <glib/gvarianttype.h>
+#include <glib/gstring.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GVariant        GVariant;
+
+typedef enum
+{
+  G_VARIANT_CLASS_BOOLEAN       = 'b',
+  G_VARIANT_CLASS_BYTE          = 'y',
+  G_VARIANT_CLASS_INT16         = 'n',
+  G_VARIANT_CLASS_UINT16        = 'q',
+  G_VARIANT_CLASS_INT32         = 'i',
+  G_VARIANT_CLASS_UINT32        = 'u',
+  G_VARIANT_CLASS_INT64         = 'x',
+  G_VARIANT_CLASS_UINT64        = 't',
+  G_VARIANT_CLASS_HANDLE        = 'h',
+  G_VARIANT_CLASS_DOUBLE        = 'd',
+  G_VARIANT_CLASS_STRING        = 's',
+  G_VARIANT_CLASS_OBJECT_PATH   = 'o',
+  G_VARIANT_CLASS_SIGNATURE     = 'g',
+  G_VARIANT_CLASS_VARIANT       = 'v',
+  G_VARIANT_CLASS_MAYBE         = 'm',
+  G_VARIANT_CLASS_ARRAY         = 'a',
+  G_VARIANT_CLASS_TUPLE         = '(',
+  G_VARIANT_CLASS_DICT_ENTRY    = '{'
+} GVariantClass;
+
+void                            g_variant_unref                         (GVariant             *value);
+GVariant *                      g_variant_ref                           (GVariant             *value);
+GVariant *                      g_variant_ref_sink                      (GVariant             *value);
+gboolean                        g_variant_is_floating                   (GVariant             *value);
+
+const GVariantType *            g_variant_get_type                      (GVariant             *value);
+const gchar *                   g_variant_get_type_string               (GVariant             *value);
+gboolean                        g_variant_is_of_type                    (GVariant             *value,
+                                                                         const GVariantType   *type);
+gboolean                        g_variant_is_container                  (GVariant             *value);
+GVariantClass                   g_variant_classify                      (GVariant             *value);
+GVariant *                      g_variant_new_boolean                   (gboolean              boolean);
+GVariant *                      g_variant_new_byte                      (guchar                byte);
+GVariant *                      g_variant_new_int16                     (gint16                int16);
+GVariant *                      g_variant_new_uint16                    (guint16               uint16);
+GVariant *                      g_variant_new_int32                     (gint32                int32);
+GVariant *                      g_variant_new_uint32                    (guint32               uint32);
+GVariant *                      g_variant_new_int64                     (gint64                int64);
+GVariant *                      g_variant_new_uint64                    (guint64               uint64);
+GVariant *                      g_variant_new_handle                    (gint32                handle);
+GVariant *                      g_variant_new_double                    (gdouble               floating);
+GVariant *                      g_variant_new_string                    (const gchar          *string);
+GVariant *                      g_variant_new_object_path               (const gchar          *object_path);
+gboolean                        g_variant_is_object_path                (const gchar          *string);
+GVariant *                      g_variant_new_signature                 (const gchar          *signature);
+gboolean                        g_variant_is_signature                  (const gchar          *string);
+GVariant *                      g_variant_new_variant                   (GVariant             *value);
+GVariant *                      g_variant_new_strv                      (const gchar * const  *strv,
+                                                                         gssize                length);
+GVariant *                      g_variant_new_bytestring                (const gchar          *string);
+GVariant *                      g_variant_new_bytestring_array          (const gchar * const  *strv,
+                                                                         gssize                length);
+
+gboolean                        g_variant_get_boolean                   (GVariant             *value);
+guchar                          g_variant_get_byte                      (GVariant             *value);
+gint16                          g_variant_get_int16                     (GVariant             *value);
+guint16                         g_variant_get_uint16                    (GVariant             *value);
+gint32                          g_variant_get_int32                     (GVariant             *value);
+guint32                         g_variant_get_uint32                    (GVariant             *value);
+gint64                          g_variant_get_int64                     (GVariant             *value);
+guint64                         g_variant_get_uint64                    (GVariant             *value);
+gint32                          g_variant_get_handle                    (GVariant             *value);
+gdouble                         g_variant_get_double                    (GVariant             *value);
+GVariant *                      g_variant_get_variant                   (GVariant             *value);
+const gchar *                   g_variant_get_string                    (GVariant             *value,
+                                                                         gsize                *length);
+gchar *                         g_variant_dup_string                    (GVariant             *value,
+                                                                         gsize                *length);
+const gchar **                  g_variant_get_strv                      (GVariant             *value,
+                                                                         gsize                *length);
+gchar **                        g_variant_dup_strv                      (GVariant             *value,
+                                                                         gsize                *length);
+const gchar *                   g_variant_get_bytestring                (GVariant             *value);
+gchar *                         g_variant_dup_bytestring                (GVariant             *value,
+                                                                         gsize                *length);
+const gchar **                  g_variant_get_bytestring_array          (GVariant             *value,
+                                                                         gsize                *length);
+gchar **                        g_variant_dup_bytestring_array          (GVariant             *value,
+                                                                         gsize                *length);
+
+GVariant *                      g_variant_new_maybe                     (const GVariantType   *child_type,
+                                                                         GVariant             *child);
+GVariant *                      g_variant_new_array                     (const GVariantType   *child_type,
+                                                                         GVariant * const     *children,
+                                                                         gsize                 n_children);
+GVariant *                      g_variant_new_tuple                     (GVariant * const     *children,
+                                                                         gsize                 n_children);
+GVariant *                      g_variant_new_dict_entry                (GVariant             *key,
+                                                                         GVariant             *value);
+
+GVariant *                      g_variant_get_maybe                     (GVariant             *value);
+gsize                           g_variant_n_children                    (GVariant             *value);
+void                            g_variant_get_child                     (GVariant             *value,
+                                                                         gsize                 index_,
+                                                                         const gchar          *format_string,
+                                                                         ...);
+GVariant *                      g_variant_get_child_value               (GVariant             *value,
+                                                                         gsize                 index_);
+gconstpointer                   g_variant_get_fixed_array               (GVariant             *value,
+                                                                         gsize                *n_elements,
+                                                                         gsize                 element_size);
+
+gsize                           g_variant_get_size                      (GVariant             *value);
+gconstpointer                   g_variant_get_data                      (GVariant             *value);
+void                            g_variant_store                         (GVariant             *value,
+                                                                         gpointer              data);
+
+gchar *                         g_variant_print                         (GVariant             *value,
+                                                                         gboolean              type_annotate);
+GString *                       g_variant_print_string                  (GVariant             *value,
+                                                                         GString              *string,
+                                                                         gboolean              type_annotate);
+
+guint                           g_variant_hash                          (gconstpointer         value);
+gboolean                        g_variant_equal                         (gconstpointer         one,
+                                                                         gconstpointer         two);
+
+GVariant *                      g_variant_get_normal_form               (GVariant             *value);
+gboolean                        g_variant_is_normal_form                (GVariant             *value);
+GVariant *                      g_variant_byteswap                      (GVariant             *value);
+GVariant *                      g_variant_new_from_data                 (const GVariantType   *type,
+                                                                         gconstpointer         data,
+                                                                         gsize                 size,
+                                                                         gboolean              trusted,
+                                                                         GDestroyNotify        notify,
+                                                                         gpointer              user_data);
+
+typedef struct _GVariantIter GVariantIter;
+struct _GVariantIter {
+  /*< private >*/
+  gsize x[16];
+};
+
+GVariantIter *                  g_variant_iter_new                      (GVariant             *value);
+gsize                           g_variant_iter_init                     (GVariantIter         *iter,
+                                                                         GVariant             *value);
+GVariantIter *                  g_variant_iter_copy                     (GVariantIter         *iter);
+gsize                           g_variant_iter_n_children               (GVariantIter         *iter);
+void                            g_variant_iter_free                     (GVariantIter         *iter);
+GVariant *                      g_variant_iter_next_value               (GVariantIter         *iter);
+gboolean                        g_variant_iter_next                     (GVariantIter         *iter,
+                                                                         const gchar          *format_string,
+                                                                         ...);
+gboolean                        g_variant_iter_loop                     (GVariantIter         *iter,
+                                                                         const gchar          *format_string,
+                                                                         ...);
+
+
+typedef struct _GVariantBuilder GVariantBuilder;
+struct _GVariantBuilder {
+  /*< private >*/
+  gsize x[16];
+};
+
+typedef enum
+{
+  G_VARIANT_PARSE_ERROR_FAILED
+} GVariantParseError;
+#define G_VARIANT_PARSE_ERROR (g_variant_parser_get_error_quark ())
+
+GQuark                          g_variant_parser_get_error_quark        (void);
+
+GVariantBuilder *               g_variant_builder_new                   (const GVariantType   *type);
+void                            g_variant_builder_unref                 (GVariantBuilder      *builder);
+GVariantBuilder *               g_variant_builder_ref                   (GVariantBuilder      *builder);
+void                            g_variant_builder_init                  (GVariantBuilder      *builder,
+                                                                         const GVariantType   *type);
+GVariant *                      g_variant_builder_end                   (GVariantBuilder      *builder);
+void                            g_variant_builder_clear                 (GVariantBuilder      *builder);
+void                            g_variant_builder_open                  (GVariantBuilder      *builder,
+                                                                         const GVariantType   *type);
+void                            g_variant_builder_close                 (GVariantBuilder      *builder);
+void                            g_variant_builder_add_value             (GVariantBuilder      *builder,
+                                                                         GVariant             *value);
+void                            g_variant_builder_add                   (GVariantBuilder      *builder,
+                                                                         const gchar          *format_string,
+                                                                         ...);
+void                            g_variant_builder_add_parsed            (GVariantBuilder      *builder,
+                                                                         const gchar          *format,
+                                                                         ...);
+
+GVariant *                      g_variant_new                           (const gchar          *format_string,
+                                                                         ...);
+void                            g_variant_get                           (GVariant             *value,
+                                                                         const gchar          *format_string,
+                                                                         ...);
+GVariant *                      g_variant_new_va                        (const gchar          *format_string,
+                                                                         const gchar         **endptr,
+                                                                         va_list              *app);
+void                            g_variant_get_va                        (GVariant             *value,
+                                                                         const gchar          *format_string,
+                                                                         const gchar         **endptr,
+                                                                         va_list              *app);
+
+
+GVariant *                      g_variant_parse                         (const GVariantType   *type,
+                                                                         const gchar          *text,
+                                                                         const gchar          *limit,
+                                                                         const gchar         **endptr,
+                                                                         GError              **error);
+GVariant *                      g_variant_new_parsed                    (const gchar          *format,
+                                                                         ...);
+GVariant *                      g_variant_new_parsed_va                 (const gchar          *format,
+                                                                         va_list              *app);
+
+gint                            g_variant_compare                       (gconstpointer one,
+                                                                         gconstpointer two);
+G_END_DECLS
+
+#endif /* __G_VARIANT_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gvarianttype.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gvarianttype.c
new file mode 100644 (file)
index 0000000..b33d60e
--- /dev/null
@@ -0,0 +1,1490 @@
+/*
+ * Copyright © 2007, 2008 Ryan Lortie
+ * Copyright © 2009, 2010 Codethink Limited
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gvarianttype.h"
+
+#include <glib/gtestutils.h>
+#include <glib/gstrfuncs.h>
+
+#include <string.h>
+
+
+/**
+ * SECTION: gvarianttype
+ * @title: GVariantType
+ * @short_description: introduction to the GVariant type system
+ * @see_also: #GVariantType, #GVariant
+ *
+ * This section introduces the GVariant type system.  It is based, in
+ * large part, on the DBus type system, with two major changes and some minor
+ * lifting of restrictions.  The <ulink
+ * url='http://dbus.freedesktop.org/doc/dbus-specification.html'>DBus
+ * specification</ulink>, therefore, provides a significant amount of
+ * information that is useful when working with GVariant.
+ *
+ * The first major change with respect to the DBus type system is the
+ * introduction of maybe (or "nullable") types.  Any type in GVariant can be
+ * converted to a maybe type, in which case, "nothing" (or "null") becomes a
+ * valid value.  Maybe types have been added by introducing the
+ * character "<literal>m</literal>" to type strings.
+ *
+ * The second major change is that the GVariant type system supports the
+ * concept of "indefinite types" -- types that are less specific than
+ * the normal types found in DBus.  For example, it is possible to speak
+ * of "an array of any type" in GVariant, where the DBus type system
+ * would require you to speak of "an array of integers" or "an array of
+ * strings".  Indefinite types have been added by introducing the
+ * characters "<literal>*</literal>", "<literal>?</literal>" and
+ * "<literal>r</literal>" to type strings.
+ *
+ * Finally, all arbitrary restrictions relating to the complexity of
+ * types are lifted along with the restriction that dictionary entries
+ * may only appear nested inside of arrays.
+ *
+ * Just as in DBus, GVariant types are described with strings ("type
+ * strings").  Subject to the differences mentioned above, these strings
+ * are of the same form as those found in DBus.  Note, however: DBus
+ * always works in terms of messages and therefore individual type
+ * strings appear nowhere in its interface.  Instead, "signatures"
+ * are a concatenation of the strings of the type of each argument in a
+ * message.  GVariant deals with single values directly so GVariant type
+ * strings always describe the type of exactly one value.  This means
+ * that a DBus signature string is generally not a valid GVariant type
+ * string -- except in the case that it is the signature of a message
+ * containing exactly one argument.
+ *
+ * An indefinite type is similar in spirit to what may be called an
+ * abstract type in other type systems.  No value can exist that has an
+ * indefinite type as its type, but values can exist that have types
+ * that are subtypes of indefinite types.  That is to say,
+ * g_variant_get_type() will never return an indefinite type, but
+ * calling g_variant_is_a() with an indefinite type may return %TRUE.
+ * For example, you can not have a value that represents "an array of no
+ * particular type", but you can have an "array of integers" which
+ * certainly matches the type of "an array of no particular type", since
+ * "array of integers" is a subtype of "array of no particular type".
+ *
+ * This is similar to how instances of abstract classes may not
+ * directly exist in other type systems, but instances of their
+ * non-abstract subtypes may.  For example, in GTK, no object that has
+ * the type of #GtkBin can exist (since #GtkBin is an abstract class),
+ * but a #GtkWindow can certainly be instantiated, and you would say
+ * that the #GtkWindow is a #GtkBin (since #GtkWindow is a subclass of
+ * #GtkBin).
+ *
+ * A detailed description of GVariant type strings is given here:
+ *
+ * <refsect2 id='gvariant-typestrings'>
+ *  <title>GVariant Type Strings</title>
+ *  <para>
+ *   A GVariant type string can be any of the following:
+ *  </para>
+ *  <itemizedlist>
+ *   <listitem>
+ *    <para>
+ *     any basic type string (listed below)
+ *    </para>
+ *   </listitem>
+ *   <listitem>
+ *    <para>
+ *     "<literal>v</literal>", "<literal>r</literal>" or
+ *     "<literal>*</literal>"
+ *    </para>
+ *   </listitem>
+ *   <listitem>
+ *    <para>
+ *     one of the characters '<literal>a</literal>' or
+ *     '<literal>m</literal>', followed by another type string
+ *    </para>
+ *   </listitem>
+ *   <listitem>
+ *    <para>
+ *     the character '<literal>(</literal>', followed by a concatenation
+ *     of zero or more other type strings, followed by the character
+ *     '<literal>)</literal>'
+ *    </para>
+ *   </listitem>
+ *   <listitem>
+ *    <para>
+ *     the character '<literal>{</literal>', followed by a basic type
+ *     string (see below), followed by another type string, followed by
+ *     the character '<literal>}</literal>'
+ *    </para>
+ *   </listitem>
+ *  </itemizedlist>
+ *  <para>
+ *   A basic type string describes a basic type (as per
+ *   g_variant_type_is_basic()) and is always a single
+ *   character in length.  The valid basic type strings are
+ *   "<literal>b</literal>", "<literal>y</literal>",
+ *   "<literal>n</literal>", "<literal>q</literal>",
+ *   "<literal>i</literal>", "<literal>u</literal>",
+ *   "<literal>x</literal>", "<literal>t</literal>",
+ *   "<literal>h</literal>", "<literal>d</literal>",
+ *   "<literal>s</literal>", "<literal>o</literal>",
+ *   "<literal>g</literal>" and "<literal>?</literal>".
+ *  </para>
+ *  <para>
+ *   The above definition is recursive to arbitrary depth.
+ *   "<literal>aaaaai</literal>" and "<literal>(ui(nq((y)))s)</literal>"
+ *   are both valid type strings, as is
+ *   "<literal>a(aa(ui)(qna{ya(yd)}))</literal>".
+ *  </para>
+ *  <para>
+ *   The meaning of each of the characters is as follows:
+ *  </para>
+ *  <informaltable>
+ *   <tgroup cols='2'>
+ *    <tbody>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <emphasis role='strong'>Character</emphasis>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        <emphasis role='strong'>Meaning</emphasis>
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>b</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_BOOLEAN; a boolean value.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>y</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_BYTE; a byte.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>n</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_INT16; a signed 16 bit
+ *        integer.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>q</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_UINT16; an unsigned 16 bit
+ *        integer.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>i</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_INT32; a signed 32 bit
+ *        integer.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>u</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_UINT32; an unsigned 32 bit
+ *        integer.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>x</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_INT64; a signed 64 bit
+ *        integer.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>t</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_UINT64; an unsigned 64 bit
+ *        integer.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>h</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_HANDLE; a signed 32 bit
+ *        value that, by convention, is used as an index into an array
+ *        of file descriptors that are sent alongside a DBus message.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>d</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_DOUBLE; a double precision
+ *        floating point value.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>s</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_STRING; a string.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>o</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_OBJECT_PATH; a string in
+ *        the form of a DBus object path.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>g</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_STRING; a string in the
+ *        form of a DBus type signature.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>?</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_BASIC; an indefinite type
+ *        that is a supertype of any of the basic types.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>v</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_VARIANT; a container type
+ *        that contain any other type of value.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>a</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        used as a prefix on another type string to mean an array of
+ *        that type; the type string "<literal>ai</literal>", for
+ *        example, is the type of an array of 32 bit signed integers.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>m</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        used as a prefix on another type string to mean a "maybe", or
+ *        "nullable", version of that type; the type string
+ *        "<literal>ms</literal>", for example, is the type of a value
+ *        that maybe contains a string, or maybe contains nothing.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>()</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        used to enclose zero or more other concatenated type strings
+ *        to create a tuple type; the type string
+ *        "<literal>(is)</literal>", for example, is the type of a pair
+ *        of an integer and a string.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>r</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_TUPLE; an indefinite type
+ *        that is a supertype of any tuple type, regardless of the
+ *        number of items.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>{}</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        used to enclose a basic type string concatenated with another
+ *        type string to create a dictionary entry type, which usually
+ *        appears inside of an array to form a dictionary; the type
+ *        string "<literal>a{sd}</literal>", for example, is the type of
+ *        a dictionary that maps strings to double precision floating
+ *        point values.
+ *       </para>
+ *       <para>
+ *        The first type (the basic type) is the key type and the second
+ *        type is the value type.  The reason that the first type is
+ *        restricted to being a basic type is so that it can easily be
+ *        hashed.
+ *       </para>
+ *      </entry>
+ *     </row>
+ *     <row>
+ *      <entry>
+ *       <para>
+ *        <literal>*</literal>
+ *       </para>
+ *      </entry>
+ *      <entry>
+ *       <para>
+ *        the type string of %G_VARIANT_TYPE_ANY; the indefinite type
+ *        that is a supertype of all types.  Note that, as with all type
+ *        strings, this character represents exactly one type.  It
+ *        cannot be used inside of tuples to mean "any number of items".
+ *       </para>
+ *      </entry>
+ *     </row>
+ *    </tbody>
+ *   </tgroup>
+ *  </informaltable>
+ *  <para>
+ *   Any type string of a container that contains an indefinite type is,
+ *   itself, an indefinite type.  For example, the type string
+ *   "<literal>a*</literal>" (corresponding to %G_VARIANT_TYPE_ARRAY) is
+ *   an indefinite type that is a supertype of every array type.
+ *   "<literal>(*s)</literal>" is a supertype of all tuples that
+ *   contain exactly two items where the second item is a string.
+ *  </para>
+ *  <para>
+ *   "<literal>a{?*}</literal>" is an indefinite type that is a
+ *   supertype of all arrays containing dictionary entries where the key
+ *   is any basic type and the value is any type at all.  This is, by
+ *   definition, a dictionary, so this type string corresponds to
+ *   %G_VARIANT_TYPE_DICTIONARY.  Note that, due to the restriction that
+ *   the key of a dictionary entry must be a basic type,
+ *   "<literal>{**}</literal>" is not a valid type string.
+ *  </para>
+ * </refsect2>
+ */
+
+
+static gboolean
+g_variant_type_check (const GVariantType *type)
+{
+  const gchar *type_string;
+
+  if (type == NULL)
+    return FALSE;
+
+  type_string = (const gchar *) type;
+#ifndef G_DISABLE_CHECKS
+  return g_variant_type_string_scan (type_string, NULL, NULL);
+#else
+  return TRUE;
+#endif
+}
+
+/**
+ * g_variant_type_string_scan:
+ * @string: a pointer to any string
+ * @limit: the end of @string, or %NULL
+ * @endptr: location to store the end pointer, or %NULL
+ * @returns: %TRUE if a valid type string was found
+ *
+ * Scan for a single complete and valid GVariant type string in @string.
+ * The memory pointed to by @limit (or bytes beyond it) is never
+ * accessed.
+ *
+ * If a valid type string is found, @endptr is updated to point to the
+ * first character past the end of the string that was found and %TRUE
+ * is returned.
+ *
+ * If there is no valid type string starting at @string, or if the type
+ * string does not end before @limit then %FALSE is returned.
+ *
+ * For the simple case of checking if a string is a valid type string,
+ * see g_variant_type_string_is_valid().
+ *
+ * Since: 2.24
+ **/
+gboolean
+g_variant_type_string_scan (const gchar  *string,
+                            const gchar  *limit,
+                            const gchar **endptr)
+{
+  g_return_val_if_fail (string != NULL, FALSE);
+
+  if (string == limit || *string == '\0')
+    return FALSE;
+
+  switch (*string++)
+    {
+    case '(':
+      while (string == limit || *string != ')')
+        if (!g_variant_type_string_scan (string, limit, &string))
+          return FALSE;
+
+      string++;
+      break;
+
+    case '{':
+      if (string == limit || *string == '\0' ||                    /* { */
+          !strchr ("bynqihuxtdsog?", *string++) ||                 /* key */
+          !g_variant_type_string_scan (string, limit, &string) ||  /* value */
+          string == limit || *string++ != '}')                     /* } */
+        return FALSE;
+
+      break;
+
+    case 'm': case 'a':
+      return g_variant_type_string_scan (string, limit, endptr);
+
+    case 'b': case 'y': case 'n': case 'q': case 'i': case 'u':
+    case 'x': case 't': case 'd': case 's': case 'o': case 'g':
+    case 'v': case 'r': case '*': case '?': case 'h':
+      break;
+
+    default:
+      return FALSE;
+    }
+
+  if (endptr != NULL)
+    *endptr = string;
+
+  return TRUE;
+}
+
+/**
+ * g_variant_type_string_is_valid:
+ * @type_string: a pointer to any string
+ * @returns: %TRUE if @type_string is exactly one valid type string
+ *
+ * Checks if @type_string is a valid GVariant type string.  This call is
+ * equivalent to calling g_variant_type_string_scan() and confirming
+ * that the following character is a nul terminator.
+ *
+ * Since 2.24
+ **/
+gboolean
+g_variant_type_string_is_valid (const gchar *type_string)
+{
+  const gchar *endptr;
+
+  g_return_val_if_fail (type_string != NULL, FALSE);
+
+  if (!g_variant_type_string_scan (type_string, NULL, &endptr))
+    return FALSE;
+
+  return *endptr == '\0';
+}
+
+/**
+ * g_variant_type_free:
+ * @type: a #GVariantType, or %NULL
+ *
+ * Frees a #GVariantType that was allocated with
+ * g_variant_type_copy(), g_variant_type_new() or one of the container
+ * type constructor functions.
+ *
+ * In the case that @type is %NULL, this function does nothing.
+ *
+ * Since 2.24
+ **/
+void
+g_variant_type_free (GVariantType *type)
+{
+  g_return_if_fail (type == NULL || g_variant_type_check (type));
+
+  g_free (type);
+}
+
+/**
+ * g_variant_type_copy:
+ * @type: a #GVariantType
+ * @returns: a new #GVariantType
+ *
+ * Makes a copy of a #GVariantType.  It is appropriate to call
+ * g_variant_type_free() on the return value.  @type may not be %NULL.
+ *
+ * Since 2.24
+ **/
+GVariantType *
+g_variant_type_copy (const GVariantType *type)
+{
+  gsize length;
+  gchar *new;
+
+  g_return_val_if_fail (g_variant_type_check (type), NULL);
+
+  length = g_variant_type_get_string_length (type);
+  new = g_malloc (length + 1);
+
+  memcpy (new, type, length);
+  new[length] = '\0';
+
+  return (GVariantType *) new;
+}
+
+/**
+ * g_variant_type_new:
+ * @type_string: a valid GVariant type string
+ * @returns: a new #GVariantType
+ *
+ * Creates a new #GVariantType corresponding to the type string given
+ * by @type_string.  It is appropriate to call g_variant_type_free() on
+ * the return value.
+ *
+ * It is a programmer error to call this function with an invalid type
+ * string.  Use g_variant_type_string_is_valid() if you are unsure.
+ *
+ * Since: 2.24
+ */
+GVariantType *
+g_variant_type_new (const gchar *type_string)
+{
+  g_return_val_if_fail (type_string != NULL, NULL);
+
+  return g_variant_type_copy (G_VARIANT_TYPE (type_string));
+}
+
+/**
+ * g_variant_type_get_string_length:
+ * @type: a #GVariantType
+ * @returns: the length of the corresponding type string
+ *
+ * Returns the length of the type string corresponding to the given
+ * @type.  This function must be used to determine the valid extent of
+ * the memory region returned by g_variant_type_peek_string().
+ *
+ * Since 2.24
+ **/
+gsize
+g_variant_type_get_string_length (const GVariantType *type)
+{
+  const gchar *type_string = (const gchar *) type;
+  gint brackets = 0;
+  gsize index = 0;
+
+  g_return_val_if_fail (g_variant_type_check (type), 0);
+
+  do
+    {
+      while (type_string[index] == 'a' || type_string[index] == 'm')
+        index++;
+
+      if (type_string[index] == '(' || type_string[index] == '{')
+        brackets++;
+
+      else if (type_string[index] == ')' || type_string[index] == '}')
+        brackets--;
+
+      index++;
+    }
+  while (brackets);
+
+  return index;
+}
+
+/**
+ * g_variant_type_peek_string:
+ * @type: a #GVariantType
+ * @returns: the corresponding type string (not nul-terminated)
+ *
+ * Returns the type string corresponding to the given @type.  The
+ * result is not nul-terminated; in order to determine its length you
+ * must call g_variant_type_get_string_length().
+ *
+ * To get a nul-terminated string, see g_variant_type_dup_string().
+ *
+ * Since 2.24
+ **/
+const gchar *
+g_variant_type_peek_string (const GVariantType *type)
+{
+  g_return_val_if_fail (g_variant_type_check (type), NULL);
+
+  return (const gchar *) type;
+}
+
+/**
+ * g_variant_type_dup_string:
+ * @type: a #GVariantType
+ * @returns: the corresponding type string
+ *
+ * Returns a newly-allocated copy of the type string corresponding to
+ * @type.  The returned string is nul-terminated.  It is appropriate to
+ * call g_free() on the return value.
+ *
+ * Since 2.24
+ **/
+gchar *
+g_variant_type_dup_string (const GVariantType *type)
+{
+  g_return_val_if_fail (g_variant_type_check (type), NULL);
+
+  return g_strndup (g_variant_type_peek_string (type),
+                    g_variant_type_get_string_length (type));
+}
+
+/**
+ * g_variant_type_is_definite:
+ * @type: a #GVariantType
+ * @returns: %TRUE if @type is definite
+ *
+ * Determines if the given @type is definite (ie: not indefinite).
+ *
+ * A type is definite if its type string does not contain any indefinite
+ * type characters ('*', '?', or 'r').
+ *
+ * A #GVariant instance may not have an indefinite type, so calling
+ * this function on the result of g_variant_get_type() will always
+ * result in %TRUE being returned.  Calling this function on an
+ * indefinite type like %G_VARIANT_TYPE_ARRAY, however, will result in
+ * %FALSE being returned.
+ *
+ * Since 2.24
+ **/
+gboolean
+g_variant_type_is_definite (const GVariantType *type)
+{
+  const gchar *type_string;
+  gsize type_length;
+  gsize i;
+
+  g_return_val_if_fail (g_variant_type_check (type), FALSE);
+
+  type_length = g_variant_type_get_string_length (type);
+  type_string = g_variant_type_peek_string (type);
+
+  for (i = 0; i < type_length; i++)
+    if (type_string[i] == '*' ||
+        type_string[i] == '?' ||
+        type_string[i] == 'r')
+      return FALSE;
+
+  return TRUE;
+}
+
+/**
+ * g_variant_type_is_container:
+ * @type: a #GVariantType
+ * @returns: %TRUE if @type is a container type
+ *
+ * Determines if the given @type is a container type.
+ *
+ * Container types are any array, maybe, tuple, or dictionary
+ * entry types plus the variant type.
+ *
+ * This function returns %TRUE for any indefinite type for which every
+ * definite subtype is a container -- %G_VARIANT_TYPE_ARRAY, for
+ * example.
+ *
+ * Since 2.24
+ **/
+gboolean
+g_variant_type_is_container (const GVariantType *type)
+{
+  gchar first_char;
+
+  g_return_val_if_fail (g_variant_type_check (type), FALSE);
+
+  first_char = g_variant_type_peek_string (type)[0];
+  switch (first_char)
+  {
+    case 'a':
+    case 'm':
+    case 'r':
+    case '(':
+    case '{':
+    case 'v':
+      return TRUE;
+
+    default:
+      return FALSE;
+  }
+}
+
+/**
+ * g_variant_type_is_basic:
+ * @type: a #GVariantType
+ * @returns: %TRUE if @type is a basic type
+ *
+ * Determines if the given @type is a basic type.
+ *
+ * Basic types are booleans, bytes, integers, doubles, strings, object
+ * paths and signatures.
+ *
+ * Only a basic type may be used as the key of a dictionary entry.
+ *
+ * This function returns %FALSE for all indefinite types except
+ * %G_VARIANT_TYPE_BASIC.
+ *
+ * Since 2.24
+ **/
+gboolean
+g_variant_type_is_basic (const GVariantType *type)
+{
+  gchar first_char;
+
+  g_return_val_if_fail (g_variant_type_check (type), FALSE);
+
+  first_char = g_variant_type_peek_string (type)[0];
+  switch (first_char)
+  {
+    case 'b':
+    case 'y':
+    case 'n':
+    case 'q':
+    case 'i':
+    case 'h':
+    case 'u':
+    case 't':
+    case 'x':
+    case 'd':
+    case 's':
+    case 'o':
+    case 'g':
+    case '?':
+      return TRUE;
+
+    default:
+      return FALSE;
+  }
+}
+
+/**
+ * g_variant_type_is_maybe:
+ * @type: a #GVariantType
+ * @returns: %TRUE if @type is a maybe type
+ *
+ * Determines if the given @type is a maybe type.  This is true if the
+ * type string for @type starts with an 'm'.
+ *
+ * This function returns %TRUE for any indefinite type for which every
+ * definite subtype is a maybe type -- %G_VARIANT_TYPE_MAYBE, for
+ * example.
+ *
+ * Since 2.24
+ **/
+gboolean
+g_variant_type_is_maybe (const GVariantType *type)
+{
+  g_return_val_if_fail (g_variant_type_check (type), FALSE);
+
+  return g_variant_type_peek_string (type)[0] == 'm';
+}
+
+/**
+ * g_variant_type_is_array:
+ * @type: a #GVariantType
+ * @returns: %TRUE if @type is an array type
+ *
+ * Determines if the given @type is an array type.  This is true if the
+ * type string for @type starts with an 'a'.
+ *
+ * This function returns %TRUE for any indefinite type for which every
+ * definite subtype is an array type -- %G_VARIANT_TYPE_ARRAY, for
+ * example.
+ *
+ * Since 2.24
+ **/
+gboolean
+g_variant_type_is_array (const GVariantType *type)
+{
+  g_return_val_if_fail (g_variant_type_check (type), FALSE);
+
+  return g_variant_type_peek_string (type)[0] == 'a';
+}
+
+/**
+ * g_variant_type_is_tuple:
+ * @type: a #GVariantType
+ * @returns: %TRUE if @type is a tuple type
+ *
+ * Determines if the given @type is a tuple type.  This is true if the
+ * type string for @type starts with a '(' or if @type is
+ * %G_VARIANT_TYPE_TUPLE.
+ *
+ * This function returns %TRUE for any indefinite type for which every
+ * definite subtype is a tuple type -- %G_VARIANT_TYPE_TUPLE, for
+ * example.
+ *
+ * Since 2.24
+ **/
+gboolean
+g_variant_type_is_tuple (const GVariantType *type)
+{
+  gchar type_char;
+
+  g_return_val_if_fail (g_variant_type_check (type), FALSE);
+
+  type_char = g_variant_type_peek_string (type)[0];
+  return type_char == 'r' || type_char == '(';
+}
+
+/**
+ * g_variant_type_is_dict_entry:
+ * @type: a #GVariantType
+ * @returns: %TRUE if @type is a dictionary entry type
+ *
+ * Determines if the given @type is a dictionary entry type.  This is
+ * true if the type string for @type starts with a '{'.
+ *
+ * This function returns %TRUE for any indefinite type for which every
+ * definite subtype is a dictionary entry type --
+ * %G_VARIANT_TYPE_DICT_ENTRY, for example.
+ *
+ * Since 2.24
+ **/
+gboolean
+g_variant_type_is_dict_entry (const GVariantType *type)
+{
+  g_return_val_if_fail (g_variant_type_check (type), FALSE);
+
+  return g_variant_type_peek_string (type)[0] == '{';
+}
+
+/**
+ * g_variant_type_is_variant:
+ * @type: a #GVariantType
+ * @returns: %TRUE if @type is the variant type
+ *
+ * Determines if the given @type is the variant type.
+ *
+ * Since 2.24
+ **/
+gboolean
+g_variant_type_is_variant (const GVariantType *type)
+{
+  g_return_val_if_fail (g_variant_type_check (type), FALSE);
+
+  return g_variant_type_peek_string (type)[0] == 'v';
+}
+
+/**
+ * g_variant_type_hash:
+ * @type: a #GVariantType
+ * @returns: the hash value
+ *
+ * Hashes @type.
+ *
+ * The argument type of @type is only #gconstpointer to allow use with
+ * #GHashTable without function pointer casting.  A valid
+ * #GVariantType must be provided.
+ *
+ * Since 2.24
+ **/
+guint
+g_variant_type_hash (gconstpointer type)
+{
+  const gchar *type_string;
+  guint value = 0;
+  gsize length;
+  gsize i;
+
+  g_return_val_if_fail (g_variant_type_check (type), 0);
+
+  type_string = g_variant_type_peek_string (type);
+  length = g_variant_type_get_string_length (type);
+
+  for (i = 0; i < length; i++)
+    value = (value << 5) - value + type_string[i];
+
+  return value;
+}
+
+/**
+ * g_variant_type_equal:
+ * @type1: a #GVariantType
+ * @type2: a #GVariantType
+ * @returns: %TRUE if @type1 and @type2 are exactly equal
+ *
+ * Compares @type1 and @type2 for equality.
+ *
+ * Only returns %TRUE if the types are exactly equal.  Even if one type
+ * is an indefinite type and the other is a subtype of it, %FALSE will
+ * be returned if they are not exactly equal.  If you want to check for
+ * subtypes, use g_variant_type_is_subtype_of().
+ *
+ * The argument types of @type1 and @type2 are only #gconstpointer to
+ * allow use with #GHashTable without function pointer casting.  For
+ * both arguments, a valid #GVariantType must be provided.
+ *
+ * Since 2.24
+ **/
+gboolean
+g_variant_type_equal (gconstpointer type1,
+                      gconstpointer type2)
+{
+  const gchar *string1, *string2;
+  gsize size1, size2;
+
+  g_return_val_if_fail (g_variant_type_check (type1), FALSE);
+  g_return_val_if_fail (g_variant_type_check (type2), FALSE);
+
+  if (type1 == type2)
+    return TRUE;
+
+  size1 = g_variant_type_get_string_length (type1);
+  size2 = g_variant_type_get_string_length (type2);
+
+  if (size1 != size2)
+    return FALSE;
+
+  string1 = g_variant_type_peek_string (type1);
+  string2 = g_variant_type_peek_string (type2);
+
+  return memcmp (string1, string2, size1) == 0;
+}
+
+/**
+ * g_variant_type_is_subtype_of:
+ * @type: a #GVariantType
+ * @supertype: a #GVariantType
+ * @returns: %TRUE if @type is a subtype of @supertype
+ *
+ * Checks if @type is a subtype of @supertype.
+ *
+ * This function returns %TRUE if @type is a subtype of @supertype.  All
+ * types are considered to be subtypes of themselves.  Aside from that,
+ * only indefinite types can have subtypes.
+ *
+ * Since 2.24
+ **/
+gboolean
+g_variant_type_is_subtype_of (const GVariantType *type,
+                              const GVariantType *supertype)
+{
+  const gchar *supertype_string;
+  const gchar *supertype_end;
+  const gchar *type_string;
+
+  g_return_val_if_fail (g_variant_type_check (type), FALSE);
+  g_return_val_if_fail (g_variant_type_check (supertype), FALSE);
+
+  supertype_string = g_variant_type_peek_string (supertype);
+  type_string = g_variant_type_peek_string (type);
+
+  supertype_end = supertype_string +
+                  g_variant_type_get_string_length (supertype);
+
+  /* we know that type and supertype are both well-formed, so it's
+   * safe to treat this merely as a text processing problem.
+   */
+  while (supertype_string < supertype_end)
+    {
+      char supertype_char = *supertype_string++;
+
+      if (supertype_char == *type_string)
+        type_string++;
+
+      else if (*type_string == ')')
+        return FALSE;
+
+      else
+        {
+          const GVariantType *target_type = (GVariantType *) type_string;
+
+          switch (supertype_char)
+            {
+            case 'r':
+              if (!g_variant_type_is_tuple (target_type))
+                return FALSE;
+              break;
+
+            case '*':
+              break;
+
+            case '?':
+              if (!g_variant_type_is_basic (target_type))
+                return FALSE;
+              break;
+
+            default:
+              return FALSE;
+            }
+
+          type_string += g_variant_type_get_string_length (target_type);
+        }
+    }
+
+  return TRUE;
+}
+
+/**
+ * g_variant_type_element:
+ * @type: an array or maybe #GVariantType
+ * @returns: the element type of @type
+ *
+ * Determines the element type of an array or maybe type.
+ *
+ * This function may only be used with array or maybe types.
+ *
+ * Since 2.24
+ **/
+const GVariantType *
+g_variant_type_element (const GVariantType *type)
+{
+  const gchar *type_string;
+
+  g_return_val_if_fail (g_variant_type_check (type), NULL);
+
+  type_string = g_variant_type_peek_string (type);
+
+  g_assert (type_string[0] == 'a' || type_string[0] == 'm');
+
+  return (const GVariantType *) &type_string[1];
+}
+
+/**
+ * g_variant_type_first:
+ * @type: a tuple or dictionary entry #GVariantType
+ * @returns: the first item type of @type, or %NULL
+ *
+ * Determines the first item type of a tuple or dictionary entry
+ * type.
+ *
+ * This function may only be used with tuple or dictionary entry types,
+ * but must not be used with the generic tuple type
+ * %G_VARIANT_TYPE_TUPLE.
+ *
+ * In the case of a dictionary entry type, this returns the type of
+ * the key.
+ *
+ * %NULL is returned in case of @type being %G_VARIANT_TYPE_UNIT.
+ *
+ * This call, together with g_variant_type_next() provides an iterator
+ * interface over tuple and dictionary entry types.
+ *
+ * Since 2.24
+ **/
+const GVariantType *
+g_variant_type_first (const GVariantType *type)
+{
+  const gchar *type_string;
+
+  g_return_val_if_fail (g_variant_type_check (type), NULL);
+
+  type_string = g_variant_type_peek_string (type);
+  g_assert (type_string[0] == '(' || type_string[0] == '{');
+
+  if (type_string[1] == ')')
+    return NULL;
+
+  return (const GVariantType *) &type_string[1];
+}
+
+/**
+ * g_variant_type_next:
+ * @type: a #GVariantType from a previous call
+ * @returns: the next #GVariantType after @type, or %NULL
+ *
+ * Determines the next item type of a tuple or dictionary entry
+ * type.
+ *
+ * @type must be the result of a previous call to
+ * g_variant_type_first() or g_variant_type_next().
+ *
+ * If called on the key type of a dictionary entry then this call
+ * returns the value type.  If called on the value type of a dictionary
+ * entry then this call returns %NULL.
+ *
+ * For tuples, %NULL is returned when @type is the last item in a tuple.
+ *
+ * Since 2.24
+ **/
+const GVariantType *
+g_variant_type_next (const GVariantType *type)
+{
+  const gchar *type_string;
+
+  g_return_val_if_fail (g_variant_type_check (type), NULL);
+
+  type_string = g_variant_type_peek_string (type);
+  type_string += g_variant_type_get_string_length (type);
+
+  if (*type_string == ')' || *type_string == '}')
+    return NULL;
+
+  return (const GVariantType *) type_string;
+}
+
+/**
+ * g_variant_type_n_items:
+ * @type: a tuple or dictionary entry #GVariantType
+ * @returns: the number of items in @type
+ *
+ * Determines the number of items contained in a tuple or
+ * dictionary entry type.
+ *
+ * This function may only be used with tuple or dictionary entry types,
+ * but must not be used with the generic tuple type
+ * %G_VARIANT_TYPE_TUPLE.
+ *
+ * In the case of a dictionary entry type, this function will always
+ * return 2.
+ *
+ * Since 2.24
+ **/
+gsize
+g_variant_type_n_items (const GVariantType *type)
+{
+  gsize count = 0;
+
+  g_return_val_if_fail (g_variant_type_check (type), 0);
+
+  for (type = g_variant_type_first (type);
+       type;
+       type = g_variant_type_next (type))
+    count++;
+
+  return count;
+}
+
+/**
+ * g_variant_type_key:
+ * @type: a dictionary entry #GVariantType
+ * @returns: the key type of the dictionary entry
+ *
+ * Determines the key type of a dictionary entry type.
+ *
+ * This function may only be used with a dictionary entry type.  Other
+ * than the additional restriction, this call is equivalent to
+ * g_variant_type_first().
+ *
+ * Since 2.24
+ **/
+const GVariantType *
+g_variant_type_key (const GVariantType *type)
+{
+  const gchar *type_string;
+
+  g_return_val_if_fail (g_variant_type_check (type), NULL);
+
+  type_string = g_variant_type_peek_string (type);
+  g_assert (type_string[0] == '{');
+
+  return (const GVariantType *) &type_string[1];
+}
+
+/**
+ * g_variant_type_value:
+ * @type: a dictionary entry #GVariantType
+ * @returns: the value type of the dictionary entry
+ *
+ * Determines the value type of a dictionary entry type.
+ *
+ * This function may only be used with a dictionary entry type.
+ *
+ * Since 2.24
+ **/
+const GVariantType *
+g_variant_type_value (const GVariantType *type)
+{
+  const gchar *type_string;
+
+  g_return_val_if_fail (g_variant_type_check (type), NULL);
+
+  type_string = g_variant_type_peek_string (type);
+  g_assert (type_string[0] == '{');
+
+  return g_variant_type_next (g_variant_type_key (type));
+}
+
+/**
+ * g_variant_type_new_tuple:
+ * @items: an array of #GVariantTypes, one for each item
+ * @length: the length of @items, or -1
+ * @returns: a new tuple #GVariantType
+ *
+ * Constructs a new tuple type, from @items.
+ *
+ * @length is the number of items in @items, or -1 to indicate that
+ * @items is %NULL-terminated.
+ *
+ * It is appropriate to call g_variant_type_free() on the return value.
+ *
+ * Since 2.24
+ **/
+static GVariantType *
+g_variant_type_new_tuple_slow (const GVariantType * const *items,
+                               gint                        length)
+{
+  /* the "slow" version is needed in case the static buffer of 1024
+   * bytes is exceeded when running the normal version.  this will
+   * happen only in truly insane code, so it can be slow.
+   */
+  GString *string;
+  gsize i;
+
+  string = g_string_new ("(");
+  for (i = 0; i < length; i++)
+    {
+      const GVariantType *type;
+      gsize size;
+
+      g_return_val_if_fail (g_variant_type_check (items[i]), NULL);
+
+      type = items[i];
+      size = g_variant_type_get_string_length (type);
+      g_string_append_len (string, (const gchar *) type, size);
+    }
+  g_string_append_c (string, ')');
+
+  return (GVariantType *) g_string_free (string, FALSE);
+}
+
+GVariantType *
+g_variant_type_new_tuple (const GVariantType * const *items,
+                          gint                        length)
+{
+  char buffer[1024];
+  gsize offset;
+  gsize i;
+
+  g_return_val_if_fail (length == 0 || items != NULL, NULL);
+
+  if (length < 0)
+    for (length = 0; items[length] != NULL; length++);
+
+  offset = 0;
+  buffer[offset++] = '(';
+
+  for (i = 0; i < length; i++)
+    {
+      const GVariantType *type;
+      gsize size;
+
+      g_return_val_if_fail (g_variant_type_check (items[i]), NULL);
+
+      type = items[i];
+      size = g_variant_type_get_string_length (type);
+
+      if (offset + size >= sizeof buffer) /* leave room for ')' */
+        return g_variant_type_new_tuple_slow (items, length);
+
+      memcpy (&buffer[offset], type, size);
+      offset += size;
+    }
+
+  g_assert (offset < sizeof buffer);
+  buffer[offset++] = ')';
+
+  return (GVariantType *) g_memdup (buffer, offset);
+}
+
+/**
+ * g_variant_type_new_array:
+ * @element: a #GVariantType
+ * @returns: a new array #GVariantType
+ *
+ * Constructs the type corresponding to an array of elements of the
+ * type @type.
+ *
+ * It is appropriate to call g_variant_type_free() on the return value.
+ *
+ * Since 2.24
+ **/
+GVariantType *
+g_variant_type_new_array (const GVariantType *element)
+{
+  gsize size;
+  gchar *new;
+
+  g_return_val_if_fail (g_variant_type_check (element), NULL);
+
+  size = g_variant_type_get_string_length (element);
+  new = g_malloc (size + 1);
+
+  new[0] = 'a';
+  memcpy (new + 1, element, size);
+
+  return (GVariantType *) new;
+}
+
+/**
+ * g_variant_type_new_maybe:
+ * @element: a #GVariantType
+ * @returns: a new maybe #GVariantType
+ *
+ * Constructs the type corresponding to a maybe instance containing
+ * type @type or Nothing.
+ *
+ * It is appropriate to call g_variant_type_free() on the return value.
+ *
+ * Since 2.24
+ **/
+GVariantType *
+g_variant_type_new_maybe (const GVariantType *element)
+{
+  gsize size;
+  gchar *new;
+
+  g_return_val_if_fail (g_variant_type_check (element), NULL);
+
+  size = g_variant_type_get_string_length (element);
+  new = g_malloc (size + 1);
+
+  new[0] = 'm';
+  memcpy (new + 1, element, size);
+
+  return (GVariantType *) new;
+}
+
+/**
+ * g_variant_type_new_dict_entry:
+ * @key: a basic #GVariantType
+ * @value: a #GVariantType
+ * @returns: a new dictionary entry #GVariantType
+ *
+ * Constructs the type corresponding to a dictionary entry with a key
+ * of type @key and a value of type @value.
+ *
+ * It is appropriate to call g_variant_type_free() on the return value.
+ *
+ * Since 2.24
+ **/
+GVariantType *
+g_variant_type_new_dict_entry (const GVariantType *key,
+                               const GVariantType *value)
+{
+  gsize keysize, valsize;
+  gchar *new;
+
+  g_return_val_if_fail (g_variant_type_check (key), NULL);
+  g_return_val_if_fail (g_variant_type_check (value), NULL);
+
+  keysize = g_variant_type_get_string_length (key);
+  valsize = g_variant_type_get_string_length (value);
+
+  new = g_malloc (1 + keysize + valsize + 1);
+
+  new[0] = '{';
+  memcpy (new + 1, key, keysize);
+  memcpy (new + 1 + keysize, value, valsize);
+  new[1 + keysize + valsize] = '}';
+
+  return (GVariantType *) new;
+}
+
+/* private */
+const GVariantType *
+g_variant_type_checked_ (const gchar *type_string)
+{
+  g_return_val_if_fail (g_variant_type_string_is_valid (type_string), NULL);
+  return (const GVariantType *) type_string;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gvarianttype.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gvarianttype.h
new file mode 100644 (file)
index 0000000..124fa46
--- /dev/null
@@ -0,0 +1,334 @@
+/*
+ * Copyright © 2007, 2008 Ryan Lortie
+ * Copyright © 2009, 2010 Codethink Limited
+ *
+ * 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 of the licence, 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_VARIANT_TYPE_H__
+#define __G_VARIANT_TYPE_H__
+
+#include <glib/gmessages.h>
+#include <glib/gtypes.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GVariantType:
+ *
+ * A type in the GVariant type system.
+ *
+ * Two types may not be compared by value; use g_variant_type_equal() or
+ * g_variant_type_is_subtype().  May be copied using
+ * g_variant_type_copy() and freed using g_variant_type_free().
+ **/
+typedef struct _GVariantType GVariantType;
+
+/**
+ * G_VARIANT_TYPE_BOOLEAN:
+ *
+ * The type of a value that can be either %TRUE or %FALSE.
+ **/
+#define G_VARIANT_TYPE_BOOLEAN              ((const GVariantType *) "b")
+
+/**
+ * G_VARIANT_TYPE_BYTE:
+ *
+ * The type of an integer value that can range from 0 to 255.
+ **/
+#define G_VARIANT_TYPE_BYTE                 ((const GVariantType *) "y")
+
+/**
+ * G_VARIANT_TYPE_INT16:
+ *
+ * The type of an integer value that can range from -32768 to 32767.
+ **/
+#define G_VARIANT_TYPE_INT16                ((const GVariantType *) "n")
+
+/**
+ * G_VARIANT_TYPE_UINT16:
+ *
+ * The type of an integer value that can range from 0 to 65535.
+ * There were about this many people living in Toronto in the 1870s.
+ **/
+#define G_VARIANT_TYPE_UINT16               ((const GVariantType *) "q")
+
+/**
+ * G_VARIANT_TYPE_INT32:
+ *
+ * The type of an integer value that can range from -2147483648 to
+ * 2147483647.
+ **/
+#define G_VARIANT_TYPE_INT32                ((const GVariantType *) "i")
+
+/**
+ * G_VARIANT_TYPE_UINT32:
+ *
+ * The type of an integer value that can range from 0 to 4294967295.
+ * That's one number for everyone who was around in the late 1970s.
+ **/
+#define G_VARIANT_TYPE_UINT32               ((const GVariantType *) "u")
+
+/**
+ * G_VARIANT_TYPE_INT64:
+ *
+ * The type of an integer value that can range from
+ * -9223372036854775808 to 9223372036854775807.
+ **/
+#define G_VARIANT_TYPE_INT64                ((const GVariantType *) "x")
+
+/**
+ * G_VARIANT_TYPE_UINT64:
+ *
+ * The type of an integer value that can range from 0 to
+ * 18446744073709551616.  That's a really big number, but a Rubik's
+ * cube can have a bit more than twice as many possible positions.
+ **/
+#define G_VARIANT_TYPE_UINT64               ((const GVariantType *) "t")
+
+/**
+ * G_VARIANT_TYPE_DOUBLE:
+ *
+ * The type of a double precision IEEE754 floating point number.
+ * These guys go up to about 1.80e308 (plus and minus) but miss out on
+ * some numbers in between.  In any case, that's far greater than the
+ * estimated number of fundamental particles in the observable
+ * universe.
+ **/
+#define G_VARIANT_TYPE_DOUBLE               ((const GVariantType *) "d")
+
+/**
+ * G_VARIANT_TYPE_STRING:
+ *
+ * The type of a string.  "" is a string.  %NULL is not a string.
+ **/
+#define G_VARIANT_TYPE_STRING               ((const GVariantType *) "s")
+
+/**
+ * G_VARIANT_TYPE_OBJECT_PATH:
+ *
+ * The type of a DBus object reference.  These are strings of a
+ * specific format used to identify objects at a given destination on
+ * the bus.
+ *
+ * If you are not interacting with DBus, then there is no reason to make
+ * use of this type.  If you are, then the DBus specification contains a
+ * precise description of valid object paths.
+ **/
+#define G_VARIANT_TYPE_OBJECT_PATH          ((const GVariantType *) "o")
+
+/**
+ * G_VARIANT_TYPE_SIGNATURE:
+ *
+ * The type of a DBus type signature.  These are strings of a specific
+ * format used as type signatures for DBus methods and messages.
+ *
+ * If you are not interacting with DBus, then there is no reason to make
+ * use of this type.  If you are, then the DBus specification contains a
+ * precise description of valid signature strings.
+ **/
+#define G_VARIANT_TYPE_SIGNATURE            ((const GVariantType *) "g")
+
+/**
+ * G_VARIANT_TYPE_VARIANT:
+ *
+ * The type of a box that contains any other value (including another
+ * variant).
+ **/
+#define G_VARIANT_TYPE_VARIANT              ((const GVariantType *) "v")
+
+/**
+ * G_VARIANT_TYPE_HANDLE:
+ *
+ * The type of a 32bit signed integer value, that by convention, is used
+ * as an index into an array of file descriptors that are sent alongside
+ * a DBus message.
+ *
+ * If you are not interacting with DBus, then there is no reason to make
+ * use of this type.
+ **/
+#define G_VARIANT_TYPE_HANDLE               ((const GVariantType *) "h")
+
+/**
+ * G_VARIANT_TYPE_UNIT:
+ *
+ * The empty tuple type.  Has only one instance.  Known also as "triv"
+ * or "void".
+ **/
+#define G_VARIANT_TYPE_UNIT                 ((const GVariantType *) "()")
+
+/**
+ * G_VARIANT_TYPE_ANY:
+ *
+ * An indefinite type that is a supertype of every type (including
+ * itself).
+ **/
+#define G_VARIANT_TYPE_ANY                  ((const GVariantType *) "*")
+
+/**
+ * G_VARIANT_TYPE_BASIC:
+ *
+ * An indefinite type that is a supertype of every basic (ie:
+ * non-container) type.
+ **/
+#define G_VARIANT_TYPE_BASIC                ((const GVariantType *) "?")
+
+/**
+ * G_VARIANT_TYPE_MAYBE:
+ *
+ * An indefinite type that is a supertype of every maybe type.
+ **/
+#define G_VARIANT_TYPE_MAYBE                ((const GVariantType *) "m*")
+
+/**
+ * G_VARIANT_TYPE_ARRAY:
+ *
+ * An indefinite type that is a supertype of every array type.
+ **/
+#define G_VARIANT_TYPE_ARRAY                ((const GVariantType *) "a*")
+
+/**
+ * G_VARIANT_TYPE_TUPLE:
+ *
+ * An indefinite type that is a supertype of every tuple type,
+ * regardless of the number of items in the tuple.
+ **/
+#define G_VARIANT_TYPE_TUPLE                ((const GVariantType *) "r")
+
+/**
+ * G_VARIANT_TYPE_DICT_ENTRY:
+ *
+ * An indefinite type that is a supertype of every dictionary entry
+ * type.
+ **/
+#define G_VARIANT_TYPE_DICT_ENTRY           ((const GVariantType *) "{?*}")
+
+/**
+ * G_VARIANT_TYPE_DICTIONARY:
+ *
+ * An indefinite type that is a supertype of every dictionary type --
+ * that is, any array type that has an element type equal to any
+ * dictionary entry type.
+ **/
+#define G_VARIANT_TYPE_DICTIONARY           ((const GVariantType *) "a{?*}")
+
+/**
+ * G_VARIANT_TYPE_STRING_ARRAY:
+ *
+ * The type of an array of strings.
+ **/
+#define G_VARIANT_TYPE_STRING_ARRAY         ((const GVariantType *) "as")
+
+/**
+ * G_VARIANT_TYPE_BYTESTRING:
+ *
+ * The type of an array of bytes.  This type is commonly used to pass
+ * around strings that may not be valid utf8.  In that case, the
+ * convention is that the nul terminator character should be included as
+ * the last character in the array.
+ **/
+#define G_VARIANT_TYPE_BYTESTRING           ((const GVariantType *) "ay")
+
+/**
+ * G_VARIANT_TYPE_BYTESTRING_ARRAY:
+ *
+ * The type of an array of byte strings (an array of arrays of bytes).
+ **/
+#define G_VARIANT_TYPE_BYTESTRING_ARRAY     ((const GVariantType *) "aay")
+
+
+/**
+ * G_VARIANT_TYPE:
+ * @type_string: a well-formed #GVariantType type string
+ *
+ * Converts a string to a const #GVariantType.  Depending on the
+ * current debugging level, this function may perform a runtime check
+ * to ensure that @string is a valid GVariant type string.
+ *
+ * It is always a programmer error to use this macro with an invalid
+ * type string.
+ *
+ * Since 2.24
+ **/
+#ifndef G_DISABLE_CHECKS
+# define G_VARIANT_TYPE(type_string)            (g_variant_type_checked_ ((type_string)))
+#else
+# define G_VARIANT_TYPE(type_string)            ((const GVariantType *) (type_string))
+#endif
+
+/* type string checking */
+gboolean                        g_variant_type_string_is_valid          (const gchar         *type_string);
+gboolean                        g_variant_type_string_scan              (const gchar         *string,
+                                                                         const gchar         *limit,
+                                                                         const gchar        **endptr);
+
+/* create/destroy */
+void                            g_variant_type_free                     (GVariantType        *type);
+GVariantType *                  g_variant_type_copy                     (const GVariantType  *type);
+GVariantType *                  g_variant_type_new                      (const gchar         *type_string);
+
+/* getters */
+gsize                           g_variant_type_get_string_length        (const GVariantType  *type);
+const gchar *                   g_variant_type_peek_string              (const GVariantType  *type);
+gchar *                         g_variant_type_dup_string               (const GVariantType  *type);
+
+/* classification */
+gboolean                        g_variant_type_is_definite              (const GVariantType  *type);
+gboolean                        g_variant_type_is_container             (const GVariantType  *type);
+gboolean                        g_variant_type_is_basic                 (const GVariantType  *type);
+gboolean                        g_variant_type_is_maybe                 (const GVariantType  *type);
+gboolean                        g_variant_type_is_array                 (const GVariantType  *type);
+gboolean                        g_variant_type_is_tuple                 (const GVariantType  *type);
+gboolean                        g_variant_type_is_dict_entry            (const GVariantType  *type);
+gboolean                        g_variant_type_is_variant               (const GVariantType  *type);
+
+/* for hash tables */
+guint                           g_variant_type_hash                     (gconstpointer        type);
+gboolean                        g_variant_type_equal                    (gconstpointer        type1,
+                                                                         gconstpointer        type2);
+
+/* subtypes */
+gboolean                        g_variant_type_is_subtype_of            (const GVariantType  *type,
+                                                                         const GVariantType  *supertype);
+
+/* type iterator interface */
+const GVariantType *            g_variant_type_element                  (const GVariantType  *type);
+const GVariantType *            g_variant_type_first                    (const GVariantType  *type);
+const GVariantType *            g_variant_type_next                     (const GVariantType  *type);
+gsize                           g_variant_type_n_items                  (const GVariantType  *type);
+const GVariantType *            g_variant_type_key                      (const GVariantType  *type);
+const GVariantType *            g_variant_type_value                    (const GVariantType  *type);
+
+/* constructors */
+GVariantType *                  g_variant_type_new_array                (const GVariantType  *element);
+GVariantType *                  g_variant_type_new_maybe                (const GVariantType  *element);
+GVariantType *                  g_variant_type_new_tuple                (const GVariantType * const *items,
+                                                                         gint                 length);
+GVariantType *                  g_variant_type_new_dict_entry           (const GVariantType  *key,
+                                                                         const GVariantType  *value);
+
+/*< private >*/
+const GVariantType *            g_variant_type_checked_                 (const gchar *);
+
+G_END_DECLS
+
+#endif /* __G_VARIANT_TYPE_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gvarianttypeinfo.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gvarianttypeinfo.c
new file mode 100644 (file)
index 0000000..c5998d3
--- /dev/null
@@ -0,0 +1,869 @@
+/*
+ * Copyright © 2008 Ryan Lortie
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#include "config.h"
+
+#include "gvarianttypeinfo.h"
+
+#include <glib/gtestutils.h>
+#include <glib/gthread.h>
+#include <glib/ghash.h>
+
+
+/* < private >
+ * GVariantTypeInfo:
+ *
+ * This structure contains the necessary information to facilitate the
+ * serialisation and fast deserialisation of a given type of GVariant
+ * value.  A GVariant instance holds a pointer to one of these
+ * structures to provide for efficient operation.
+ *
+ * The GVariantTypeInfo structures for all of the base types, plus the
+ * "variant" type are stored in a read-only static array.
+ *
+ * For container types, a hash table and reference counting is used to
+ * ensure that only one of these structures exists for any given type.
+ * In general, a container GVariantTypeInfo will exist for a given type
+ * only if one or more GVariant instances of that type exist or if
+ * another GVariantTypeInfo has that type as a subtype.  For example, if
+ * a process contains a single GVariant instance with type "(asv)", then
+ * container GVariantTypeInfo structures will exist for "(asv)" and
+ * for "as" (note that "s" and "v" always exist in the static array).
+ *
+ * The trickiest part of GVariantTypeInfo (and in fact, the major reason
+ * for its existance) is the storage of somewhat magical constants that
+ * allow for O(1) lookups of items in tuples.  This is described below.
+ *
+ * 'container_class' is set to 'a' or 'r' if the GVariantTypeInfo is
+ * contained inside of an ArrayInfo or TupleInfo, respectively.  This
+ * allows the storage of the necessary additional information.
+ *
+ * 'fixed_size' is set to the fixed size of the type, if applicable, or
+ * 0 otherwise (since no type has a fixed size of 0).
+ *
+ * 'alignment' is set to one less than the alignment requirement for
+ * this type.  This makes many operations much more convenient.
+ */
+struct _GVariantTypeInfo
+{
+  gsize fixed_size;
+  guchar alignment;
+  guchar container_class;
+};
+
+/* Container types are reference counted.  They also need to have their
+ * type string stored explicitly since it is not merely a single letter.
+ */
+typedef struct
+{
+  GVariantTypeInfo info;
+
+  gchar *type_string;
+  gint ref_count;
+} ContainerInfo;
+
+/* For 'array' and 'maybe' types, we store some extra information on the
+ * end of the GVariantTypeInfo struct -- the element type (ie: "s" for
+ * "as").  The container GVariantTypeInfo structure holds a reference to
+ * the element typeinfo.
+ */
+typedef struct
+{
+  ContainerInfo container;
+
+  GVariantTypeInfo *element;
+} ArrayInfo;
+
+/* For 'tuple' and 'dict entry' types, we store extra information for
+ * each member -- its type and how to find it inside the serialised data
+ * in O(1) time using 4 variables -- 'i', 'a', 'b', and 'c'.  See the
+ * comment on GVariantMemberInfo in gvarianttypeinfo.h.
+ */
+typedef struct
+{
+  ContainerInfo container;
+
+  GVariantMemberInfo *members;
+  gsize n_members;
+} TupleInfo;
+
+
+/* Hard-code the base types in a constant array */
+static const GVariantTypeInfo g_variant_type_info_basic_table[24] = {
+#define fixed_aligned(x)  x, x - 1
+#define not_a_type             0,
+#define unaligned         0, 0
+#define aligned(x)        0, x - 1
+  /* 'b' */ { fixed_aligned(1) },   /* boolean */
+  /* 'c' */ { not_a_type },
+  /* 'd' */ { fixed_aligned(8) },   /* double */
+  /* 'e' */ { not_a_type },
+  /* 'f' */ { not_a_type },
+  /* 'g' */ { unaligned        },   /* signature string */
+  /* 'h' */ { fixed_aligned(4) },   /* file handle (int32) */
+  /* 'i' */ { fixed_aligned(4) },   /* int32 */
+  /* 'j' */ { not_a_type },
+  /* 'k' */ { not_a_type },
+  /* 'l' */ { not_a_type },
+  /* 'm' */ { not_a_type },
+  /* 'n' */ { fixed_aligned(2) },   /* int16 */
+  /* 'o' */ { unaligned        },   /* object path string */
+  /* 'p' */ { not_a_type },
+  /* 'q' */ { fixed_aligned(2) },   /* uint16 */
+  /* 'r' */ { not_a_type },
+  /* 's' */ { unaligned        },   /* string */
+  /* 't' */ { fixed_aligned(8) },   /* uint64 */
+  /* 'u' */ { fixed_aligned(4) },   /* uint32 */
+  /* 'v' */ { aligned(8)       },   /* variant */
+  /* 'w' */ { not_a_type },
+  /* 'x' */ { fixed_aligned(8) },   /* int64 */
+  /* 'y' */ { fixed_aligned(1) },   /* byte */
+#undef fixed_aligned
+#undef not_a_type
+#undef unaligned
+#undef aligned
+};
+
+/* We need to have type strings to return for the base types.  We store
+ * those in another array.  Since all base type strings are single
+ * characters this is easy.  By not storing pointers to strings into the
+ * GVariantTypeInfo itself, we save a bunch of relocations.
+ */
+static const char g_variant_type_info_basic_chars[24][2] = {
+  "b", " ", "d", " ", " ", "g", "h", "i", " ", " ", " ", " ",
+  "n", "o", " ", "q", " ", "s", "t", "u", "v", " ", "x", "y"
+};
+
+/* sanity checks to make debugging easier */
+static void
+g_variant_type_info_check (const GVariantTypeInfo *info,
+                           char                    container_class)
+{
+  g_assert (!container_class || info->container_class == container_class);
+
+  /* alignment can only be one of these */
+  g_assert (info->alignment == 0 || info->alignment == 1 ||
+            info->alignment == 3 || info->alignment == 7);
+
+  if (info->container_class)
+    {
+      ContainerInfo *container = (ContainerInfo *) info;
+
+      /* extra checks for containers */
+      g_assert_cmpint (container->ref_count, >, 0);
+      g_assert (container->type_string != NULL);
+    }
+  else
+    {
+      gint index;
+
+      /* if not a container, then ensure that it is a valid member of
+       * the basic types table
+       */
+      index = info - g_variant_type_info_basic_table;
+
+      g_assert (G_N_ELEMENTS (g_variant_type_info_basic_table) == 24);
+      g_assert (G_N_ELEMENTS (g_variant_type_info_basic_chars) == 24);
+      g_assert (0 <= index && index < 24);
+      g_assert (g_variant_type_info_basic_chars[index][0] != ' ');
+    }
+}
+
+/* < private >
+ * g_variant_type_info_get_type_string:
+ * @info: a #GVariantTypeInfo
+ *
+ * Gets the type string for @info.  The string is nul-terminated.
+ */
+const gchar *
+g_variant_type_info_get_type_string (GVariantTypeInfo *info)
+{
+  g_variant_type_info_check (info, 0);
+
+  if (info->container_class)
+    {
+      ContainerInfo *container = (ContainerInfo *) info;
+
+      /* containers have their type string stored inside them */
+      return container->type_string;
+    }
+  else
+    {
+      gint index;
+
+      /* look up the type string in the base type array.  the call to
+       * g_variant_type_info_check() above already ensured validity.
+       */
+      index = info - g_variant_type_info_basic_table;
+
+      return g_variant_type_info_basic_chars[index];
+    }
+}
+
+/* < private >
+ * g_variant_type_info_query:
+ * @info: a #GVariantTypeInfo
+ * @alignment: the location to store the alignment, or %NULL
+ * @fixed_size: the location to store the fixed size, or %NULL
+ *
+ * Queries @info to determine the alignment requirements and fixed size
+ * (if any) of the type.
+ *
+ * @fixed_size, if non-%NULL is set to the fixed size of the type, or 0
+ * to indicate that the type is a variable-sized type.  No type has a
+ * fixed size of 0.
+ *
+ * @alignment, if non-%NULL, is set to one less than the required
+ * alignment of the type.  For example, for a 32bit integer, @alignment
+ * would be set to 3.  This allows you to round an integer up to the
+ * proper alignment by performing the following efficient calculation:
+ *
+ *   offset += ((-offset) & alignment);
+ */
+void
+g_variant_type_info_query (GVariantTypeInfo *info,
+                           guint            *alignment,
+                           gsize            *fixed_size)
+{
+  g_variant_type_info_check (info, 0);
+
+  if (alignment)
+    *alignment = info->alignment;
+
+  if (fixed_size)
+    *fixed_size = info->fixed_size;
+}
+
+/* == array == */
+#define ARRAY_INFO_CLASS 'a'
+static ArrayInfo *
+ARRAY_INFO (GVariantTypeInfo *info)
+{
+  g_variant_type_info_check (info, ARRAY_INFO_CLASS);
+
+  return (ArrayInfo *) info;
+}
+
+static void
+array_info_free (GVariantTypeInfo *info)
+{
+  ArrayInfo *array_info;
+
+  g_assert (info->container_class == ARRAY_INFO_CLASS);
+  array_info = (ArrayInfo *) info;
+
+  g_variant_type_info_unref (array_info->element);
+  g_slice_free (ArrayInfo, array_info);
+}
+
+static ContainerInfo *
+array_info_new (const GVariantType *type)
+{
+  ArrayInfo *info;
+
+  info = g_slice_new (ArrayInfo);
+  info->container.info.container_class = ARRAY_INFO_CLASS;
+
+  info->element = g_variant_type_info_get (g_variant_type_element (type));
+  info->container.info.alignment = info->element->alignment;
+  info->container.info.fixed_size = 0;
+
+  return (ContainerInfo *) info;
+}
+
+/* < private >
+ * g_variant_type_info_element:
+ * @info: a #GVariantTypeInfo for an array or maybe type
+ *
+ * Returns the element type for the array or maybe type.  A reference is
+ * not added, so the caller must add their own.
+ */
+GVariantTypeInfo *
+g_variant_type_info_element (GVariantTypeInfo *info)
+{
+  return ARRAY_INFO (info)->element;
+}
+
+/* < private >
+ * g_variant_type_query_element:
+ * @info: a #GVariantTypeInfo for an array or maybe type
+ * @alignment: the location to store the alignment, or %NULL
+ * @fixed_size: the location to store the fixed size, or %NULL
+ *
+ * Returns the alignment requires and fixed size (if any) for the
+ * element type of the array.  This call is a convenience wrapper around
+ * g_variant_type_info_element() and g_variant_type_info_query().
+ */
+void
+g_variant_type_info_query_element (GVariantTypeInfo *info,
+                                   guint            *alignment,
+                                   gsize            *fixed_size)
+{
+  g_variant_type_info_query (ARRAY_INFO (info)->element,
+                             alignment, fixed_size);
+}
+
+/* == tuple == */
+#define TUPLE_INFO_CLASS 'r'
+static TupleInfo *
+TUPLE_INFO (GVariantTypeInfo *info)
+{
+  g_variant_type_info_check (info, TUPLE_INFO_CLASS);
+
+  return (TupleInfo *) info;
+}
+
+static void
+tuple_info_free (GVariantTypeInfo *info)
+{
+  TupleInfo *tuple_info;
+  gint i;
+
+  g_assert (info->container_class == TUPLE_INFO_CLASS);
+  tuple_info = (TupleInfo *) info;
+
+  for (i = 0; i < tuple_info->n_members; i++)
+    g_variant_type_info_unref (tuple_info->members[i].type_info);
+
+  g_slice_free1 (sizeof (GVariantMemberInfo) * tuple_info->n_members,
+                 tuple_info->members);
+  g_slice_free (TupleInfo, tuple_info);
+}
+
+static void
+tuple_allocate_members (const GVariantType  *type,
+                        GVariantMemberInfo **members,
+                        gsize               *n_members)
+{
+  const GVariantType *item_type;
+  gsize i = 0;
+
+  *n_members = g_variant_type_n_items (type);
+  *members = g_slice_alloc (sizeof (GVariantMemberInfo) * *n_members);
+
+  item_type = g_variant_type_first (type);
+  while (item_type)
+    {
+      GVariantMemberInfo *member = &(*members)[i++];
+
+      member->type_info = g_variant_type_info_get (item_type);
+      item_type = g_variant_type_next (item_type);
+
+      if (member->type_info->fixed_size)
+        member->ending_type = G_VARIANT_MEMBER_ENDING_FIXED;
+      else if (item_type == NULL)
+        member->ending_type = G_VARIANT_MEMBER_ENDING_LAST;
+      else
+        member->ending_type = G_VARIANT_MEMBER_ENDING_OFFSET;
+    }
+
+  g_assert (i == *n_members);
+}
+
+/* this is g_variant_type_info_query for a given member of the tuple.
+ * before the access is done, it is ensured that the item is within
+ * range and %FALSE is returned if not.
+ */
+static gboolean
+tuple_get_item (TupleInfo          *info,
+                GVariantMemberInfo *item,
+                gsize              *d,
+                gsize              *e)
+{
+  if (&info->members[info->n_members] == item)
+    return FALSE;
+
+  *d = item->type_info->alignment;
+  *e = item->type_info->fixed_size;
+  return TRUE;
+}
+
+/* Read the documentation for #GVariantMemberInfo in gvarianttype.h
+ * before attempting to understand this.
+ *
+ * This function adds one set of "magic constant" values (for one item
+ * in the tuple) to the table.
+ *
+ * The algorithm in tuple_generate_table() calculates values of 'a', 'b'
+ * and 'c' for each item, such that the procedure for finding the item
+ * is to start at the end of the previous variable-sized item, add 'a',
+ * then round up to the nearest multiple of 'b', then then add 'c'.
+ * Note that 'b' is stored in the usual "one less than" form.  ie:
+ *
+ *   start = ROUND_UP(prev_end + a, (b + 1)) + c;
+ *
+ * We tweak these values a little to allow for a slightly easier
+ * computation and more compact storage.
+ */
+static void
+tuple_table_append (GVariantMemberInfo **items,
+                    gsize                i,
+                    gsize                a,
+                    gsize                b,
+                    gsize                c)
+{
+  GVariantMemberInfo *item = (*items)++;
+
+  /* We can shift multiples of the alignment size from 'c' into 'a'.
+   * As long as we're shifting whole multiples, it won't affect the
+   * result.  This means that we can take the "aligned" portion off of
+   * 'c' and add it into 'a'.
+   *
+   *  Imagine (for sake of clarity) that ROUND_10 rounds up to the
+   *  nearest 10.  It is clear that:
+   *
+   *   ROUND_10(a) + c == ROUND_10(a + 10*(c / 10)) + (c % 10)
+   *
+   * ie: remove the 10s portion of 'c' and add it onto 'a'.
+   *
+   * To put some numbers on it, imagine we start with a = 34 and c = 27:
+   *
+   *  ROUND_10(34) + 27 = 40 + 27 = 67
+   *
+   * but also, we can split 27 up into 20 and 7 and do this:
+   *
+   *  ROUND_10(34 + 20) + 7 = ROUND_10(54) + 7 = 60 + 7 = 67
+   *                ^^    ^
+   * without affecting the result.  We do that here.
+   *
+   * This reduction in the size of 'c' means that we can store it in a
+   * gchar instead of a gsize.  Due to how the structure is packed, this
+   * ends up saving us 'two pointer sizes' per item in each tuple when
+   * allocating using GSlice.
+   */
+  a += ~b & c;    /* take the "aligned" part of 'c' and add to 'a' */
+  c &= b;         /* chop 'c' to contain only the unaligned part */
+
+
+  /* Finally, we made one last adjustment.  Recall:
+   *
+   *   start = ROUND_UP(prev_end + a, (b + 1)) + c;
+   *
+   * Forgetting the '+ c' for the moment:
+   *
+   *   ROUND_UP(prev_end + a, (b + 1));
+   *
+   * we can do a "round up" operation by adding 1 less than the amount
+   * to round up to, then rounding down.  ie:
+   *
+   *   #define ROUND_UP(x, y)    ROUND_DOWN(x + (y-1), y)
+   *
+   * Of course, for rounding down to a power of two, we can just mask
+   * out the appropriate number of low order bits:
+   *
+   *   #define ROUND_DOWN(x, y)  (x & ~(y - 1))
+   *
+   * Which gives us
+   *
+   *   #define ROUND_UP(x, y)    (x + (y - 1) & ~(y - 1))
+   *
+   * but recall that our alignment value 'b' is already "one less".
+   * This means that to round 'prev_end + a' up to 'b' we can just do:
+   *
+   *   ((prev_end + a) + b) & ~b
+   *
+   * Associativity, and putting the 'c' back on:
+   *
+   *   (prev_end + (a + b)) & ~b + c
+   *
+   * Now, since (a + b) is constant, we can just add 'b' to 'a' now and
+   * store that as the number to add to prev_end.  Then we use ~b as the
+   * number to take a bitwise 'and' with.  Finally, 'c' is added on.
+   *
+   * Note, however, that all the low order bits of the 'aligned' value
+   * are masked out and that all of the high order bits of 'c' have been
+   * "moved" to 'a' (in the previous step).  This means that there are
+   * no overlapping bits in the addition -- so we can do a bitwise 'or'
+   * equivalently.
+   *
+   * This means that we can now compute the start address of a given
+   * item in the tuple using the algorithm given in the documentation
+   * for #GVariantMemberInfo:
+   *
+   *   item_start = ((prev_end + a) & b) | c;
+   */
+
+  item->i = i;
+  item->a = a + b;
+  item->b = ~b;
+  item->c = c;
+}
+
+static gsize
+tuple_align (gsize offset,
+             guint alignment)
+{
+  return offset + ((-offset) & alignment);
+}
+
+/* This function is the heart of the algorithm for calculating 'i', 'a',
+ * 'b' and 'c' for each item in the tuple.
+ *
+ * Imagine we want to find the start of the "i" in the type "(su(qx)ni)".
+ * That's a string followed by a uint32, then a tuple containing a
+ * uint16 and a int64, then an int16, then our "i".  In order to get to
+ * our "i" we:
+ *
+ * Start at the end of the string, align to 4 (for the uint32), add 4.
+ * Align to 8, add 16 (for the tuple).  Align to 2, add 2 (for the
+ * int16).  Then we're there.  It turns out that, given 3 simple rules,
+ * we can flatten this iteration into one addition, one alignment, then
+ * one more addition.
+ *
+ * The loop below plays through each item in the tuple, querying its
+ * alignment and fixed_size into 'd' and 'e', respectively.  At all
+ * times the variables 'a', 'b', and 'c' are maintained such that in
+ * order to get to the current point, you add 'a', align to 'b' then add
+ * 'c'.  'b' is kept in "one less than" form.  For each item, the proper
+ * alignment is applied to find the values of 'a', 'b' and 'c' to get to
+ * the start of that item.  Those values are recorded into the table.
+ * The fixed size of the item (if applicable) is then added on.
+ *
+ * These 3 rules are how 'a', 'b' and 'c' are modified for alignment and
+ * addition of fixed size.  They have been proven correct but are
+ * presented here, without proof:
+ *
+ *  1) in order to "align to 'd'" where 'd' is less than or equal to the
+ *     largest level of alignment seen so far ('b'), you align 'c' to
+ *     'd'.
+ *  2) in order to "align to 'd'" where 'd' is greater than the largest
+ *     level of alignment seen so far, you add 'c' aligned to 'b' to the
+ *     value of 'a', set 'b' to 'd' (ie: increase the 'largest alignment
+ *     seen') and reset 'c' to 0.
+ *  3) in order to "add 'e'", just add 'e' to 'c'.
+ */
+static void
+tuple_generate_table (TupleInfo *info)
+{
+  GVariantMemberInfo *items = info->members;
+  gsize i = -1, a = 0, b = 0, c = 0, d, e;
+
+  /* iterate over each item in the tuple.
+   *   'd' will be the alignment of the item (in one-less form)
+   *   'e' will be the fixed size (or 0 for variable-size items)
+   */
+  while (tuple_get_item (info, items, &d, &e))
+    {
+      /* align to 'd' */
+      if (d <= b)
+        c = tuple_align (c, d);                   /* rule 1 */
+      else
+        a += tuple_align (c, b), b = d, c = 0;    /* rule 2 */
+
+      /* the start of the item is at this point (ie: right after we
+       * have aligned for it).  store this information in the table.
+       */
+      tuple_table_append (&items, i, a, b, c);
+
+      /* "move past" the item by adding in its size. */
+      if (e == 0)
+        /* variable size:
+         *
+         * we'll have an offset stored to mark the end of this item, so
+         * just bump the offset index to give us a new starting point
+         * and reset all the counters.
+         */
+        i++, a = b = c = 0;
+      else
+        /* fixed size */
+        c += e;                                   /* rule 3 */
+    }
+}
+
+static void
+tuple_set_base_info (TupleInfo *info)
+{
+  GVariantTypeInfo *base = &info->container.info;
+
+  if (info->n_members > 0)
+    {
+      GVariantMemberInfo *m;
+
+      /* the alignment requirement of the tuple is the alignment
+       * requirement of its largest item.
+       */
+      base->alignment = 0;
+      for (m = info->members; m < &info->members[info->n_members]; m++)
+        /* can find the max of a list of "one less than" powers of two
+         * by 'or'ing them
+         */
+        base->alignment |= m->type_info->alignment;
+
+      m--; /* take 'm' back to the last item */
+
+      /* the structure only has a fixed size if no variable-size
+       * offsets are stored and the last item is fixed-sized too (since
+       * an offset is never stored for the last item).
+       */
+      if (m->i == -1 && m->type_info->fixed_size)
+        /* in that case, the fixed size can be found by finding the
+         * start of the last item (in the usual way) and adding its
+         * fixed size.
+         *
+         * if a tuple has a fixed size then it is always a multiple of
+         * the alignment requirement (to make packing into arrays
+         * easier) so we round up to that here.
+         */
+        base->fixed_size =
+          tuple_align (((m->a & m->b) | m->c) + m->type_info->fixed_size,
+                       base->alignment);
+      else
+        /* else, the tuple is not fixed size */
+        base->fixed_size = 0;
+    }
+  else
+    {
+      /* the empty tuple: '()'.
+       *
+       * has a size of 1 and an no alignment requirement.
+       *
+       * It has a size of 1 (not 0) for two practical reasons:
+       *
+       *  1) So we can determine how many of them are in an array
+       *     without dividing by zero or without other tricks.
+       *
+       *  2) Even if we had some trick to know the number of items in
+       *     the array (as GVariant did at one time) this would open a
+       *     potential denial of service attack: an attacker could send
+       *     you an extremely small array (in terms of number of bytes)
+       *     containing trillions of zero-sized items.  If you iterated
+       *     over this array you would effectively infinite-loop your
+       *     program.  By forcing a size of at least one, we bound the
+       *     amount of computation done in response to a message to a
+       *     reasonable function of the size of that message.
+       */
+      base->alignment = 0;
+      base->fixed_size = 1;
+    }
+}
+
+static ContainerInfo *
+tuple_info_new (const GVariantType *type)
+{
+  TupleInfo *info;
+
+  info = g_slice_new (TupleInfo);
+  info->container.info.container_class = TUPLE_INFO_CLASS;
+
+  tuple_allocate_members (type, &info->members, &info->n_members);
+  tuple_generate_table (info);
+  tuple_set_base_info (info);
+
+  return (ContainerInfo *) info;
+}
+
+/* < private >
+ * g_variant_type_info_n_members:
+ * @info: a #GVariantTypeInfo for a tuple or dictionary entry type
+ *
+ * Returns the number of members in a tuple or dictionary entry type.
+ * For a dictionary entry this will always be 2.
+ */
+gsize
+g_variant_type_info_n_members (GVariantTypeInfo *info)
+{
+  return TUPLE_INFO (info)->n_members;
+}
+
+/* < private >
+ * g_variant_type_info_member_info:
+ * @info: a #GVariantTypeInfo for a tuple or dictionary entry type
+ * @index: the member to fetch information for
+ *
+ * Returns the #GVariantMemberInfo for a given member.  See
+ * documentation for that structure for why you would want this
+ * information.
+ *
+ * @index must refer to a valid child (ie: strictly less than
+ * g_variant_type_info_n_members() returns).
+ */
+const GVariantMemberInfo *
+g_variant_type_info_member_info (GVariantTypeInfo *info,
+                                 gsize             index)
+{
+  TupleInfo *tuple_info = TUPLE_INFO (info);
+
+  if (index < tuple_info->n_members)
+    return &tuple_info->members[index];
+
+  return NULL;
+}
+
+/* == new/ref/unref == */
+static GStaticRecMutex g_variant_type_info_lock = G_STATIC_REC_MUTEX_INIT;
+static GHashTable *g_variant_type_info_table;
+
+/* < private >
+ * g_variant_type_info_get:
+ * @type: a #GVariantType
+ *
+ * Returns a reference to a #GVariantTypeInfo for @type.
+ *
+ * If an info structure already exists for this type, a new reference is
+ * returned.  If not, the required calculations are performed and a new
+ * info structure is returned.
+ *
+ * It is appropriate to call g_variant_type_info_unref() on the return
+ * value.
+ */
+GVariantTypeInfo *
+g_variant_type_info_get (const GVariantType *type)
+{
+  char type_char;
+
+  type_char = g_variant_type_peek_string (type)[0];
+
+  if (type_char == G_VARIANT_TYPE_INFO_CHAR_MAYBE ||
+      type_char == G_VARIANT_TYPE_INFO_CHAR_ARRAY ||
+      type_char == G_VARIANT_TYPE_INFO_CHAR_TUPLE ||
+      type_char == G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY)
+    {
+      GVariantTypeInfo *info;
+      gchar *type_string;
+
+      type_string = g_variant_type_dup_string (type);
+
+      g_static_rec_mutex_lock (&g_variant_type_info_lock);
+
+      if (g_variant_type_info_table == NULL)
+        g_variant_type_info_table = g_hash_table_new (g_str_hash,
+                                                      g_str_equal);
+      info = g_hash_table_lookup (g_variant_type_info_table, type_string);
+
+      if (info == NULL)
+        {
+          ContainerInfo *container;
+
+          if (type_char == G_VARIANT_TYPE_INFO_CHAR_MAYBE ||
+              type_char == G_VARIANT_TYPE_INFO_CHAR_ARRAY)
+            {
+              container = array_info_new (type);
+            }
+          else /* tuple or dict entry */
+            {
+              container = tuple_info_new (type);
+            }
+
+          info = (GVariantTypeInfo *) container;
+          container->type_string = type_string;
+          container->ref_count = 1;
+
+          g_hash_table_insert (g_variant_type_info_table, type_string, info);
+          type_string = NULL;
+        }
+      else
+        g_variant_type_info_ref (info);
+
+      g_static_rec_mutex_unlock (&g_variant_type_info_lock);
+      g_variant_type_info_check (info, 0);
+      g_free (type_string);
+
+      return info;
+    }
+  else
+    {
+      const GVariantTypeInfo *info;
+      int index;
+
+      index = type_char - 'b';
+      g_assert (G_N_ELEMENTS (g_variant_type_info_basic_table) == 24);
+      g_assert_cmpint (0, <=, index);
+      g_assert_cmpint (index, <, 24);
+
+      info = g_variant_type_info_basic_table + index;
+      g_variant_type_info_check (info, 0);
+
+      return (GVariantTypeInfo *) info;
+    }
+}
+
+/* < private >
+ * g_variant_type_info_ref:
+ * @info: a #GVariantTypeInfo
+ *
+ * Adds a reference to @info.
+ */
+GVariantTypeInfo *
+g_variant_type_info_ref (GVariantTypeInfo *info)
+{
+  g_variant_type_info_check (info, 0);
+
+  if (info->container_class)
+    {
+      ContainerInfo *container = (ContainerInfo *) info;
+
+      g_assert_cmpint (container->ref_count, >, 0);
+      g_atomic_int_inc (&container->ref_count);
+    }
+
+  return info;
+}
+
+/* < private >
+ * g_variant_type_info_unref:
+ * @info: a #GVariantTypeInfo
+ *
+ * Releases a reference held on @info.  This may result in @info being
+ * freed.
+ */
+void
+g_variant_type_info_unref (GVariantTypeInfo *info)
+{
+  g_variant_type_info_check (info, 0);
+
+  if (info->container_class)
+    {
+      ContainerInfo *container = (ContainerInfo *) info;
+
+      g_static_rec_mutex_lock (&g_variant_type_info_lock);
+      if (g_atomic_int_dec_and_test (&container->ref_count))
+        {
+          g_hash_table_remove (g_variant_type_info_table,
+                               container->type_string);
+          if (g_hash_table_size (g_variant_type_info_table) == 0)
+            {
+              g_hash_table_unref (g_variant_type_info_table);
+              g_variant_type_info_table = NULL;
+            }
+          g_static_rec_mutex_unlock (&g_variant_type_info_lock);
+
+          g_free (container->type_string);
+
+          if (info->container_class == ARRAY_INFO_CLASS)
+            array_info_free (info);
+
+          else if (info->container_class == TUPLE_INFO_CLASS)
+            tuple_info_free (info);
+
+          else
+            g_assert_not_reached ();
+        }
+      else
+        g_static_rec_mutex_unlock (&g_variant_type_info_lock);
+    }
+}
+
+void
+g_variant_type_info_assert_no_infos (void)
+{
+  g_assert (g_variant_type_info_table == NULL);
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gvarianttypeinfo.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gvarianttypeinfo.h
new file mode 100644 (file)
index 0000000..7c7b544
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ * Copyright © 2008 Ryan Lortie
+ * Copyright © 2010 Codethink Limited
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ *
+ * Author: Ryan Lortie <desrt@desrt.ca>
+ */
+
+#ifndef __G_VARIANT_TYPE_INFO_H__
+#define __G_VARIANT_TYPE_INFO_H__
+
+#include <glib/gvarianttype.h>
+
+#define G_VARIANT_TYPE_INFO_CHAR_MAYBE      'm'
+#define G_VARIANT_TYPE_INFO_CHAR_ARRAY      'a'
+#define G_VARIANT_TYPE_INFO_CHAR_TUPLE      '('
+#define G_VARIANT_TYPE_INFO_CHAR_DICT_ENTRY '{'
+#define G_VARIANT_TYPE_INFO_CHAR_VARIANT    'v'
+#define g_variant_type_info_get_type_char(info) \
+  (g_variant_type_info_get_type_string(info)[0])
+
+typedef struct _GVariantTypeInfo GVariantTypeInfo;
+
+/* < private >
+ * GVariantMemberInfo:
+ *
+ * This structure describes how to construct a GVariant instance
+ * corresponding to a given child of a tuple or dictionary entry in a
+ * very short constant time.  It contains the typeinfo of the child,
+ * along with 4 constants that allow the bounds of the child's
+ * serialised data within the container's serialised data to be found
+ * very efficiently.
+ *
+ * Since dictionary entries are serialised as if they were tuples of 2
+ * items, the term "tuple" will be used here in the general sense to
+ * refer to tuples and dictionary entries.
+ *
+ * BACKGROUND:
+ *   The serialised data for a tuple contains an array of "offsets" at
+ *   the end.  There is one "offset" in this array for each
+ *   variable-sized item in the tuple (except for the last one).  The
+ *   offset points to the end point of that item's serialised data.  The
+ *   procedure for finding the start point is described below.  An
+ *   offset is not needed for the last item because the end point of the
+ *   last item is merely the end point of the container itself (after
+ *   the offsets array has been accounted for).  An offset is not needed
+ *   for fixed-sized items (like integers) because, due to their fixed
+ *   size, the end point is a constant addition to the start point.
+ *
+ *   It is clear that the starting point of a given item in the tuple is
+ *   determined by the items that preceed it in the tuple.  Logically,
+ *   the start point of a particular item in a given type of tuple can
+ *   be determined entirely by the end point of the nearest
+ *   variable-sized item that came before it (or from the start of the
+ *   container itself in case there is no preceeding variable-sized
+ *   item).  In the case of "(isis)" for example, in order to find out
+ *   the start point of the last string, one must start at the end point
+ *   of the first string, align to 4 (for the integer's alignment) and
+ *   then add 4 (for storing the integer).  That's the point where the
+ *   string starts (since no special alignment is required for strings).
+ *
+ *   Of course, this process requires iterating over the types in the
+ *   tuple up to the item of interest.  As it turns out, it is possible
+ *   to determine 3 constants 'a', 'b', and 'c' for each item in the
+ *   tuple, such that, given the ending offset of the nearest previous
+ *   variable-sized item (prev_end), a very simple calculation can be
+ *   performed to determine the start of the item of interest.
+ *
+ * The constants in this structure are used as follows:
+ *
+ * First, among the array of offets contained in the tuple, 'i' is the
+ * index of the offset that refers to the end of the variable-sized item
+ * preceeding the item of interest.  If no variable-sized items preceed
+ * this item, then 'i' will be -1.
+ *
+ * Let 'prev_end' be the end offset of the previous item (or 0 in the
+ * case that there was no such item).  The start address of this item
+ * can then be calculate using 'a', 'b', and 'c':
+ *
+ *    item_start = ((prev_end + a) & b) | c;
+ *
+ * For details about how 'a', 'b' and 'c' are calculated, see the
+ * comments at the point of the implementation in gvariantypeinfo.c.
+ *
+ * The end address of the item is then determined in one of three ways,
+ * according to the 'end_type' field.
+ *
+ *   - FIXED: For fixed sized items, the end address is equal to the
+ *     start address plus the fixed size.
+ *
+ *   - LAST: For the last variable sized item in the tuple, the end
+ *     address is equal to the end address of the tuple, minus the size
+ *     of the offset array.
+ *
+ *   - OFFSET: For other variable sized items, the next index past 'i'
+ *     (ie: 'i + 1') must be consulted to find the end of this item.
+ */
+
+typedef struct
+{
+  GVariantTypeInfo *type_info;
+
+  gsize i, a;
+  gint8 b, c;
+
+  guint8 ending_type;
+} GVariantMemberInfo;
+
+#define G_VARIANT_MEMBER_ENDING_FIXED   0
+#define G_VARIANT_MEMBER_ENDING_LAST    1
+#define G_VARIANT_MEMBER_ENDING_OFFSET  2
+
+/* query */
+const gchar *                   g_variant_type_info_get_type_string     (GVariantTypeInfo   *typeinfo);
+
+void                            g_variant_type_info_query               (GVariantTypeInfo   *typeinfo,
+                                                                         guint              *alignment,
+                                                                         gsize              *size);
+
+/* array */
+GVariantTypeInfo *              g_variant_type_info_element             (GVariantTypeInfo   *typeinfo);
+void                            g_variant_type_info_query_element       (GVariantTypeInfo   *typeinfo,
+                                                                         guint              *alignment,
+                                                                         gsize              *size);
+
+/* structure */
+gsize                           g_variant_type_info_n_members           (GVariantTypeInfo   *typeinfo);
+const GVariantMemberInfo *      g_variant_type_info_member_info         (GVariantTypeInfo   *typeinfo,
+                                                                         gsize               index);
+
+/* new/ref/unref */
+GVariantTypeInfo *              g_variant_type_info_get                 (const GVariantType *type);
+GVariantTypeInfo *              g_variant_type_info_ref                 (GVariantTypeInfo   *typeinfo);
+void                            g_variant_type_info_unref               (GVariantTypeInfo   *typeinfo);
+void                            g_variant_type_info_assert_no_infos     (void);
+
+#endif /* __G_VARIANT_TYPE_INFO_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gwin32.c b/resource/csdk/connectivity/lib/android/glib-master/glib/gwin32.c
new file mode 100644 (file)
index 0000000..9ba02ad
--- /dev/null
@@ -0,0 +1,596 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1998  Peter Mattis, Spencer Kimball and Josh MacDonald
+ * Copyright (C) 1998-1999  Tor Lillqvist
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/* 
+ * MT safe for the unix part, FIXME: make the win32 part MT safe as well.
+ */
+
+#include "config.h"
+
+#include "glibconfig.h"
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <wchar.h>
+#include <errno.h>
+
+#define STRICT                 /* Strict typing, please */
+#include <windows.h>
+#undef STRICT
+#ifndef G_WITH_CYGWIN
+#include <direct.h>
+#endif
+#include <errno.h>
+#include <ctype.h>
+#if defined(_MSC_VER) || defined(__DMC__)
+#  include <io.h>
+#endif /* _MSC_VER || __DMC__ */
+
+#include "glib.h"
+
+#ifdef G_WITH_CYGWIN
+#include <sys/cygwin.h>
+#endif
+
+#ifndef G_WITH_CYGWIN
+
+gint
+g_win32_ftruncate (gint  fd,
+                  guint size)
+{
+  return _chsize (fd, size);
+}
+
+#endif
+
+/**
+ * g_win32_getlocale:
+ *
+ * The setlocale() function in the Microsoft C library uses locale
+ * names of the form "English_United States.1252" etc. We want the
+ * UNIXish standard form "en_US", "zh_TW" etc. This function gets the
+ * current thread locale from Windows - without any encoding info -
+ * and returns it as a string of the above form for use in forming
+ * file names etc. The returned string should be deallocated with
+ * g_free().
+ *
+ * Returns: newly-allocated locale name.
+ **/
+
+#ifndef SUBLANG_SERBIAN_LATIN_BA
+#define SUBLANG_SERBIAN_LATIN_BA 0x06
+#endif
+
+gchar *
+g_win32_getlocale (void)
+{
+  LCID lcid;
+  LANGID langid;
+  gchar *ev;
+  gint primary, sub;
+  char iso639[10];
+  char iso3166[10];
+  const gchar *script = NULL;
+
+  /* Let the user override the system settings through environment
+   * variables, as on POSIX systems. Note that in GTK+ applications
+   * since GTK+ 2.10.7 setting either LC_ALL or LANG also sets the
+   * Win32 locale and C library locale through code in gtkmain.c.
+   */
+  if (((ev = getenv ("LC_ALL")) != NULL && ev[0] != '\0')
+      || ((ev = getenv ("LC_MESSAGES")) != NULL && ev[0] != '\0')
+      || ((ev = getenv ("LANG")) != NULL && ev[0] != '\0'))
+    return g_strdup (ev);
+
+  lcid = GetThreadLocale ();
+
+  if (!GetLocaleInfo (lcid, LOCALE_SISO639LANGNAME, iso639, sizeof (iso639)) ||
+      !GetLocaleInfo (lcid, LOCALE_SISO3166CTRYNAME, iso3166, sizeof (iso3166)))
+    return g_strdup ("C");
+  
+  /* Strip off the sorting rules, keep only the language part.  */
+  langid = LANGIDFROMLCID (lcid);
+
+  /* Split into language and territory part.  */
+  primary = PRIMARYLANGID (langid);
+  sub = SUBLANGID (langid);
+
+  /* Handle special cases */
+  switch (primary)
+    {
+    case LANG_AZERI:
+      switch (sub)
+       {
+       case SUBLANG_AZERI_LATIN:
+         script = "@Latn";
+         break;
+       case SUBLANG_AZERI_CYRILLIC:
+         script = "@Cyrl";
+         break;
+       }
+      break;
+    case LANG_SERBIAN:         /* LANG_CROATIAN == LANG_SERBIAN */
+      switch (sub)
+       {
+       case SUBLANG_SERBIAN_LATIN:
+       case 0x06: /* Serbian (Latin) - Bosnia and Herzegovina */
+         script = "@Latn";
+         break;
+       }
+      break;
+    case LANG_UZBEK:
+      switch (sub)
+       {
+       case SUBLANG_UZBEK_LATIN:
+         script = "@Latn";
+         break;
+       case SUBLANG_UZBEK_CYRILLIC:
+         script = "@Cyrl";
+         break;
+       }
+      break;
+    }
+  return g_strconcat (iso639, "_", iso3166, script, NULL);
+}
+
+/**
+ * g_win32_error_message:
+ * @error: error code.
+ *
+ * Translate a Win32 error code (as returned by GetLastError()) into
+ * the corresponding message. The message is either language neutral,
+ * or in the thread's language, or the user's language, the system's
+ * language, or US English (see docs for FormatMessage()). The
+ * returned string is in UTF-8. It should be deallocated with
+ * g_free().
+ *
+ * Returns: newly-allocated error message
+ **/
+gchar *
+g_win32_error_message (gint error)
+{
+  gchar *retval;
+  wchar_t *msg = NULL;
+  int nchars;
+
+  FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER
+                 |FORMAT_MESSAGE_IGNORE_INSERTS
+                 |FORMAT_MESSAGE_FROM_SYSTEM,
+                 NULL, error, 0,
+                 (LPWSTR) &msg, 0, NULL);
+  if (msg != NULL)
+    {
+      nchars = wcslen (msg);
+      
+      if (nchars > 2 && msg[nchars-1] == '\n' && msg[nchars-2] == '\r')
+       msg[nchars-2] = '\0';
+      
+      retval = g_utf16_to_utf8 (msg, -1, NULL, NULL, NULL);
+      
+      LocalFree (msg);
+    }
+  else
+    retval = g_strdup ("");
+
+  return retval;
+}
+
+/**
+ * g_win32_get_package_installation_directory_of_module:
+ * @hmodule: The Win32 handle for a DLL loaded into the current process, or %NULL
+ *
+ * This function tries to determine the installation directory of a
+ * software package based on the location of a DLL of the software
+ * package.
+ *
+ * @hmodule should be the handle of a loaded DLL or %NULL. The
+ * function looks up the directory that DLL was loaded from. If
+ * @hmodule is NULL, the directory the main executable of the current
+ * process is looked up. If that directory's last component is "bin"
+ * or "lib", its parent directory is returned, otherwise the directory
+ * itself.
+ *
+ * It thus makes sense to pass only the handle to a "public" DLL of a
+ * software package to this function, as such DLLs typically are known
+ * to be installed in a "bin" or occasionally "lib" subfolder of the
+ * installation folder. DLLs that are of the dynamically loaded module
+ * or plugin variety are often located in more private locations
+ * deeper down in the tree, from which it is impossible for GLib to
+ * deduce the root of the package installation.
+ *
+ * The typical use case for this function is to have a DllMain() that
+ * saves the handle for the DLL. Then when code in the DLL needs to
+ * construct names of files in the installation tree it calls this
+ * function passing the DLL handle.
+ *
+ * Returns: a string containing the guessed installation directory for
+ * the software package @hmodule is from. The string is in the GLib
+ * file name encoding, i.e. UTF-8. The return value should be freed
+ * with g_free() when not needed any longer. If the function fails
+ * %NULL is returned.
+ *
+ * Since: 2.16
+ */
+gchar *
+g_win32_get_package_installation_directory_of_module (gpointer hmodule)
+{
+  gchar *retval;
+  gchar *p;
+  wchar_t wc_fn[MAX_PATH];
+
+  if (!GetModuleFileNameW (hmodule, wc_fn, MAX_PATH))
+    return NULL;
+
+  retval = g_utf16_to_utf8 (wc_fn, -1, NULL, NULL, NULL);
+
+  if ((p = strrchr (retval, G_DIR_SEPARATOR)) != NULL)
+    *p = '\0';
+
+  p = strrchr (retval, G_DIR_SEPARATOR);
+  if (p && (g_ascii_strcasecmp (p + 1, "bin") == 0 ||
+           g_ascii_strcasecmp (p + 1, "lib") == 0))
+    *p = '\0';
+
+#ifdef G_WITH_CYGWIN
+  /* In Cygwin we need to have POSIX paths */
+  {
+    gchar tmp[MAX_PATH];
+
+    cygwin_conv_to_posix_path (retval, tmp);
+    g_free (retval);
+    retval = g_strdup (tmp);
+  }
+#endif
+
+  return retval;
+}
+
+static gchar *
+get_package_directory_from_module (const gchar *module_name)
+{
+  static GHashTable *module_dirs = NULL;
+  G_LOCK_DEFINE_STATIC (module_dirs);
+  HMODULE hmodule = NULL;
+  gchar *fn;
+
+  G_LOCK (module_dirs);
+
+  if (module_dirs == NULL)
+    module_dirs = g_hash_table_new (g_str_hash, g_str_equal);
+  
+  fn = g_hash_table_lookup (module_dirs, module_name ? module_name : "");
+      
+  if (fn)
+    {
+      G_UNLOCK (module_dirs);
+      return g_strdup (fn);
+    }
+
+  if (module_name)
+    {
+      wchar_t *wc_module_name = g_utf8_to_utf16 (module_name, -1, NULL, NULL, NULL);
+      hmodule = GetModuleHandleW (wc_module_name);
+      g_free (wc_module_name);
+
+      if (!hmodule)
+       {
+         G_UNLOCK (module_dirs);
+         return NULL;
+       }
+    }
+
+  fn = g_win32_get_package_installation_directory_of_module (hmodule);
+
+  if (fn == NULL)
+    {
+      G_UNLOCK (module_dirs);
+      return NULL;
+    }
+  
+  g_hash_table_insert (module_dirs, module_name ? g_strdup (module_name) : "", fn);
+
+  G_UNLOCK (module_dirs);
+
+  return g_strdup (fn);
+}
+
+/**
+ * g_win32_get_package_installation_directory:
+ * @package: You should pass %NULL for this.
+ * @dll_name: The name of a DLL that a package provides in UTF-8, or %NULL.
+ *
+ * Try to determine the installation directory for a software package.
+ *
+ * This function is deprecated. Use
+ * g_win32_get_package_installation_directory_of_module() instead.
+ *
+ * The use of @package is deprecated. You should always pass %NULL. A
+ * warning is printed if non-NULL is passed as @package.
+ *
+ * The original intended use of @package was for a short identifier of
+ * the package, typically the same identifier as used for
+ * <literal>GETTEXT_PACKAGE</literal> in software configured using GNU
+ * autotools. The function first looks in the Windows Registry for the
+ * value <literal>&num;InstallationDirectory</literal> in the key
+ * <literal>&num;HKLM\Software\@package</literal>, and if that value
+ * exists and is a string, returns that.
+ *
+ * It is strongly recommended that packagers of GLib-using libraries
+ * for Windows do not store installation paths in the Registry to be
+ * used by this function as that interfers with having several
+ * parallel installations of the library. Enabling multiple
+ * installations of different versions of some GLib-using library, or
+ * GLib itself, is desirable for various reasons.
+ *
+ * For this reason it is recommeded to always pass %NULL as
+ * @package to this function, to avoid the temptation to use the
+ * Registry. In version 2.20 of GLib the @package parameter
+ * will be ignored and this function won't look in the Registry at all.
+ *
+ * If @package is %NULL, or the above value isn't found in the
+ * Registry, but @dll_name is non-%NULL, it should name a DLL loaded
+ * into the current process. Typically that would be the name of the
+ * DLL calling this function, looking for its installation
+ * directory. The function then asks Windows what directory that DLL
+ * was loaded from. If that directory's last component is "bin" or
+ * "lib", the parent directory is returned, otherwise the directory
+ * itself. If that DLL isn't loaded, the function proceeds as if
+ * @dll_name was %NULL.
+ *
+ * If both @package and @dll_name are %NULL, the directory from where
+ * the main executable of the process was loaded is used instead in
+ * the same way as above.
+ *
+ * Returns: a string containing the installation directory for
+ * @package. The string is in the GLib file name encoding,
+ * i.e. UTF-8. The return value should be freed with g_free() when not
+ * needed any longer. If the function fails %NULL is returned.
+ *
+ * Deprecated: 2.18: Pass the HMODULE of a DLL or EXE to
+ * g_win32_get_package_installation_directory_of_module() instead.
+ **/
+
+ gchar *
+g_win32_get_package_installation_directory_utf8 (const gchar *package,
+                                                const gchar *dll_name)
+{
+  gchar *result = NULL;
+
+  if (package != NULL)
+      g_warning ("Passing a non-NULL package to g_win32_get_package_installation_directory() is deprecated and it is ignored.");
+
+  if (dll_name != NULL)
+    result = get_package_directory_from_module (dll_name);
+
+  if (result == NULL)
+    result = get_package_directory_from_module (NULL);
+
+  return result;
+}
+
+#if !defined (_WIN64)
+
+/* DLL ABI binary compatibility version that uses system codepage file names */
+
+gchar *
+g_win32_get_package_installation_directory (const gchar *package,
+                                           const gchar *dll_name)
+{
+  gchar *utf8_package = NULL, *utf8_dll_name = NULL;
+  gchar *utf8_retval, *retval;
+
+  if (package != NULL)
+    utf8_package = g_locale_to_utf8 (package, -1, NULL, NULL, NULL);
+
+  if (dll_name != NULL)
+    utf8_dll_name = g_locale_to_utf8 (dll_name, -1, NULL, NULL, NULL);
+
+  utf8_retval =
+    g_win32_get_package_installation_directory_utf8 (utf8_package,
+                                                    utf8_dll_name);
+
+  retval = g_locale_from_utf8 (utf8_retval, -1, NULL, NULL, NULL);
+
+  g_free (utf8_package);
+  g_free (utf8_dll_name);
+  g_free (utf8_retval);
+
+  return retval;
+}
+
+#endif
+
+/**
+ * g_win32_get_package_installation_subdirectory:
+ * @package: You should pass %NULL for this.
+ * @dll_name: The name of a DLL that a package provides, in UTF-8, or %NULL.
+ * @subdir: A subdirectory of the package installation directory, also in UTF-8
+ *
+ * This function is deprecated. Use
+ * g_win32_get_package_installation_directory_of_module() and
+ * g_build_filename() instead.
+ *
+ * Returns a newly-allocated string containing the path of the
+ * subdirectory @subdir in the return value from calling
+ * g_win32_get_package_installation_directory() with the @package and
+ * @dll_name parameters. See the documentation for
+ * g_win32_get_package_installation_directory() for more details. In
+ * particular, note that it is deprecated to pass anything except NULL
+ * as @package.
+ *
+ * Returns: a string containing the complete path to @subdir inside
+ * the installation directory of @package. The returned string is in
+ * the GLib file name encoding, i.e. UTF-8. The return value should be
+ * freed with g_free() when no longer needed. If something goes wrong,
+ * %NULL is returned.
+ *
+ * Deprecated: 2.18: Pass the HMODULE of a DLL or EXE to
+ * g_win32_get_package_installation_directory_of_module() instead, and
+ * then construct a subdirectory pathname with g_build_filename().
+ **/
+
+gchar *
+g_win32_get_package_installation_subdirectory_utf8 (const gchar *package,
+                                                   const gchar *dll_name,
+                                                   const gchar *subdir)
+{
+  gchar *prefix;
+  gchar *dirname;
+
+  prefix = g_win32_get_package_installation_directory_utf8 (package, dll_name);
+
+  dirname = g_build_filename (prefix, subdir, NULL);
+  g_free (prefix);
+
+  return dirname;
+}
+
+#if !defined (_WIN64)
+
+/* DLL ABI binary compatibility version that uses system codepage file names */
+
+gchar *
+g_win32_get_package_installation_subdirectory (const gchar *package,
+                                              const gchar *dll_name,
+                                              const gchar *subdir)
+{
+  gchar *prefix;
+  gchar *dirname;
+
+  prefix = g_win32_get_package_installation_directory (package, dll_name);
+
+  dirname = g_build_filename (prefix, subdir, NULL);
+  g_free (prefix);
+
+  return dirname;
+}
+
+#endif
+
+static guint windows_version;
+
+static void 
+g_win32_windows_version_init (void)
+{
+  static gboolean beenhere = FALSE;
+
+  if (!beenhere)
+    {
+      beenhere = TRUE;
+      windows_version = GetVersion ();
+
+      if (windows_version & 0x80000000)
+       g_error ("This version of GLib requires NT-based Windows.");
+    }
+}
+
+void 
+_g_win32_thread_init (void)
+{
+  g_win32_windows_version_init ();
+}
+
+/**
+ * g_win32_get_windows_version:
+ *
+ * Returns version information for the Windows operating system the
+ * code is running on. See MSDN documentation for the GetVersion()
+ * function. To summarize, the most significant bit is one on Win9x,
+ * and zero on NT-based systems. Since version 2.14, GLib works only
+ * on NT-based systems, so checking whether your are running on Win9x
+ * in your own software is moot. The least significant byte is 4 on
+ * Windows NT 4, and 5 on Windows XP. Software that needs really
+ * detailled version and feature information should use Win32 API like
+ * GetVersionEx() and VerifyVersionInfo().
+ *
+ * Returns: The version information.
+ * 
+ * Since: 2.6
+ **/
+guint
+g_win32_get_windows_version (void)
+{
+  g_win32_windows_version_init ();
+  
+  return windows_version;
+}
+
+/**
+ * g_win32_locale_filename_from_utf8:
+ * @utf8filename: a UTF-8 encoded filename.
+ *
+ * Converts a filename from UTF-8 to the system codepage.
+ *
+ * On NT-based Windows, on NTFS file systems, file names are in
+ * Unicode. It is quite possible that Unicode file names contain
+ * characters not representable in the system codepage. (For instance,
+ * Greek or Cyrillic characters on Western European or US Windows
+ * installations, or various less common CJK characters on CJK Windows
+ * installations.)
+ *
+ * In such a case, and if the filename refers to an existing file, and
+ * the file system stores alternate short (8.3) names for directory
+ * entries, the short form of the filename is returned. Note that the
+ * "short" name might in fact be longer than the Unicode name if the
+ * Unicode name has very short pathname components containing
+ * non-ASCII characters. If no system codepage name for the file is
+ * possible, %NULL is returned.
+ *
+ * The return value is dynamically allocated and should be freed with
+ * g_free() when no longer needed.
+ *
+ * Return value: The converted filename, or %NULL on conversion
+ * failure and lack of short names.
+ *
+ * Since: 2.8
+ */
+gchar *
+g_win32_locale_filename_from_utf8 (const gchar *utf8filename)
+{
+  gchar *retval = g_locale_from_utf8 (utf8filename, -1, NULL, NULL, NULL);
+
+  if (retval == NULL)
+    {
+      /* Conversion failed, so convert to wide chars, check if there
+       * is a 8.3 version, and use that.
+       */
+      wchar_t *wname = g_utf8_to_utf16 (utf8filename, -1, NULL, NULL, NULL);
+      if (wname != NULL)
+       {
+         wchar_t wshortname[MAX_PATH + 1];
+         if (GetShortPathNameW (wname, wshortname, G_N_ELEMENTS (wshortname)))
+           {
+             gchar *tem = g_utf16_to_utf8 (wshortname, -1, NULL, NULL, NULL);
+             retval = g_locale_from_utf8 (tem, -1, NULL, NULL, NULL);
+             g_free (tem);
+           }
+         g_free (wname);
+       }
+    }
+  return retval;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/gwin32.h b/resource/csdk/connectivity/lib/android/glib-master/glib/gwin32.h
new file mode 100644 (file)
index 0000000..5793335
--- /dev/null
@@ -0,0 +1,114 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+#if defined(G_DISABLE_SINGLE_INCLUDES) && !defined (__GLIB_H_INSIDE__) && !defined (GLIB_COMPILATION)
+#error "Only <glib.h> can be included directly."
+#endif
+
+#ifndef __G_WIN32_H__
+#define __G_WIN32_H__
+
+#include <glib/gtypes.h>
+
+#ifdef G_PLATFORM_WIN32
+
+G_BEGIN_DECLS
+
+#ifndef MAXPATHLEN
+#define MAXPATHLEN 1024
+#endif
+
+#ifdef G_OS_WIN32
+
+/*
+ * To get prototypes for the following POSIXish functions, you have to
+ * include the indicated non-POSIX headers. The functions are defined
+ * in OLDNAMES.LIB (MSVC) or -lmoldname-msvc (mingw32). But note that
+ * for POSIX functions that take or return file names in the system
+ * codepage, in many cases you would want to use the GLib wrappers in
+ * gstdio.h and UTF-8 instead.
+ *
+ * getcwd: <direct.h> (MSVC), <io.h> (mingw32)
+ * getpid: <process.h>
+ * access: <io.h>
+ * unlink: <stdio.h> or <io.h>
+ * open, read, write, lseek, close: <io.h>
+ * rmdir: <io.h>
+ * pipe: <io.h> (actually, _pipe())
+ */
+
+/* For some POSIX functions that are not provided by the MS runtime,
+ * we provide emulation functions in glib, which are prefixed with
+ * g_win32_. Or that was the idea at some time, but there is just one
+ * of those:
+ */
+gint           g_win32_ftruncate       (gint            f,
+                                        guint           size);
+#endif /* G_OS_WIN32 */
+
+/* The MS setlocale uses locale names of the form "English_United
+ * States.1252" etc. We want the Unixish standard form "en", "zh_TW"
+ * etc. This function gets the current thread locale from Windows and
+ * returns it as a string of the above form for use in forming file
+ * names etc. The returned string should be deallocated with g_free().
+ */
+gchar*                 g_win32_getlocale  (void);
+
+/* Translate a Win32 error code (as returned by GetLastError()) into
+ * the corresponding message. The returned string should be deallocated
+ * with g_free().
+ */
+gchar*          g_win32_error_message (gint error);
+
+#ifndef G_DISABLE_DEPRECATED
+
+#define g_win32_get_package_installation_directory g_win32_get_package_installation_directory_utf8
+#define g_win32_get_package_installation_subdirectory g_win32_get_package_installation_subdirectory_utf8
+
+gchar*          g_win32_get_package_installation_directory (const gchar *package,
+                                                           const gchar *dll_name);
+
+gchar*          g_win32_get_package_installation_subdirectory (const gchar *package,
+                                                              const gchar *dll_name,
+                                                              const gchar *subdir);
+
+#endif
+
+gchar*          g_win32_get_package_installation_directory_of_module (gpointer hmodule);
+
+guint          g_win32_get_windows_version (void);
+
+gchar*          g_win32_locale_filename_from_utf8 (const gchar *utf8filename);
+
+/* As of GLib 2.14 we only support NT-based Windows */
+#define G_WIN32_IS_NT_BASED() TRUE
+#define G_WIN32_HAVE_WIDECHAR_API() TRUE
+
+G_END_DECLS
+
+#endif  /* G_PLATFORM_WIN32 */
+
+#endif /* __G_WIN32_H__ */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/.gitignore b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/.gitignore
new file mode 100644 (file)
index 0000000..0cef440
--- /dev/null
@@ -0,0 +1,3 @@
+charset.alias
+ref-add.sed
+ref-del.sed
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/Makefile.am b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/Makefile.am
new file mode 100644 (file)
index 0000000..5571388
--- /dev/null
@@ -0,0 +1,64 @@
+## Process this file with automake to produce Makefile.in
+include $(top_srcdir)/Makefile.decl
+
+INCLUDES =                     \
+       -DLIBDIR=\"$(libdir)\" $(config_h_INCLUDES)
+
+noinst_LTLIBRARIES = libcharset.la
+
+libcharset_la_SOURCES =        \
+       libcharset.h            \
+       localcharset.h          \
+       localcharset.c
+
+EXTRA_DIST +=                  \
+       README                  \
+       config.charset          \
+       ref-add.sin             \
+       ref-del.sin             \
+       glibc21.m4              \
+       codeset.m4              \
+       update.sh               \
+       make-patch.sh           \
+       libcharset-glib.patch
+
+charset_alias = $(DESTDIR)$(libdir)/charset.alias
+charset_tmp = $(DESTDIR)$(libdir)/charset.tmp
+install-exec-local: all-local
+       $(mkinstalldirs) $(DESTDIR)$(libdir)
+       if test -f $(charset_alias); then \
+         sed -f ref-add.sed $(charset_alias) > $(charset_tmp) ; \
+         $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \
+         rm -f $(charset_tmp) ; \
+       else \
+         if test @GLIBC21@ = no; then \
+           sed -f ref-add.sed charset.alias > $(charset_tmp) ; \
+           $(INSTALL_DATA) $(charset_tmp) $(charset_alias) ; \
+           rm -f $(charset_tmp) ; \
+         fi ; \
+       fi
+
+uninstall-local: all-local
+       if test -f $(charset_alias); then \
+         sed -f ref-del.sed $(charset_alias) > $(charset_tmp); \
+         if grep '^# Packages using this file: $$' $(charset_tmp) \
+             > /dev/null; then \
+           rm -f $(charset_alias); \
+         else \
+           $(INSTALL_DATA) $(charset_tmp) $(charset_alias); \
+         fi; \
+         rm -f $(charset_tmp); \
+       fi
+
+charset.alias: config.charset
+       $(SHELL) $(srcdir)/config.charset '@host@' > t-$@
+       mv t-$@ $@
+
+all-local: ref-add.sed ref-del.sed charset.alias
+
+SUFFIXES = .sed .sin
+.sin.sed:
+       sed -e '/^#/d' -e 's/@''PACKAGE''@/@PACKAGE@/g' $< > t-$@
+       mv t-$@ $@
+
+CLEANFILES = charset.alias ref-add.sed ref-del.sed
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/README b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/README
new file mode 100644 (file)
index 0000000..c8f53bd
--- /dev/null
@@ -0,0 +1,46 @@
+The sources are derived from Bruno Haible's libcharset library included
+with libiconv:
+
+ http//www.gnu.org/software/libiconv
+
+The 'update.sh' script in this directory, when pointed at
+the original sources updates the files in this directory
+(and elsewhere in the GLib distribution) to the new version
+
+The 'make-patch.sh' script in this directory regenerates
+the patch files included in this directory from a copy
+of the pristine sources and the files in this directory.
+
+The license on the portions from libiconv portions is reproduced
+below.
+
+Owen Taylor
+26 September 2001
+
+Updated to libiconv-1.12.
+
+Behdad Esfahbod
+20 May 2008
+
+====
+
+/* Determine a canonical name for the current locale's character encoding.
+
+   Copyright (C) 2000-2001 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library General Public License as published
+   by the Free Software Foundation; either version 2, 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library 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.  */
+
+/* Written by Bruno Haible <haible@clisp.cons.org>.  */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/codeset.m4 b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/codeset.m4
new file mode 100644 (file)
index 0000000..a6e67ec
--- /dev/null
@@ -0,0 +1,21 @@
+# codeset.m4 serial AM1 (gettext-0.10.40)
+dnl Copyright (C) 2000-2002 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+dnl From Bruno Haible.
+
+AC_DEFUN([AM_LANGINFO_CODESET],
+[
+  AC_CACHE_CHECK([for nl_langinfo and CODESET], am_cv_langinfo_codeset,
+    [AC_TRY_LINK([#include <langinfo.h>],
+      [char* cs = nl_langinfo(CODESET);],
+      am_cv_langinfo_codeset=yes,
+      am_cv_langinfo_codeset=no)
+    ])
+  if test $am_cv_langinfo_codeset = yes; then
+    AC_DEFINE(HAVE_LANGINFO_CODESET, 1,
+      [Define if you have <langinfo.h> and nl_langinfo(CODESET).])
+  fi
+])
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/config.charset b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/config.charset
new file mode 100644 (file)
index 0000000..e8c258b
--- /dev/null
@@ -0,0 +1,640 @@
+#! /bin/sh
+# Output a system dependent table of character encoding aliases.
+#
+#   Copyright (C) 2000-2004, 2006 Free Software Foundation, Inc.
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU Library General Public License as published
+#   by the Free Software Foundation; either version 2, 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
+#   Library General Public License for more details.
+#
+#   You should have received a copy of the GNU Library General Public
+#   License along with this program; if not, write to the Free Software
+#   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+#   USA.
+#
+# The table consists of lines of the form
+#    ALIAS  CANONICAL
+#
+# ALIAS is the (system dependent) result of "nl_langinfo (CODESET)".
+# ALIAS is compared in a case sensitive way.
+#
+# CANONICAL is the GNU canonical name for this character encoding.
+# It must be an encoding supported by libiconv. Support by GNU libc is
+# also desirable. CANONICAL is case insensitive. Usually an upper case
+# MIME charset name is preferred.
+# The current list of GNU canonical charset names is as follows.
+#
+#       name              MIME?             used by which systems
+#   ASCII, ANSI_X3.4-1968       glibc solaris freebsd netbsd darwin
+#   ISO-8859-1              Y   glibc aix hpux irix osf solaris freebsd netbsd darwin
+#   ISO-8859-2              Y   glibc aix hpux irix osf solaris freebsd netbsd darwin
+#   ISO-8859-3              Y   glibc solaris
+#   ISO-8859-4              Y   osf solaris freebsd netbsd darwin
+#   ISO-8859-5              Y   glibc aix hpux irix osf solaris freebsd netbsd darwin
+#   ISO-8859-6              Y   glibc aix hpux solaris
+#   ISO-8859-7              Y   glibc aix hpux irix osf solaris netbsd darwin
+#   ISO-8859-8              Y   glibc aix hpux osf solaris
+#   ISO-8859-9              Y   glibc aix hpux irix osf solaris darwin
+#   ISO-8859-13                 glibc netbsd darwin
+#   ISO-8859-14                 glibc
+#   ISO-8859-15                 glibc aix osf solaris freebsd darwin
+#   KOI8-R                  Y   glibc solaris freebsd netbsd darwin
+#   KOI8-U                  Y   glibc freebsd netbsd darwin
+#   KOI8-T                      glibc
+#   CP437                       dos
+#   CP775                       dos
+#   CP850                       aix osf dos
+#   CP852                       dos
+#   CP855                       dos
+#   CP856                       aix
+#   CP857                       dos
+#   CP861                       dos
+#   CP862                       dos
+#   CP864                       dos
+#   CP865                       dos
+#   CP866                       freebsd netbsd darwin dos
+#   CP869                       dos
+#   CP874                       woe32 dos
+#   CP922                       aix
+#   CP932                       aix woe32 dos
+#   CP943                       aix
+#   CP949                       osf woe32 dos
+#   CP950                       woe32 dos
+#   CP1046                      aix
+#   CP1124                      aix
+#   CP1125                      dos
+#   CP1129                      aix
+#   CP1250                      woe32
+#   CP1251                      glibc solaris netbsd darwin woe32
+#   CP1252                      aix woe32
+#   CP1253                      woe32
+#   CP1254                      woe32
+#   CP1255                      glibc woe32
+#   CP1256                      woe32
+#   CP1257                      woe32
+#   GB2312                  Y   glibc aix hpux irix solaris freebsd netbsd darwin
+#   EUC-JP                  Y   glibc aix hpux irix osf solaris freebsd netbsd darwin
+#   EUC-KR                  Y   glibc aix hpux irix osf solaris freebsd netbsd darwin
+#   EUC-TW                      glibc aix hpux irix osf solaris netbsd
+#   BIG5                    Y   glibc aix hpux osf solaris freebsd netbsd darwin
+#   BIG5-HKSCS                  glibc solaris
+#   GBK                         glibc aix osf solaris woe32 dos
+#   GB18030                     glibc solaris netbsd
+#   SHIFT_JIS               Y   hpux osf solaris freebsd netbsd darwin
+#   JOHAB                       glibc solaris woe32
+#   TIS-620                     glibc aix hpux osf solaris
+#   VISCII                  Y   glibc
+#   TCVN5712-1                  glibc
+#   GEORGIAN-PS                 glibc
+#   HP-ROMAN8                   hpux
+#   HP-ARABIC8                  hpux
+#   HP-GREEK8                   hpux
+#   HP-HEBREW8                  hpux
+#   HP-TURKISH8                 hpux
+#   HP-KANA8                    hpux
+#   DEC-KANJI                   osf
+#   DEC-HANYU                   osf
+#   UTF-8                   Y   glibc aix hpux osf solaris netbsd darwin
+#
+# Note: Names which are not marked as being a MIME name should not be used in
+# Internet protocols for information interchange (mail, news, etc.).
+#
+# Note: ASCII and ANSI_X3.4-1968 are synonymous canonical names. Applications
+# must understand both names and treat them as equivalent.
+#
+# The first argument passed to this file is the canonical host specification,
+#    CPU_TYPE-MANUFACTURER-OPERATING_SYSTEM
+# or
+#    CPU_TYPE-MANUFACTURER-KERNEL-OPERATING_SYSTEM
+
+host="$1"
+os=`echo "$host" | sed -e 's/^[^-]*-[^-]*-\(.*\)$/\1/'`
+echo "# This file contains a table of character encoding aliases,"
+echo "# suitable for operating system '${os}'."
+echo "# It was automatically generated from config.charset."
+# List of references, updated during installation:
+echo "# Packages using this file: "
+case "$os" in
+    linux-gnulibc1*)
+       # Linux libc5 doesn't have nl_langinfo(CODESET); therefore
+       # localcharset.c falls back to using the full locale name
+       # from the environment variables.
+       echo "C ASCII"
+       echo "POSIX ASCII"
+       for l in af af_ZA ca ca_ES da da_DK de de_AT de_BE de_CH de_DE de_LU \
+                en en_AU en_BW en_CA en_DK en_GB en_IE en_NZ en_US en_ZA \
+                en_ZW es es_AR es_BO es_CL es_CO es_DO es_EC es_ES es_GT \
+                es_HN es_MX es_PA es_PE es_PY es_SV es_US es_UY es_VE et \
+                et_EE eu eu_ES fi fi_FI fo fo_FO fr fr_BE fr_CA fr_CH fr_FR \
+                fr_LU ga ga_IE gl gl_ES id id_ID in in_ID is is_IS it it_CH \
+                it_IT kl kl_GL nl nl_BE nl_NL no no_NO pt pt_BR pt_PT sv \
+                sv_FI sv_SE; do
+         echo "$l ISO-8859-1"
+         echo "$l.iso-8859-1 ISO-8859-1"
+         echo "$l.iso-8859-15 ISO-8859-15"
+         echo "$l.iso-8859-15@euro ISO-8859-15"
+         echo "$l@euro ISO-8859-15"
+         echo "$l.cp-437 CP437"
+         echo "$l.cp-850 CP850"
+         echo "$l.cp-1252 CP1252"
+         echo "$l.cp-1252@euro CP1252"
+         #echo "$l.atari-st ATARI-ST" # not a commonly used encoding
+         echo "$l.utf-8 UTF-8"
+         echo "$l.utf-8@euro UTF-8"
+       done
+       for l in cs cs_CZ hr hr_HR hu hu_HU pl pl_PL ro ro_RO sk sk_SK sl \
+                sl_SI sr sr_CS sr_YU; do
+         echo "$l ISO-8859-2"
+         echo "$l.iso-8859-2 ISO-8859-2"
+         echo "$l.cp-852 CP852"
+         echo "$l.cp-1250 CP1250"
+         echo "$l.utf-8 UTF-8"
+       done
+       for l in mk mk_MK ru ru_RU; do
+         echo "$l ISO-8859-5"
+         echo "$l.iso-8859-5 ISO-8859-5"
+         echo "$l.koi8-r KOI8-R"
+         echo "$l.cp-866 CP866"
+         echo "$l.cp-1251 CP1251"
+         echo "$l.utf-8 UTF-8"
+       done
+       for l in ar ar_SA; do
+         echo "$l ISO-8859-6"
+         echo "$l.iso-8859-6 ISO-8859-6"
+         echo "$l.cp-864 CP864"
+         #echo "$l.cp-868 CP868" # not a commonly used encoding
+         echo "$l.cp-1256 CP1256"
+         echo "$l.utf-8 UTF-8"
+       done
+       for l in el el_GR gr gr_GR; do
+         echo "$l ISO-8859-7"
+         echo "$l.iso-8859-7 ISO-8859-7"
+         echo "$l.cp-869 CP869"
+         echo "$l.cp-1253 CP1253"
+         echo "$l.cp-1253@euro CP1253"
+         echo "$l.utf-8 UTF-8"
+         echo "$l.utf-8@euro UTF-8"
+       done
+       for l in he he_IL iw iw_IL; do
+         echo "$l ISO-8859-8"
+         echo "$l.iso-8859-8 ISO-8859-8"
+         echo "$l.cp-862 CP862"
+         echo "$l.cp-1255 CP1255"
+         echo "$l.utf-8 UTF-8"
+       done
+       for l in tr tr_TR; do
+         echo "$l ISO-8859-9"
+         echo "$l.iso-8859-9 ISO-8859-9"
+         echo "$l.cp-857 CP857"
+         echo "$l.cp-1254 CP1254"
+         echo "$l.utf-8 UTF-8"
+       done
+       for l in lt lt_LT lv lv_LV; do
+         #echo "$l BALTIC" # not a commonly used encoding, wrong encoding name
+         echo "$l ISO-8859-13"
+       done
+       for l in ru_UA uk uk_UA; do
+         echo "$l KOI8-U"
+       done
+       for l in zh zh_CN; do
+         #echo "$l GB_2312-80" # not a commonly used encoding, wrong encoding name
+         echo "$l GB2312"
+       done
+       for l in ja ja_JP ja_JP.EUC; do
+         echo "$l EUC-JP"
+       done
+       for l in ko ko_KR; do
+         echo "$l EUC-KR"
+       done
+       for l in th th_TH; do
+         echo "$l TIS-620"
+       done
+       for l in fa fa_IR; do
+         #echo "$l ISIRI-3342" # a broken encoding
+         echo "$l.utf-8 UTF-8"
+       done
+       ;;
+    linux* | *-gnu*)
+       # With glibc-2.1 or newer, we don't need any canonicalization,
+       # because glibc has iconv and both glibc and libiconv support all
+       # GNU canonical names directly. Therefore, the Makefile does not
+       # need to install the alias file at all.
+       # The following applies only to glibc-2.0.x and older libcs.
+       echo "ISO_646.IRV:1983 ASCII"
+       ;;
+    aix*)
+       echo "ISO8859-1 ISO-8859-1"
+       echo "ISO8859-2 ISO-8859-2"
+       echo "ISO8859-5 ISO-8859-5"
+       echo "ISO8859-6 ISO-8859-6"
+       echo "ISO8859-7 ISO-8859-7"
+       echo "ISO8859-8 ISO-8859-8"
+       echo "ISO8859-9 ISO-8859-9"
+       echo "ISO8859-15 ISO-8859-15"
+       echo "IBM-850 CP850"
+       echo "IBM-856 CP856"
+       echo "IBM-921 ISO-8859-13"
+       echo "IBM-922 CP922"
+       echo "IBM-932 CP932"
+       echo "IBM-943 CP943"
+       echo "IBM-1046 CP1046"
+       echo "IBM-1124 CP1124"
+       echo "IBM-1129 CP1129"
+       echo "IBM-1252 CP1252"
+       echo "IBM-eucCN GB2312"
+       echo "IBM-eucJP EUC-JP"
+       echo "IBM-eucKR EUC-KR"
+       echo "IBM-eucTW EUC-TW"
+       echo "big5 BIG5"
+       echo "GBK GBK"
+       echo "TIS-620 TIS-620"
+       echo "UTF-8 UTF-8"
+       ;;
+    hpux*)
+       echo "iso88591 ISO-8859-1"
+       echo "iso88592 ISO-8859-2"
+       echo "iso88595 ISO-8859-5"
+       echo "iso88596 ISO-8859-6"
+       echo "iso88597 ISO-8859-7"
+       echo "iso88598 ISO-8859-8"
+       echo "iso88599 ISO-8859-9"
+       echo "iso885915 ISO-8859-15"
+       echo "roman8 HP-ROMAN8"
+       echo "arabic8 HP-ARABIC8"
+       echo "greek8 HP-GREEK8"
+       echo "hebrew8 HP-HEBREW8"
+       echo "turkish8 HP-TURKISH8"
+       echo "kana8 HP-KANA8"
+       echo "tis620 TIS-620"
+       echo "big5 BIG5"
+       echo "eucJP EUC-JP"
+       echo "eucKR EUC-KR"
+       echo "eucTW EUC-TW"
+       echo "hp15CN GB2312"
+       #echo "ccdc ?" # what is this?
+       echo "SJIS SHIFT_JIS"
+       echo "utf8 UTF-8"
+       ;;
+    irix*)
+       echo "ISO8859-1 ISO-8859-1"
+       echo "ISO8859-2 ISO-8859-2"
+       echo "ISO8859-5 ISO-8859-5"
+       echo "ISO8859-7 ISO-8859-7"
+       echo "ISO8859-9 ISO-8859-9"
+       echo "eucCN GB2312"
+       echo "eucJP EUC-JP"
+       echo "eucKR EUC-KR"
+       echo "eucTW EUC-TW"
+       ;;
+    osf*)
+       echo "ISO8859-1 ISO-8859-1"
+       echo "ISO8859-2 ISO-8859-2"
+       echo "ISO8859-4 ISO-8859-4"
+       echo "ISO8859-5 ISO-8859-5"
+       echo "ISO8859-7 ISO-8859-7"
+       echo "ISO8859-8 ISO-8859-8"
+       echo "ISO8859-9 ISO-8859-9"
+       echo "ISO8859-15 ISO-8859-15"
+       echo "cp850 CP850"
+       echo "big5 BIG5"
+       echo "dechanyu DEC-HANYU"
+       echo "dechanzi GB2312"
+       echo "deckanji DEC-KANJI"
+       echo "deckorean EUC-KR"
+       echo "eucJP EUC-JP"
+       echo "eucKR EUC-KR"
+       echo "eucTW EUC-TW"
+       echo "GBK GBK"
+       echo "KSC5601 CP949"
+       echo "sdeckanji EUC-JP"
+       echo "SJIS SHIFT_JIS"
+       echo "TACTIS TIS-620"
+       echo "UTF-8 UTF-8"
+       ;;
+    solaris*)
+       echo "646 ASCII"
+       echo "ISO8859-1 ISO-8859-1"
+       echo "ISO8859-2 ISO-8859-2"
+       echo "ISO8859-3 ISO-8859-3"
+       echo "ISO8859-4 ISO-8859-4"
+       echo "ISO8859-5 ISO-8859-5"
+       echo "ISO8859-6 ISO-8859-6"
+       echo "ISO8859-7 ISO-8859-7"
+       echo "ISO8859-8 ISO-8859-8"
+       echo "ISO8859-9 ISO-8859-9"
+       echo "ISO8859-15 ISO-8859-15"
+       echo "koi8-r KOI8-R"
+       echo "ansi-1251 CP1251"
+       echo "BIG5 BIG5"
+       echo "Big5-HKSCS BIG5-HKSCS"
+       echo "gb2312 GB2312"
+       echo "GBK GBK"
+       echo "GB18030 GB18030"
+       echo "cns11643 EUC-TW"
+       echo "5601 EUC-KR"
+       echo "ko_KR.johap92 JOHAB"
+       echo "eucJP EUC-JP"
+       echo "PCK SHIFT_JIS"
+       echo "TIS620.2533 TIS-620"
+       #echo "sun_eu_greek ?" # what is this?
+       echo "UTF-8 UTF-8"
+       ;;
+    freebsd* | os2*)
+       # FreeBSD 4.2 doesn't have nl_langinfo(CODESET); therefore
+       # localcharset.c falls back to using the full locale name
+       # from the environment variables.
+       # Likewise for OS/2. OS/2 has XFree86 just like FreeBSD. Just
+       # reuse FreeBSD's locale data for OS/2.
+       echo "C ASCII"
+       echo "US-ASCII ASCII"
+       for l in la_LN lt_LN; do
+         echo "$l.ASCII ASCII"
+       done
+       for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \
+                fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT la_LN \
+                lt_LN nl_BE nl_NL no_NO pt_PT sv_SE; do
+         echo "$l.ISO_8859-1 ISO-8859-1"
+         echo "$l.DIS_8859-15 ISO-8859-15"
+       done
+       for l in cs_CZ hr_HR hu_HU la_LN lt_LN pl_PL sl_SI; do
+         echo "$l.ISO_8859-2 ISO-8859-2"
+       done
+       for l in la_LN lt_LT; do
+         echo "$l.ISO_8859-4 ISO-8859-4"
+       done
+       for l in ru_RU ru_SU; do
+         echo "$l.KOI8-R KOI8-R"
+         echo "$l.ISO_8859-5 ISO-8859-5"
+         echo "$l.CP866 CP866"
+       done
+       echo "uk_UA.KOI8-U KOI8-U"
+       echo "zh_TW.BIG5 BIG5"
+       echo "zh_TW.Big5 BIG5"
+       echo "zh_CN.EUC GB2312"
+       echo "ja_JP.EUC EUC-JP"
+       echo "ja_JP.SJIS SHIFT_JIS"
+       echo "ja_JP.Shift_JIS SHIFT_JIS"
+       echo "ko_KR.EUC EUC-KR"
+       ;;
+    netbsd*)
+       echo "646 ASCII"
+       echo "ISO8859-1 ISO-8859-1"
+       echo "ISO8859-2 ISO-8859-2"
+       echo "ISO8859-4 ISO-8859-4"
+       echo "ISO8859-5 ISO-8859-5"
+       echo "ISO8859-7 ISO-8859-7"
+       echo "ISO8859-13 ISO-8859-13"
+       echo "ISO8859-15 ISO-8859-15"
+       echo "eucCN GB2312"
+       echo "eucJP EUC-JP"
+       echo "eucKR EUC-KR"
+       echo "eucTW EUC-TW"
+       echo "BIG5 BIG5"
+       echo "SJIS SHIFT_JIS"
+       ;;
+    darwin[56]*)
+       # Darwin 6.8 doesn't have nl_langinfo(CODESET); therefore
+       # localcharset.c falls back to using the full locale name
+       # from the environment variables.
+       echo "C ASCII"
+       for l in en_AU en_CA en_GB en_US la_LN; do
+         echo "$l.US-ASCII ASCII"
+       done
+       for l in da_DK de_AT de_CH de_DE en_AU en_CA en_GB en_US es_ES \
+                fi_FI fr_BE fr_CA fr_CH fr_FR is_IS it_CH it_IT nl_BE \
+                nl_NL no_NO pt_PT sv_SE; do
+         echo "$l ISO-8859-1"
+         echo "$l.ISO8859-1 ISO-8859-1"
+         echo "$l.ISO8859-15 ISO-8859-15"
+       done
+       for l in la_LN; do
+         echo "$l.ISO8859-1 ISO-8859-1"
+         echo "$l.ISO8859-15 ISO-8859-15"
+       done
+       for l in cs_CZ hr_HR hu_HU la_LN pl_PL sl_SI; do
+         echo "$l.ISO8859-2 ISO-8859-2"
+       done
+       for l in la_LN lt_LT; do
+         echo "$l.ISO8859-4 ISO-8859-4"
+       done
+       for l in ru_RU; do
+         echo "$l.KOI8-R KOI8-R"
+         echo "$l.ISO8859-5 ISO-8859-5"
+         echo "$l.CP866 CP866"
+       done
+       for l in bg_BG; do
+         echo "$l.CP1251 CP1251"
+       done
+       echo "uk_UA.KOI8-U KOI8-U"
+       echo "zh_TW.BIG5 BIG5"
+       echo "zh_TW.Big5 BIG5"
+       echo "zh_CN.EUC GB2312"
+       echo "ja_JP.EUC EUC-JP"
+       echo "ja_JP.SJIS SHIFT_JIS"
+       echo "ko_KR.EUC EUC-KR"
+       ;;
+    darwin*)
+       # Darwin 7.5 has nl_langinfo(CODESET), but it is useless:
+       # - It returns the empty string when LANG is set to a locale of the
+       #   form ll_CC, although ll_CC/LC_CTYPE is a symlink to an UTF-8
+       #   LC_CTYPE file.
+       # - The environment variables LANG, LC_CTYPE, LC_ALL are not set by
+       #   the system; nl_langinfo(CODESET) returns "US-ASCII" in this case.
+       # - The documentation says:
+       #     "... all code that calls BSD system routines should ensure
+       #      that the const *char parameters of these routines are in UTF-8
+       #      encoding. All BSD system functions expect their string
+       #      parameters to be in UTF-8 encoding and nothing else."
+       #   It also says
+       #     "An additional caveat is that string parameters for files,
+       #      paths, and other file-system entities must be in canonical
+       #      UTF-8. In a canonical UTF-8 Unicode string, all decomposable
+       #      characters are decomposed ..."
+       #   but this is not true: You can pass non-decomposed UTF-8 strings
+       #   to file system functions, and it is the OS which will convert
+       #   them to decomposed UTF-8 before accessing the file system.
+       # - The Apple Terminal application displays UTF-8 by default.
+       # - However, other applications are free to use different encodings:
+       #   - xterm uses ISO-8859-1 by default.
+       #   - TextEdit uses MacRoman by default.
+       # We prefer UTF-8 over decomposed UTF-8-MAC because one should
+       # minimize the use of decomposed Unicode. Unfortunately, through the
+       # Darwin file system, decomposed UTF-8 strings are leaked into user
+       # space nevertheless.
+       echo "* UTF-8"
+       ;;
+    beos*)
+       # BeOS has a single locale, and it has UTF-8 encoding.
+       echo "* UTF-8"
+       ;;
+    msdosdjgpp*)
+       # DJGPP 2.03 doesn't have nl_langinfo(CODESET); therefore
+       # localcharset.c falls back to using the full locale name
+       # from the environment variables.
+       echo "#"
+       echo "# The encodings given here may not all be correct."
+       echo "# If you find that the encoding given for your language and"
+       echo "# country is not the one your DOS machine actually uses, just"
+       echo "# correct it in this file, and send a mail to"
+       echo "# Juan Manuel Guerrero <juan.guerrero@gmx.de>"
+       echo "# and Bruno Haible <bruno@clisp.org>."
+       echo "#"
+       echo "C ASCII"
+       # ISO-8859-1 languages
+       echo "ca CP850"
+       echo "ca_ES CP850"
+       echo "da CP865"    # not CP850 ??
+       echo "da_DK CP865" # not CP850 ??
+       echo "de CP850"
+       echo "de_AT CP850"
+       echo "de_CH CP850"
+       echo "de_DE CP850"
+       echo "en CP850"
+       echo "en_AU CP850" # not CP437 ??
+       echo "en_CA CP850"
+       echo "en_GB CP850"
+       echo "en_NZ CP437"
+       echo "en_US CP437"
+       echo "en_ZA CP850" # not CP437 ??
+       echo "es CP850"
+       echo "es_AR CP850"
+       echo "es_BO CP850"
+       echo "es_CL CP850"
+       echo "es_CO CP850"
+       echo "es_CR CP850"
+       echo "es_CU CP850"
+       echo "es_DO CP850"
+       echo "es_EC CP850"
+       echo "es_ES CP850"
+       echo "es_GT CP850"
+       echo "es_HN CP850"
+       echo "es_MX CP850"
+       echo "es_NI CP850"
+       echo "es_PA CP850"
+       echo "es_PY CP850"
+       echo "es_PE CP850"
+       echo "es_SV CP850"
+       echo "es_UY CP850"
+       echo "es_VE CP850"
+       echo "et CP850"
+       echo "et_EE CP850"
+       echo "eu CP850"
+       echo "eu_ES CP850"
+       echo "fi CP850"
+       echo "fi_FI CP850"
+       echo "fr CP850"
+       echo "fr_BE CP850"
+       echo "fr_CA CP850"
+       echo "fr_CH CP850"
+       echo "fr_FR CP850"
+       echo "ga CP850"
+       echo "ga_IE CP850"
+       echo "gd CP850"
+       echo "gd_GB CP850"
+       echo "gl CP850"
+       echo "gl_ES CP850"
+       echo "id CP850"    # not CP437 ??
+       echo "id_ID CP850" # not CP437 ??
+       echo "is CP861"    # not CP850 ??
+       echo "is_IS CP861" # not CP850 ??
+       echo "it CP850"
+       echo "it_CH CP850"
+       echo "it_IT CP850"
+       echo "lt CP775"
+       echo "lt_LT CP775"
+       echo "lv CP775"
+       echo "lv_LV CP775"
+       echo "nb CP865"    # not CP850 ??
+       echo "nb_NO CP865" # not CP850 ??
+       echo "nl CP850"
+       echo "nl_BE CP850"
+       echo "nl_NL CP850"
+       echo "nn CP865"    # not CP850 ??
+       echo "nn_NO CP865" # not CP850 ??
+       echo "no CP865"    # not CP850 ??
+       echo "no_NO CP865" # not CP850 ??
+       echo "pt CP850"
+       echo "pt_BR CP850"
+       echo "pt_PT CP850"
+       echo "sv CP850"
+       echo "sv_SE CP850"
+       # ISO-8859-2 languages
+       echo "cs CP852"
+       echo "cs_CZ CP852"
+       echo "hr CP852"
+       echo "hr_HR CP852"
+       echo "hu CP852"
+       echo "hu_HU CP852"
+       echo "pl CP852"
+       echo "pl_PL CP852"
+       echo "ro CP852"
+       echo "ro_RO CP852"
+       echo "sk CP852"
+       echo "sk_SK CP852"
+       echo "sl CP852"
+       echo "sl_SI CP852"
+       echo "sq CP852"
+       echo "sq_AL CP852"
+       echo "sr CP852"    # CP852 or CP866 or CP855 ??
+       echo "sr_CS CP852" # CP852 or CP866 or CP855 ??
+       echo "sr_YU CP852" # CP852 or CP866 or CP855 ??
+       # ISO-8859-3 languages
+       echo "mt CP850"
+       echo "mt_MT CP850"
+       # ISO-8859-5 languages
+       echo "be CP866"
+       echo "be_BE CP866"
+       echo "bg CP866"    # not CP855 ??
+       echo "bg_BG CP866" # not CP855 ??
+       echo "mk CP866"    # not CP855 ??
+       echo "mk_MK CP866" # not CP855 ??
+       echo "ru CP866"
+       echo "ru_RU CP866"
+       echo "uk CP1125"
+       echo "uk_UA CP1125"
+       # ISO-8859-6 languages
+       echo "ar CP864"
+       echo "ar_AE CP864"
+       echo "ar_DZ CP864"
+       echo "ar_EG CP864"
+       echo "ar_IQ CP864"
+       echo "ar_IR CP864"
+       echo "ar_JO CP864"
+       echo "ar_KW CP864"
+       echo "ar_MA CP864"
+       echo "ar_OM CP864"
+       echo "ar_QA CP864"
+       echo "ar_SA CP864"
+       echo "ar_SY CP864"
+       # ISO-8859-7 languages
+       echo "el CP869"
+       echo "el_GR CP869"
+       # ISO-8859-8 languages
+       echo "he CP862"
+       echo "he_IL CP862"
+       # ISO-8859-9 languages
+       echo "tr CP857"
+       echo "tr_TR CP857"
+       # Japanese
+       echo "ja CP932"
+       echo "ja_JP CP932"
+       # Chinese
+       echo "zh_CN GBK"
+       echo "zh_TW CP950" # not CP938 ??
+       # Korean
+       echo "kr CP949"    # not CP934 ??
+       echo "kr_KR CP949" # not CP934 ??
+       # Thai
+       echo "th CP874"
+       echo "th_TH CP874"
+       # Other
+       echo "eo CP850"
+       echo "eo_EO CP850"
+       ;;
+esac
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/glibc21.m4 b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/glibc21.m4
new file mode 100644 (file)
index 0000000..d95fd98
--- /dev/null
@@ -0,0 +1,30 @@
+# glibc21.m4 serial 3
+dnl Copyright (C) 2000-2002, 2004 Free Software Foundation, Inc.
+dnl This file is free software; the Free Software Foundation
+dnl gives unlimited permission to copy and/or distribute it,
+dnl with or without modifications, as long as this notice is preserved.
+
+# Test for the GNU C Library, version 2.1 or newer.
+# From Bruno Haible.
+
+AC_DEFUN([gl_GLIBC21],
+  [
+    AC_CACHE_CHECK(whether we are using the GNU C Library 2.1 or newer,
+      ac_cv_gnu_library_2_1,
+      [AC_EGREP_CPP([Lucky GNU user],
+       [
+#include <features.h>
+#ifdef __GNU_LIBRARY__
+ #if (__GLIBC__ == 2 && __GLIBC_MINOR__ >= 1) || (__GLIBC__ > 2)
+  Lucky GNU user
+ #endif
+#endif
+       ],
+       ac_cv_gnu_library_2_1=yes,
+       ac_cv_gnu_library_2_1=no)
+      ]
+    )
+    AC_SUBST(GLIBC21)
+    GLIBC21="$ac_cv_gnu_library_2_1"
+  ]
+)
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/libcharset-glib.patch b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/libcharset-glib.patch
new file mode 100644 (file)
index 0000000..358d774
--- /dev/null
@@ -0,0 +1,77 @@
+# Patch against libcharset version 1.4
+--- libiconv-1.12/libcharset//lib/localcharset.c       2006-10-18 07:55:49.000000000 -0400
++++ localcharset.c     2008-05-20 18:36:24.000000000 -0400
+@@ -103,8 +103,8 @@
+ static const char * volatile charset_aliases;
+ /* Return a pointer to the contents of the charset.alias file.  */
+-static const char *
+-get_charset_aliases (void)
++const char *
++_g_locale_get_charset_aliases (void)
+ {
+   const char *cp;
+@@ -280,14 +280,10 @@
+    If the canonical name cannot be determined, the result is a non-canonical
+    name.  */
+-#ifdef STATIC
+-STATIC
+-#endif
+ const char *
+-locale_charset (void)
++_g_locale_charset_raw (void)
+ {
+   const char *codeset;
+-  const char *aliases;
+ #if !(defined WIN32_NATIVE || defined OS2)
+@@ -436,12 +432,20 @@
+ #endif
++  return codeset;
++}
++
++const char *
++_g_locale_charset_unalias (const char *codeset)
++{
++  const char *aliases;
++
+   if (codeset == NULL)
+     /* The canonical name cannot be determined.  */
+     codeset = "";
+   /* Resolve alias. */
+-  for (aliases = get_charset_aliases ();
++  for (aliases = _g_locale_get_charset_aliases ();
+        *aliases != '\0';
+        aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
+     if (strcmp (codeset, aliases) == 0
+--- libiconv-1.12/libcharset//include/libcharset.h.in  2005-05-19 13:14:56.000000000 -0400
++++ libcharset.h       2008-05-20 18:39:44.000000000 -0400
+@@ -19,7 +19,7 @@
+ #ifndef _LIBCHARSET_H
+ #define _LIBCHARSET_H
+-#include <localcharset.h>
++#include "localcharset.h"
+ #ifdef __cplusplus
+--- libiconv-1.12/libcharset//include/localcharset.h.in        2005-05-19 13:14:57.000000000 -0400
++++ localcharset.h     2008-05-20 18:36:24.000000000 -0400
+@@ -31,8 +31,9 @@
+    The result must not be freed; it is statically allocated.
+    If the canonical name cannot be determined, the result is a non-canonical
+    name.  */
+-extern const char * locale_charset (void);
+-
++extern const char * _g_locale_charset_raw (void);
++extern const char * _g_locale_charset_unalias (const char *codeset);
++extern const char * _g_locale_get_charset_aliases (void);
+ #ifdef __cplusplus
+ }
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/libcharset.h b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/libcharset.h
new file mode 100644 (file)
index 0000000..686241e
--- /dev/null
@@ -0,0 +1,46 @@
+/* Copyright (C) 2003 Free Software Foundation, Inc.
+   This file is part of the GNU CHARSET Library.
+
+   The GNU CHARSET Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The GNU CHARSET 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 Library General Public License
+   along with the GNU CHARSET Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 51 Franklin Street,
+   Fifth Floor, Boston, MA 02110-1301, USA.  */
+
+#ifndef _LIBCHARSET_H
+#define _LIBCHARSET_H
+
+#include "localcharset.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Support for relocatable packages.  */
+
+/* Sets the original and the current installation prefix of the package.
+   Relocation simply replaces a pathname starting with the original prefix
+   by the corresponding pathname with the current prefix instead.  Both
+   prefixes should be directory names without trailing slash (i.e. use ""
+   instead of "/").  */
+extern void libcharset_set_relocation_prefix (const char *orig_prefix,
+                                             const char *curr_prefix);
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _LIBCHARSET_H */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/localcharset.c b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/localcharset.c
new file mode 100644 (file)
index 0000000..0d001f9
--- /dev/null
@@ -0,0 +1,465 @@
+/* Determine a canonical name for the current locale's character encoding.
+
+   Copyright (C) 2000-2006 Free Software Foundation, Inc.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library General Public License as published
+   by the Free Software Foundation; either version 2, 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+   USA.  */
+
+/* Written by Bruno Haible <bruno@clisp.org>.  */
+
+#include "config.h"
+
+/* Specification.  */
+#include "localcharset.h"
+
+#include <stddef.h>
+#include <stdio.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if defined _WIN32 || defined __WIN32__
+# define WIN32_NATIVE
+#endif
+
+#if defined __EMX__
+/* Assume EMX program runs on OS/2, even if compiled under DOS.  */
+# define OS2
+#endif
+
+#if !defined WIN32_NATIVE
+# if HAVE_LANGINFO_CODESET
+#  include <langinfo.h>
+# else
+#  if 0 /* see comment below */
+#   include <locale.h>
+#  endif
+# endif
+# ifdef __CYGWIN__
+#  define WIN32_LEAN_AND_MEAN
+#  include <windows.h>
+# endif
+#elif defined WIN32_NATIVE
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+#endif
+#if defined OS2
+# define INCL_DOS
+# include <os2.h>
+#endif
+
+#if ENABLE_RELOCATABLE
+# include "relocatable.h"
+#else
+# define relocate(pathname) (pathname)
+#endif
+
+/* Get LIBDIR.  */
+#ifndef LIBDIR
+# include "configmake.h"
+#endif
+
+#if defined _WIN32 || defined __WIN32__ || defined __CYGWIN__ || defined __EMX__ || defined __DJGPP__
+  /* Win32, Cygwin, OS/2, DOS */
+# define ISSLASH(C) ((C) == '/' || (C) == '\\')
+#endif
+
+#ifndef DIRECTORY_SEPARATOR
+# define DIRECTORY_SEPARATOR '/'
+#endif
+
+#ifndef ISSLASH
+# define ISSLASH(C) ((C) == DIRECTORY_SEPARATOR)
+#endif
+
+#if HAVE_DECL_GETC_UNLOCKED
+# undef getc
+# define getc getc_unlocked
+#endif
+
+/* The following static variable is declared 'volatile' to avoid a
+   possible multithread problem in the function get_charset_aliases. If we
+   are running in a threaded environment, and if two threads initialize
+   'charset_aliases' simultaneously, both will produce the same value,
+   and everything will be ok if the two assignments to 'charset_aliases'
+   are atomic. But I don't know what will happen if the two assignments mix.  */
+#if __STDC__ != 1
+# define volatile /* empty */
+#endif
+/* Pointer to the contents of the charset.alias file, if it has already been
+   read, else NULL.  Its format is:
+   ALIAS_1 '\0' CANONICAL_1 '\0' ... ALIAS_n '\0' CANONICAL_n '\0' '\0'  */
+static const char * volatile charset_aliases;
+
+/* Return a pointer to the contents of the charset.alias file.  */
+const char *
+_g_locale_get_charset_aliases (void)
+{
+  const char *cp;
+
+  cp = charset_aliases;
+  if (cp == NULL)
+    {
+#if !(defined VMS || defined WIN32_NATIVE || defined __CYGWIN__)
+      FILE *fp;
+      const char *dir;
+      const char *base = "charset.alias";
+      char *file_name;
+
+      /* Make it possible to override the charset.alias location.  This is
+        necessary for running the testsuite before "make install".  */
+      dir = getenv ("CHARSETALIASDIR");
+      if (dir == NULL || dir[0] == '\0')
+       dir = relocate (LIBDIR);
+
+      /* Concatenate dir and base into freshly allocated file_name.  */
+      {
+       size_t dir_len = strlen (dir);
+       size_t base_len = strlen (base);
+       int add_slash = (dir_len > 0 && !ISSLASH (dir[dir_len - 1]));
+       file_name = (char *) malloc (dir_len + add_slash + base_len + 1);
+       if (file_name != NULL)
+         {
+           memcpy (file_name, dir, dir_len);
+           if (add_slash)
+             file_name[dir_len] = DIRECTORY_SEPARATOR;
+           memcpy (file_name + dir_len + add_slash, base, base_len + 1);
+         }
+      }
+
+      if (file_name == NULL || (fp = fopen (file_name, "r")) == NULL)
+       /* Out of memory or file not found, treat it as empty.  */
+       cp = "";
+      else
+       {
+         /* Parse the file's contents.  */
+         char *res_ptr = NULL;
+         size_t res_size = 0;
+
+         for (;;)
+           {
+             int c;
+             char buf1[50+1];
+             char buf2[50+1];
+             size_t l1, l2;
+             char *old_res_ptr;
+
+             c = getc (fp);
+             if (c == EOF)
+               break;
+             if (c == '\n' || c == ' ' || c == '\t')
+               continue;
+             if (c == '#')
+               {
+                 /* Skip comment, to end of line.  */
+                 do
+                   c = getc (fp);
+                 while (!(c == EOF || c == '\n'));
+                 if (c == EOF)
+                   break;
+                 continue;
+               }
+             ungetc (c, fp);
+             if (fscanf (fp, "%50s %50s", buf1, buf2) < 2)
+               break;
+             l1 = strlen (buf1);
+             l2 = strlen (buf2);
+             old_res_ptr = res_ptr;
+             if (res_size == 0)
+               {
+                 res_size = l1 + 1 + l2 + 1;
+                 res_ptr = (char *) malloc (res_size + 1);
+               }
+             else
+               {
+                 res_size += l1 + 1 + l2 + 1;
+                 res_ptr = (char *) realloc (res_ptr, res_size + 1);
+               }
+             if (res_ptr == NULL)
+               {
+                 /* Out of memory. */
+                 res_size = 0;
+                 if (old_res_ptr != NULL)
+                   free (old_res_ptr);
+                 break;
+               }
+             strcpy (res_ptr + res_size - (l2 + 1) - (l1 + 1), buf1);
+             strcpy (res_ptr + res_size - (l2 + 1), buf2);
+           }
+         fclose (fp);
+         if (res_size == 0)
+           cp = "";
+         else
+           {
+             *(res_ptr + res_size) = '\0';
+             cp = res_ptr;
+           }
+       }
+
+      if (file_name != NULL)
+       free (file_name);
+
+#else
+
+# if defined VMS
+      /* To avoid the troubles of an extra file charset.alias_vms in the
+        sources of many GNU packages, simply inline the aliases here.  */
+      /* The list of encodings is taken from the OpenVMS 7.3-1 documentation
+        "Compaq C Run-Time Library Reference Manual for OpenVMS systems"
+        section 10.7 "Handling Different Character Sets".  */
+      cp = "ISO8859-1" "\0" "ISO-8859-1" "\0"
+          "ISO8859-2" "\0" "ISO-8859-2" "\0"
+          "ISO8859-5" "\0" "ISO-8859-5" "\0"
+          "ISO8859-7" "\0" "ISO-8859-7" "\0"
+          "ISO8859-8" "\0" "ISO-8859-8" "\0"
+          "ISO8859-9" "\0" "ISO-8859-9" "\0"
+          /* Japanese */
+          "eucJP" "\0" "EUC-JP" "\0"
+          "SJIS" "\0" "SHIFT_JIS" "\0"
+          "DECKANJI" "\0" "DEC-KANJI" "\0"
+          "SDECKANJI" "\0" "EUC-JP" "\0"
+          /* Chinese */
+          "eucTW" "\0" "EUC-TW" "\0"
+          "DECHANYU" "\0" "DEC-HANYU" "\0"
+          "DECHANZI" "\0" "GB2312" "\0"
+          /* Korean */
+          "DECKOREAN" "\0" "EUC-KR" "\0";
+# endif
+
+# if defined WIN32_NATIVE || defined __CYGWIN__
+      /* To avoid the troubles of installing a separate file in the same
+        directory as the DLL and of retrieving the DLL's directory at
+        runtime, simply inline the aliases here.  */
+
+      cp = "CP936" "\0" "GBK" "\0"
+          "CP1361" "\0" "JOHAB" "\0"
+          "CP20127" "\0" "ASCII" "\0"
+          "CP20866" "\0" "KOI8-R" "\0"
+          "CP20936" "\0" "GB2312" "\0"
+          "CP21866" "\0" "KOI8-RU" "\0"
+          "CP28591" "\0" "ISO-8859-1" "\0"
+          "CP28592" "\0" "ISO-8859-2" "\0"
+          "CP28593" "\0" "ISO-8859-3" "\0"
+          "CP28594" "\0" "ISO-8859-4" "\0"
+          "CP28595" "\0" "ISO-8859-5" "\0"
+          "CP28596" "\0" "ISO-8859-6" "\0"
+          "CP28597" "\0" "ISO-8859-7" "\0"
+          "CP28598" "\0" "ISO-8859-8" "\0"
+          "CP28599" "\0" "ISO-8859-9" "\0"
+          "CP28605" "\0" "ISO-8859-15" "\0"
+          "CP38598" "\0" "ISO-8859-8" "\0"
+          "CP51932" "\0" "EUC-JP" "\0"
+          "CP51936" "\0" "GB2312" "\0"
+          "CP51949" "\0" "EUC-KR" "\0"
+          "CP51950" "\0" "EUC-TW" "\0"
+          "CP54936" "\0" "GB18030" "\0"
+          "CP65001" "\0" "UTF-8" "\0";
+# endif
+#endif
+
+      charset_aliases = cp;
+    }
+
+  return cp;
+}
+
+/* Determine the current locale's character encoding, and canonicalize it
+   into one of the canonical names listed in config.charset.
+   The result must not be freed; it is statically allocated.
+   If the canonical name cannot be determined, the result is a non-canonical
+   name.  */
+
+const char *
+_g_locale_charset_raw (void)
+{
+  const char *codeset;
+
+#if !(defined WIN32_NATIVE || defined OS2)
+
+# if HAVE_LANGINFO_CODESET
+
+  /* Most systems support nl_langinfo (CODESET) nowadays.  */
+  codeset = nl_langinfo (CODESET);
+
+#  ifdef __CYGWIN__
+  /* Cygwin 2006 does not have locales.  nl_langinfo (CODESET) always
+     returns "US-ASCII".  As long as this is not fixed, return the suffix
+     of the locale name from the environment variables (if present) or
+     the codepage as a number.  */
+  if (codeset != NULL && strcmp (codeset, "US-ASCII") == 0)
+    {
+      const char *locale;
+      static char buf[2 + 10 + 1];
+
+      locale = getenv ("LC_ALL");
+      if (locale == NULL || locale[0] == '\0')
+       {
+         locale = getenv ("LC_CTYPE");
+         if (locale == NULL || locale[0] == '\0')
+           locale = getenv ("LANG");
+       }
+      if (locale != NULL && locale[0] != '\0')
+       {
+         /* If the locale name contains an encoding after the dot, return
+            it.  */
+         const char *dot = strchr (locale, '.');
+
+         if (dot != NULL)
+           {
+             const char *modifier;
+
+             dot++;
+             /* Look for the possible @... trailer and remove it, if any.  */
+             modifier = strchr (dot, '@');
+             if (modifier == NULL)
+               return dot;
+             if (modifier - dot < sizeof (buf))
+               {
+                 memcpy (buf, dot, modifier - dot);
+                 buf [modifier - dot] = '\0';
+                 return buf;
+               }
+           }
+       }
+
+      /* Woe32 has a function returning the locale's codepage as a number.  */
+      sprintf (buf, "CP%u", GetACP ());
+      codeset = buf;
+    }
+#  endif
+
+# else
+
+  /* On old systems which lack it, use setlocale or getenv.  */
+  const char *locale = NULL;
+
+  /* But most old systems don't have a complete set of locales.  Some
+     (like SunOS 4 or DJGPP) have only the C locale.  Therefore we don't
+     use setlocale here; it would return "C" when it doesn't support the
+     locale name the user has set.  */
+#  if 0
+  locale = setlocale (LC_CTYPE, NULL);
+#  endif
+  if (locale == NULL || locale[0] == '\0')
+    {
+      locale = getenv ("LC_ALL");
+      if (locale == NULL || locale[0] == '\0')
+       {
+         locale = getenv ("LC_CTYPE");
+         if (locale == NULL || locale[0] == '\0')
+           locale = getenv ("LANG");
+       }
+    }
+
+  /* On some old systems, one used to set locale = "iso8859_1". On others,
+     you set it to "language_COUNTRY.charset". In any case, we resolve it
+     through the charset.alias file.  */
+  codeset = locale;
+
+# endif
+
+#elif defined WIN32_NATIVE
+
+  static char buf[2 + 10 + 1];
+
+  /* Woe32 has a function returning the locale's codepage as a number.  */
+  sprintf (buf, "CP%u", GetACP ());
+  codeset = buf;
+
+#elif defined OS2
+
+  const char *locale;
+  static char buf[2 + 10 + 1];
+  ULONG cp[3];
+  ULONG cplen;
+
+  /* Allow user to override the codeset, as set in the operating system,
+     with standard language environment variables.  */
+  locale = getenv ("LC_ALL");
+  if (locale == NULL || locale[0] == '\0')
+    {
+      locale = getenv ("LC_CTYPE");
+      if (locale == NULL || locale[0] == '\0')
+       locale = getenv ("LANG");
+    }
+  if (locale != NULL && locale[0] != '\0')
+    {
+      /* If the locale name contains an encoding after the dot, return it.  */
+      const char *dot = strchr (locale, '.');
+
+      if (dot != NULL)
+       {
+         const char *modifier;
+
+         dot++;
+         /* Look for the possible @... trailer and remove it, if any.  */
+         modifier = strchr (dot, '@');
+         if (modifier == NULL)
+           return dot;
+         if (modifier - dot < sizeof (buf))
+           {
+             memcpy (buf, dot, modifier - dot);
+             buf [modifier - dot] = '\0';
+             return buf;
+           }
+       }
+
+      /* Resolve through the charset.alias file.  */
+      codeset = locale;
+    }
+  else
+    {
+      /* OS/2 has a function returning the locale's codepage as a number.  */
+      if (DosQueryCp (sizeof (cp), cp, &cplen))
+       codeset = "";
+      else
+       {
+         sprintf (buf, "CP%u", cp[0]);
+         codeset = buf;
+       }
+    }
+
+#endif
+
+  return codeset;
+}
+
+const char *
+_g_locale_charset_unalias (const char *codeset)
+{
+  const char *aliases;
+
+  if (codeset == NULL)
+    /* The canonical name cannot be determined.  */
+    codeset = "";
+
+  /* Resolve alias. */
+  for (aliases = _g_locale_get_charset_aliases ();
+       *aliases != '\0';
+       aliases += strlen (aliases) + 1, aliases += strlen (aliases) + 1)
+    if (strcmp (codeset, aliases) == 0
+       || (aliases[0] == '*' && aliases[1] == '\0'))
+      {
+       codeset = aliases + strlen (aliases) + 1;
+       break;
+      }
+
+  /* Don't return an empty string.  GNU libc and GNU libiconv interpret
+     the empty string as denoting "the locale's character encoding",
+     thus GNU libiconv would call this function a second time.  */
+  if (codeset[0] == '\0')
+    codeset = "ASCII";
+
+  return codeset;
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/localcharset.h b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/localcharset.h
new file mode 100644 (file)
index 0000000..674aa3a
--- /dev/null
@@ -0,0 +1,43 @@
+/* Determine a canonical name for the current locale's character encoding.
+   Copyright (C) 2000-2003 Free Software Foundation, Inc.
+   This file is part of the GNU CHARSET Library.
+
+   This program is free software; you can redistribute it and/or modify it
+   under the terms of the GNU Library General Public License as published
+   by the Free Software Foundation; either version 2, 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with this program; if not, write to the Free Software
+   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+   USA.  */
+
+#ifndef _LOCALCHARSET_H
+#define _LOCALCHARSET_H
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/* Determine the current locale's character encoding, and canonicalize it
+   into one of the canonical names listed in config.charset.
+   The result must not be freed; it is statically allocated.
+   If the canonical name cannot be determined, the result is a non-canonical
+   name.  */
+extern const char * _g_locale_charset_raw (void);
+extern const char * _g_locale_charset_unalias (const char *codeset);
+extern const char * _g_locale_get_charset_aliases (void);
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif /* _LOCALCHARSET_H */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/make-patch.sh b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/make-patch.sh
new file mode 100644 (file)
index 0000000..e60014a
--- /dev/null
@@ -0,0 +1,28 @@
+#!/bin/sh
+
+if test $# = 1 ; then 
+  ORIGINAL=$1
+else
+  echo "Usage: make-patch.sh /path/to/libcharset" 1>&2
+  exit 1
+fi
+
+if test -f $ORIGINAL/lib/localcharset.c ; then : ; else
+  echo "Usage: make-patch.sh /path/to/libcharset" 1>&2
+  exit 1
+fi
+
+VERSION=`grep VERSION= $ORIGINAL/configure.ac | sed s/VERSION=//`
+
+echo "# Patch against libcharset version $VERSION" > libcharset-glib.patch
+
+for i in localcharset.c ref-add.sin ref-del.sin ; do
+  diff -u $ORIGINAL/lib/$i $i >> libcharset-glib.patch
+done
+
+for i in glibc21.m4 codeset.m4 ; do
+  diff -u $ORIGINAL/m4/$i $i >> libcharset-glib.patch
+done
+
+diff -u $ORIGINAL/include/libcharset.h.in libcharset.h >> libcharset-glib.patch
+diff -u $ORIGINAL/include/localcharset.h.in localcharset.h >> libcharset-glib.patch
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/ref-add.sin b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/ref-add.sin
new file mode 100644 (file)
index 0000000..0e2b97b
--- /dev/null
@@ -0,0 +1,31 @@
+# Add this package to a list of references stored in a text file.
+#
+#   Copyright (C) 2000 Free Software Foundation, Inc.
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU Library General Public License as published
+#   by the Free Software Foundation; either version 2, 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
+#   Library General Public License for more details.
+#
+#   You should have received a copy of the GNU Library General Public
+#   License along with this program; if not, write to the Free Software
+#   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+#   USA.
+#
+# Written by Bruno Haible <bruno@clisp.org>.
+#
+/^# Packages using this file: / {
+  s/# Packages using this file://
+  ta
+  :a
+  s/ @PACKAGE@ / @PACKAGE@ /
+  tb
+  s/ $/ @PACKAGE@ /
+  :b
+  s/^/# Packages using this file:/
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/ref-del.sin b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/ref-del.sin
new file mode 100644 (file)
index 0000000..1fafbfc
--- /dev/null
@@ -0,0 +1,26 @@
+# Remove this package from a list of references stored in a text file.
+#
+#   Copyright (C) 2000 Free Software Foundation, Inc.
+#
+#   This program is free software; you can redistribute it and/or modify it
+#   under the terms of the GNU Library General Public License as published
+#   by the Free Software Foundation; either version 2, 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
+#   Library General Public License for more details.
+#
+#   You should have received a copy of the GNU Library General Public
+#   License along with this program; if not, write to the Free Software
+#   Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301,
+#   USA.
+#
+# Written by Bruno Haible <bruno@clisp.org>.
+#
+/^# Packages using this file: / {
+  s/# Packages using this file://
+  s/ @PACKAGE@ / /
+  s/^/# Packages using this file:/
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/update.sh b/resource/csdk/connectivity/lib/android/glib-master/glib/libcharset/update.sh
new file mode 100644 (file)
index 0000000..5873fc7
--- /dev/null
@@ -0,0 +1,33 @@
+#!/bin/sh
+
+if test $# = 1 ; then 
+  ORIGINAL=$1
+else
+  echo "Usage: update.sh /path/to/libcharset" 1>&2
+  exit 1
+fi
+
+if test -f $ORIGINAL/lib/localcharset.c ; then : ; else
+  echo "Usage: update.sh /path/to/libcharset" 1>&2
+  exit 1
+fi
+
+VERSION=`grep VERSION= $ORIGINAL/configure.ac | sed s/VERSION=//`
+
+for i in localcharset.c ref-add.sin ref-del.sin config.charset ; do
+  cp $ORIGINAL/lib/$i .
+done
+
+for i in libcharset.h localcharset.h ; do
+  cp $ORIGINAL/include/$i.in ./$i
+done
+
+for i in codeset.m4 glibc21.m4 ; do
+  cp $ORIGINAL/m4/$i .
+done
+
+patch -p0 < libcharset-glib.patch
+
+echo "dnl From libcharset $VERSION" > ../../aclibcharset.m4
+
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/libglib-gdb.py.in b/resource/csdk/connectivity/lib/android/glib-master/glib/libglib-gdb.py.in
new file mode 100644 (file)
index 0000000..78316be
--- /dev/null
@@ -0,0 +1,10 @@
+import sys
+import gdb
+
+# Update module path.
+dir = '@datadir@/glib-2.0/gdb'
+if not dir in sys.path:
+    sys.path.insert(0, dir)
+
+from glib import register
+register (gdb.current_objfile ())
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/makefile.msc.in b/resource/csdk/connectivity/lib/android/glib-master/glib/makefile.msc.in
new file mode 100644 (file)
index 0000000..936d656
--- /dev/null
@@ -0,0 +1,143 @@
+## Makefile for building the GLib dlls with Microsoft C
+## Use: nmake -f makefile.msc
+
+TOP = ..\..
+
+!INCLUDE ..\build\win32\make.msc
+
+################################################################
+
+INCLUDES = -FImsvc_recommended_pragmas.h -I . -I ..
+DEFINES = \
+       -DHAVE_CONFIG_H -DGLIB_COMPILATION -DG_LOG_DOMAIN=\"GLib\" \
+       -DG_ENABLE_DEBUG -DPCRE_STATIC -DG_DISABLE_DEPRECATED \
+       -DDLL_EXPORT=1
+
+DEPCFLAGS = -Zm400 $(INTL_CFLAGS) $(DIRENT_CFLAGS)
+
+all :                          \
+       ..\config.h             \
+       ..\glibconfig.h \
+       gnulib\gnulib.lib       \
+       pcre\pcre.lib           \
+       libglib-2.0-0.dll \
+       glib-@GLIB_MAJOR_VERSION@.@GLIB_MINOR_VERSION@s.lib \
+       gspawn-win32-helper.exe \
+       gspawn-win32-helper-console.exe \
+
+
+gnulib\gnulib.lib :
+       cd gnulib
+       nmake -f makefile.msc
+       cd ..
+
+pcre\pcre.lib :
+       cd pcre
+       nmake -f makefile.msc
+       cd ..
+
+glib_OBJECTS =                 \
+       garray.obj              \
+       gasyncqueue.obj         \
+       gatomic.obj     \
+       gbacktrace.obj          \
+       gbase64.obj     \
+       gbookmarkfile.obj \
+       gcache.obj \
+       gchecksum.obj   \
+       gcompletion.obj \
+       gconvert.obj \
+       gdataset.obj \
+       gdate.obj \
+       gdir.obj \
+       gerror.obj \
+       gfileutils.obj \
+       ghash.obj \
+       ghostutils.obj \
+       ghook.obj \
+       giochannel.obj \
+       giowin32.obj \
+       gpoll.obj \
+       gkeyfile.obj \
+       glist.obj \
+       gmain.obj \
+       gmappedfile.obj \
+       gmarkup.obj \
+       gmem.obj \
+       gmessages.obj \
+       gnode.obj \
+       goption.obj \
+       gpattern.obj \
+       gprimes.obj \
+       gprintf.obj \
+       gqsort.obj \
+       gqueue.obj \
+       grand.obj \
+       gregex.obj \
+       grel.obj \
+       gscanner.obj \
+       gsequence.obj \
+       gshell.obj \
+       gslice.obj \
+       gslist.obj \
+       gspawn-win32.obj \
+       gstdio.obj \
+       gstrfuncs.obj \
+       gstring.obj \
+       gtestutils.obj \
+       gthread.obj \
+       gthreadpool.obj \
+       gtimer.obj \
+       gtree.obj \
+       gunibreak.obj \
+       gunicollate.obj \
+       gunidecomp.obj \
+       guniprop.obj \
+       gurifuncs.obj \
+       gutf8.obj               \
+       gutils.obj              \
+       gwin32.obj              \
+       localcharset.obj
+
+..\glibconfig.h: ..\glibconfig.h.win32
+       copy ..\glibconfig.h.win32 ..\glibconfig.h
+
+..\config.h: ..\config.h.win32
+       copy ..\config.h.win32 ..\config.h
+
+localcharset.obj : libcharset\localcharset.c
+       $(CC) $(CFLAGS) -DLIBDIR=\".\" -c libcharset\localcharset.c
+
+glib.def: glib.symbols
+       echo EXPORTS > glib.def
+       cl /EP -DINCLUDE_VARIABLES -DG_OS_WIN32 -DINCLUDE_INTERNAL_SYMBOLS -DALL_FILES \
+               -DG_GNUC_MALLOC= -DG_GNUC_CONST= -DG_GNUC_NULL_TERMINATED= -DG_GNUC_NORETURN= \
+               -DG_GNUC_PRINTF=;G_GNUC_PRINTF -DG_GNUC_FORMAT=;G_GNUC_FORMAT glib.symbols >> glib.def
+
+glib.res : glib.rc
+       rc -DBUILDNUMBER=0 -r -fo glib.res glib.rc
+
+################ glib
+
+# create a static libary
+# static library can well have the real version number in the name
+glib-@GLIB_MAJOR_VERSION@.@GLIB_MINOR_VERSION@s.lib : $(glib_OBJECTS) gnulib\gnulib.lib pcre\pcre.lib
+       lib /out:glib-@GLIB_MAJOR_VERSION@.@GLIB_MINOR_VERSION@s.lib $(glib_OBJECTS) gnulib\gnulib.lib pcre\pcre.lib
+
+libglib-2.0-0.dll : $(glib_OBJECTS) gnulib\gnulib.lib pcre\pcre.lib glib.def glib.res
+       $(CC) $(CFLAGS) -LD -Fe$@ $(glib_OBJECTS) glib.res $(INTL_LIBS) \
+       gnulib\gnulib.lib pcre\pcre.lib $(DIRENT_LIBS) user32.lib advapi32.lib shell32.lib wsock32.lib ole32.lib ws2_32.lib \
+       $(LDFLAGS) /implib:glib-2.0.lib /def:glib.def
+
+gspawn-win32-helper.exe : gspawn-win32-helper.c libglib-2.0-@LT_CURRENT_MINUS_AGE@.dll
+       $(CC) $(CFLAGS) -Fe$@ -DG_LOG_DOMAIN=\"gspawn-win32-helper\" gspawn-win32-helper.c glib-2.0.lib $(LDFLAGS) /subsystem:windows user32.lib
+
+gspawn-win32-helper-console.exe : gspawn-win32-helper.c libglib-2.0-@LT_CURRENT_MINUS_AGE@.dll
+       $(CC) $(CFLAGS) -Fe$@ -DG_LOG_DOMAIN=\"gspawn-win32-helper\" gspawn-win32-helper.c glib-2.0.lib $(LDFLAGS) /subsystem:console user32.lib
+
+################ other stuff
+
+clean::
+       del ..\config.h
+       del ..\glibconfig.h
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/Android.mk b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/Android.mk
new file mode 100644 (file)
index 0000000..627ab38
--- /dev/null
@@ -0,0 +1,43 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES:= \
+       pcre_compile.c \
+       pcre_chartables.c \
+       pcre_config.c \
+       pcre_dfa_exec.c \
+       pcre_exec.c \
+       pcre_fullinfo.c \
+       pcre_get.c \
+       pcre_globals.c \
+       pcre_newline.c \
+       pcre_ord2utf8.c \
+       pcre_study.c \
+       pcre_tables.c \
+       pcre_try_flipped.c \
+       pcre_ucp_searchfuncs.c \
+       pcre_xclass.c
+
+LOCAL_MODULE:= libpcre
+
+LOCAL_C_INCLUDES :=                            \
+       $(GLIB_TOP)/android-internal            \
+       $(GLIB_TOP)/glib/android-internal       \
+       $(GLIB_C_INCLUDES)
+
+LOCAL_CFLAGS := \
+    -DG_LOG_DOMAIN=\"GLib-GRegex\" \
+    -DSUPPORT_UCP \
+    -DSUPPORT_UTF8 \
+    -DNEWLINE=-1 \
+    -DMATCH_LIMIT=10000000 \
+    -DMATCH_LIMIT_RECURSION=10000000 \
+    -DMAX_NAME_SIZE=32 \
+    -DMAX_NAME_COUNT=10000 \
+    -DMAX_DUPLENGTH=30000 \
+    -DLINK_SIZE=2 \
+    -DPCRE_STATIC \
+    -DPOSIX_MALLOC_THRESHOLD=10
+
+include $(BUILD_STATIC_LIBRARY)
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/COPYING b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/COPYING
new file mode 100644 (file)
index 0000000..58eed01
--- /dev/null
@@ -0,0 +1,5 @@
+PCRE LICENCE
+
+Please see the file LICENCE in the PCRE distribution for licensing details.
+
+End
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/Makefile.am b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/Makefile.am
new file mode 100644 (file)
index 0000000..07e8526
--- /dev/null
@@ -0,0 +1,57 @@
+include $(top_srcdir)/Makefile.decl
+
+INCLUDES = \
+       -DG_LOG_DOMAIN=\"GLib-GRegex\" \
+       -DSUPPORT_UCP \
+       -DSUPPORT_UTF8 \
+       -DNEWLINE=-1 \
+       -DMATCH_LIMIT=10000000 \
+       -DMATCH_LIMIT_RECURSION=8192 \
+       -DMAX_NAME_SIZE=32 \
+       -DMAX_NAME_COUNT=10000 \
+       -DMAX_DUPLENGTH=30000 \
+       -DLINK_SIZE=2 \
+       -DPOSIX_MALLOC_THRESHOLD=10 \
+       -DPCRE_STATIC \
+       $(glib_INCLUDES) \
+       @GLIB_DEBUG_FLAGS@ \
+       -DG_DISABLE_DEPRECATED \
+       -DGLIB_COMPILATION \
+       $(DEPRECATED_FLAGS)\
+       $(WARN_CFLAGS) \
+       $(PCRE_WARN_CFLAGS) \
+       $(DEP_CFLAGS)
+
+noinst_LTLIBRARIES = libpcre.la
+
+libpcre_headers =
+
+libpcre_la_SOURCES = \
+       pcre_compile.c \
+       pcre_chartables.c \
+       pcre_config.c \
+       pcre_dfa_exec.c \
+       pcre_exec.c \
+       pcre_fullinfo.c \
+       pcre_get.c \
+       pcre_globals.c \
+       pcre_newline.c \
+       pcre_ord2utf8.c \
+       pcre_study.c \
+       pcre_tables.c \
+       pcre_try_flipped.c \
+       pcre_ucp_searchfuncs.c \
+       pcre_xclass.c \
+       pcre.h \
+       pcre_internal.h \
+       ucp.h \
+       $(libpcre_headers)
+
+libpcre_la_LIBADD = $(DEP_LIBS)
+
+libpcre_la_LDFLAGS = -no-undefined
+
+EXTRA_DIST +=                          \
+               COPYING                 \
+               makefile.msc
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/makefile.msc b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/makefile.msc
new file mode 100644 (file)
index 0000000..1ec1d72
--- /dev/null
@@ -0,0 +1,30 @@
+TOP = ..\..\..
+!INCLUDE ..\..\build\win32\make.msc
+
+INCLUDES = \
+        -I ..\.. \
+        -I ..
+        
+DEFINES = \
+        -DPCRE_STATIC \
+        -DHAVE_CONFIG_H \
+        -DHAVE_LONG_LONG_FORMAT \
+        -DSUPPORT_UCP \
+        -DSUPPORT_UTF8 \
+        -DNEWLINE=-1 \
+        -DMATCH_LIMIT=10000000 \
+        -DMATCH_LIMIT_RECURSION=10000000 \
+        -DMAX_NAME_SIZE=32 \
+        -DMAX_NAME_COUNT=10000 \
+        -DMAX_DUPLENGTH=30000 \
+        -DLINK_SIZE=2 \
+        -DEBCDIC=0 \
+        -DPOSIX_MALLOC_THRESHOLD=10
+
+OBJECTS = \
+
+
+all : pcre.lib
+
+pcre.lib : $(OBJECTS)
+        lib -out:pcre.lib $(OBJECTS)
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre.h b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre.h
new file mode 100644 (file)
index 0000000..4864bd0
--- /dev/null
@@ -0,0 +1,299 @@
+/*************************************************
+*       Perl-Compatible Regular Expressions      *
+*************************************************/
+
+/* This is the public header file for the PCRE library, to be #included by
+applications that call the PCRE functions.
+
+           Copyright (c) 1997-2009 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+#ifndef _PCRE_H
+#define _PCRE_H
+
+/* The current PCRE version information. */
+
+#define PCRE_MAJOR          8
+#define PCRE_MINOR          02
+#define PCRE_PRERELEASE     
+#define PCRE_DATE           2010-03-19
+
+/* When an application links to a PCRE DLL in Windows, the symbols that are
+imported have to be identified as such. When building PCRE, the appropriate
+export setting is defined in pcre_internal.h, which includes this file. So we
+don't change existing definitions of PCRE_EXP_DECL and PCRECPP_EXP_DECL. */
+
+#if defined(_WIN32) && !defined(PCRE_STATIC)
+#  ifndef PCRE_EXP_DECL
+#    define PCRE_EXP_DECL  extern __declspec(dllimport)
+#  endif
+#  ifdef __cplusplus
+#    ifndef PCRECPP_EXP_DECL
+#      define PCRECPP_EXP_DECL  extern __declspec(dllimport)
+#    endif
+#    ifndef PCRECPP_EXP_DEFN
+#      define PCRECPP_EXP_DEFN  __declspec(dllimport)
+#    endif
+#  endif
+#endif
+
+/* By default, we use the standard "extern" declarations. */
+
+#ifndef PCRE_EXP_DECL
+#  ifdef __cplusplus
+#    define PCRE_EXP_DECL  extern "C"
+#  else
+#    define PCRE_EXP_DECL  extern
+#  endif
+#endif
+
+#ifdef __cplusplus
+#  ifndef PCRECPP_EXP_DECL
+#    define PCRECPP_EXP_DECL  extern
+#  endif
+#  ifndef PCRECPP_EXP_DEFN
+#    define PCRECPP_EXP_DEFN
+#  endif
+#endif
+
+/* Have to include stdlib.h in order to ensure that size_t is defined;
+it is needed here for malloc. */
+
+#include <stdlib.h>
+
+/* Allow for C++ users */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/* Options. Some are compile-time only, some are run-time only, and some are
+both, so we keep them all distinct. */
+
+#define PCRE_CASELESS           0x00000001
+#define PCRE_MULTILINE          0x00000002
+#define PCRE_DOTALL             0x00000004
+#define PCRE_EXTENDED           0x00000008
+#define PCRE_ANCHORED           0x00000010
+#define PCRE_DOLLAR_ENDONLY     0x00000020
+#define PCRE_EXTRA              0x00000040
+#define PCRE_NOTBOL             0x00000080
+#define PCRE_NOTEOL             0x00000100
+#define PCRE_UNGREEDY           0x00000200
+#define PCRE_NOTEMPTY           0x00000400
+#define PCRE_UTF8               0x00000800
+#define PCRE_NO_AUTO_CAPTURE    0x00001000
+#define PCRE_NO_UTF8_CHECK      0x00002000
+#define PCRE_AUTO_CALLOUT       0x00004000
+#define PCRE_PARTIAL_SOFT       0x00008000
+#define PCRE_PARTIAL            0x00008000  /* Backwards compatible synonym */
+#define PCRE_DFA_SHORTEST       0x00010000
+#define PCRE_DFA_RESTART        0x00020000
+#define PCRE_FIRSTLINE          0x00040000
+#define PCRE_DUPNAMES           0x00080000
+#define PCRE_NEWLINE_CR         0x00100000
+#define PCRE_NEWLINE_LF         0x00200000
+#define PCRE_NEWLINE_CRLF       0x00300000
+#define PCRE_NEWLINE_ANY        0x00400000
+#define PCRE_NEWLINE_ANYCRLF    0x00500000
+#define PCRE_BSR_ANYCRLF        0x00800000
+#define PCRE_BSR_UNICODE        0x01000000
+#define PCRE_JAVASCRIPT_COMPAT  0x02000000
+#define PCRE_NO_START_OPTIMIZE  0x04000000
+#define PCRE_NO_START_OPTIMISE  0x04000000
+#define PCRE_PARTIAL_HARD       0x08000000
+#define PCRE_NOTEMPTY_ATSTART   0x10000000
+
+/* Exec-time and get/set-time error codes */
+
+#define PCRE_ERROR_NOMATCH         (-1)
+#define PCRE_ERROR_NULL            (-2)
+#define PCRE_ERROR_BADOPTION       (-3)
+#define PCRE_ERROR_BADMAGIC        (-4)
+#define PCRE_ERROR_UNKNOWN_OPCODE  (-5)
+#define PCRE_ERROR_UNKNOWN_NODE    (-5)  /* For backward compatibility */
+#define PCRE_ERROR_NOMEMORY        (-6)
+#define PCRE_ERROR_NOSUBSTRING     (-7)
+#define PCRE_ERROR_MATCHLIMIT      (-8)
+#define PCRE_ERROR_CALLOUT         (-9)  /* Never used by PCRE itself */
+#define PCRE_ERROR_BADUTF8        (-10)
+#define PCRE_ERROR_BADUTF8_OFFSET (-11)
+#define PCRE_ERROR_PARTIAL        (-12)
+#define PCRE_ERROR_BADPARTIAL     (-13)
+#define PCRE_ERROR_INTERNAL       (-14)
+#define PCRE_ERROR_BADCOUNT       (-15)
+#define PCRE_ERROR_DFA_UITEM      (-16)
+#define PCRE_ERROR_DFA_UCOND      (-17)
+#define PCRE_ERROR_DFA_UMLIMIT    (-18)
+#define PCRE_ERROR_DFA_WSSIZE     (-19)
+#define PCRE_ERROR_DFA_RECURSE    (-20)
+#define PCRE_ERROR_RECURSIONLIMIT (-21)
+#define PCRE_ERROR_NULLWSLIMIT    (-22)  /* No longer actually used */
+#define PCRE_ERROR_BADNEWLINE     (-23)
+
+/* Request types for pcre_fullinfo() */
+
+#define PCRE_INFO_OPTIONS            0
+#define PCRE_INFO_SIZE               1
+#define PCRE_INFO_CAPTURECOUNT       2
+#define PCRE_INFO_BACKREFMAX         3
+#define PCRE_INFO_FIRSTBYTE          4
+#define PCRE_INFO_FIRSTCHAR          4  /* For backwards compatibility */
+#define PCRE_INFO_FIRSTTABLE         5
+#define PCRE_INFO_LASTLITERAL        6
+#define PCRE_INFO_NAMEENTRYSIZE      7
+#define PCRE_INFO_NAMECOUNT          8
+#define PCRE_INFO_NAMETABLE          9
+#define PCRE_INFO_STUDYSIZE         10
+#define PCRE_INFO_DEFAULT_TABLES    11
+#define PCRE_INFO_OKPARTIAL         12
+#define PCRE_INFO_JCHANGED          13
+#define PCRE_INFO_HASCRORLF         14
+#define PCRE_INFO_MINLENGTH         15
+
+/* Request types for pcre_config(). Do not re-arrange, in order to remain
+compatible. */
+
+#define PCRE_CONFIG_UTF8                    0
+#define PCRE_CONFIG_NEWLINE                 1
+#define PCRE_CONFIG_LINK_SIZE               2
+#define PCRE_CONFIG_POSIX_MALLOC_THRESHOLD  3
+#define PCRE_CONFIG_MATCH_LIMIT             4
+#define PCRE_CONFIG_STACKRECURSE            5
+#define PCRE_CONFIG_UNICODE_PROPERTIES      6
+#define PCRE_CONFIG_MATCH_LIMIT_RECURSION   7
+#define PCRE_CONFIG_BSR                     8
+
+/* Bit flags for the pcre_extra structure. Do not re-arrange or redefine
+these bits, just add new ones on the end, in order to remain compatible. */
+
+#define PCRE_EXTRA_STUDY_DATA             0x0001
+#define PCRE_EXTRA_MATCH_LIMIT            0x0002
+#define PCRE_EXTRA_CALLOUT_DATA           0x0004
+#define PCRE_EXTRA_TABLES                 0x0008
+#define PCRE_EXTRA_MATCH_LIMIT_RECURSION  0x0010
+
+/* Types */
+
+struct real_pcre;                 /* declaration; the definition is private  */
+typedef struct real_pcre pcre;
+
+/* When PCRE is compiled as a C++ library, the subject pointer type can be
+replaced with a custom type. For conventional use, the public interface is a
+const char *. */
+
+#ifndef PCRE_SPTR
+#define PCRE_SPTR const char *
+#endif
+
+/* The structure for passing additional data to pcre_exec(). This is defined in
+such as way as to be extensible. Always add new fields at the end, in order to
+remain compatible. */
+
+typedef struct pcre_extra {
+  unsigned long int flags;        /* Bits for which fields are set */
+  void *study_data;               /* Opaque data from pcre_study() */
+  unsigned long int match_limit;  /* Maximum number of calls to match() */
+  void *callout_data;             /* Data passed back in callouts */
+  const unsigned char *tables;    /* Pointer to character tables */
+  unsigned long int match_limit_recursion; /* Max recursive calls to match() */
+} pcre_extra;
+
+/* The structure for passing out data via the pcre_callout_function. We use a
+structure so that new fields can be added on the end in future versions,
+without changing the API of the function, thereby allowing old clients to work
+without modification. */
+
+typedef struct pcre_callout_block {
+  int          version;           /* Identifies version of block */
+  /* ------------------------ Version 0 ------------------------------- */
+  int          callout_number;    /* Number compiled into pattern */
+  int         *offset_vector;     /* The offset vector */
+  PCRE_SPTR    subject;           /* The subject being matched */
+  int          subject_length;    /* The length of the subject */
+  int          start_match;       /* Offset to start of this match attempt */
+  int          current_position;  /* Where we currently are in the subject */
+  int          capture_top;       /* Max current capture */
+  int          capture_last;      /* Most recently closed capture */
+  void        *callout_data;      /* Data passed in with the call */
+  /* ------------------- Added for Version 1 -------------------------- */
+  int          pattern_position;  /* Offset to next item in the pattern */
+  int          next_item_length;  /* Length of next item in the pattern */
+  /* ------------------------------------------------------------------ */
+} pcre_callout_block;
+
+#include "glib.h"
+
+#define pcre_malloc g_try_malloc
+#define pcre_free g_free
+#define pcre_stack_malloc g_try_malloc
+
+PCRE_EXP_DECL int   (*pcre_callout)(pcre_callout_block *);
+
+/* Exported PCRE functions */
+
+PCRE_EXP_DECL pcre *pcre_compile(const char *, int, const char **, int *,
+                  const unsigned char *);
+PCRE_EXP_DECL pcre *pcre_compile2(const char *, int, int *, const char **,
+                  int *, const unsigned char *);
+PCRE_EXP_DECL int  pcre_config(int, void *);
+PCRE_EXP_DECL int  pcre_copy_named_substring(const pcre *, const char *,
+                  int *, int, const char *, char *, int);
+PCRE_EXP_DECL int  pcre_copy_substring(const char *, int *, int, int, char *,
+                  int);
+PCRE_EXP_DECL int  pcre_dfa_exec(const pcre *, const pcre_extra *,
+                  const char *, int, int, int, int *, int , int *, int);
+PCRE_EXP_DECL int  pcre_exec(const pcre *, const pcre_extra *, PCRE_SPTR,
+                   int, int, int, int *, int);
+PCRE_EXP_DECL void pcre_free_substring(const char *);
+PCRE_EXP_DECL void pcre_free_substring_list(const char **);
+PCRE_EXP_DECL int  pcre_fullinfo(const pcre *, const pcre_extra *, int,
+                  void *);
+PCRE_EXP_DECL int  pcre_get_named_substring(const pcre *, const char *,
+                  int *, int, const char *, const char **);
+PCRE_EXP_DECL int  pcre_get_stringnumber(const pcre *, const char *);
+PCRE_EXP_DECL int  pcre_get_stringtable_entries(const pcre *, const char *,
+                  char **, char **);
+PCRE_EXP_DECL int  pcre_get_substring(const char *, int *, int, int,
+                  const char **);
+PCRE_EXP_DECL int  pcre_get_substring_list(const char *, int *, int,
+                  const char ***);
+PCRE_EXP_DECL int  pcre_info(const pcre *, int *, int *);
+PCRE_EXP_DECL const unsigned char *pcre_maketables(void);
+PCRE_EXP_DECL int  pcre_refcount(pcre *, int);
+PCRE_EXP_DECL pcre_extra *pcre_study(const pcre *, int, const char **);
+PCRE_EXP_DECL const char *pcre_version(void);
+
+#ifdef __cplusplus
+}  /* extern "C" */
+#endif
+
+#endif /* End of pcre.h */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_chartables.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_chartables.c
new file mode 100644 (file)
index 0000000..ae45db0
--- /dev/null
@@ -0,0 +1,198 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* This file contains character tables that are used when no external tables
+are passed to PCRE by the application that calls it. The tables are used only
+for characters whose code values are less than 256.
+
+This is a default version of the tables that assumes ASCII encoding. A program
+called dftables (which is distributed with PCRE) can be used to build
+alternative versions of this file. This is necessary if you are running in an
+EBCDIC environment, or if you want to default to a different encoding, for
+example ISO-8859-1. When dftables is run, it creates these tables in the
+current locale. If PCRE is configured with --enable-rebuild-chartables, this
+happens automatically.
+
+The following #includes are present because without the gcc 4.x may remove the
+array definition from the final binary if PCRE is built into a static library
+and dead code stripping is activated. This leads to link errors. Pulling in the
+header ensures that the array gets flagged as "someone outside this compilation
+unit might reference this" and so it will always be supplied to the linker. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+const unsigned char _pcre_default_tables[] = {
+
+/* This table is a lower casing table. */
+
+    0,  1,  2,  3,  4,  5,  6,  7,
+    8,  9, 10, 11, 12, 13, 14, 15,
+   16, 17, 18, 19, 20, 21, 22, 23,
+   24, 25, 26, 27, 28, 29, 30, 31,
+   32, 33, 34, 35, 36, 37, 38, 39,
+   40, 41, 42, 43, 44, 45, 46, 47,
+   48, 49, 50, 51, 52, 53, 54, 55,
+   56, 57, 58, 59, 60, 61, 62, 63,
+   64, 97, 98, 99,100,101,102,103,
+  104,105,106,107,108,109,110,111,
+  112,113,114,115,116,117,118,119,
+  120,121,122, 91, 92, 93, 94, 95,
+   96, 97, 98, 99,100,101,102,103,
+  104,105,106,107,108,109,110,111,
+  112,113,114,115,116,117,118,119,
+  120,121,122,123,124,125,126,127,
+  128,129,130,131,132,133,134,135,
+  136,137,138,139,140,141,142,143,
+  144,145,146,147,148,149,150,151,
+  152,153,154,155,156,157,158,159,
+  160,161,162,163,164,165,166,167,
+  168,169,170,171,172,173,174,175,
+  176,177,178,179,180,181,182,183,
+  184,185,186,187,188,189,190,191,
+  192,193,194,195,196,197,198,199,
+  200,201,202,203,204,205,206,207,
+  208,209,210,211,212,213,214,215,
+  216,217,218,219,220,221,222,223,
+  224,225,226,227,228,229,230,231,
+  232,233,234,235,236,237,238,239,
+  240,241,242,243,244,245,246,247,
+  248,249,250,251,252,253,254,255,
+
+/* This table is a case flipping table. */
+
+    0,  1,  2,  3,  4,  5,  6,  7,
+    8,  9, 10, 11, 12, 13, 14, 15,
+   16, 17, 18, 19, 20, 21, 22, 23,
+   24, 25, 26, 27, 28, 29, 30, 31,
+   32, 33, 34, 35, 36, 37, 38, 39,
+   40, 41, 42, 43, 44, 45, 46, 47,
+   48, 49, 50, 51, 52, 53, 54, 55,
+   56, 57, 58, 59, 60, 61, 62, 63,
+   64, 97, 98, 99,100,101,102,103,
+  104,105,106,107,108,109,110,111,
+  112,113,114,115,116,117,118,119,
+  120,121,122, 91, 92, 93, 94, 95,
+   96, 65, 66, 67, 68, 69, 70, 71,
+   72, 73, 74, 75, 76, 77, 78, 79,
+   80, 81, 82, 83, 84, 85, 86, 87,
+   88, 89, 90,123,124,125,126,127,
+  128,129,130,131,132,133,134,135,
+  136,137,138,139,140,141,142,143,
+  144,145,146,147,148,149,150,151,
+  152,153,154,155,156,157,158,159,
+  160,161,162,163,164,165,166,167,
+  168,169,170,171,172,173,174,175,
+  176,177,178,179,180,181,182,183,
+  184,185,186,187,188,189,190,191,
+  192,193,194,195,196,197,198,199,
+  200,201,202,203,204,205,206,207,
+  208,209,210,211,212,213,214,215,
+  216,217,218,219,220,221,222,223,
+  224,225,226,227,228,229,230,231,
+  232,233,234,235,236,237,238,239,
+  240,241,242,243,244,245,246,247,
+  248,249,250,251,252,253,254,255,
+
+/* This table contains bit maps for various character classes. Each map is 32
+bytes long and the bits run from the least significant end of each byte. The
+classes that have their own maps are: space, xdigit, digit, upper, lower, word,
+graph, print, punct, and cntrl. Other classes are built from combinations. */
+
+  0x00,0x3e,0x00,0x00,0x01,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+  0x7e,0x00,0x00,0x00,0x7e,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0xfe,0xff,0xff,0x07,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0x07,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+  0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x03,
+  0xfe,0xff,0xff,0x87,0xfe,0xff,0xff,0x07,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+  0x00,0x00,0x00,0x00,0xfe,0xff,0xff,0xff,
+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+  0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
+  0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x7f,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+  0x00,0x00,0x00,0x00,0xfe,0xff,0x00,0xfc,
+  0x01,0x00,0x00,0xf8,0x01,0x00,0x00,0x78,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+  0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
+
+/* This table identifies various classes of character by individual bits:
+  0x01   white space character
+  0x02   letter
+  0x04   decimal digit
+  0x08   hexadecimal digit
+  0x10   alphanumeric or '_'
+  0x80   regular expression metacharacter or binary zero
+*/
+
+  0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*   0-  7 */
+  0x00,0x01,0x01,0x00,0x01,0x01,0x00,0x00, /*   8- 15 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  16- 23 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /*  24- 31 */
+  0x01,0x00,0x00,0x00,0x80,0x00,0x00,0x00, /*    - '  */
+  0x80,0x80,0x80,0x80,0x00,0x00,0x80,0x00, /*  ( - /  */
+  0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c,0x1c, /*  0 - 7  */
+  0x1c,0x1c,0x00,0x00,0x00,0x00,0x00,0x80, /*  8 - ?  */
+  0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /*  @ - G  */
+  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  H - O  */
+  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  P - W  */
+  0x12,0x12,0x12,0x80,0x80,0x00,0x80,0x10, /*  X - _  */
+  0x00,0x1a,0x1a,0x1a,0x1a,0x1a,0x1a,0x12, /*  ` - g  */
+  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  h - o  */
+  0x12,0x12,0x12,0x12,0x12,0x12,0x12,0x12, /*  p - w  */
+  0x12,0x12,0x12,0x80,0x80,0x00,0x00,0x00, /*  x -127 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 128-135 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 136-143 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 144-151 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 152-159 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 160-167 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 168-175 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 176-183 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 184-191 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 192-199 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 200-207 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 208-215 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 216-223 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 224-231 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 232-239 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, /* 240-247 */
+  0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};/* 248-255 */
+
+/* End of pcre_chartables.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_compile.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_compile.c
new file mode 100644 (file)
index 0000000..a00a990
--- /dev/null
@@ -0,0 +1,6774 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2010 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_compile(), along with
+supporting internal functions that are not used by other modules. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define NLBLOCK cd             /* Block containing newline information */
+#define PSSTART start_pattern  /* Field containing processed string start */
+#define PSEND   end_pattern    /* Field containing processed string end */
+
+#include "pcre_internal.h"
+
+
+/* When PCRE_DEBUG is defined, we need the pcre_printint() function, which is
+also used by pcretest. PCRE_DEBUG is not defined when building a production
+library. */
+
+#ifdef PCRE_DEBUG
+#include "pcre_printint.src"
+#endif
+
+
+/* Macro for setting individual bits in class bitmaps. */
+
+#define SETBIT(a,b) a[b/8] |= (1 << (b%8))
+
+/* Maximum length value to check against when making sure that the integer that
+holds the compiled pattern length does not overflow. We make it a bit less than
+INT_MAX to allow for adding in group terminating bytes, so that we don't have
+to check them every time. */
+
+#define OFLOW_MAX (INT_MAX - 20)
+
+
+/*************************************************
+*      Code parameters and static tables         *
+*************************************************/
+
+/* This value specifies the size of stack workspace that is used during the
+first pre-compile phase that determines how much memory is required. The regex
+is partly compiled into this space, but the compiled parts are discarded as
+soon as they can be, so that hopefully there will never be an overrun. The code
+does, however, check for an overrun. The largest amount I've seen used is 218,
+so this number is very generous.
+
+The same workspace is used during the second, actual compile phase for
+remembering forward references to groups so that they can be filled in at the
+end. Each entry in this list occupies LINK_SIZE bytes, so even when LINK_SIZE
+is 4 there is plenty of room. */
+
+#define COMPILE_WORK_SIZE (4096)
+
+/* The overrun tests check for a slightly smaller size so that they detect the
+overrun before it actually does run off the end of the data block. */
+
+#define WORK_SIZE_CHECK (COMPILE_WORK_SIZE - 100)
+
+
+/* Table for handling escaped characters in the range '0'-'z'. Positive returns
+are simple data values; negative values are for special things like \d and so
+on. Zero means further processing is needed (for things like \x), or the escape
+is invalid. */
+
+#ifndef EBCDIC
+
+/* This is the "normal" table for ASCII systems or for EBCDIC systems running
+in UTF-8 mode. */
+
+static const short int escapes[] = {
+     0,                       0,
+     0,                       0,
+     0,                       0,
+     0,                       0,
+     0,                       0,
+     CHAR_COLON,              CHAR_SEMICOLON,
+     CHAR_LESS_THAN_SIGN,     CHAR_EQUALS_SIGN,
+     CHAR_GREATER_THAN_SIGN,  CHAR_QUESTION_MARK,
+     CHAR_COMMERCIAL_AT,      -ESC_A,
+     -ESC_B,                  -ESC_C,
+     -ESC_D,                  -ESC_E,
+     0,                       -ESC_G,
+     -ESC_H,                  0,
+     0,                       -ESC_K,
+     0,                       0,
+     0,                       0,
+     -ESC_P,                  -ESC_Q,
+     -ESC_R,                  -ESC_S,
+     0,                       0,
+     -ESC_V,                  -ESC_W,
+     -ESC_X,                  0,
+     -ESC_Z,                  CHAR_LEFT_SQUARE_BRACKET,
+     CHAR_BACKSLASH,          CHAR_RIGHT_SQUARE_BRACKET,
+     CHAR_CIRCUMFLEX_ACCENT,  CHAR_UNDERSCORE,
+     CHAR_GRAVE_ACCENT,       7,
+     -ESC_b,                  0,
+     -ESC_d,                  ESC_e,
+     ESC_f,                   0,
+     -ESC_h,                  0,
+     0,                       -ESC_k,
+     0,                       0,
+     ESC_n,                   0,
+     -ESC_p,                  0,
+     ESC_r,                   -ESC_s,
+     ESC_tee,                 0,
+     -ESC_v,                  -ESC_w,
+     0,                       0,
+     -ESC_z
+};
+
+#else
+
+/* This is the "abnormal" table for EBCDIC systems without UTF-8 support. */
+
+static const short int escapes[] = {
+/*  48 */     0,     0,      0,     '.',    '<',   '(',    '+',    '|',
+/*  50 */   '&',     0,      0,       0,      0,     0,      0,      0,
+/*  58 */     0,     0,    '!',     '$',    '*',   ')',    ';',    '~',
+/*  60 */   '-',   '/',      0,       0,      0,     0,      0,      0,
+/*  68 */     0,     0,    '|',     ',',    '%',   '_',    '>',    '?',
+/*  70 */     0,     0,      0,       0,      0,     0,      0,      0,
+/*  78 */     0,   '`',    ':',     '#',    '@',  '\'',    '=',    '"',
+/*  80 */     0,     7, -ESC_b,       0, -ESC_d, ESC_e,  ESC_f,      0,
+/*  88 */-ESC_h,     0,      0,     '{',      0,     0,      0,      0,
+/*  90 */     0,     0, -ESC_k,     'l',      0, ESC_n,      0, -ESC_p,
+/*  98 */     0, ESC_r,      0,     '}',      0,     0,      0,      0,
+/*  A0 */     0,   '~', -ESC_s, ESC_tee,      0,-ESC_v, -ESC_w,      0,
+/*  A8 */     0,-ESC_z,      0,       0,      0,   '[',      0,      0,
+/*  B0 */     0,     0,      0,       0,      0,     0,      0,      0,
+/*  B8 */     0,     0,      0,       0,      0,   ']',    '=',    '-',
+/*  C0 */   '{',-ESC_A, -ESC_B,  -ESC_C, -ESC_D,-ESC_E,      0, -ESC_G,
+/*  C8 */-ESC_H,     0,      0,       0,      0,     0,      0,      0,
+/*  D0 */   '}',     0, -ESC_K,       0,      0,     0,      0, -ESC_P,
+/*  D8 */-ESC_Q,-ESC_R,      0,       0,      0,     0,      0,      0,
+/*  E0 */  '\\',     0, -ESC_S,       0,      0,-ESC_V, -ESC_W, -ESC_X,
+/*  E8 */     0,-ESC_Z,      0,       0,      0,     0,      0,      0,
+/*  F0 */     0,     0,      0,       0,      0,     0,      0,      0,
+/*  F8 */     0,     0,      0,       0,      0,     0,      0,      0
+};
+#endif
+
+
+/* Table of special "verbs" like (*PRUNE). This is a short table, so it is
+searched linearly. Put all the names into a single string, in order to reduce
+the number of relocations when a shared library is dynamically linked. The
+string is built from string macros so that it works in UTF-8 mode on EBCDIC
+platforms. */
+
+typedef struct verbitem {
+  int   len;
+  int   op;
+} verbitem;
+
+static const char verbnames[] =
+  STRING_ACCEPT0
+  STRING_COMMIT0
+  STRING_F0
+  STRING_FAIL0
+  STRING_PRUNE0
+  STRING_SKIP0
+  STRING_THEN;
+
+static const verbitem verbs[] = {
+  { 6, OP_ACCEPT },
+  { 6, OP_COMMIT },
+  { 1, OP_FAIL },
+  { 4, OP_FAIL },
+  { 5, OP_PRUNE },
+  { 4, OP_SKIP  },
+  { 4, OP_THEN  }
+};
+
+static const int verbcount = sizeof(verbs)/sizeof(verbitem);
+
+
+/* Tables of names of POSIX character classes and their lengths. The names are
+now all in a single string, to reduce the number of relocations when a shared
+library is dynamically loaded. The list of lengths is terminated by a zero
+length entry. The first three must be alpha, lower, upper, as this is assumed
+for handling case independence. */
+
+static const char posix_names[] =
+  STRING_alpha0 STRING_lower0 STRING_upper0 STRING_alnum0
+  STRING_ascii0 STRING_blank0 STRING_cntrl0 STRING_digit0
+  STRING_graph0 STRING_print0 STRING_punct0 STRING_space0
+  STRING_word0  STRING_xdigit;
+
+static const uschar posix_name_lengths[] = {
+  5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 4, 6, 0 };
+
+/* Table of class bit maps for each POSIX class. Each class is formed from a
+base map, with an optional addition or removal of another map. Then, for some
+classes, there is some additional tweaking: for [:blank:] the vertical space
+characters are removed, and for [:alpha:] and [:alnum:] the underscore
+character is removed. The triples in the table consist of the base map offset,
+second map offset or -1 if no second map, and a non-negative value for map
+addition or a negative value for map subtraction (if there are two maps). The
+absolute value of the third field has these meanings: 0 => no tweaking, 1 =>
+remove vertical space characters, 2 => remove underscore. */
+
+static const int posix_class_maps[] = {
+  cbit_word,  cbit_digit, -2,             /* alpha */
+  cbit_lower, -1,          0,             /* lower */
+  cbit_upper, -1,          0,             /* upper */
+  cbit_word,  -1,          2,             /* alnum - word without underscore */
+  cbit_print, cbit_cntrl,  0,             /* ascii */
+  cbit_space, -1,          1,             /* blank - a GNU extension */
+  cbit_cntrl, -1,          0,             /* cntrl */
+  cbit_digit, -1,          0,             /* digit */
+  cbit_graph, -1,          0,             /* graph */
+  cbit_print, -1,          0,             /* print */
+  cbit_punct, -1,          0,             /* punct */
+  cbit_space, -1,          0,             /* space */
+  cbit_word,  -1,          0,             /* word - a Perl extension */
+  cbit_xdigit,-1,          0              /* xdigit */
+};
+
+
+#define STRING(a)  # a
+#define XSTRING(s) STRING(s)
+
+/* The texts of compile-time error messages. These are "char *" because they
+are passed to the outside world. Do not ever re-use any error number, because
+they are documented. Always add a new error instead. Messages marked DEAD below
+are no longer used. This used to be a table of strings, but in order to reduce
+the number of relocations needed when a shared library is loaded dynamically,
+it is now one long string. We cannot use a table of offsets, because the
+lengths of inserts such as XSTRING(MAX_NAME_SIZE) are not known. Instead, we
+simply count through to the one we want - this isn't a performance issue
+because these strings are used only when there is a compilation error.
+
+Each substring ends with \0 to insert a null character. This includes the final
+substring, so that the whole string ends with \0\0, which can be detected when
+counting through. */
+
+static const char error_texts[] =
+  "no error\0"
+  "\\ at end of pattern\0"
+  "\\c at end of pattern\0"
+  "unrecognized character follows \\\0"
+  "numbers out of order in {} quantifier\0"
+  /* 5 */
+  "number too big in {} quantifier\0"
+  "missing terminating ] for character class\0"
+  "invalid escape sequence in character class\0"
+  "range out of order in character class\0"
+  "nothing to repeat\0"
+  /* 10 */
+  "operand of unlimited repeat could match the empty string\0"  /** DEAD **/
+  "internal error: unexpected repeat\0"
+  "unrecognized character after (? or (?-\0"
+  "POSIX named classes are supported only within a class\0"
+  "missing )\0"
+  /* 15 */
+  "reference to non-existent subpattern\0"
+  "erroffset passed as NULL\0"
+  "unknown option bit(s) set\0"
+  "missing ) after comment\0"
+  "parentheses nested too deeply\0"  /** DEAD **/
+  /* 20 */
+  "regular expression is too large\0"
+  "failed to get memory\0"
+  "unmatched parentheses\0"
+  "internal error: code overflow\0"
+  "unrecognized character after (?<\0"
+  /* 25 */
+  "lookbehind assertion is not fixed length\0"
+  "malformed number or name after (?(\0"
+  "conditional group contains more than two branches\0"
+  "assertion expected after (?(\0"
+  "(?R or (?[+-]digits must be followed by )\0"
+  /* 30 */
+  "unknown POSIX class name\0"
+  "POSIX collating elements are not supported\0"
+  "this version of PCRE is not compiled with PCRE_UTF8 support\0"
+  "spare error\0"  /** DEAD **/
+  "character value in \\x{...} sequence is too large\0"
+  /* 35 */
+  "invalid condition (?(0)\0"
+  "\\C not allowed in lookbehind assertion\0"
+  "PCRE does not support \\L, \\l, \\N, \\U, or \\u\0"
+  "number after (?C is > 255\0"
+  "closing ) for (?C expected\0"
+  /* 40 */
+  "recursive call could loop indefinitely\0"
+  "unrecognized character after (?P\0"
+  "syntax error in subpattern name (missing terminator)\0"
+  "two named subpatterns have the same name\0"
+  "invalid UTF-8 string\0"
+  /* 45 */
+  "support for \\P, \\p, and \\X has not been compiled\0"
+  "malformed \\P or \\p sequence\0"
+  "unknown property name after \\P or \\p\0"
+  "subpattern name is too long (maximum " XSTRING(MAX_NAME_SIZE) " characters)\0"
+  "too many named subpatterns (maximum " XSTRING(MAX_NAME_COUNT) ")\0"
+  /* 50 */
+  "repeated subpattern is too long\0"    /** DEAD **/
+  "octal value is greater than \\377 (not in UTF-8 mode)\0"
+  "internal error: overran compiling workspace\0"
+  "internal error: previously-checked referenced subpattern not found\0"
+  "DEFINE group contains more than one branch\0"
+  /* 55 */
+  "repeating a DEFINE group is not allowed\0"
+  "inconsistent NEWLINE options\0"
+  "\\g is not followed by a braced, angle-bracketed, or quoted name/number or by a plain number\0"
+  "a numbered reference must not be zero\0"
+  "(*VERB) with an argument is not supported\0"
+  /* 60 */
+  "(*VERB) not recognized\0"
+  "number is too big\0"
+  "subpattern name expected\0"
+  "digit expected after (?+\0"
+  "] is an invalid data character in JavaScript compatibility mode\0"
+  /* 65 */
+  "different names for subpatterns of the same number are not allowed\0";
+
+
+/* Definition to allow mutual recursion */
+
+static BOOL
+  compile_regex(int, int, uschar **, const uschar **, int *, BOOL, BOOL, int,
+    int *, int *, branch_chain *, compile_data *, int *);
+
+
+
+/*************************************************
+*            Find an error text                  *
+*************************************************/
+
+/* The error texts are now all in one long string, to save on relocations. As
+some of the text is of unknown length, we can't use a table of offsets.
+Instead, just count through the strings. This is not a performance issue
+because it happens only when there has been a compilation error.
+
+Argument:   the error number
+Returns:    pointer to the error string
+*/
+
+static const char *
+find_error_text(int n)
+{
+const char *s = error_texts;
+for (; n > 0; n--)
+  {
+  while (*s++ != 0) {};
+  if (*s == 0) return "Error text not found (please report)";
+  }
+return s;
+}
+
+
+/*************************************************
+*            Handle escapes                      *
+*************************************************/
+
+/* This function is called when a \ has been encountered. It either returns a
+positive value for a simple escape such as \n, or a negative value which
+encodes one of the more complicated things such as \d. A backreference to group
+n is returned as -(ESC_REF + n); ESC_REF is the highest ESC_xxx macro. When
+UTF-8 is enabled, a positive value greater than 255 may be returned. On entry,
+ptr is pointing at the \. On exit, it is on the final character of the escape
+sequence.
+
+Arguments:
+  ptrptr         points to the pattern position pointer
+  errorcodeptr   points to the errorcode variable
+  bracount       number of previous extracting brackets
+  options        the options bits
+  isclass        TRUE if inside a character class
+
+Returns:         zero or positive => a data character
+                 negative => a special escape sequence
+                 on error, errorcodeptr is set
+*/
+
+static int
+check_escape(const uschar **ptrptr, int *errorcodeptr, int bracount,
+  int options, BOOL isclass)
+{
+BOOL utf8 = (options & PCRE_UTF8) != 0;
+const uschar *ptr = *ptrptr + 1;
+int c, i;
+
+GETCHARINCTEST(c, ptr);           /* Get character value, increment pointer */
+ptr--;                            /* Set pointer back to the last byte */
+
+/* If backslash is at the end of the pattern, it's an error. */
+
+if (c == 0) *errorcodeptr = ERR1;
+
+/* Non-alphanumerics are literals. For digits or letters, do an initial lookup
+in a table. A non-zero result is something that can be returned immediately.
+Otherwise further processing may be required. */
+
+#ifndef EBCDIC  /* ASCII/UTF-8 coding */
+else if (c < CHAR_0 || c > CHAR_z) {}                     /* Not alphanumeric */
+else if ((i = escapes[c - CHAR_0]) != 0) c = i;
+
+#else           /* EBCDIC coding */
+else if (c < 'a' || (ebcdic_chartab[c] & 0x0E) == 0) {}   /* Not alphanumeric */
+else if ((i = escapes[c - 0x48]) != 0)  c = i;
+#endif
+
+/* Escapes that need further processing, or are illegal. */
+
+else
+  {
+  const uschar *oldptr;
+  BOOL braced, negated;
+
+  switch (c)
+    {
+    /* A number of Perl escapes are not handled by PCRE. We give an explicit
+    error. */
+
+    case CHAR_l:
+    case CHAR_L:
+    case CHAR_N:
+    case CHAR_u:
+    case CHAR_U:
+    *errorcodeptr = ERR37;
+    break;
+
+    /* \g must be followed by one of a number of specific things:
+
+    (1) A number, either plain or braced. If positive, it is an absolute
+    backreference. If negative, it is a relative backreference. This is a Perl
+    5.10 feature.
+
+    (2) Perl 5.10 also supports \g{name} as a reference to a named group. This
+    is part of Perl's movement towards a unified syntax for back references. As
+    this is synonymous with \k{name}, we fudge it up by pretending it really
+    was \k.
+
+    (3) For Oniguruma compatibility we also support \g followed by a name or a
+    number either in angle brackets or in single quotes. However, these are
+    (possibly recursive) subroutine calls, _not_ backreferences. Just return
+    the -ESC_g code (cf \k). */
+
+    case CHAR_g:
+    if (ptr[1] == CHAR_LESS_THAN_SIGN || ptr[1] == CHAR_APOSTROPHE)
+      {
+      c = -ESC_g;
+      break;
+      }
+
+    /* Handle the Perl-compatible cases */
+
+    if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
+      {
+      const uschar *p;
+      for (p = ptr+2; *p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET; p++)
+        if (*p != CHAR_MINUS && g_ascii_isdigit(*p) == 0) break;
+      if (*p != 0 && *p != CHAR_RIGHT_CURLY_BRACKET)
+        {
+        c = -ESC_k;
+        break;
+        }
+      braced = TRUE;
+      ptr++;
+      }
+    else braced = FALSE;
+
+    if (ptr[1] == CHAR_MINUS)
+      {
+      negated = TRUE;
+      ptr++;
+      }
+    else negated = FALSE;
+
+    c = 0;
+    while (g_ascii_isdigit(ptr[1]) != 0)
+      c = c * 10 + *(++ptr) - CHAR_0;
+
+    if (c < 0)   /* Integer overflow */
+      {
+      *errorcodeptr = ERR61;
+      break;
+      }
+
+    if (braced && *(++ptr) != CHAR_RIGHT_CURLY_BRACKET)
+      {
+      *errorcodeptr = ERR57;
+      break;
+      }
+
+    if (c == 0)
+      {
+      *errorcodeptr = ERR58;
+      break;
+      }
+
+    if (negated)
+      {
+      if (c > bracount)
+        {
+        *errorcodeptr = ERR15;
+        break;
+        }
+      c = bracount - (c - 1);
+      }
+
+    c = -(ESC_REF + c);
+    break;
+
+    /* The handling of escape sequences consisting of a string of digits
+    starting with one that is not zero is not straightforward. By experiment,
+    the way Perl works seems to be as follows:
+
+    Outside a character class, the digits are read as a decimal number. If the
+    number is less than 10, or if there are that many previous extracting
+    left brackets, then it is a back reference. Otherwise, up to three octal
+    digits are read to form an escaped byte. Thus \123 is likely to be octal
+    123 (cf \0123, which is octal 012 followed by the literal 3). If the octal
+    value is greater than 377, the least significant 8 bits are taken. Inside a
+    character class, \ followed by a digit is always an octal number. */
+
+    case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4: case CHAR_5:
+    case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
+
+    if (!isclass)
+      {
+      oldptr = ptr;
+      c -= CHAR_0;
+      while (g_ascii_isdigit(ptr[1]) != 0)
+        c = c * 10 + *(++ptr) - CHAR_0;
+      if (c < 0)    /* Integer overflow */
+        {
+        *errorcodeptr = ERR61;
+        break;
+        }
+      if (c < 10 || c <= bracount)
+        {
+        c = -(ESC_REF + c);
+        break;
+        }
+      ptr = oldptr;      /* Put the pointer back and fall through */
+      }
+
+    /* Handle an octal number following \. If the first digit is 8 or 9, Perl
+    generates a binary zero byte and treats the digit as a following literal.
+    Thus we have to pull back the pointer by one. */
+
+    if ((c = *ptr) >= CHAR_8)
+      {
+      ptr--;
+      c = 0;
+      break;
+      }
+
+    /* \0 always starts an octal number, but we may drop through to here with a
+    larger first octal digit. The original code used just to take the least
+    significant 8 bits of octal numbers (I think this is what early Perls used
+    to do). Nowadays we allow for larger numbers in UTF-8 mode, but no more
+    than 3 octal digits. */
+
+    case CHAR_0:
+    c -= CHAR_0;
+    while(i++ < 2 && ptr[1] >= CHAR_0 && ptr[1] <= CHAR_7)
+        c = c * 8 + *(++ptr) - CHAR_0;
+    if (!utf8 && c > 255) *errorcodeptr = ERR51;
+    break;
+
+    /* \x is complicated. \x{ddd} is a character number which can be greater
+    than 0xff in utf8 mode, but only if the ddd are hex digits. If not, { is
+    treated as a data character. */
+
+    case CHAR_x:
+    if (ptr[1] == CHAR_LEFT_CURLY_BRACKET)
+      {
+      const uschar *pt = ptr + 2;
+      int count = 0;
+
+      c = 0;
+      while (g_ascii_isxdigit(*pt) != 0)
+        {
+        register int cc = *pt++;
+        if (c == 0 && cc == CHAR_0) continue;     /* Leading zeroes */
+        count++;
+
+#ifndef EBCDIC  /* ASCII/UTF-8 coding */
+        if (cc >= CHAR_a) cc -= 32;               /* Convert to upper case */
+        c = (c << 4) + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
+#else           /* EBCDIC coding */
+        if (cc >= CHAR_a && cc <= CHAR_z) cc += 64;  /* Convert to upper case */
+        c = (c << 4) + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
+#endif
+        }
+
+      if (*pt == CHAR_RIGHT_CURLY_BRACKET)
+        {
+        if (c < 0 || count > (utf8? 8 : 2)) *errorcodeptr = ERR34;
+        ptr = pt;
+        break;
+        }
+
+      /* If the sequence of hex digits does not end with '}', then we don't
+      recognize this construct; fall through to the normal \x handling. */
+      }
+
+    /* Read just a single-byte hex-defined char */
+
+    c = 0;
+    while (i++ < 2 && g_ascii_isxdigit(ptr[1]) != 0)
+      {
+      int cc;                                  /* Some compilers don't like */
+      cc = *(++ptr);                           /* ++ in initializers */
+#ifndef EBCDIC  /* ASCII/UTF-8 coding */
+      if (cc >= CHAR_a) cc -= 32;              /* Convert to upper case */
+      c = c * 16 + cc - ((cc < CHAR_A)? CHAR_0 : (CHAR_A - 10));
+#else           /* EBCDIC coding */
+      if (cc <= CHAR_z) cc += 64;              /* Convert to upper case */
+      c = c * 16 + cc - ((cc >= CHAR_0)? CHAR_0 : (CHAR_A - 10));
+#endif
+      }
+    break;
+
+    /* For \c, a following letter is upper-cased; then the 0x40 bit is flipped.
+    This coding is ASCII-specific, but then the whole concept of \cx is
+    ASCII-specific. (However, an EBCDIC equivalent has now been added.) */
+
+    case CHAR_c:
+    c = *(++ptr);
+    if (c == 0)
+      {
+      *errorcodeptr = ERR2;
+      break;
+      }
+
+#ifndef EBCDIC  /* ASCII/UTF-8 coding */
+    if (c >= CHAR_a && c <= CHAR_z) c -= 32;
+    c ^= 0x40;
+#else           /* EBCDIC coding */
+    if (c >= CHAR_a && c <= CHAR_z) c += 64;
+    c ^= 0xC0;
+#endif
+    break;
+
+    /* PCRE_EXTRA enables extensions to Perl in the matter of escapes. Any
+    other alphanumeric following \ is an error if PCRE_EXTRA was set;
+    otherwise, for Perl compatibility, it is a literal. This code looks a bit
+    odd, but there used to be some cases other than the default, and there may
+    be again in future, so I haven't "optimized" it. */
+
+    default:
+    if ((options & PCRE_EXTRA) != 0) switch(c)
+      {
+      default:
+      *errorcodeptr = ERR3;
+      break;
+      }
+    break;
+    }
+  }
+
+*ptrptr = ptr;
+return c;
+}
+
+
+
+#ifdef SUPPORT_UCP
+/*************************************************
+*               Handle \P and \p                 *
+*************************************************/
+
+/* This function is called after \P or \p has been encountered, provided that
+PCRE is compiled with support for Unicode properties. On entry, ptrptr is
+pointing at the P or p. On exit, it is pointing at the final character of the
+escape sequence.
+
+Argument:
+  ptrptr         points to the pattern position pointer
+  negptr         points to a boolean that is set TRUE for negation else FALSE
+  dptr           points to an int that is set to the detailed property value
+  errorcodeptr   points to the error code variable
+
+Returns:         type value from ucp_type_table, or -1 for an invalid type
+*/
+
+static int
+get_ucp(const uschar **ptrptr, BOOL *negptr, int *dptr, int *errorcodeptr)
+{
+int c, i, bot, top;
+const uschar *ptr = *ptrptr;
+char name[32];
+
+c = *(++ptr);
+if (c == 0) goto ERROR_RETURN;
+
+*negptr = FALSE;
+
+/* \P or \p can be followed by a name in {}, optionally preceded by ^ for
+negation. */
+
+if (c == CHAR_LEFT_CURLY_BRACKET)
+  {
+  if (ptr[1] == CHAR_CIRCUMFLEX_ACCENT)
+    {
+    *negptr = TRUE;
+    ptr++;
+    }
+  for (i = 0; i < (int)sizeof(name) - 1; i++)
+    {
+    c = *(++ptr);
+    if (c == 0) goto ERROR_RETURN;
+    if (c == CHAR_RIGHT_CURLY_BRACKET) break;
+    name[i] = c;
+    }
+  if (c != CHAR_RIGHT_CURLY_BRACKET) goto ERROR_RETURN;
+  name[i] = 0;
+  }
+
+/* Otherwise there is just one following character */
+
+else
+  {
+  name[0] = c;
+  name[1] = 0;
+  }
+
+*ptrptr = ptr;
+
+/* Search for a recognized property name using binary chop */
+
+bot = 0;
+top = _pcre_utt_size;
+
+while (bot < top)
+  {
+  i = (bot + top) >> 1;
+  c = strcmp(name, _pcre_utt_names + _pcre_utt[i].name_offset);
+  if (c == 0)
+    {
+    *dptr = _pcre_utt[i].value;
+    return _pcre_utt[i].type;
+    }
+  if (c > 0) bot = i + 1; else top = i;
+  }
+
+*errorcodeptr = ERR47;
+*ptrptr = ptr;
+return -1;
+
+ERROR_RETURN:
+*errorcodeptr = ERR46;
+*ptrptr = ptr;
+return -1;
+}
+#endif
+
+
+
+
+/*************************************************
+*            Check for counted repeat            *
+*************************************************/
+
+/* This function is called when a '{' is encountered in a place where it might
+start a quantifier. It looks ahead to see if it really is a quantifier or not.
+It is only a quantifier if it is one of the forms {ddd} {ddd,} or {ddd,ddd}
+where the ddds are digits.
+
+Arguments:
+  p         pointer to the first char after '{'
+
+Returns:    TRUE or FALSE
+*/
+
+static BOOL
+is_counted_repeat(const uschar *p)
+{
+if (g_ascii_isdigit(*p++) == 0) return FALSE;
+while (g_ascii_isdigit(*p) != 0) p++;
+if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
+
+if (*p++ != CHAR_COMMA) return FALSE;
+if (*p == CHAR_RIGHT_CURLY_BRACKET) return TRUE;
+
+if (g_ascii_isdigit(*p++) == 0) return FALSE;
+while (g_ascii_isdigit(*p) != 0) p++;
+
+return (*p == CHAR_RIGHT_CURLY_BRACKET);
+}
+
+
+
+/*************************************************
+*         Read repeat counts                     *
+*************************************************/
+
+/* Read an item of the form {n,m} and return the values. This is called only
+after is_counted_repeat() has confirmed that a repeat-count quantifier exists,
+so the syntax is guaranteed to be correct, but we need to check the values.
+
+Arguments:
+  p              pointer to first char after '{'
+  minp           pointer to int for min
+  maxp           pointer to int for max
+                 returned as -1 if no max
+  errorcodeptr   points to error code variable
+
+Returns:         pointer to '}' on success;
+                 current ptr on error, with errorcodeptr set non-zero
+*/
+
+static const uschar *
+read_repeat_counts(const uschar *p, int *minp, int *maxp, int *errorcodeptr)
+{
+int min = 0;
+int max = -1;
+
+/* Read the minimum value and do a paranoid check: a negative value indicates
+an integer overflow. */
+
+while (g_ascii_isdigit(*p) != 0) min = min * 10 + *p++ - CHAR_0;
+if (min < 0 || min > 65535)
+  {
+  *errorcodeptr = ERR5;
+  return p;
+  }
+
+/* Read the maximum value if there is one, and again do a paranoid on its size.
+Also, max must not be less than min. */
+
+if (*p == CHAR_RIGHT_CURLY_BRACKET) max = min; else
+  {
+  if (*(++p) != CHAR_RIGHT_CURLY_BRACKET)
+    {
+    max = 0;
+    while(g_ascii_isdigit(*p) != 0) max = max * 10 + *p++ - CHAR_0;
+    if (max < 0 || max > 65535)
+      {
+      *errorcodeptr = ERR5;
+      return p;
+      }
+    if (max < min)
+      {
+      *errorcodeptr = ERR4;
+      return p;
+      }
+    }
+  }
+
+/* Fill in the required variables, and pass back the pointer to the terminating
+'}'. */
+
+*minp = min;
+*maxp = max;
+return p;
+}
+
+
+
+/*************************************************
+*  Subroutine for finding forward reference      *
+*************************************************/
+
+/* This recursive function is called only from find_parens() below. The
+top-level call starts at the beginning of the pattern. All other calls must
+start at a parenthesis. It scans along a pattern's text looking for capturing
+subpatterns, and counting them. If it finds a named pattern that matches the
+name it is given, it returns its number. Alternatively, if the name is NULL, it
+returns when it reaches a given numbered subpattern. We know that if (?P< is
+encountered, the name will be terminated by '>' because that is checked in the
+first pass. Recursion is used to keep track of subpatterns that reset the
+capturing group numbers - the (?| feature.
+
+Arguments:
+  ptrptr       address of the current character pointer (updated)
+  cd           compile background data
+  name         name to seek, or NULL if seeking a numbered subpattern
+  lorn         name length, or subpattern number if name is NULL
+  xmode        TRUE if we are in /x mode
+  count        pointer to the current capturing subpattern number (updated)
+
+Returns:       the number of the named subpattern, or -1 if not found
+*/
+
+static int
+find_parens_sub(uschar **ptrptr, compile_data *cd, const uschar *name, int lorn,
+  BOOL xmode, int *count)
+{
+uschar *ptr = *ptrptr;
+int start_count = *count;
+int hwm_count = start_count;
+BOOL dup_parens = FALSE;
+
+/* If the first character is a parenthesis, check on the type of group we are
+dealing with. The very first call may not start with a parenthesis. */
+
+if (ptr[0] == CHAR_LEFT_PARENTHESIS)
+  {
+  if (ptr[1] == CHAR_QUESTION_MARK &&
+      ptr[2] == CHAR_VERTICAL_LINE)
+    {
+    ptr += 3;
+    dup_parens = TRUE;
+    }
+
+  /* Handle a normal, unnamed capturing parenthesis */
+
+  else if (ptr[1] != CHAR_QUESTION_MARK && ptr[1] != CHAR_ASTERISK)
+    {
+    *count += 1;
+    if (name == NULL && *count == lorn) return *count;
+    ptr++;
+    }
+
+  /* Handle a condition. If it is an assertion, just carry on so that it
+  is processed as normal. If not, skip to the closing parenthesis of the
+  condition (there can't be any nested parens. */
+
+  else if (ptr[2] == CHAR_LEFT_PARENTHESIS)
+    {
+    ptr += 2;
+    if (ptr[1] != CHAR_QUESTION_MARK)
+      {
+      while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
+      if (*ptr != 0) ptr++;
+      }
+    }
+
+  /* We have either (? or (* and not a condition */
+
+  else
+    {
+    ptr += 2;
+    if (*ptr == CHAR_P) ptr++;                      /* Allow optional P */
+
+    /* We have to disambiguate (?<! and (?<= from (?<name> for named groups */
+
+    if ((*ptr == CHAR_LESS_THAN_SIGN && ptr[1] != CHAR_EXCLAMATION_MARK &&
+        ptr[1] != CHAR_EQUALS_SIGN) || *ptr == CHAR_APOSTROPHE)
+      {
+      int term;
+      const uschar *thisname;
+      *count += 1;
+      if (name == NULL && *count == lorn) return *count;
+      term = *ptr++;
+      if (term == CHAR_LESS_THAN_SIGN) term = CHAR_GREATER_THAN_SIGN;
+      thisname = ptr;
+      while (*ptr != term) ptr++;
+      if (name != NULL && lorn == ptr - thisname &&
+          strncmp((const char *)name, (const char *)thisname, lorn) == 0)
+        return *count;
+      term++;
+      }
+    }
+  }
+
+/* Past any initial parenthesis handling, scan for parentheses or vertical
+bars. */
+
+for (; *ptr != 0; ptr++)
+  {
+  /* Skip over backslashed characters and also entire \Q...\E */
+
+  if (*ptr == CHAR_BACKSLASH)
+    {
+    if (*(++ptr) == 0) goto FAIL_EXIT;
+    if (*ptr == CHAR_Q) for (;;)
+      {
+      while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};
+      if (*ptr == 0) goto FAIL_EXIT;
+      if (*(++ptr) == CHAR_E) break;
+      }
+    continue;
+    }
+
+  /* Skip over character classes; this logic must be similar to the way they
+  are handled for real. If the first character is '^', skip it. Also, if the
+  first few characters (either before or after ^) are \Q\E or \E we skip them
+  too. This makes for compatibility with Perl. Note the use of STR macros to
+  encode "Q\\E" so that it works in UTF-8 on EBCDIC platforms. */
+
+  if (*ptr == CHAR_LEFT_SQUARE_BRACKET)
+    {
+    BOOL negate_class = FALSE;
+    for (;;)
+      {
+      if (ptr[1] == CHAR_BACKSLASH)
+        {
+        if (ptr[2] == CHAR_E)
+          ptr+= 2;
+        else if (strncmp((const char *)ptr+2,
+                 STR_Q STR_BACKSLASH STR_E, 3) == 0)
+          ptr += 4;
+        else
+          break;
+        }
+      else if (!negate_class && ptr[1] == CHAR_CIRCUMFLEX_ACCENT)
+        {
+        negate_class = TRUE;
+        ptr++;
+        }
+      else break;
+      }
+
+    /* If the next character is ']', it is a data character that must be
+    skipped, except in JavaScript compatibility mode. */
+
+    if (ptr[1] == CHAR_RIGHT_SQUARE_BRACKET &&
+        (cd->external_options & PCRE_JAVASCRIPT_COMPAT) == 0)
+      ptr++;
+
+    while (*(++ptr) != CHAR_RIGHT_SQUARE_BRACKET)
+      {
+      if (*ptr == 0) return -1;
+      if (*ptr == CHAR_BACKSLASH)
+        {
+        if (*(++ptr) == 0) goto FAIL_EXIT;
+        if (*ptr == CHAR_Q) for (;;)
+          {
+          while (*(++ptr) != 0 && *ptr != CHAR_BACKSLASH) {};
+          if (*ptr == 0) goto FAIL_EXIT;
+          if (*(++ptr) == CHAR_E) break;
+          }
+        continue;
+        }
+      }
+    continue;
+    }
+
+  /* Skip comments in /x mode */
+
+  if (xmode && *ptr == CHAR_NUMBER_SIGN)
+    {
+    while (*(++ptr) != 0 && *ptr != CHAR_NL) {};
+    if (*ptr == 0) goto FAIL_EXIT;
+    continue;
+    }
+
+  /* Check for the special metacharacters */
+
+  if (*ptr == CHAR_LEFT_PARENTHESIS)
+    {
+    int rc = find_parens_sub(&ptr, cd, name, lorn, xmode, count);
+    if (rc > 0) return rc;
+    if (*ptr == 0) goto FAIL_EXIT;
+    }
+
+  else if (*ptr == CHAR_RIGHT_PARENTHESIS)
+    {
+    if (dup_parens && *count < hwm_count) *count = hwm_count;
+    *ptrptr = ptr;
+    return -1;
+    }
+
+  else if (*ptr == CHAR_VERTICAL_LINE && dup_parens)
+    {
+    if (*count > hwm_count) hwm_count = *count;
+    *count = start_count;
+    }
+  }
+
+FAIL_EXIT:
+*ptrptr = ptr;
+return -1;
+}
+
+
+
+
+/*************************************************
+*       Find forward referenced subpattern       *
+*************************************************/
+
+/* This function scans along a pattern's text looking for capturing
+subpatterns, and counting them. If it finds a named pattern that matches the
+name it is given, it returns its number. Alternatively, if the name is NULL, it
+returns when it reaches a given numbered subpattern. This is used for forward
+references to subpatterns. We used to be able to start this scan from the
+current compiling point, using the current count value from cd->bracount, and
+do it all in a single loop, but the addition of the possibility of duplicate
+subpattern numbers means that we have to scan from the very start, in order to
+take account of such duplicates, and to use a recursive function to keep track
+of the different types of group.
+
+Arguments:
+  cd           compile background data
+  name         name to seek, or NULL if seeking a numbered subpattern
+  lorn         name length, or subpattern number if name is NULL
+  xmode        TRUE if we are in /x mode
+
+Returns:       the number of the found subpattern, or -1 if not found
+*/
+
+static int
+find_parens(compile_data *cd, const uschar *name, int lorn, BOOL xmode)
+{
+uschar *ptr = (uschar *)cd->start_pattern;
+int count = 0;
+int rc;
+
+/* If the pattern does not start with an opening parenthesis, the first call
+to find_parens_sub() will scan right to the end (if necessary). However, if it
+does start with a parenthesis, find_parens_sub() will return when it hits the
+matching closing parens. That is why we have to have a loop. */
+
+for (;;)
+  {
+  rc = find_parens_sub(&ptr, cd, name, lorn, xmode, &count);
+  if (rc > 0 || *ptr++ == 0) break;
+  }
+
+return rc;
+}
+
+
+
+
+/*************************************************
+*      Find first significant op code            *
+*************************************************/
+
+/* This is called by several functions that scan a compiled expression looking
+for a fixed first character, or an anchoring op code etc. It skips over things
+that do not influence this. For some calls, a change of option is important.
+For some calls, it makes sense to skip negative forward and all backward
+assertions, and also the \b assertion; for others it does not.
+
+Arguments:
+  code         pointer to the start of the group
+  options      pointer to external options
+  optbit       the option bit whose changing is significant, or
+                 zero if none are
+  skipassert   TRUE if certain assertions are to be skipped
+
+Returns:       pointer to the first significant opcode
+*/
+
+static const uschar*
+first_significant_code(const uschar *code, int *options, int optbit,
+  BOOL skipassert)
+{
+for (;;)
+  {
+  switch ((int)*code)
+    {
+    case OP_OPT:
+    if (optbit > 0 && ((int)code[1] & optbit) != (*options & optbit))
+      *options = (int)code[1];
+    code += 2;
+    break;
+
+    case OP_ASSERT_NOT:
+    case OP_ASSERTBACK:
+    case OP_ASSERTBACK_NOT:
+    if (!skipassert) return code;
+    do code += GET(code, 1); while (*code == OP_ALT);
+    code += _pcre_OP_lengths[*code];
+    break;
+
+    case OP_WORD_BOUNDARY:
+    case OP_NOT_WORD_BOUNDARY:
+    if (!skipassert) return code;
+    /* Fall through */
+
+    case OP_CALLOUT:
+    case OP_CREF:
+    case OP_NCREF:
+    case OP_RREF:
+    case OP_NRREF:
+    case OP_DEF:
+    code += _pcre_OP_lengths[*code];
+    break;
+
+    default:
+    return code;
+    }
+  }
+/* Control never reaches here */
+}
+
+
+
+
+/*************************************************
+*        Find the fixed length of a branch       *
+*************************************************/
+
+/* Scan a branch and compute the fixed length of subject that will match it,
+if the length is fixed. This is needed for dealing with backward assertions.
+In UTF8 mode, the result is in characters rather than bytes. The branch is
+temporarily terminated with OP_END when this function is called.
+
+This function is called when a backward assertion is encountered, so that if it
+fails, the error message can point to the correct place in the pattern.
+However, we cannot do this when the assertion contains subroutine calls,
+because they can be forward references. We solve this by remembering this case
+and doing the check at the end; a flag specifies which mode we are running in.
+
+Arguments:
+  code     points to the start of the pattern (the bracket)
+  options  the compiling options
+  atend    TRUE if called when the pattern is complete
+  cd       the "compile data" structure
+
+Returns:   the fixed length,
+             or -1 if there is no fixed length,
+             or -2 if \C was encountered
+             or -3 if an OP_RECURSE item was encountered and atend is FALSE
+*/
+
+static int
+find_fixedlength(uschar *code, int options, BOOL atend, compile_data *cd)
+{
+int length = -1;
+
+register int branchlength = 0;
+register uschar *cc = code + 1 + LINK_SIZE;
+
+/* Scan along the opcodes for this branch. If we get to the end of the
+branch, check the length against that of the other branches. */
+
+for (;;)
+  {
+  int d;
+  uschar *ce, *cs;
+  register int op = *cc;
+  switch (op)
+    {
+    case OP_CBRA:
+    case OP_BRA:
+    case OP_ONCE:
+    case OP_COND:
+    d = find_fixedlength(cc + ((op == OP_CBRA)? 2:0), options, atend, cd);
+    if (d < 0) return d;
+    branchlength += d;
+    do cc += GET(cc, 1); while (*cc == OP_ALT);
+    cc += 1 + LINK_SIZE;
+    break;
+
+    /* Reached end of a branch; if it's a ket it is the end of a nested
+    call. If it's ALT it is an alternation in a nested call. If it is
+    END it's the end of the outer call. All can be handled by the same code. */
+
+    case OP_ALT:
+    case OP_KET:
+    case OP_KETRMAX:
+    case OP_KETRMIN:
+    case OP_END:
+    if (length < 0) length = branchlength;
+      else if (length != branchlength) return -1;
+    if (*cc != OP_ALT) return length;
+    cc += 1 + LINK_SIZE;
+    branchlength = 0;
+    break;
+
+    /* A true recursion implies not fixed length, but a subroutine call may
+    be OK. If the subroutine is a forward reference, we can't deal with
+    it until the end of the pattern, so return -3. */
+
+    case OP_RECURSE:
+    if (!atend) return -3;
+    cs = ce = (uschar *)cd->start_code + GET(cc, 1);  /* Start subpattern */
+    do ce += GET(ce, 1); while (*ce == OP_ALT);       /* End subpattern */
+    if (cc > cs && cc < ce) return -1;                /* Recursion */
+    d = find_fixedlength(cs + 2, options, atend, cd);
+    if (d < 0) return d;
+    branchlength += d;
+    cc += 1 + LINK_SIZE;
+    break;
+
+    /* Skip over assertive subpatterns */
+
+    case OP_ASSERT:
+    case OP_ASSERT_NOT:
+    case OP_ASSERTBACK:
+    case OP_ASSERTBACK_NOT:
+    do cc += GET(cc, 1); while (*cc == OP_ALT);
+    /* Fall through */
+
+    /* Skip over things that don't match chars */
+
+    case OP_REVERSE:
+    case OP_CREF:
+    case OP_NCREF:
+    case OP_RREF:
+    case OP_NRREF:
+    case OP_DEF:
+    case OP_OPT:
+    case OP_CALLOUT:
+    case OP_SOD:
+    case OP_SOM:
+    case OP_SET_SOM:
+    case OP_EOD:
+    case OP_EODN:
+    case OP_CIRC:
+    case OP_DOLL:
+    case OP_NOT_WORD_BOUNDARY:
+    case OP_WORD_BOUNDARY:
+    cc += _pcre_OP_lengths[*cc];
+    break;
+
+    /* Handle literal characters */
+
+    case OP_CHAR:
+    case OP_CHARNC:
+    case OP_NOT:
+    branchlength++;
+    cc += 2;
+#ifdef SUPPORT_UTF8
+    if ((options & PCRE_UTF8) != 0 && cc[-1] >= 0xc0)
+      cc += _pcre_utf8_table4[cc[-1] & 0x3f];
+#endif
+    break;
+
+    /* Handle exact repetitions. The count is already in characters, but we
+    need to skip over a multibyte character in UTF8 mode.  */
+
+    case OP_EXACT:
+    branchlength += GET2(cc,1);
+    cc += 4;
+#ifdef SUPPORT_UTF8
+    if ((options & PCRE_UTF8) != 0 && cc[-1] >= 0xc0)
+      cc += _pcre_utf8_table4[cc[-1] & 0x3f];
+#endif
+    break;
+
+    case OP_TYPEEXACT:
+    branchlength += GET2(cc,1);
+    if (cc[3] == OP_PROP || cc[3] == OP_NOTPROP) cc += 2;
+    cc += 4;
+    break;
+
+    /* Handle single-char matchers */
+
+    case OP_PROP:
+    case OP_NOTPROP:
+    cc += 2;
+    /* Fall through */
+
+    case OP_NOT_DIGIT:
+    case OP_DIGIT:
+    case OP_NOT_WHITESPACE:
+    case OP_WHITESPACE:
+    case OP_NOT_WORDCHAR:
+    case OP_WORDCHAR:
+    case OP_ANY:
+    case OP_ALLANY:
+    branchlength++;
+    cc++;
+    break;
+
+    /* The single-byte matcher isn't allowed */
+
+    case OP_ANYBYTE:
+    return -2;
+
+    /* Check a class for variable quantification */
+
+#ifdef SUPPORT_UTF8
+    case OP_XCLASS:
+    cc += GET(cc, 1) - 33;
+    /* Fall through */
+#endif
+
+    case OP_CLASS:
+    case OP_NCLASS:
+    cc += 33;
+
+    switch (*cc)
+      {
+      case OP_CRSTAR:
+      case OP_CRMINSTAR:
+      case OP_CRQUERY:
+      case OP_CRMINQUERY:
+      return -1;
+
+      case OP_CRRANGE:
+      case OP_CRMINRANGE:
+      if (GET2(cc,1) != GET2(cc,3)) return -1;
+      branchlength += GET2(cc,1);
+      cc += 5;
+      break;
+
+      default:
+      branchlength++;
+      }
+    break;
+
+    /* Anything else is variable length */
+
+    default:
+    return -1;
+    }
+  }
+/* Control never gets here */
+}
+
+
+
+
+/*************************************************
+*    Scan compiled regex for specific bracket    *
+*************************************************/
+
+/* This little function scans through a compiled pattern until it finds a
+capturing bracket with the given number, or, if the number is negative, an
+instance of OP_REVERSE for a lookbehind. The function is global in the C sense
+so that it can be called from pcre_study() when finding the minimum matching
+length.
+
+Arguments:
+  code        points to start of expression
+  utf8        TRUE in UTF-8 mode
+  number      the required bracket number or negative to find a lookbehind
+
+Returns:      pointer to the opcode for the bracket, or NULL if not found
+*/
+
+const uschar *
+_pcre_find_bracket(const uschar *code, BOOL utf8, int number)
+{
+for (;;)
+  {
+  register int c = *code;
+  if (c == OP_END) return NULL;
+
+  /* XCLASS is used for classes that cannot be represented just by a bit
+  map. This includes negated single high-valued characters. The length in
+  the table is zero; the actual length is stored in the compiled code. */
+
+  if (c == OP_XCLASS) code += GET(code, 1);
+
+  /* Handle recursion */
+
+  else if (c == OP_REVERSE)
+    {
+    if (number < 0) return (uschar *)code;
+    code += _pcre_OP_lengths[c];
+    }
+
+  /* Handle capturing bracket */
+
+  else if (c == OP_CBRA)
+    {
+    int n = GET2(code, 1+LINK_SIZE);
+    if (n == number) return (uschar *)code;
+    code += _pcre_OP_lengths[c];
+    }
+
+  /* Otherwise, we can get the item's length from the table, except that for
+  repeated character types, we have to test for \p and \P, which have an extra
+  two bytes of parameters. */
+
+  else
+    {
+    switch(c)
+      {
+      case OP_TYPESTAR:
+      case OP_TYPEMINSTAR:
+      case OP_TYPEPLUS:
+      case OP_TYPEMINPLUS:
+      case OP_TYPEQUERY:
+      case OP_TYPEMINQUERY:
+      case OP_TYPEPOSSTAR:
+      case OP_TYPEPOSPLUS:
+      case OP_TYPEPOSQUERY:
+      if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
+      break;
+
+      case OP_TYPEUPTO:
+      case OP_TYPEMINUPTO:
+      case OP_TYPEEXACT:
+      case OP_TYPEPOSUPTO:
+      if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
+      break;
+      }
+
+    /* Add in the fixed length from the table */
+
+    code += _pcre_OP_lengths[c];
+
+  /* In UTF-8 mode, opcodes that are followed by a character may be followed by
+  a multi-byte character. The length in the table is a minimum, so we have to
+  arrange to skip the extra bytes. */
+
+#ifdef SUPPORT_UTF8
+    if (utf8) switch(c)
+      {
+      case OP_CHAR:
+      case OP_CHARNC:
+      case OP_EXACT:
+      case OP_UPTO:
+      case OP_MINUPTO:
+      case OP_POSUPTO:
+      case OP_STAR:
+      case OP_MINSTAR:
+      case OP_POSSTAR:
+      case OP_PLUS:
+      case OP_MINPLUS:
+      case OP_POSPLUS:
+      case OP_QUERY:
+      case OP_MINQUERY:
+      case OP_POSQUERY:
+      if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];
+      break;
+      }
+#else
+    (void)(utf8);  /* Keep compiler happy by referencing function argument */
+#endif
+    }
+  }
+}
+
+
+
+/*************************************************
+*   Scan compiled regex for recursion reference  *
+*************************************************/
+
+/* This little function scans through a compiled pattern until it finds an
+instance of OP_RECURSE.
+
+Arguments:
+  code        points to start of expression
+  utf8        TRUE in UTF-8 mode
+
+Returns:      pointer to the opcode for OP_RECURSE, or NULL if not found
+*/
+
+static const uschar *
+find_recurse(const uschar *code, BOOL utf8)
+{
+for (;;)
+  {
+  register int c = *code;
+  if (c == OP_END) return NULL;
+  if (c == OP_RECURSE) return code;
+
+  /* XCLASS is used for classes that cannot be represented just by a bit
+  map. This includes negated single high-valued characters. The length in
+  the table is zero; the actual length is stored in the compiled code. */
+
+  if (c == OP_XCLASS) code += GET(code, 1);
+
+  /* Otherwise, we can get the item's length from the table, except that for
+  repeated character types, we have to test for \p and \P, which have an extra
+  two bytes of parameters. */
+
+  else
+    {
+    switch(c)
+      {
+      case OP_TYPESTAR:
+      case OP_TYPEMINSTAR:
+      case OP_TYPEPLUS:
+      case OP_TYPEMINPLUS:
+      case OP_TYPEQUERY:
+      case OP_TYPEMINQUERY:
+      case OP_TYPEPOSSTAR:
+      case OP_TYPEPOSPLUS:
+      case OP_TYPEPOSQUERY:
+      if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
+      break;
+
+      case OP_TYPEPOSUPTO:
+      case OP_TYPEUPTO:
+      case OP_TYPEMINUPTO:
+      case OP_TYPEEXACT:
+      if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
+      break;
+      }
+
+    /* Add in the fixed length from the table */
+
+    code += _pcre_OP_lengths[c];
+
+    /* In UTF-8 mode, opcodes that are followed by a character may be followed
+    by a multi-byte character. The length in the table is a minimum, so we have
+    to arrange to skip the extra bytes. */
+
+#ifdef SUPPORT_UTF8
+    if (utf8) switch(c)
+      {
+      case OP_CHAR:
+      case OP_CHARNC:
+      case OP_EXACT:
+      case OP_UPTO:
+      case OP_MINUPTO:
+      case OP_POSUPTO:
+      case OP_STAR:
+      case OP_MINSTAR:
+      case OP_POSSTAR:
+      case OP_PLUS:
+      case OP_MINPLUS:
+      case OP_POSPLUS:
+      case OP_QUERY:
+      case OP_MINQUERY:
+      case OP_POSQUERY:
+      if (code[-1] >= 0xc0) code += _pcre_utf8_table4[code[-1] & 0x3f];
+      break;
+      }
+#else
+    (void)(utf8);  /* Keep compiler happy by referencing function argument */
+#endif
+    }
+  }
+}
+
+
+
+/*************************************************
+*    Scan compiled branch for non-emptiness      *
+*************************************************/
+
+/* This function scans through a branch of a compiled pattern to see whether it
+can match the empty string or not. It is called from could_be_empty()
+below and from compile_branch() when checking for an unlimited repeat of a
+group that can match nothing. Note that first_significant_code() skips over
+backward and negative forward assertions when its final argument is TRUE. If we
+hit an unclosed bracket, we return "empty" - this means we've struck an inner
+bracket whose current branch will already have been scanned.
+
+Arguments:
+  code        points to start of search
+  endcode     points to where to stop
+  utf8        TRUE if in UTF8 mode
+  cd          contains pointers to tables etc.
+
+Returns:      TRUE if what is matched could be empty
+*/
+
+static BOOL
+could_be_empty_branch(const uschar *code, const uschar *endcode, BOOL utf8,
+  compile_data *cd)
+{
+register int c;
+for (code = first_significant_code(code + _pcre_OP_lengths[*code], NULL, 0, TRUE);
+     code < endcode;
+     code = first_significant_code(code + _pcre_OP_lengths[c], NULL, 0, TRUE))
+  {
+  const uschar *ccode;
+
+  c = *code;
+
+  /* Skip over forward assertions; the other assertions are skipped by
+  first_significant_code() with a TRUE final argument. */
+
+  if (c == OP_ASSERT)
+    {
+    do code += GET(code, 1); while (*code == OP_ALT);
+    c = *code;
+    continue;
+    }
+
+  /* Groups with zero repeats can of course be empty; skip them. */
+
+  if (c == OP_BRAZERO || c == OP_BRAMINZERO || c == OP_SKIPZERO)
+    {
+    code += _pcre_OP_lengths[c];
+    do code += GET(code, 1); while (*code == OP_ALT);
+    c = *code;
+    continue;
+    }
+
+  /* For a recursion/subroutine call, if its end has been reached, which
+  implies a subroutine call, we can scan it. */
+
+  if (c == OP_RECURSE)
+    {
+    BOOL empty_branch = FALSE;
+    const uschar *scode = cd->start_code + GET(code, 1);
+    if (GET(scode, 1) == 0) return TRUE;    /* Unclosed */
+    do
+      {
+      if (could_be_empty_branch(scode, endcode, utf8, cd))
+        {
+        empty_branch = TRUE;
+        break;
+        }
+      scode += GET(scode, 1);
+      }
+    while (*scode == OP_ALT);
+    if (!empty_branch) return FALSE;  /* All branches are non-empty */
+    continue;
+    }
+
+  /* For other groups, scan the branches. */
+
+  if (c == OP_BRA || c == OP_CBRA || c == OP_ONCE || c == OP_COND)
+    {
+    BOOL empty_branch;
+    if (GET(code, 1) == 0) return TRUE;    /* Hit unclosed bracket */
+
+    /* If a conditional group has only one branch, there is a second, implied,
+    empty branch, so just skip over the conditional, because it could be empty.
+    Otherwise, scan the individual branches of the group. */
+
+    if (c == OP_COND && code[GET(code, 1)] != OP_ALT)
+      code += GET(code, 1);
+    else
+      {
+      empty_branch = FALSE;
+      do
+        {
+        if (!empty_branch && could_be_empty_branch(code, endcode, utf8, cd))
+          empty_branch = TRUE;
+        code += GET(code, 1);
+        }
+      while (*code == OP_ALT);
+      if (!empty_branch) return FALSE;   /* All branches are non-empty */
+      }
+
+    c = *code;
+    continue;
+    }
+
+  /* Handle the other opcodes */
+
+  switch (c)
+    {
+    /* Check for quantifiers after a class. XCLASS is used for classes that
+    cannot be represented just by a bit map. This includes negated single
+    high-valued characters. The length in _pcre_OP_lengths[] is zero; the
+    actual length is stored in the compiled code, so we must update "code"
+    here. */
+
+#ifdef SUPPORT_UTF8
+    case OP_XCLASS:
+    ccode = code += GET(code, 1);
+    goto CHECK_CLASS_REPEAT;
+#endif
+
+    case OP_CLASS:
+    case OP_NCLASS:
+    ccode = code + 33;
+
+#ifdef SUPPORT_UTF8
+    CHECK_CLASS_REPEAT:
+#endif
+
+    switch (*ccode)
+      {
+      case OP_CRSTAR:            /* These could be empty; continue */
+      case OP_CRMINSTAR:
+      case OP_CRQUERY:
+      case OP_CRMINQUERY:
+      break;
+
+      default:                   /* Non-repeat => class must match */
+      case OP_CRPLUS:            /* These repeats aren't empty */
+      case OP_CRMINPLUS:
+      return FALSE;
+
+      case OP_CRRANGE:
+      case OP_CRMINRANGE:
+      if (GET2(ccode, 1) > 0) return FALSE;  /* Minimum > 0 */
+      break;
+      }
+    break;
+
+    /* Opcodes that must match a character */
+
+    case OP_PROP:
+    case OP_NOTPROP:
+    case OP_EXTUNI:
+    case OP_NOT_DIGIT:
+    case OP_DIGIT:
+    case OP_NOT_WHITESPACE:
+    case OP_WHITESPACE:
+    case OP_NOT_WORDCHAR:
+    case OP_WORDCHAR:
+    case OP_ANY:
+    case OP_ALLANY:
+    case OP_ANYBYTE:
+    case OP_CHAR:
+    case OP_CHARNC:
+    case OP_NOT:
+    case OP_PLUS:
+    case OP_MINPLUS:
+    case OP_POSPLUS:
+    case OP_EXACT:
+    case OP_NOTPLUS:
+    case OP_NOTMINPLUS:
+    case OP_NOTPOSPLUS:
+    case OP_NOTEXACT:
+    case OP_TYPEPLUS:
+    case OP_TYPEMINPLUS:
+    case OP_TYPEPOSPLUS:
+    case OP_TYPEEXACT:
+    return FALSE;
+
+    /* These are going to continue, as they may be empty, but we have to
+    fudge the length for the \p and \P cases. */
+
+    case OP_TYPESTAR:
+    case OP_TYPEMINSTAR:
+    case OP_TYPEPOSSTAR:
+    case OP_TYPEQUERY:
+    case OP_TYPEMINQUERY:
+    case OP_TYPEPOSQUERY:
+    if (code[1] == OP_PROP || code[1] == OP_NOTPROP) code += 2;
+    break;
+
+    /* Same for these */
+
+    case OP_TYPEUPTO:
+    case OP_TYPEMINUPTO:
+    case OP_TYPEPOSUPTO:
+    if (code[3] == OP_PROP || code[3] == OP_NOTPROP) code += 2;
+    break;
+
+    /* End of branch */
+
+    case OP_KET:
+    case OP_KETRMAX:
+    case OP_KETRMIN:
+    case OP_ALT:
+    return TRUE;
+
+    /* In UTF-8 mode, STAR, MINSTAR, POSSTAR, QUERY, MINQUERY, POSQUERY, UPTO,
+    MINUPTO, and POSUPTO may be followed by a multibyte character */
+
+#ifdef SUPPORT_UTF8
+    case OP_STAR:
+    case OP_MINSTAR:
+    case OP_POSSTAR:
+    case OP_QUERY:
+    case OP_MINQUERY:
+    case OP_POSQUERY:
+    if (utf8 && code[1] >= 0xc0) code += _pcre_utf8_table4[code[1] & 0x3f];
+    break;
+
+    case OP_UPTO:
+    case OP_MINUPTO:
+    case OP_POSUPTO:
+    if (utf8 && code[3] >= 0xc0) code += _pcre_utf8_table4[code[3] & 0x3f];
+    break;
+#endif
+
+    /* None of the remaining opcodes are required to match a character. */
+
+    default:
+    break;
+    }
+  }
+
+return TRUE;
+}
+
+
+
+/*************************************************
+*    Scan compiled regex for non-emptiness       *
+*************************************************/
+
+/* This function is called to check for left recursive calls. We want to check
+the current branch of the current pattern to see if it could match the empty
+string. If it could, we must look outwards for branches at other levels,
+stopping when we pass beyond the bracket which is the subject of the recursion.
+
+Arguments:
+  code        points to start of the recursion
+  endcode     points to where to stop (current RECURSE item)
+  bcptr       points to the chain of current (unclosed) branch starts
+  utf8        TRUE if in UTF-8 mode
+  cd          pointers to tables etc
+
+Returns:      TRUE if what is matched could be empty
+*/
+
+static BOOL
+could_be_empty(const uschar *code, const uschar *endcode, branch_chain *bcptr,
+  BOOL utf8, compile_data *cd)
+{
+while (bcptr != NULL && bcptr->current_branch >= code)
+  {
+  if (!could_be_empty_branch(bcptr->current_branch, endcode, utf8, cd))
+    return FALSE;
+  bcptr = bcptr->outer;
+  }
+return TRUE;
+}
+
+
+
+/*************************************************
+*           Check for POSIX class syntax         *
+*************************************************/
+
+/* This function is called when the sequence "[:" or "[." or "[=" is
+encountered in a character class. It checks whether this is followed by a
+sequence of characters terminated by a matching ":]" or ".]" or "=]". If we
+reach an unescaped ']' without the special preceding character, return FALSE.
+
+Originally, this function only recognized a sequence of letters between the
+terminators, but it seems that Perl recognizes any sequence of characters,
+though of course unknown POSIX names are subsequently rejected. Perl gives an
+"Unknown POSIX class" error for [:f\oo:] for example, where previously PCRE
+didn't consider this to be a POSIX class. Likewise for [:1234:].
+
+The problem in trying to be exactly like Perl is in the handling of escapes. We
+have to be sure that [abc[:x\]pqr] is *not* treated as containing a POSIX
+class, but [abc[:x\]pqr:]] is (so that an error can be generated). The code
+below handles the special case of \], but does not try to do any other escape
+processing. This makes it different from Perl for cases such as [:l\ower:]
+where Perl recognizes it as the POSIX class "lower" but PCRE does not recognize
+"l\ower". This is a lesser evil that not diagnosing bad classes when Perl does,
+I think.
+
+Arguments:
+  ptr      pointer to the initial [
+  endptr   where to return the end pointer
+
+Returns:   TRUE or FALSE
+*/
+
+static BOOL
+check_posix_syntax(const uschar *ptr, const uschar **endptr)
+{
+int terminator;          /* Don't combine these lines; the Solaris cc */
+terminator = *(++ptr);   /* compiler warns about "non-constant" initializer. */
+for (++ptr; *ptr != 0; ptr++)
+  {
+  if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET) ptr++; else
+    {
+    if (*ptr == CHAR_RIGHT_SQUARE_BRACKET) return FALSE;
+    if (*ptr == terminator && ptr[1] == CHAR_RIGHT_SQUARE_BRACKET)
+      {
+      *endptr = ptr;
+      return TRUE;
+      }
+    }
+  }
+return FALSE;
+}
+
+
+
+
+/*************************************************
+*          Check POSIX class name                *
+*************************************************/
+
+/* This function is called to check the name given in a POSIX-style class entry
+such as [:alnum:].
+
+Arguments:
+  ptr        points to the first letter
+  len        the length of the name
+
+Returns:     a value representing the name, or -1 if unknown
+*/
+
+static int
+check_posix_name(const uschar *ptr, int len)
+{
+const char *pn = posix_names;
+register int yield = 0;
+while (posix_name_lengths[yield] != 0)
+  {
+  if (len == posix_name_lengths[yield] &&
+    strncmp((const char *)ptr, pn, len) == 0) return yield;
+  pn += posix_name_lengths[yield] + 1;
+  yield++;
+  }
+return -1;
+}
+
+
+/*************************************************
+*    Adjust OP_RECURSE items in repeated group   *
+*************************************************/
+
+/* OP_RECURSE items contain an offset from the start of the regex to the group
+that is referenced. This means that groups can be replicated for fixed
+repetition simply by copying (because the recursion is allowed to refer to
+earlier groups that are outside the current group). However, when a group is
+optional (i.e. the minimum quantifier is zero), OP_BRAZERO or OP_SKIPZERO is
+inserted before it, after it has been compiled. This means that any OP_RECURSE
+items within it that refer to the group itself or any contained groups have to
+have their offsets adjusted. That one of the jobs of this function. Before it
+is called, the partially compiled regex must be temporarily terminated with
+OP_END.
+
+This function has been extended with the possibility of forward references for
+recursions and subroutine calls. It must also check the list of such references
+for the group we are dealing with. If it finds that one of the recursions in
+the current group is on this list, it adjusts the offset in the list, not the
+value in the reference (which is a group number).
+
+Arguments:
+  group      points to the start of the group
+  adjust     the amount by which the group is to be moved
+  utf8       TRUE in UTF-8 mode
+  cd         contains pointers to tables etc.
+  save_hwm   the hwm forward reference pointer at the start of the group
+
+Returns:     nothing
+*/
+
+static void
+adjust_recurse(uschar *group, int adjust, BOOL utf8, compile_data *cd,
+  uschar *save_hwm)
+{
+uschar *ptr = group;
+
+while ((ptr = (uschar *)find_recurse(ptr, utf8)) != NULL)
+  {
+  int offset;
+  uschar *hc;
+
+  /* See if this recursion is on the forward reference list. If so, adjust the
+  reference. */
+
+  for (hc = save_hwm; hc < cd->hwm; hc += LINK_SIZE)
+    {
+    offset = GET(hc, 0);
+    if (cd->start_code + offset == ptr + 1)
+      {
+      PUT(hc, 0, offset + adjust);
+      break;
+      }
+    }
+
+  /* Otherwise, adjust the recursion offset if it's after the start of this
+  group. */
+
+  if (hc >= cd->hwm)
+    {
+    offset = GET(ptr, 1);
+    if (cd->start_code + offset >= group) PUT(ptr, 1, offset + adjust);
+    }
+
+  ptr += 1 + LINK_SIZE;
+  }
+}
+
+
+
+/*************************************************
+*        Insert an automatic callout point       *
+*************************************************/
+
+/* This function is called when the PCRE_AUTO_CALLOUT option is set, to insert
+callout points before each pattern item.
+
+Arguments:
+  code           current code pointer
+  ptr            current pattern pointer
+  cd             pointers to tables etc
+
+Returns:         new code pointer
+*/
+
+static uschar *
+auto_callout(uschar *code, const uschar *ptr, compile_data *cd)
+{
+*code++ = OP_CALLOUT;
+*code++ = 255;
+PUT(code, 0, ptr - cd->start_pattern);  /* Pattern offset */
+PUT(code, LINK_SIZE, 0);                /* Default length */
+return code + 2*LINK_SIZE;
+}
+
+
+
+/*************************************************
+*         Complete a callout item                *
+*************************************************/
+
+/* A callout item contains the length of the next item in the pattern, which
+we can't fill in till after we have reached the relevant point. This is used
+for both automatic and manual callouts.
+
+Arguments:
+  previous_callout   points to previous callout item
+  ptr                current pattern pointer
+  cd                 pointers to tables etc
+
+Returns:             nothing
+*/
+
+static void
+complete_callout(uschar *previous_callout, const uschar *ptr, compile_data *cd)
+{
+int length = ptr - cd->start_pattern - GET(previous_callout, 2);
+PUT(previous_callout, 2 + LINK_SIZE, length);
+}
+
+
+
+#ifdef SUPPORT_UCP
+/*************************************************
+*           Get othercase range                  *
+*************************************************/
+
+/* This function is passed the start and end of a class range, in UTF-8 mode
+with UCP support. It searches up the characters, looking for internal ranges of
+characters in the "other" case. Each call returns the next one, updating the
+start address.
+
+Arguments:
+  cptr        points to starting character value; updated
+  d           end value
+  ocptr       where to put start of othercase range
+  odptr       where to put end of othercase range
+
+Yield:        TRUE when range returned; FALSE when no more
+*/
+
+static BOOL
+get_othercase_range(unsigned int *cptr, unsigned int d, unsigned int *ocptr,
+  unsigned int *odptr)
+{
+unsigned int c, othercase, next;
+
+for (c = *cptr; c <= d; c++)
+  { if ((othercase = UCD_OTHERCASE(c)) != c) break; }
+
+if (c > d) return FALSE;
+
+*ocptr = othercase;
+next = othercase + 1;
+
+for (++c; c <= d; c++)
+  {
+  if (UCD_OTHERCASE(c) != next) break;
+  next++;
+  }
+
+*odptr = next - 1;
+*cptr = c;
+
+return TRUE;
+}
+#endif  /* SUPPORT_UCP */
+
+
+
+/*************************************************
+*     Check if auto-possessifying is possible    *
+*************************************************/
+
+/* This function is called for unlimited repeats of certain items, to see
+whether the next thing could possibly match the repeated item. If not, it makes
+sense to automatically possessify the repeated item.
+
+Arguments:
+  op_code       the repeated op code
+  this          data for this item, depends on the opcode
+  utf8          TRUE in UTF-8 mode
+  utf8_char     used for utf8 character bytes, NULL if not relevant
+  ptr           next character in pattern
+  options       options bits
+  cd            contains pointers to tables etc.
+
+Returns:        TRUE if possessifying is wanted
+*/
+
+static BOOL
+check_auto_possessive(int op_code, int item, BOOL utf8, uschar *utf8_char,
+  const uschar *ptr, int options, compile_data *cd)
+{
+int next;
+
+/* Skip whitespace and comments in extended mode */
+
+if ((options & PCRE_EXTENDED) != 0)
+  {
+  for (;;)
+    {
+    while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
+    if (*ptr == CHAR_NUMBER_SIGN)
+      {
+      while (*(++ptr) != 0)
+        if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
+      }
+    else break;
+    }
+  }
+
+/* If the next item is one that we can handle, get its value. A non-negative
+value is a character, a negative value is an escape value. */
+
+if (*ptr == CHAR_BACKSLASH)
+  {
+  int temperrorcode = 0;
+  next = check_escape(&ptr, &temperrorcode, cd->bracount, options, FALSE);
+  if (temperrorcode != 0) return FALSE;
+  ptr++;    /* Point after the escape sequence */
+  }
+
+else if ((cd->ctypes[*ptr] & ctype_meta) == 0)
+  {
+#ifdef SUPPORT_UTF8
+  if (utf8) { GETCHARINC(next, ptr); } else
+#endif
+  next = *ptr++;
+  }
+
+else return FALSE;
+
+/* Skip whitespace and comments in extended mode */
+
+if ((options & PCRE_EXTENDED) != 0)
+  {
+  for (;;)
+    {
+    while ((cd->ctypes[*ptr] & ctype_space) != 0) ptr++;
+    if (*ptr == CHAR_NUMBER_SIGN)
+      {
+      while (*(++ptr) != 0)
+        if (IS_NEWLINE(ptr)) { ptr += cd->nllen; break; }
+      }
+    else break;
+    }
+  }
+
+/* If the next thing is itself optional, we have to give up. */
+
+if (*ptr == CHAR_ASTERISK || *ptr == CHAR_QUESTION_MARK ||
+  strncmp((char *)ptr, STR_LEFT_CURLY_BRACKET STR_0 STR_COMMA, 3) == 0)
+    return FALSE;
+
+/* Now compare the next item with the previous opcode. If the previous is a
+positive single character match, "item" either contains the character or, if
+"item" is greater than 127 in utf8 mode, the character's bytes are in
+utf8_char. */
+
+
+/* Handle cases when the next item is a character. */
+
+if (next >= 0) switch(op_code)
+  {
+  case OP_CHAR:
+#ifdef SUPPORT_UTF8
+  if (utf8 && item > 127) { GETCHAR(item, utf8_char); }
+#else
+  (void)(utf8_char);  /* Keep compiler happy by referencing function argument */
+#endif
+  return item != next;
+
+  /* For CHARNC (caseless character) we must check the other case. If we have
+  Unicode property support, we can use it to test the other case of
+  high-valued characters. */
+
+  case OP_CHARNC:
+#ifdef SUPPORT_UTF8
+  if (utf8 && item > 127) { GETCHAR(item, utf8_char); }
+#endif
+  if (item == next) return FALSE;
+#ifdef SUPPORT_UTF8
+  if (utf8)
+    {
+    unsigned int othercase;
+    if (next < 128) othercase = cd->fcc[next]; else
+#ifdef SUPPORT_UCP
+    othercase = UCD_OTHERCASE((unsigned int)next);
+#else
+    othercase = NOTACHAR;
+#endif
+    return (unsigned int)item != othercase;
+    }
+  else
+#endif  /* SUPPORT_UTF8 */
+  return (item != cd->fcc[next]);  /* Non-UTF-8 mode */
+
+  /* For OP_NOT, "item" must be a single-byte character. */
+
+  case OP_NOT:
+  if (item == next) return TRUE;
+  if ((options & PCRE_CASELESS) == 0) return FALSE;
+#ifdef SUPPORT_UTF8
+  if (utf8)
+    {
+    unsigned int othercase;
+    if (next < 128) othercase = cd->fcc[next]; else
+#ifdef SUPPORT_UCP
+    othercase = UCD_OTHERCASE(next);
+#else
+    othercase = NOTACHAR;
+#endif
+    return (unsigned int)item == othercase;
+    }
+  else
+#endif  /* SUPPORT_UTF8 */
+  return (item == cd->fcc[next]);  /* Non-UTF-8 mode */
+
+  case OP_DIGIT:
+  return next > 127 || (cd->ctypes[next] & ctype_digit) == 0;
+
+  case OP_NOT_DIGIT:
+  return next <= 127 && (cd->ctypes[next] & ctype_digit) != 0;
+
+  case OP_WHITESPACE:
+  return next > 127 || (cd->ctypes[next] & ctype_space) == 0;
+
+  case OP_NOT_WHITESPACE:
+  return next <= 127 && (cd->ctypes[next] & ctype_space) != 0;
+
+  case OP_WORDCHAR:
+  return next > 127 || (cd->ctypes[next] & ctype_word) == 0;
+
+  case OP_NOT_WORDCHAR:
+  return next <= 127 && (cd->ctypes[next] & ctype_word) != 0;
+
+  case OP_HSPACE:
+  case OP_NOT_HSPACE:
+  switch(next)
+    {
+    case 0x09:
+    case 0x20:
+    case 0xa0:
+    case 0x1680:
+    case 0x180e:
+    case 0x2000:
+    case 0x2001:
+    case 0x2002:
+    case 0x2003:
+    case 0x2004:
+    case 0x2005:
+    case 0x2006:
+    case 0x2007:
+    case 0x2008:
+    case 0x2009:
+    case 0x200A:
+    case 0x202f:
+    case 0x205f:
+    case 0x3000:
+    return op_code != OP_HSPACE;
+    default:
+    return op_code == OP_HSPACE;
+    }
+
+  case OP_VSPACE:
+  case OP_NOT_VSPACE:
+  switch(next)
+    {
+    case 0x0a:
+    case 0x0b:
+    case 0x0c:
+    case 0x0d:
+    case 0x85:
+    case 0x2028:
+    case 0x2029:
+    return op_code != OP_VSPACE;
+    default:
+    return op_code == OP_VSPACE;
+    }
+
+  default:
+  return FALSE;
+  }
+
+
+/* Handle the case when the next item is \d, \s, etc. */
+
+switch(op_code)
+  {
+  case OP_CHAR:
+  case OP_CHARNC:
+#ifdef SUPPORT_UTF8
+  if (utf8 && item > 127) { GETCHAR(item, utf8_char); }
+#endif
+  switch(-next)
+    {
+    case ESC_d:
+    return item > 127 || (cd->ctypes[item] & ctype_digit) == 0;
+
+    case ESC_D:
+    return item <= 127 && (cd->ctypes[item] & ctype_digit) != 0;
+
+    case ESC_s:
+    return item > 127 || (cd->ctypes[item] & ctype_space) == 0;
+
+    case ESC_S:
+    return item <= 127 && (cd->ctypes[item] & ctype_space) != 0;
+
+    case ESC_w:
+    return item > 127 || (cd->ctypes[item] & ctype_word) == 0;
+
+    case ESC_W:
+    return item <= 127 && (cd->ctypes[item] & ctype_word) != 0;
+
+    case ESC_h:
+    case ESC_H:
+    switch(item)
+      {
+      case 0x09:
+      case 0x20:
+      case 0xa0:
+      case 0x1680:
+      case 0x180e:
+      case 0x2000:
+      case 0x2001:
+      case 0x2002:
+      case 0x2003:
+      case 0x2004:
+      case 0x2005:
+      case 0x2006:
+      case 0x2007:
+      case 0x2008:
+      case 0x2009:
+      case 0x200A:
+      case 0x202f:
+      case 0x205f:
+      case 0x3000:
+      return -next != ESC_h;
+      default:
+      return -next == ESC_h;
+      }
+
+    case ESC_v:
+    case ESC_V:
+    switch(item)
+      {
+      case 0x0a:
+      case 0x0b:
+      case 0x0c:
+      case 0x0d:
+      case 0x85:
+      case 0x2028:
+      case 0x2029:
+      return -next != ESC_v;
+      default:
+      return -next == ESC_v;
+      }
+
+    default:
+    return FALSE;
+    }
+
+  case OP_DIGIT:
+  return next == -ESC_D || next == -ESC_s || next == -ESC_W ||
+         next == -ESC_h || next == -ESC_v;
+
+  case OP_NOT_DIGIT:
+  return next == -ESC_d;
+
+  case OP_WHITESPACE:
+  return next == -ESC_S || next == -ESC_d || next == -ESC_w;
+
+  case OP_NOT_WHITESPACE:
+  return next == -ESC_s || next == -ESC_h || next == -ESC_v;
+
+  case OP_HSPACE:
+  return next == -ESC_S || next == -ESC_H || next == -ESC_d || next == -ESC_w;
+
+  case OP_NOT_HSPACE:
+  return next == -ESC_h;
+
+  /* Can't have \S in here because VT matches \S (Perl anomaly) */
+  case OP_VSPACE:
+  return next == -ESC_V || next == -ESC_d || next == -ESC_w;
+
+  case OP_NOT_VSPACE:
+  return next == -ESC_v;
+
+  case OP_WORDCHAR:
+  return next == -ESC_W || next == -ESC_s || next == -ESC_h || next == -ESC_v;
+
+  case OP_NOT_WORDCHAR:
+  return next == -ESC_w || next == -ESC_d;
+
+  default:
+  return FALSE;
+  }
+
+/* Control does not reach here */
+}
+
+
+
+/*************************************************
+*           Compile one branch                   *
+*************************************************/
+
+/* Scan the pattern, compiling it into the a vector. If the options are
+changed during the branch, the pointer is used to change the external options
+bits. This function is used during the pre-compile phase when we are trying
+to find out the amount of memory needed, as well as during the real compile
+phase. The value of lengthptr distinguishes the two phases.
+
+Arguments:
+  optionsptr     pointer to the option bits
+  codeptr        points to the pointer to the current code point
+  ptrptr         points to the current pattern pointer
+  errorcodeptr   points to error code variable
+  firstbyteptr   set to initial literal character, or < 0 (REQ_UNSET, REQ_NONE)
+  reqbyteptr     set to the last literal character required, else < 0
+  bcptr          points to current branch chain
+  cd             contains pointers to tables etc.
+  lengthptr      NULL during the real compile phase
+                 points to length accumulator during pre-compile phase
+
+Returns:         TRUE on success
+                 FALSE, with *errorcodeptr set non-zero on error
+*/
+
+static BOOL
+compile_branch(int *optionsptr, uschar **codeptr, const uschar **ptrptr,
+  int *errorcodeptr, int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr,
+  compile_data *cd, int *lengthptr)
+{
+int repeat_type, op_type;
+int repeat_min = 0, repeat_max = 0;      /* To please picky compilers */
+int bravalue = 0;
+int greedy_default, greedy_non_default;
+int firstbyte, reqbyte;
+int zeroreqbyte, zerofirstbyte;
+int req_caseopt, reqvary, tempreqvary;
+int options = *optionsptr;
+int after_manual_callout = 0;
+int length_prevgroup = 0;
+register int c;
+register uschar *code = *codeptr;
+uschar *last_code = code;
+uschar *orig_code = code;
+uschar *tempcode;
+BOOL inescq = FALSE;
+BOOL groupsetfirstbyte = FALSE;
+const uschar *ptr = *ptrptr;
+const uschar *tempptr;
+uschar *previous = NULL;
+uschar *previous_callout = NULL;
+uschar *save_hwm = NULL;
+uschar classbits[32];
+
+#ifdef SUPPORT_UTF8
+BOOL class_utf8;
+BOOL utf8 = (options & PCRE_UTF8) != 0;
+uschar *class_utf8data;
+uschar *class_utf8data_base;
+uschar utf8_char[6];
+#else
+BOOL utf8 = FALSE;
+uschar *utf8_char = NULL;
+#endif
+
+#ifdef PCRE_DEBUG
+if (lengthptr != NULL) DPRINTF((">> start branch\n"));
+#endif
+
+/* Set up the default and non-default settings for greediness */
+
+greedy_default = ((options & PCRE_UNGREEDY) != 0);
+greedy_non_default = greedy_default ^ 1;
+
+/* Initialize no first byte, no required byte. REQ_UNSET means "no char
+matching encountered yet". It gets changed to REQ_NONE if we hit something that
+matches a non-fixed char first char; reqbyte just remains unset if we never
+find one.
+
+When we hit a repeat whose minimum is zero, we may have to adjust these values
+to take the zero repeat into account. This is implemented by setting them to
+zerofirstbyte and zeroreqbyte when such a repeat is encountered. The individual
+item types that can be repeated set these backoff variables appropriately. */
+
+firstbyte = reqbyte = zerofirstbyte = zeroreqbyte = REQ_UNSET;
+
+/* The variable req_caseopt contains either the REQ_CASELESS value or zero,
+according to the current setting of the caseless flag. REQ_CASELESS is a bit
+value > 255. It is added into the firstbyte or reqbyte variables to record the
+case status of the value. This is used only for ASCII characters. */
+
+req_caseopt = ((options & PCRE_CASELESS) != 0)? REQ_CASELESS : 0;
+
+/* Switch on next character until the end of the branch */
+
+for (;; ptr++)
+  {
+  BOOL negate_class;
+  BOOL should_flip_negation;
+  BOOL possessive_quantifier;
+  BOOL is_quantifier;
+  BOOL is_recurse;
+  BOOL reset_bracount;
+  int class_charcount;
+  int class_lastchar;
+  int newoptions;
+  int recno;
+  int refsign;
+  int skipbytes;
+  int subreqbyte;
+  int subfirstbyte;
+  int terminator;
+  int mclength;
+  uschar mcbuffer[8];
+
+  /* Get next byte in the pattern */
+
+  c = *ptr;
+
+  /* If we are in the pre-compile phase, accumulate the length used for the
+  previous cycle of this loop. */
+
+  if (lengthptr != NULL)
+    {
+#ifdef PCRE_DEBUG
+    if (code > cd->hwm) cd->hwm = code;                 /* High water info */
+#endif
+    if (code > cd->start_workspace + WORK_SIZE_CHECK)   /* Check for overrun */
+      {
+      *errorcodeptr = ERR52;
+      goto FAILED;
+      }
+
+    /* There is at least one situation where code goes backwards: this is the
+    case of a zero quantifier after a class (e.g. [ab]{0}). At compile time,
+    the class is simply eliminated. However, it is created first, so we have to
+    allow memory for it. Therefore, don't ever reduce the length at this point.
+    */
+
+    if (code < last_code) code = last_code;
+
+    /* Paranoid check for integer overflow */
+
+    if (OFLOW_MAX - *lengthptr < code - last_code)
+      {
+      *errorcodeptr = ERR20;
+      goto FAILED;
+      }
+
+    *lengthptr += code - last_code;
+    DPRINTF(("length=%d added %d c=%c\n", *lengthptr, code - last_code, c));
+
+    /* If "previous" is set and it is not at the start of the work space, move
+    it back to there, in order to avoid filling up the work space. Otherwise,
+    if "previous" is NULL, reset the current code pointer to the start. */
+
+    if (previous != NULL)
+      {
+      if (previous > orig_code)
+        {
+        memmove(orig_code, previous, code - previous);
+        code -= previous - orig_code;
+        previous = orig_code;
+        }
+      }
+    else code = orig_code;
+
+    /* Remember where this code item starts so we can pick up the length
+    next time round. */
+
+    last_code = code;
+    }
+
+  /* In the real compile phase, just check the workspace used by the forward
+  reference list. */
+
+  else if (cd->hwm > cd->start_workspace + WORK_SIZE_CHECK)
+    {
+    *errorcodeptr = ERR52;
+    goto FAILED;
+    }
+
+  /* If in \Q...\E, check for the end; if not, we have a literal */
+
+  if (inescq && c != 0)
+    {
+    if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E)
+      {
+      inescq = FALSE;
+      ptr++;
+      continue;
+      }
+    else
+      {
+      if (previous_callout != NULL)
+        {
+        if (lengthptr == NULL)  /* Don't attempt in pre-compile phase */
+          complete_callout(previous_callout, ptr, cd);
+        previous_callout = NULL;
+        }
+      if ((options & PCRE_AUTO_CALLOUT) != 0)
+        {
+        previous_callout = code;
+        code = auto_callout(code, ptr, cd);
+        }
+      goto NORMAL_CHAR;
+      }
+    }
+
+  /* Fill in length of a previous callout, except when the next thing is
+  a quantifier. */
+
+  is_quantifier =
+    c == CHAR_ASTERISK || c == CHAR_PLUS || c == CHAR_QUESTION_MARK ||
+    (c == CHAR_LEFT_CURLY_BRACKET && is_counted_repeat(ptr+1));
+
+  if (!is_quantifier && previous_callout != NULL &&
+       after_manual_callout-- <= 0)
+    {
+    if (lengthptr == NULL)      /* Don't attempt in pre-compile phase */
+      complete_callout(previous_callout, ptr, cd);
+    previous_callout = NULL;
+    }
+
+  /* In extended mode, skip white space and comments */
+
+  if ((options & PCRE_EXTENDED) != 0)
+    {
+    if ((cd->ctypes[c] & ctype_space) != 0) continue;
+    if (c == CHAR_NUMBER_SIGN)
+      {
+      while (*(++ptr) != 0)
+        {
+        if (IS_NEWLINE(ptr)) { ptr += cd->nllen - 1; break; }
+        }
+      if (*ptr != 0) continue;
+
+      /* Else fall through to handle end of string */
+      c = 0;
+      }
+    }
+
+  /* No auto callout for quantifiers. */
+
+  if ((options & PCRE_AUTO_CALLOUT) != 0 && !is_quantifier)
+    {
+    previous_callout = code;
+    code = auto_callout(code, ptr, cd);
+    }
+
+  switch(c)
+    {
+    /* ===================================================================*/
+    case 0:                        /* The branch terminates at string end */
+    case CHAR_VERTICAL_LINE:       /* or | or ) */
+    case CHAR_RIGHT_PARENTHESIS:
+    *firstbyteptr = firstbyte;
+    *reqbyteptr = reqbyte;
+    *codeptr = code;
+    *ptrptr = ptr;
+    if (lengthptr != NULL)
+      {
+      if (OFLOW_MAX - *lengthptr < code - last_code)
+        {
+        *errorcodeptr = ERR20;
+        goto FAILED;
+        }
+      *lengthptr += code - last_code;   /* To include callout length */
+      DPRINTF((">> end branch\n"));
+      }
+    return TRUE;
+
+
+    /* ===================================================================*/
+    /* Handle single-character metacharacters. In multiline mode, ^ disables
+    the setting of any following char as a first character. */
+
+    case CHAR_CIRCUMFLEX_ACCENT:
+    if ((options & PCRE_MULTILINE) != 0)
+      {
+      if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
+      }
+    previous = NULL;
+    *code++ = OP_CIRC;
+    break;
+
+    case CHAR_DOLLAR_SIGN:
+    previous = NULL;
+    *code++ = OP_DOLL;
+    break;
+
+    /* There can never be a first char if '.' is first, whatever happens about
+    repeats. The value of reqbyte doesn't change either. */
+
+    case CHAR_DOT:
+    if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
+    zerofirstbyte = firstbyte;
+    zeroreqbyte = reqbyte;
+    previous = code;
+    *code++ = ((options & PCRE_DOTALL) != 0)? OP_ALLANY: OP_ANY;
+    break;
+
+
+    /* ===================================================================*/
+    /* Character classes. If the included characters are all < 256, we build a
+    32-byte bitmap of the permitted characters, except in the special case
+    where there is only one such character. For negated classes, we build the
+    map as usual, then invert it at the end. However, we use a different opcode
+    so that data characters > 255 can be handled correctly.
+
+    If the class contains characters outside the 0-255 range, a different
+    opcode is compiled. It may optionally have a bit map for characters < 256,
+    but those above are are explicitly listed afterwards. A flag byte tells
+    whether the bitmap is present, and whether this is a negated class or not.
+
+    In JavaScript compatibility mode, an isolated ']' causes an error. In
+    default (Perl) mode, it is treated as a data character. */
+
+    case CHAR_RIGHT_SQUARE_BRACKET:
+    if ((cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
+      {
+      *errorcodeptr = ERR64;
+      goto FAILED;
+      }
+    goto NORMAL_CHAR;
+
+    case CHAR_LEFT_SQUARE_BRACKET:
+    previous = code;
+
+    /* PCRE supports POSIX class stuff inside a class. Perl gives an error if
+    they are encountered at the top level, so we'll do that too. */
+
+    if ((ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
+         ptr[1] == CHAR_EQUALS_SIGN) &&
+        check_posix_syntax(ptr, &tempptr))
+      {
+      *errorcodeptr = (ptr[1] == CHAR_COLON)? ERR13 : ERR31;
+      goto FAILED;
+      }
+
+    /* If the first character is '^', set the negation flag and skip it. Also,
+    if the first few characters (either before or after ^) are \Q\E or \E we
+    skip them too. This makes for compatibility with Perl. */
+
+    negate_class = FALSE;
+    for (;;)
+      {
+      c = *(++ptr);
+      if (c == CHAR_BACKSLASH)
+        {
+        if (ptr[1] == CHAR_E)
+          ptr++;
+        else if (strncmp((const char *)ptr+1,
+                          STR_Q STR_BACKSLASH STR_E, 3) == 0)
+          ptr += 3;
+        else
+          break;
+        }
+      else if (!negate_class && c == CHAR_CIRCUMFLEX_ACCENT)
+        negate_class = TRUE;
+      else break;
+      }
+
+    /* Empty classes are allowed in JavaScript compatibility mode. Otherwise,
+    an initial ']' is taken as a data character -- the code below handles
+    that. In JS mode, [] must always fail, so generate OP_FAIL, whereas
+    [^] must match any character, so generate OP_ALLANY. */
+
+    if (c == CHAR_RIGHT_SQUARE_BRACKET &&
+        (cd->external_options & PCRE_JAVASCRIPT_COMPAT) != 0)
+      {
+      *code++ = negate_class? OP_ALLANY : OP_FAIL;
+      if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
+      zerofirstbyte = firstbyte;
+      break;
+      }
+
+    /* If a class contains a negative special such as \S, we need to flip the
+    negation flag at the end, so that support for characters > 255 works
+    correctly (they are all included in the class). */
+
+    should_flip_negation = FALSE;
+
+    /* Keep a count of chars with values < 256 so that we can optimize the case
+    of just a single character (as long as it's < 256). However, For higher
+    valued UTF-8 characters, we don't yet do any optimization. */
+
+    class_charcount = 0;
+    class_lastchar = -1;
+
+    /* Initialize the 32-char bit map to all zeros. We build the map in a
+    temporary bit of memory, in case the class contains only 1 character (less
+    than 256), because in that case the compiled code doesn't use the bit map.
+    */
+
+    memset(classbits, 0, 32 * sizeof(uschar));
+
+#ifdef SUPPORT_UTF8
+    class_utf8 = FALSE;                       /* No chars >= 256 */
+    class_utf8data = code + LINK_SIZE + 2;    /* For UTF-8 items */
+    class_utf8data_base = class_utf8data;     /* For resetting in pass 1 */
+#endif
+
+    /* Process characters until ] is reached. By writing this as a "do" it
+    means that an initial ] is taken as a data character. At the start of the
+    loop, c contains the first byte of the character. */
+
+    if (c != 0) do
+      {
+      const uschar *oldptr;
+
+#ifdef SUPPORT_UTF8
+      if (utf8 && c > 127)
+        {                           /* Braces are required because the */
+        GETCHARLEN(c, ptr, ptr);    /* macro generates multiple statements */
+        }
+
+      /* In the pre-compile phase, accumulate the length of any UTF-8 extra
+      data and reset the pointer. This is so that very large classes that
+      contain a zillion UTF-8 characters no longer overwrite the work space
+      (which is on the stack). */
+
+      if (lengthptr != NULL)
+        {
+        *lengthptr += class_utf8data - class_utf8data_base;
+        class_utf8data = class_utf8data_base;
+        }
+
+#endif
+
+      /* Inside \Q...\E everything is literal except \E */
+
+      if (inescq)
+        {
+        if (c == CHAR_BACKSLASH && ptr[1] == CHAR_E)  /* If we are at \E */
+          {
+          inescq = FALSE;                   /* Reset literal state */
+          ptr++;                            /* Skip the 'E' */
+          continue;                         /* Carry on with next */
+          }
+        goto CHECK_RANGE;                   /* Could be range if \E follows */
+        }
+
+      /* Handle POSIX class names. Perl allows a negation extension of the
+      form [:^name:]. A square bracket that doesn't match the syntax is
+      treated as a literal. We also recognize the POSIX constructions
+      [.ch.] and [=ch=] ("collating elements") and fault them, as Perl
+      5.6 and 5.8 do. */
+
+      if (c == CHAR_LEFT_SQUARE_BRACKET &&
+          (ptr[1] == CHAR_COLON || ptr[1] == CHAR_DOT ||
+           ptr[1] == CHAR_EQUALS_SIGN) && check_posix_syntax(ptr, &tempptr))
+        {
+        BOOL local_negate = FALSE;
+        int posix_class, taboffset, tabopt;
+        register const uschar *cbits = cd->cbits;
+        uschar pbits[32];
+
+        if (ptr[1] != CHAR_COLON)
+          {
+          *errorcodeptr = ERR31;
+          goto FAILED;
+          }
+
+        ptr += 2;
+        if (*ptr == CHAR_CIRCUMFLEX_ACCENT)
+          {
+          local_negate = TRUE;
+          should_flip_negation = TRUE;  /* Note negative special */
+          ptr++;
+          }
+
+        posix_class = check_posix_name(ptr, tempptr - ptr);
+        if (posix_class < 0)
+          {
+          *errorcodeptr = ERR30;
+          goto FAILED;
+          }
+
+        /* If matching is caseless, upper and lower are converted to
+        alpha. This relies on the fact that the class table starts with
+        alpha, lower, upper as the first 3 entries. */
+
+        if ((options & PCRE_CASELESS) != 0 && posix_class <= 2)
+          posix_class = 0;
+
+        /* We build the bit map for the POSIX class in a chunk of local store
+        because we may be adding and subtracting from it, and we don't want to
+        subtract bits that may be in the main map already. At the end we or the
+        result into the bit map that is being built. */
+
+        posix_class *= 3;
+
+        /* Copy in the first table (always present) */
+
+        memcpy(pbits, cbits + posix_class_maps[posix_class],
+          32 * sizeof(uschar));
+
+        /* If there is a second table, add or remove it as required. */
+
+        taboffset = posix_class_maps[posix_class + 1];
+        tabopt = posix_class_maps[posix_class + 2];
+
+        if (taboffset >= 0)
+          {
+          if (tabopt >= 0)
+            for (c = 0; c < 32; c++) pbits[c] |= cbits[c + taboffset];
+          else
+            for (c = 0; c < 32; c++) pbits[c] &= ~cbits[c + taboffset];
+          }
+
+        /* Not see if we need to remove any special characters. An option
+        value of 1 removes vertical space and 2 removes underscore. */
+
+        if (tabopt < 0) tabopt = -tabopt;
+        if (tabopt == 1) pbits[1] &= ~0x3c;
+          else if (tabopt == 2) pbits[11] &= 0x7f;
+
+        /* Add the POSIX table or its complement into the main table that is
+        being built and we are done. */
+
+        if (local_negate)
+          for (c = 0; c < 32; c++) classbits[c] |= ~pbits[c];
+        else
+          for (c = 0; c < 32; c++) classbits[c] |= pbits[c];
+
+        ptr = tempptr + 1;
+        class_charcount = 10;  /* Set > 1; assumes more than 1 per class */
+        continue;    /* End of POSIX syntax handling */
+        }
+
+      /* Backslash may introduce a single character, or it may introduce one
+      of the specials, which just set a flag. The sequence \b is a special
+      case. Inside a class (and only there) it is treated as backspace.
+      Elsewhere it marks a word boundary. Other escapes have preset maps ready
+      to 'or' into the one we are building. We assume they have more than one
+      character in them, so set class_charcount bigger than one. */
+
+      if (c == CHAR_BACKSLASH)
+        {
+        c = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);
+        if (*errorcodeptr != 0) goto FAILED;
+
+        if (-c == ESC_b) c = CHAR_BS;       /* \b is backspace in a class */
+        else if (-c == ESC_X) c = CHAR_X;   /* \X is literal X in a class */
+        else if (-c == ESC_R) c = CHAR_R;   /* \R is literal R in a class */
+        else if (-c == ESC_Q)            /* Handle start of quoted string */
+          {
+          if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
+            {
+            ptr += 2; /* avoid empty string */
+            }
+          else inescq = TRUE;
+          continue;
+          }
+        else if (-c == ESC_E) continue;  /* Ignore orphan \E */
+
+        if (c < 0)
+          {
+          register const uschar *cbits = cd->cbits;
+          class_charcount += 2;     /* Greater than 1 is what matters */
+
+          /* Save time by not doing this in the pre-compile phase. */
+
+          if (lengthptr == NULL) switch (-c)
+            {
+            case ESC_d:
+            for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_digit];
+            continue;
+
+            case ESC_D:
+            should_flip_negation = TRUE;
+            for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_digit];
+            continue;
+
+            case ESC_w:
+            for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_word];
+            continue;
+
+            case ESC_W:
+            should_flip_negation = TRUE;
+            for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_word];
+            continue;
+
+            case ESC_s:
+            for (c = 0; c < 32; c++) classbits[c] |= cbits[c+cbit_space];
+            classbits[1] &= ~0x08;   /* Perl 5.004 onwards omits VT from \s */
+            continue;
+
+            case ESC_S:
+            should_flip_negation = TRUE;
+            for (c = 0; c < 32; c++) classbits[c] |= ~cbits[c+cbit_space];
+            classbits[1] |= 0x08;    /* Perl 5.004 onwards omits VT from \s */
+            continue;
+
+            default:    /* Not recognized; fall through */
+            break;      /* Need "default" setting to stop compiler warning. */
+            }
+
+          /* In the pre-compile phase, just do the recognition. */
+
+          else if (c == -ESC_d || c == -ESC_D || c == -ESC_w ||
+                   c == -ESC_W || c == -ESC_s || c == -ESC_S) continue;
+
+          /* We need to deal with \H, \h, \V, and \v in both phases because
+          they use extra memory. */
+
+          if (-c == ESC_h)
+            {
+            SETBIT(classbits, 0x09); /* VT */
+            SETBIT(classbits, 0x20); /* SPACE */
+            SETBIT(classbits, 0xa0); /* NSBP */
+#ifdef SUPPORT_UTF8
+            if (utf8)
+              {
+              class_utf8 = TRUE;
+              *class_utf8data++ = XCL_SINGLE;
+              class_utf8data += _pcre_ord2utf8(0x1680, class_utf8data);
+              *class_utf8data++ = XCL_SINGLE;
+              class_utf8data += _pcre_ord2utf8(0x180e, class_utf8data);
+              *class_utf8data++ = XCL_RANGE;
+              class_utf8data += _pcre_ord2utf8(0x2000, class_utf8data);
+              class_utf8data += _pcre_ord2utf8(0x200A, class_utf8data);
+              *class_utf8data++ = XCL_SINGLE;
+              class_utf8data += _pcre_ord2utf8(0x202f, class_utf8data);
+              *class_utf8data++ = XCL_SINGLE;
+              class_utf8data += _pcre_ord2utf8(0x205f, class_utf8data);
+              *class_utf8data++ = XCL_SINGLE;
+              class_utf8data += _pcre_ord2utf8(0x3000, class_utf8data);
+              }
+#endif
+            continue;
+            }
+
+          if (-c == ESC_H)
+            {
+            for (c = 0; c < 32; c++)
+              {
+              int x = 0xff;
+              switch (c)
+                {
+                case 0x09/8: x ^= 1 << (0x09%8); break;
+                case 0x20/8: x ^= 1 << (0x20%8); break;
+                case 0xa0/8: x ^= 1 << (0xa0%8); break;
+                default: break;
+                }
+              classbits[c] |= x;
+              }
+
+#ifdef SUPPORT_UTF8
+            if (utf8)
+              {
+              class_utf8 = TRUE;
+              *class_utf8data++ = XCL_RANGE;
+              class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
+              class_utf8data += _pcre_ord2utf8(0x167f, class_utf8data);
+              *class_utf8data++ = XCL_RANGE;
+              class_utf8data += _pcre_ord2utf8(0x1681, class_utf8data);
+              class_utf8data += _pcre_ord2utf8(0x180d, class_utf8data);
+              *class_utf8data++ = XCL_RANGE;
+              class_utf8data += _pcre_ord2utf8(0x180f, class_utf8data);
+              class_utf8data += _pcre_ord2utf8(0x1fff, class_utf8data);
+              *class_utf8data++ = XCL_RANGE;
+              class_utf8data += _pcre_ord2utf8(0x200B, class_utf8data);
+              class_utf8data += _pcre_ord2utf8(0x202e, class_utf8data);
+              *class_utf8data++ = XCL_RANGE;
+              class_utf8data += _pcre_ord2utf8(0x2030, class_utf8data);
+              class_utf8data += _pcre_ord2utf8(0x205e, class_utf8data);
+              *class_utf8data++ = XCL_RANGE;
+              class_utf8data += _pcre_ord2utf8(0x2060, class_utf8data);
+              class_utf8data += _pcre_ord2utf8(0x2fff, class_utf8data);
+              *class_utf8data++ = XCL_RANGE;
+              class_utf8data += _pcre_ord2utf8(0x3001, class_utf8data);
+              class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
+              }
+#endif
+            continue;
+            }
+
+          if (-c == ESC_v)
+            {
+            SETBIT(classbits, 0x0a); /* LF */
+            SETBIT(classbits, 0x0b); /* VT */
+            SETBIT(classbits, 0x0c); /* FF */
+            SETBIT(classbits, 0x0d); /* CR */
+            SETBIT(classbits, 0x85); /* NEL */
+#ifdef SUPPORT_UTF8
+            if (utf8)
+              {
+              class_utf8 = TRUE;
+              *class_utf8data++ = XCL_RANGE;
+              class_utf8data += _pcre_ord2utf8(0x2028, class_utf8data);
+              class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
+              }
+#endif
+            continue;
+            }
+
+          if (-c == ESC_V)
+            {
+            for (c = 0; c < 32; c++)
+              {
+              int x = 0xff;
+              switch (c)
+                {
+                case 0x0a/8: x ^= 1 << (0x0a%8);
+                             x ^= 1 << (0x0b%8);
+                             x ^= 1 << (0x0c%8);
+                             x ^= 1 << (0x0d%8);
+                             break;
+                case 0x85/8: x ^= 1 << (0x85%8); break;
+                default: break;
+                }
+              classbits[c] |= x;
+              }
+
+#ifdef SUPPORT_UTF8
+            if (utf8)
+              {
+              class_utf8 = TRUE;
+              *class_utf8data++ = XCL_RANGE;
+              class_utf8data += _pcre_ord2utf8(0x0100, class_utf8data);
+              class_utf8data += _pcre_ord2utf8(0x2027, class_utf8data);
+              *class_utf8data++ = XCL_RANGE;
+              class_utf8data += _pcre_ord2utf8(0x2029, class_utf8data);
+              class_utf8data += _pcre_ord2utf8(0x7fffffff, class_utf8data);
+              }
+#endif
+            continue;
+            }
+
+          /* We need to deal with \P and \p in both phases. */
+
+#ifdef SUPPORT_UCP
+          if (-c == ESC_p || -c == ESC_P)
+            {
+            BOOL negated;
+            int pdata;
+            int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr);
+            if (ptype < 0) goto FAILED;
+            class_utf8 = TRUE;
+            *class_utf8data++ = ((-c == ESC_p) != negated)?
+              XCL_PROP : XCL_NOTPROP;
+            *class_utf8data++ = ptype;
+            *class_utf8data++ = pdata;
+            class_charcount -= 2;   /* Not a < 256 character */
+            continue;
+            }
+#endif
+          /* Unrecognized escapes are faulted if PCRE is running in its
+          strict mode. By default, for compatibility with Perl, they are
+          treated as literals. */
+
+          if ((options & PCRE_EXTRA) != 0)
+            {
+            *errorcodeptr = ERR7;
+            goto FAILED;
+            }
+
+          class_charcount -= 2;  /* Undo the default count from above */
+          c = *ptr;              /* Get the final character and fall through */
+          }
+
+        /* Fall through if we have a single character (c >= 0). This may be
+        greater than 256 in UTF-8 mode. */
+
+        }   /* End of backslash handling */
+
+      /* A single character may be followed by '-' to form a range. However,
+      Perl does not permit ']' to be the end of the range. A '-' character
+      at the end is treated as a literal. Perl ignores orphaned \E sequences
+      entirely. The code for handling \Q and \E is messy. */
+
+      CHECK_RANGE:
+      while (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
+        {
+        inescq = FALSE;
+        ptr += 2;
+        }
+
+      oldptr = ptr;
+
+      /* Remember \r or \n */
+
+      if (c == CHAR_CR || c == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF;
+
+      /* Check for range */
+
+      if (!inescq && ptr[1] == CHAR_MINUS)
+        {
+        int d;
+        ptr += 2;
+        while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E) ptr += 2;
+
+        /* If we hit \Q (not followed by \E) at this point, go into escaped
+        mode. */
+
+        while (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_Q)
+          {
+          ptr += 2;
+          if (*ptr == CHAR_BACKSLASH && ptr[1] == CHAR_E)
+            { ptr += 2; continue; }
+          inescq = TRUE;
+          break;
+          }
+
+        if (*ptr == 0 || (!inescq && *ptr == CHAR_RIGHT_SQUARE_BRACKET))
+          {
+          ptr = oldptr;
+          goto LONE_SINGLE_CHARACTER;
+          }
+
+#ifdef SUPPORT_UTF8
+        if (utf8)
+          {                           /* Braces are required because the */
+          GETCHARLEN(d, ptr, ptr);    /* macro generates multiple statements */
+          }
+        else
+#endif
+        d = *ptr;  /* Not UTF-8 mode */
+
+        /* The second part of a range can be a single-character escape, but
+        not any of the other escapes. Perl 5.6 treats a hyphen as a literal
+        in such circumstances. */
+
+        if (!inescq && d == CHAR_BACKSLASH)
+          {
+          d = check_escape(&ptr, errorcodeptr, cd->bracount, options, TRUE);
+          if (*errorcodeptr != 0) goto FAILED;
+
+          /* \b is backspace; \X is literal X; \R is literal R; any other
+          special means the '-' was literal */
+
+          if (d < 0)
+            {
+            if (d == -ESC_b) d = CHAR_BS;
+            else if (d == -ESC_X) d = CHAR_X;
+            else if (d == -ESC_R) d = CHAR_R; else
+              {
+              ptr = oldptr;
+              goto LONE_SINGLE_CHARACTER;  /* A few lines below */
+              }
+            }
+          }
+
+        /* Check that the two values are in the correct order. Optimize
+        one-character ranges */
+
+        if (d < c)
+          {
+          *errorcodeptr = ERR8;
+          goto FAILED;
+          }
+
+        if (d == c) goto LONE_SINGLE_CHARACTER;  /* A few lines below */
+
+        /* Remember \r or \n */
+
+        if (d == CHAR_CR || d == CHAR_NL) cd->external_flags |= PCRE_HASCRORLF;
+
+        /* In UTF-8 mode, if the upper limit is > 255, or > 127 for caseless
+        matching, we have to use an XCLASS with extra data items. Caseless
+        matching for characters > 127 is available only if UCP support is
+        available. */
+
+#ifdef SUPPORT_UTF8
+        if (utf8 && (d > 255 || ((options & PCRE_CASELESS) != 0 && d > 127)))
+          {
+          class_utf8 = TRUE;
+
+          /* With UCP support, we can find the other case equivalents of
+          the relevant characters. There may be several ranges. Optimize how
+          they fit with the basic range. */
+
+#ifdef SUPPORT_UCP
+          if ((options & PCRE_CASELESS) != 0)
+            {
+            unsigned int occ, ocd;
+            unsigned int cc = c;
+            unsigned int origd = d;
+            while (get_othercase_range(&cc, origd, &occ, &ocd))
+              {
+              if (occ >= (unsigned int)c &&
+                  ocd <= (unsigned int)d)
+                continue;                          /* Skip embedded ranges */
+
+              if (occ < (unsigned int)c  &&
+                  ocd >= (unsigned int)c - 1)      /* Extend the basic range */
+                {                                  /* if there is overlap,   */
+                c = occ;                           /* noting that if occ < c */
+                continue;                          /* we can't have ocd > d  */
+                }                                  /* because a subrange is  */
+              if (ocd > (unsigned int)d &&
+                  occ <= (unsigned int)d + 1)      /* always shorter than    */
+                {                                  /* the basic range.       */
+                d = ocd;
+                continue;
+                }
+
+              if (occ == ocd)
+                {
+                *class_utf8data++ = XCL_SINGLE;
+                }
+              else
+                {
+                *class_utf8data++ = XCL_RANGE;
+                class_utf8data += _pcre_ord2utf8(occ, class_utf8data);
+                }
+              class_utf8data += _pcre_ord2utf8(ocd, class_utf8data);
+              }
+            }
+#endif  /* SUPPORT_UCP */
+
+          /* Now record the original range, possibly modified for UCP caseless
+          overlapping ranges. */
+
+          *class_utf8data++ = XCL_RANGE;
+          class_utf8data += _pcre_ord2utf8(c, class_utf8data);
+          class_utf8data += _pcre_ord2utf8(d, class_utf8data);
+
+          /* With UCP support, we are done. Without UCP support, there is no
+          caseless matching for UTF-8 characters > 127; we can use the bit map
+          for the smaller ones. */
+
+#ifdef SUPPORT_UCP
+          continue;    /* With next character in the class */
+#else
+          if ((options & PCRE_CASELESS) == 0 || c > 127) continue;
+
+          /* Adjust upper limit and fall through to set up the map */
+
+          d = 127;
+
+#endif  /* SUPPORT_UCP */
+          }
+#endif  /* SUPPORT_UTF8 */
+
+        /* We use the bit map for all cases when not in UTF-8 mode; else
+        ranges that lie entirely within 0-127 when there is UCP support; else
+        for partial ranges without UCP support. */
+
+        class_charcount += d - c + 1;
+        class_lastchar = d;
+
+        /* We can save a bit of time by skipping this in the pre-compile. */
+
+        if (lengthptr == NULL) for (; c <= d; c++)
+          {
+          classbits[c/8] |= (1 << (c&7));
+          if ((options & PCRE_CASELESS) != 0)
+            {
+            int uc = cd->fcc[c];           /* flip case */
+            classbits[uc/8] |= (1 << (uc&7));
+            }
+          }
+
+        continue;   /* Go get the next char in the class */
+        }
+
+      /* Handle a lone single character - we can get here for a normal
+      non-escape char, or after \ that introduces a single character or for an
+      apparent range that isn't. */
+
+      LONE_SINGLE_CHARACTER:
+
+      /* Handle a character that cannot go in the bit map */
+
+#ifdef SUPPORT_UTF8
+      if (utf8 && (c > 255 || ((options & PCRE_CASELESS) != 0 && c > 127)))
+        {
+        class_utf8 = TRUE;
+        *class_utf8data++ = XCL_SINGLE;
+        class_utf8data += _pcre_ord2utf8(c, class_utf8data);
+
+#ifdef SUPPORT_UCP
+        if ((options & PCRE_CASELESS) != 0)
+          {
+          unsigned int othercase;
+          if ((othercase = UCD_OTHERCASE(c)) != c)
+            {
+            *class_utf8data++ = XCL_SINGLE;
+            class_utf8data += _pcre_ord2utf8(othercase, class_utf8data);
+            }
+          }
+#endif  /* SUPPORT_UCP */
+
+        }
+      else
+#endif  /* SUPPORT_UTF8 */
+
+      /* Handle a single-byte character */
+        {
+        classbits[c/8] |= (1 << (c&7));
+        if ((options & PCRE_CASELESS) != 0)
+          {
+          c = cd->fcc[c];   /* flip case */
+          classbits[c/8] |= (1 << (c&7));
+          }
+        class_charcount++;
+        class_lastchar = c;
+        }
+      }
+
+    /* Loop until ']' reached. This "while" is the end of the "do" above. */
+
+    while ((c = *(++ptr)) != 0 && (c != CHAR_RIGHT_SQUARE_BRACKET || inescq));
+
+    if (c == 0)                          /* Missing terminating ']' */
+      {
+      *errorcodeptr = ERR6;
+      goto FAILED;
+      }
+
+
+/* This code has been disabled because it would mean that \s counts as
+an explicit \r or \n reference, and that's not really what is wanted. Now
+we set the flag only if there is a literal "\r" or "\n" in the class. */
+
+#if 0
+    /* Remember whether \r or \n are in this class */
+
+    if (negate_class)
+      {
+      if ((classbits[1] & 0x24) != 0x24) cd->external_flags |= PCRE_HASCRORLF;
+      }
+    else
+      {
+      if ((classbits[1] & 0x24) != 0) cd->external_flags |= PCRE_HASCRORLF;
+      }
+#endif
+
+
+    /* If class_charcount is 1, we saw precisely one character whose value is
+    less than 256. As long as there were no characters >= 128 and there was no
+    use of \p or \P, in other words, no use of any XCLASS features, we can
+    optimize.
+
+    In UTF-8 mode, we can optimize the negative case only if there were no
+    characters >= 128 because OP_NOT and the related opcodes like OP_NOTSTAR
+    operate on single-bytes only. This is an historical hangover. Maybe one day
+    we can tidy these opcodes to handle multi-byte characters.
+
+    The optimization throws away the bit map. We turn the item into a
+    1-character OP_CHAR[NC] if it's positive, or OP_NOT if it's negative. Note
+    that OP_NOT does not support multibyte characters. In the positive case, it
+    can cause firstbyte to be set. Otherwise, there can be no first char if
+    this item is first, whatever repeat count may follow. In the case of
+    reqbyte, save the previous value for reinstating. */
+
+#ifdef SUPPORT_UTF8
+    if (class_charcount == 1 && !class_utf8 &&
+      (!utf8 || !negate_class || class_lastchar < 128))
+#else
+    if (class_charcount == 1)
+#endif
+      {
+      zeroreqbyte = reqbyte;
+
+      /* The OP_NOT opcode works on one-byte characters only. */
+
+      if (negate_class)
+        {
+        if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
+        zerofirstbyte = firstbyte;
+        *code++ = OP_NOT;
+        *code++ = class_lastchar;
+        break;
+        }
+
+      /* For a single, positive character, get the value into mcbuffer, and
+      then we can handle this with the normal one-character code. */
+
+#ifdef SUPPORT_UTF8
+      if (utf8 && class_lastchar > 127)
+        mclength = _pcre_ord2utf8(class_lastchar, mcbuffer);
+      else
+#endif
+        {
+        mcbuffer[0] = class_lastchar;
+        mclength = 1;
+        }
+      goto ONE_CHAR;
+      }       /* End of 1-char optimization */
+
+    /* The general case - not the one-char optimization. If this is the first
+    thing in the branch, there can be no first char setting, whatever the
+    repeat count. Any reqbyte setting must remain unchanged after any kind of
+    repeat. */
+
+    if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
+    zerofirstbyte = firstbyte;
+    zeroreqbyte = reqbyte;
+
+    /* If there are characters with values > 255, we have to compile an
+    extended class, with its own opcode, unless there was a negated special
+    such as \S in the class, because in that case all characters > 255 are in
+    the class, so any that were explicitly given as well can be ignored. If
+    (when there are explicit characters > 255 that must be listed) there are no
+    characters < 256, we can omit the bitmap in the actual compiled code. */
+
+#ifdef SUPPORT_UTF8
+    if (class_utf8 && !should_flip_negation)
+      {
+      *class_utf8data++ = XCL_END;    /* Marks the end of extra data */
+      *code++ = OP_XCLASS;
+      code += LINK_SIZE;
+      *code = negate_class? XCL_NOT : 0;
+
+      /* If the map is required, move up the extra data to make room for it;
+      otherwise just move the code pointer to the end of the extra data. */
+
+      if (class_charcount > 0)
+        {
+        *code++ |= XCL_MAP;
+        memmove(code + 32, code, class_utf8data - code);
+        memcpy(code, classbits, 32);
+        code = class_utf8data + 32;
+        }
+      else code = class_utf8data;
+
+      /* Now fill in the complete length of the item */
+
+      PUT(previous, 1, code - previous);
+      break;   /* End of class handling */
+      }
+#endif
+
+    /* If there are no characters > 255, set the opcode to OP_CLASS or
+    OP_NCLASS, depending on whether the whole class was negated and whether
+    there were negative specials such as \S in the class. Then copy the 32-byte
+    map into the code vector, negating it if necessary. */
+
+    *code++ = (negate_class == should_flip_negation) ? OP_CLASS : OP_NCLASS;
+    if (negate_class)
+      {
+      if (lengthptr == NULL)    /* Save time in the pre-compile phase */
+        for (c = 0; c < 32; c++) code[c] = ~classbits[c];
+      }
+    else
+      {
+      memcpy(code, classbits, 32);
+      }
+    code += 32;
+    break;
+
+
+    /* ===================================================================*/
+    /* Various kinds of repeat; '{' is not necessarily a quantifier, but this
+    has been tested above. */
+
+    case CHAR_LEFT_CURLY_BRACKET:
+    if (!is_quantifier) goto NORMAL_CHAR;
+    ptr = read_repeat_counts(ptr+1, &repeat_min, &repeat_max, errorcodeptr);
+    if (*errorcodeptr != 0) goto FAILED;
+    goto REPEAT;
+
+    case CHAR_ASTERISK:
+    repeat_min = 0;
+    repeat_max = -1;
+    goto REPEAT;
+
+    case CHAR_PLUS:
+    repeat_min = 1;
+    repeat_max = -1;
+    goto REPEAT;
+
+    case CHAR_QUESTION_MARK:
+    repeat_min = 0;
+    repeat_max = 1;
+
+    REPEAT:
+    if (previous == NULL)
+      {
+      *errorcodeptr = ERR9;
+      goto FAILED;
+      }
+
+    if (repeat_min == 0)
+      {
+      firstbyte = zerofirstbyte;    /* Adjust for zero repeat */
+      reqbyte = zeroreqbyte;        /* Ditto */
+      }
+
+    /* Remember whether this is a variable length repeat */
+
+    reqvary = (repeat_min == repeat_max)? 0 : REQ_VARY;
+
+    op_type = 0;                    /* Default single-char op codes */
+    possessive_quantifier = FALSE;  /* Default not possessive quantifier */
+
+    /* Save start of previous item, in case we have to move it up to make space
+    for an inserted OP_ONCE for the additional '+' extension. */
+
+    tempcode = previous;
+
+    /* If the next character is '+', we have a possessive quantifier. This
+    implies greediness, whatever the setting of the PCRE_UNGREEDY option.
+    If the next character is '?' this is a minimizing repeat, by default,
+    but if PCRE_UNGREEDY is set, it works the other way round. We change the
+    repeat type to the non-default. */
+
+    if (ptr[1] == CHAR_PLUS)
+      {
+      repeat_type = 0;                  /* Force greedy */
+      possessive_quantifier = TRUE;
+      ptr++;
+      }
+    else if (ptr[1] == CHAR_QUESTION_MARK)
+      {
+      repeat_type = greedy_non_default;
+      ptr++;
+      }
+    else repeat_type = greedy_default;
+
+    /* If previous was a character match, abolish the item and generate a
+    repeat item instead. If a char item has a minumum of more than one, ensure
+    that it is set in reqbyte - it might not be if a sequence such as x{3} is
+    the first thing in a branch because the x will have gone into firstbyte
+    instead.  */
+
+    if (*previous == OP_CHAR || *previous == OP_CHARNC)
+      {
+      /* Deal with UTF-8 characters that take up more than one byte. It's
+      easier to write this out separately than try to macrify it. Use c to
+      hold the length of the character in bytes, plus 0x80 to flag that it's a
+      length rather than a small character. */
+
+#ifdef SUPPORT_UTF8
+      if (utf8 && (code[-1] & 0x80) != 0)
+        {
+        uschar *lastchar = code - 1;
+        while((*lastchar & 0xc0) == 0x80) lastchar--;
+        c = code - lastchar;            /* Length of UTF-8 character */
+        memcpy(utf8_char, lastchar, c); /* Save the char */
+        c |= 0x80;                      /* Flag c as a length */
+        }
+      else
+#endif
+
+      /* Handle the case of a single byte - either with no UTF8 support, or
+      with UTF-8 disabled, or for a UTF-8 character < 128. */
+
+        {
+        c = code[-1];
+        if (repeat_min > 1) reqbyte = c | req_caseopt | cd->req_varyopt;
+        }
+
+      /* If the repetition is unlimited, it pays to see if the next thing on
+      the line is something that cannot possibly match this character. If so,
+      automatically possessifying this item gains some performance in the case
+      where the match fails. */
+
+      if (!possessive_quantifier &&
+          repeat_max < 0 &&
+          check_auto_possessive(*previous, c, utf8, utf8_char, ptr + 1,
+            options, cd))
+        {
+        repeat_type = 0;    /* Force greedy */
+        possessive_quantifier = TRUE;
+        }
+
+      goto OUTPUT_SINGLE_REPEAT;   /* Code shared with single character types */
+      }
+
+    /* If previous was a single negated character ([^a] or similar), we use
+    one of the special opcodes, replacing it. The code is shared with single-
+    character repeats by setting opt_type to add a suitable offset into
+    repeat_type. We can also test for auto-possessification. OP_NOT is
+    currently used only for single-byte chars. */
+
+    else if (*previous == OP_NOT)
+      {
+      op_type = OP_NOTSTAR - OP_STAR;  /* Use "not" opcodes */
+      c = previous[1];
+      if (!possessive_quantifier &&
+          repeat_max < 0 &&
+          check_auto_possessive(OP_NOT, c, utf8, NULL, ptr + 1, options, cd))
+        {
+        repeat_type = 0;    /* Force greedy */
+        possessive_quantifier = TRUE;
+        }
+      goto OUTPUT_SINGLE_REPEAT;
+      }
+
+    /* If previous was a character type match (\d or similar), abolish it and
+    create a suitable repeat item. The code is shared with single-character
+    repeats by setting op_type to add a suitable offset into repeat_type. Note
+    the the Unicode property types will be present only when SUPPORT_UCP is
+    defined, but we don't wrap the little bits of code here because it just
+    makes it horribly messy. */
+
+    else if (*previous < OP_EODN)
+      {
+      uschar *oldcode;
+      int prop_type, prop_value;
+      op_type = OP_TYPESTAR - OP_STAR;  /* Use type opcodes */
+      c = *previous;
+
+      if (!possessive_quantifier &&
+          repeat_max < 0 &&
+          check_auto_possessive(c, 0, utf8, NULL, ptr + 1, options, cd))
+        {
+        repeat_type = 0;    /* Force greedy */
+        possessive_quantifier = TRUE;
+        }
+
+      OUTPUT_SINGLE_REPEAT:
+      if (*previous == OP_PROP || *previous == OP_NOTPROP)
+        {
+        prop_type = previous[1];
+        prop_value = previous[2];
+        }
+      else prop_type = prop_value = -1;
+
+      oldcode = code;
+      code = previous;                  /* Usually overwrite previous item */
+
+      /* If the maximum is zero then the minimum must also be zero; Perl allows
+      this case, so we do too - by simply omitting the item altogether. */
+
+      if (repeat_max == 0) goto END_REPEAT;
+
+      /*--------------------------------------------------------------------*/
+      /* This code is obsolete from release 8.00; the restriction was finally
+      removed: */
+
+      /* All real repeats make it impossible to handle partial matching (maybe
+      one day we will be able to remove this restriction). */
+
+      /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
+      /*--------------------------------------------------------------------*/
+
+      /* Combine the op_type with the repeat_type */
+
+      repeat_type += op_type;
+
+      /* A minimum of zero is handled either as the special case * or ?, or as
+      an UPTO, with the maximum given. */
+
+      if (repeat_min == 0)
+        {
+        if (repeat_max == -1) *code++ = OP_STAR + repeat_type;
+          else if (repeat_max == 1) *code++ = OP_QUERY + repeat_type;
+        else
+          {
+          *code++ = OP_UPTO + repeat_type;
+          PUT2INC(code, 0, repeat_max);
+          }
+        }
+
+      /* A repeat minimum of 1 is optimized into some special cases. If the
+      maximum is unlimited, we use OP_PLUS. Otherwise, the original item is
+      left in place and, if the maximum is greater than 1, we use OP_UPTO with
+      one less than the maximum. */
+
+      else if (repeat_min == 1)
+        {
+        if (repeat_max == -1)
+          *code++ = OP_PLUS + repeat_type;
+        else
+          {
+          code = oldcode;                 /* leave previous item in place */
+          if (repeat_max == 1) goto END_REPEAT;
+          *code++ = OP_UPTO + repeat_type;
+          PUT2INC(code, 0, repeat_max - 1);
+          }
+        }
+
+      /* The case {n,n} is just an EXACT, while the general case {n,m} is
+      handled as an EXACT followed by an UPTO. */
+
+      else
+        {
+        *code++ = OP_EXACT + op_type;  /* NB EXACT doesn't have repeat_type */
+        PUT2INC(code, 0, repeat_min);
+
+        /* If the maximum is unlimited, insert an OP_STAR. Before doing so,
+        we have to insert the character for the previous code. For a repeated
+        Unicode property match, there are two extra bytes that define the
+        required property. In UTF-8 mode, long characters have their length in
+        c, with the 0x80 bit as a flag. */
+
+        if (repeat_max < 0)
+          {
+#ifdef SUPPORT_UTF8
+          if (utf8 && c >= 128)
+            {
+            memcpy(code, utf8_char, c & 7);
+            code += c & 7;
+            }
+          else
+#endif
+            {
+            *code++ = c;
+            if (prop_type >= 0)
+              {
+              *code++ = prop_type;
+              *code++ = prop_value;
+              }
+            }
+          *code++ = OP_STAR + repeat_type;
+          }
+
+        /* Else insert an UPTO if the max is greater than the min, again
+        preceded by the character, for the previously inserted code. If the
+        UPTO is just for 1 instance, we can use QUERY instead. */
+
+        else if (repeat_max != repeat_min)
+          {
+#ifdef SUPPORT_UTF8
+          if (utf8 && c >= 128)
+            {
+            memcpy(code, utf8_char, c & 7);
+            code += c & 7;
+            }
+          else
+#endif
+          *code++ = c;
+          if (prop_type >= 0)
+            {
+            *code++ = prop_type;
+            *code++ = prop_value;
+            }
+          repeat_max -= repeat_min;
+
+          if (repeat_max == 1)
+            {
+            *code++ = OP_QUERY + repeat_type;
+            }
+          else
+            {
+            *code++ = OP_UPTO + repeat_type;
+            PUT2INC(code, 0, repeat_max);
+            }
+          }
+        }
+
+      /* The character or character type itself comes last in all cases. */
+
+#ifdef SUPPORT_UTF8
+      if (utf8 && c >= 128)
+        {
+        memcpy(code, utf8_char, c & 7);
+        code += c & 7;
+        }
+      else
+#endif
+      *code++ = c;
+
+      /* For a repeated Unicode property match, there are two extra bytes that
+      define the required property. */
+
+#ifdef SUPPORT_UCP
+      if (prop_type >= 0)
+        {
+        *code++ = prop_type;
+        *code++ = prop_value;
+        }
+#endif
+      }
+
+    /* If previous was a character class or a back reference, we put the repeat
+    stuff after it, but just skip the item if the repeat was {0,0}. */
+
+    else if (*previous == OP_CLASS ||
+             *previous == OP_NCLASS ||
+#ifdef SUPPORT_UTF8
+             *previous == OP_XCLASS ||
+#endif
+             *previous == OP_REF)
+      {
+      if (repeat_max == 0)
+        {
+        code = previous;
+        goto END_REPEAT;
+        }
+
+      /*--------------------------------------------------------------------*/
+      /* This code is obsolete from release 8.00; the restriction was finally
+      removed: */
+
+      /* All real repeats make it impossible to handle partial matching (maybe
+      one day we will be able to remove this restriction). */
+
+      /* if (repeat_max != 1) cd->external_flags |= PCRE_NOPARTIAL; */
+      /*--------------------------------------------------------------------*/
+
+      if (repeat_min == 0 && repeat_max == -1)
+        *code++ = OP_CRSTAR + repeat_type;
+      else if (repeat_min == 1 && repeat_max == -1)
+        *code++ = OP_CRPLUS + repeat_type;
+      else if (repeat_min == 0 && repeat_max == 1)
+        *code++ = OP_CRQUERY + repeat_type;
+      else
+        {
+        *code++ = OP_CRRANGE + repeat_type;
+        PUT2INC(code, 0, repeat_min);
+        if (repeat_max == -1) repeat_max = 0;  /* 2-byte encoding for max */
+        PUT2INC(code, 0, repeat_max);
+        }
+      }
+
+    /* If previous was a bracket group, we may have to replicate it in certain
+    cases. */
+
+    else if (*previous == OP_BRA  || *previous == OP_CBRA ||
+             *previous == OP_ONCE || *previous == OP_COND)
+      {
+      register int i;
+      int ketoffset = 0;
+      int len = code - previous;
+      uschar *bralink = NULL;
+
+      /* Repeating a DEFINE group is pointless */
+
+      if (*previous == OP_COND && previous[LINK_SIZE+1] == OP_DEF)
+        {
+        *errorcodeptr = ERR55;
+        goto FAILED;
+        }
+
+      /* If the maximum repeat count is unlimited, find the end of the bracket
+      by scanning through from the start, and compute the offset back to it
+      from the current code pointer. There may be an OP_OPT setting following
+      the final KET, so we can't find the end just by going back from the code
+      pointer. */
+
+      if (repeat_max == -1)
+        {
+        register uschar *ket = previous;
+        do ket += GET(ket, 1); while (*ket != OP_KET);
+        ketoffset = code - ket;
+        }
+
+      /* The case of a zero minimum is special because of the need to stick
+      OP_BRAZERO in front of it, and because the group appears once in the
+      data, whereas in other cases it appears the minimum number of times. For
+      this reason, it is simplest to treat this case separately, as otherwise
+      the code gets far too messy. There are several special subcases when the
+      minimum is zero. */
+
+      if (repeat_min == 0)
+        {
+        /* If the maximum is also zero, we used to just omit the group from the
+        output altogether, like this:
+
+        ** if (repeat_max == 0)
+        **   {
+        **   code = previous;
+        **   goto END_REPEAT;
+        **   }
+
+        However, that fails when a group is referenced as a subroutine from
+        elsewhere in the pattern, so now we stick in OP_SKIPZERO in front of it
+        so that it is skipped on execution. As we don't have a list of which
+        groups are referenced, we cannot do this selectively.
+
+        If the maximum is 1 or unlimited, we just have to stick in the BRAZERO
+        and do no more at this point. However, we do need to adjust any
+        OP_RECURSE calls inside the group that refer to the group itself or any
+        internal or forward referenced group, because the offset is from the
+        start of the whole regex. Temporarily terminate the pattern while doing
+        this. */
+
+        if (repeat_max <= 1)    /* Covers 0, 1, and unlimited */
+          {
+          *code = OP_END;
+          adjust_recurse(previous, 1, utf8, cd, save_hwm);
+          memmove(previous+1, previous, len);
+          code++;
+          if (repeat_max == 0)
+            {
+            *previous++ = OP_SKIPZERO;
+            goto END_REPEAT;
+            }
+          *previous++ = OP_BRAZERO + repeat_type;
+          }
+
+        /* If the maximum is greater than 1 and limited, we have to replicate
+        in a nested fashion, sticking OP_BRAZERO before each set of brackets.
+        The first one has to be handled carefully because it's the original
+        copy, which has to be moved up. The remainder can be handled by code
+        that is common with the non-zero minimum case below. We have to
+        adjust the value or repeat_max, since one less copy is required. Once
+        again, we may have to adjust any OP_RECURSE calls inside the group. */
+
+        else
+          {
+          int offset;
+          *code = OP_END;
+          adjust_recurse(previous, 2 + LINK_SIZE, utf8, cd, save_hwm);
+          memmove(previous + 2 + LINK_SIZE, previous, len);
+          code += 2 + LINK_SIZE;
+          *previous++ = OP_BRAZERO + repeat_type;
+          *previous++ = OP_BRA;
+
+          /* We chain together the bracket offset fields that have to be
+          filled in later when the ends of the brackets are reached. */
+
+          offset = (bralink == NULL)? 0 : previous - bralink;
+          bralink = previous;
+          PUTINC(previous, 0, offset);
+          }
+
+        repeat_max--;
+        }
+
+      /* If the minimum is greater than zero, replicate the group as many
+      times as necessary, and adjust the maximum to the number of subsequent
+      copies that we need. If we set a first char from the group, and didn't
+      set a required char, copy the latter from the former. If there are any
+      forward reference subroutine calls in the group, there will be entries on
+      the workspace list; replicate these with an appropriate increment. */
+
+      else
+        {
+        if (repeat_min > 1)
+          {
+          /* In the pre-compile phase, we don't actually do the replication. We
+          just adjust the length as if we had. Do some paranoid checks for
+          potential integer overflow. The INT64_OR_DOUBLE type is a 64-bit
+          integer type when available, otherwise double. */
+
+          if (lengthptr != NULL)
+            {
+            int delta = (repeat_min - 1)*length_prevgroup;
+            if ((INT64_OR_DOUBLE)(repeat_min - 1)*
+                  (INT64_OR_DOUBLE)length_prevgroup >
+                    (INT64_OR_DOUBLE)INT_MAX ||
+                OFLOW_MAX - *lengthptr < delta)
+              {
+              *errorcodeptr = ERR20;
+              goto FAILED;
+              }
+            *lengthptr += delta;
+            }
+
+          /* This is compiling for real */
+
+          else
+            {
+            if (groupsetfirstbyte && reqbyte < 0) reqbyte = firstbyte;
+            for (i = 1; i < repeat_min; i++)
+              {
+              uschar *hc;
+              uschar *this_hwm = cd->hwm;
+              memcpy(code, previous, len);
+              for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
+                {
+                PUT(cd->hwm, 0, GET(hc, 0) + len);
+                cd->hwm += LINK_SIZE;
+                }
+              save_hwm = this_hwm;
+              code += len;
+              }
+            }
+          }
+
+        if (repeat_max > 0) repeat_max -= repeat_min;
+        }
+
+      /* This code is common to both the zero and non-zero minimum cases. If
+      the maximum is limited, it replicates the group in a nested fashion,
+      remembering the bracket starts on a stack. In the case of a zero minimum,
+      the first one was set up above. In all cases the repeat_max now specifies
+      the number of additional copies needed. Again, we must remember to
+      replicate entries on the forward reference list. */
+
+      if (repeat_max >= 0)
+        {
+        /* In the pre-compile phase, we don't actually do the replication. We
+        just adjust the length as if we had. For each repetition we must add 1
+        to the length for BRAZERO and for all but the last repetition we must
+        add 2 + 2*LINKSIZE to allow for the nesting that occurs. Do some
+        paranoid checks to avoid integer overflow. The INT64_OR_DOUBLE type is
+        a 64-bit integer type when available, otherwise double. */
+
+        if (lengthptr != NULL && repeat_max > 0)
+          {
+          int delta = repeat_max * (length_prevgroup + 1 + 2 + 2*LINK_SIZE) -
+                      2 - 2*LINK_SIZE;   /* Last one doesn't nest */
+          if ((INT64_OR_DOUBLE)repeat_max *
+                (INT64_OR_DOUBLE)(length_prevgroup + 1 + 2 + 2*LINK_SIZE)
+                  > (INT64_OR_DOUBLE)INT_MAX ||
+              OFLOW_MAX - *lengthptr < delta)
+            {
+            *errorcodeptr = ERR20;
+            goto FAILED;
+            }
+          *lengthptr += delta;
+          }
+
+        /* This is compiling for real */
+
+        else for (i = repeat_max - 1; i >= 0; i--)
+          {
+          uschar *hc;
+          uschar *this_hwm = cd->hwm;
+
+          *code++ = OP_BRAZERO + repeat_type;
+
+          /* All but the final copy start a new nesting, maintaining the
+          chain of brackets outstanding. */
+
+          if (i != 0)
+            {
+            int offset;
+            *code++ = OP_BRA;
+            offset = (bralink == NULL)? 0 : code - bralink;
+            bralink = code;
+            PUTINC(code, 0, offset);
+            }
+
+          memcpy(code, previous, len);
+          for (hc = save_hwm; hc < this_hwm; hc += LINK_SIZE)
+            {
+            PUT(cd->hwm, 0, GET(hc, 0) + len + ((i != 0)? 2+LINK_SIZE : 1));
+            cd->hwm += LINK_SIZE;
+            }
+          save_hwm = this_hwm;
+          code += len;
+          }
+
+        /* Now chain through the pending brackets, and fill in their length
+        fields (which are holding the chain links pro tem). */
+
+        while (bralink != NULL)
+          {
+          int oldlinkoffset;
+          int offset = code - bralink + 1;
+          uschar *bra = code - offset;
+          oldlinkoffset = GET(bra, 1);
+          bralink = (oldlinkoffset == 0)? NULL : bralink - oldlinkoffset;
+          *code++ = OP_KET;
+          PUTINC(code, 0, offset);
+          PUT(bra, 1, offset);
+          }
+        }
+
+      /* If the maximum is unlimited, set a repeater in the final copy. We
+      can't just offset backwards from the current code point, because we
+      don't know if there's been an options resetting after the ket. The
+      correct offset was computed above.
+
+      Then, when we are doing the actual compile phase, check to see whether
+      this group is a non-atomic one that could match an empty string. If so,
+      convert the initial operator to the S form (e.g. OP_BRA -> OP_SBRA) so
+      that runtime checking can be done. [This check is also applied to
+      atomic groups at runtime, but in a different way.] */
+
+      else
+        {
+        uschar *ketcode = code - ketoffset;
+        uschar *bracode = ketcode - GET(ketcode, 1);
+        *ketcode = OP_KETRMAX + repeat_type;
+        if (lengthptr == NULL && *bracode != OP_ONCE)
+          {
+          uschar *scode = bracode;
+          do
+            {
+            if (could_be_empty_branch(scode, ketcode, utf8, cd))
+              {
+              *bracode += OP_SBRA - OP_BRA;
+              break;
+              }
+            scode += GET(scode, 1);
+            }
+          while (*scode == OP_ALT);
+          }
+        }
+      }
+
+    /* If previous is OP_FAIL, it was generated by an empty class [] in
+    JavaScript mode. The other ways in which OP_FAIL can be generated, that is
+    by (*FAIL) or (?!) set previous to NULL, which gives a "nothing to repeat"
+    error above. We can just ignore the repeat in JS case. */
+
+    else if (*previous == OP_FAIL) goto END_REPEAT;
+
+    /* Else there's some kind of shambles */
+
+    else
+      {
+      *errorcodeptr = ERR11;
+      goto FAILED;
+      }
+
+    /* If the character following a repeat is '+', or if certain optimization
+    tests above succeeded, possessive_quantifier is TRUE. For some of the
+    simpler opcodes, there is an special alternative opcode for this. For
+    anything else, we wrap the entire repeated item inside OP_ONCE brackets.
+    The '+' notation is just syntactic sugar, taken from Sun's Java package,
+    but the special opcodes can optimize it a bit. The repeated item starts at
+    tempcode, not at previous, which might be the first part of a string whose
+    (former) last char we repeated.
+
+    Possessifying an 'exact' quantifier has no effect, so we can ignore it. But
+    an 'upto' may follow. We skip over an 'exact' item, and then test the
+    length of what remains before proceeding. */
+
+    if (possessive_quantifier)
+      {
+      int len;
+
+      if (*tempcode == OP_TYPEEXACT)
+        tempcode += _pcre_OP_lengths[*tempcode] +
+          ((tempcode[3] == OP_PROP || tempcode[3] == OP_NOTPROP)? 2 : 0);
+
+      else if (*tempcode == OP_EXACT || *tempcode == OP_NOTEXACT)
+        {
+        tempcode += _pcre_OP_lengths[*tempcode];
+#ifdef SUPPORT_UTF8
+        if (utf8 && tempcode[-1] >= 0xc0)
+          tempcode += _pcre_utf8_table4[tempcode[-1] & 0x3f];
+#endif
+        }
+
+      len = code - tempcode;
+      if (len > 0) switch (*tempcode)
+        {
+        case OP_STAR:  *tempcode = OP_POSSTAR; break;
+        case OP_PLUS:  *tempcode = OP_POSPLUS; break;
+        case OP_QUERY: *tempcode = OP_POSQUERY; break;
+        case OP_UPTO:  *tempcode = OP_POSUPTO; break;
+
+        case OP_TYPESTAR:  *tempcode = OP_TYPEPOSSTAR; break;
+        case OP_TYPEPLUS:  *tempcode = OP_TYPEPOSPLUS; break;
+        case OP_TYPEQUERY: *tempcode = OP_TYPEPOSQUERY; break;
+        case OP_TYPEUPTO:  *tempcode = OP_TYPEPOSUPTO; break;
+
+        case OP_NOTSTAR:  *tempcode = OP_NOTPOSSTAR; break;
+        case OP_NOTPLUS:  *tempcode = OP_NOTPOSPLUS; break;
+        case OP_NOTQUERY: *tempcode = OP_NOTPOSQUERY; break;
+        case OP_NOTUPTO:  *tempcode = OP_NOTPOSUPTO; break;
+
+        /* Because we are moving code along, we must ensure that any
+        pending recursive references are updated. */
+
+        default:
+        *code = OP_END;
+        adjust_recurse(tempcode, 1 + LINK_SIZE, utf8, cd, save_hwm);
+        memmove(tempcode + 1+LINK_SIZE, tempcode, len);
+        code += 1 + LINK_SIZE;
+        len += 1 + LINK_SIZE;
+        tempcode[0] = OP_ONCE;
+        *code++ = OP_KET;
+        PUTINC(code, 0, len);
+        PUT(tempcode, 1, len);
+        break;
+        }
+      }
+
+    /* In all case we no longer have a previous item. We also set the
+    "follows varying string" flag for subsequently encountered reqbytes if
+    it isn't already set and we have just passed a varying length item. */
+
+    END_REPEAT:
+    previous = NULL;
+    cd->req_varyopt |= reqvary;
+    break;
+
+
+    /* ===================================================================*/
+    /* Start of nested parenthesized sub-expression, or comment or lookahead or
+    lookbehind or option setting or condition or all the other extended
+    parenthesis forms.  */
+
+    case CHAR_LEFT_PARENTHESIS:
+    newoptions = options;
+    skipbytes = 0;
+    bravalue = OP_CBRA;
+    save_hwm = cd->hwm;
+    reset_bracount = FALSE;
+
+    /* First deal with various "verbs" that can be introduced by '*'. */
+
+    if (*(++ptr) == CHAR_ASTERISK && (cd->ctypes[ptr[1]] & ctype_letter) != 0)
+      {
+      int i, namelen;
+      const char *vn = verbnames;
+      const uschar *name = ++ptr;
+      previous = NULL;
+      while ((cd->ctypes[*++ptr] & ctype_letter) != 0) {};
+      if (*ptr == CHAR_COLON)
+        {
+        *errorcodeptr = ERR59;   /* Not supported */
+        goto FAILED;
+        }
+      if (*ptr != CHAR_RIGHT_PARENTHESIS)
+        {
+        *errorcodeptr = ERR60;
+        goto FAILED;
+        }
+      namelen = ptr - name;
+      for (i = 0; i < verbcount; i++)
+        {
+        if (namelen == verbs[i].len &&
+            strncmp((char *)name, vn, namelen) == 0)
+          {
+          /* Check for open captures before ACCEPT */
+
+          if (verbs[i].op == OP_ACCEPT)
+            {
+            open_capitem *oc;
+            cd->had_accept = TRUE;
+            for (oc = cd->open_caps; oc != NULL; oc = oc->next)
+              {
+              *code++ = OP_CLOSE;
+              PUT2INC(code, 0, oc->number);
+              }
+            }
+          *code++ = verbs[i].op;
+          break;
+          }
+        vn += verbs[i].len + 1;
+        }
+      if (i < verbcount) continue;
+      *errorcodeptr = ERR60;
+      goto FAILED;
+      }
+
+    /* Deal with the extended parentheses; all are introduced by '?', and the
+    appearance of any of them means that this is not a capturing group. */
+
+    else if (*ptr == CHAR_QUESTION_MARK)
+      {
+      int i, set, unset, namelen;
+      int *optset;
+      const uschar *name;
+      uschar *slot;
+
+      switch (*(++ptr))
+        {
+        case CHAR_NUMBER_SIGN:                 /* Comment; skip to ket */
+        ptr++;
+        while (*ptr != 0 && *ptr != CHAR_RIGHT_PARENTHESIS) ptr++;
+        if (*ptr == 0)
+          {
+          *errorcodeptr = ERR18;
+          goto FAILED;
+          }
+        continue;
+
+
+        /* ------------------------------------------------------------ */
+        case CHAR_VERTICAL_LINE:  /* Reset capture count for each branch */
+        reset_bracount = TRUE;
+        /* Fall through */
+
+        /* ------------------------------------------------------------ */
+        case CHAR_COLON:          /* Non-capturing bracket */
+        bravalue = OP_BRA;
+        ptr++;
+        break;
+
+
+        /* ------------------------------------------------------------ */
+        case CHAR_LEFT_PARENTHESIS:
+        bravalue = OP_COND;       /* Conditional group */
+
+        /* A condition can be an assertion, a number (referring to a numbered
+        group), a name (referring to a named group), or 'R', referring to
+        recursion. R<digits> and R&name are also permitted for recursion tests.
+
+        There are several syntaxes for testing a named group: (?(name)) is used
+        by Python; Perl 5.10 onwards uses (?(<name>) or (?('name')).
+
+        There are two unfortunate ambiguities, caused by history. (a) 'R' can
+        be the recursive thing or the name 'R' (and similarly for 'R' followed
+        by digits), and (b) a number could be a name that consists of digits.
+        In both cases, we look for a name first; if not found, we try the other
+        cases. */
+
+        /* For conditions that are assertions, check the syntax, and then exit
+        the switch. This will take control down to where bracketed groups,
+        including assertions, are processed. */
+
+        if (ptr[1] == CHAR_QUESTION_MARK && (ptr[2] == CHAR_EQUALS_SIGN ||
+            ptr[2] == CHAR_EXCLAMATION_MARK || ptr[2] == CHAR_LESS_THAN_SIGN))
+          break;
+
+        /* Most other conditions use OP_CREF (a couple change to OP_RREF
+        below), and all need to skip 3 bytes at the start of the group. */
+
+        code[1+LINK_SIZE] = OP_CREF;
+        skipbytes = 3;
+        refsign = -1;
+
+        /* Check for a test for recursion in a named group. */
+
+        if (ptr[1] == CHAR_R && ptr[2] == CHAR_AMPERSAND)
+          {
+          terminator = -1;
+          ptr += 2;
+          code[1+LINK_SIZE] = OP_RREF;    /* Change the type of test */
+          }
+
+        /* Check for a test for a named group's having been set, using the Perl
+        syntax (?(<name>) or (?('name') */
+
+        else if (ptr[1] == CHAR_LESS_THAN_SIGN)
+          {
+          terminator = CHAR_GREATER_THAN_SIGN;
+          ptr++;
+          }
+        else if (ptr[1] == CHAR_APOSTROPHE)
+          {
+          terminator = CHAR_APOSTROPHE;
+          ptr++;
+          }
+        else
+          {
+          terminator = 0;
+          if (ptr[1] == CHAR_MINUS || ptr[1] == CHAR_PLUS) refsign = *(++ptr);
+          }
+
+        /* We now expect to read a name; any thing else is an error */
+
+        if ((cd->ctypes[ptr[1]] & ctype_word) == 0)
+          {
+          ptr += 1;  /* To get the right offset */
+          *errorcodeptr = ERR28;
+          goto FAILED;
+          }
+
+        /* Read the name, but also get it as a number if it's all digits */
+
+        recno = 0;
+        name = ++ptr;
+        while ((cd->ctypes[*ptr] & ctype_word) != 0)
+          {
+          if (recno >= 0)
+            recno = (g_ascii_isdigit(*ptr) != 0)?
+              recno * 10 + *ptr - CHAR_0 : -1;
+          ptr++;
+          }
+        namelen = ptr - name;
+
+        if ((terminator > 0 && *ptr++ != terminator) ||
+            *ptr++ != CHAR_RIGHT_PARENTHESIS)
+          {
+          ptr--;      /* Error offset */
+          *errorcodeptr = ERR26;
+          goto FAILED;
+          }
+
+        /* Do no further checking in the pre-compile phase. */
+
+        if (lengthptr != NULL) break;
+
+        /* In the real compile we do the work of looking for the actual
+        reference. If the string started with "+" or "-" we require the rest to
+        be digits, in which case recno will be set. */
+
+        if (refsign > 0)
+          {
+          if (recno <= 0)
+            {
+            *errorcodeptr = ERR58;
+            goto FAILED;
+            }
+          recno = (refsign == CHAR_MINUS)?
+            cd->bracount - recno + 1 : recno +cd->bracount;
+          if (recno <= 0 || recno > cd->final_bracount)
+            {
+            *errorcodeptr = ERR15;
+            goto FAILED;
+            }
+          PUT2(code, 2+LINK_SIZE, recno);
+          break;
+          }
+
+        /* Otherwise (did not start with "+" or "-"), start by looking for the
+        name. If we find a name, add one to the opcode to change OP_CREF or
+        OP_RREF into OP_NCREF or OP_NRREF. These behave exactly the same,
+        except they record that the reference was originally to a name. The
+        information is used to check duplicate names. */
+
+        slot = cd->name_table;
+        for (i = 0; i < cd->names_found; i++)
+          {
+          if (strncmp((char *)name, (char *)slot+2, namelen) == 0) break;
+          slot += cd->name_entry_size;
+          }
+
+        /* Found a previous named subpattern */
+
+        if (i < cd->names_found)
+          {
+          recno = GET2(slot, 0);
+          PUT2(code, 2+LINK_SIZE, recno);
+          code[1+LINK_SIZE]++;
+          }
+
+        /* Search the pattern for a forward reference */
+
+        else if ((i = find_parens(cd, name, namelen,
+                        (options & PCRE_EXTENDED) != 0)) > 0)
+          {
+          PUT2(code, 2+LINK_SIZE, i);
+          code[1+LINK_SIZE]++;
+          }
+
+        /* If terminator == 0 it means that the name followed directly after
+        the opening parenthesis [e.g. (?(abc)...] and in this case there are
+        some further alternatives to try. For the cases where terminator != 0
+        [things like (?(<name>... or (?('name')... or (?(R&name)... ] we have
+        now checked all the possibilities, so give an error. */
+
+        else if (terminator != 0)
+          {
+          *errorcodeptr = ERR15;
+          goto FAILED;
+          }
+
+        /* Check for (?(R) for recursion. Allow digits after R to specify a
+        specific group number. */
+
+        else if (*name == CHAR_R)
+          {
+          recno = 0;
+          for (i = 1; i < namelen; i++)
+            {
+            if (g_ascii_isdigit(name[i]) == 0)
+              {
+              *errorcodeptr = ERR15;
+              goto FAILED;
+              }
+            recno = recno * 10 + name[i] - CHAR_0;
+            }
+          if (recno == 0) recno = RREF_ANY;
+          code[1+LINK_SIZE] = OP_RREF;      /* Change test type */
+          PUT2(code, 2+LINK_SIZE, recno);
+          }
+
+        /* Similarly, check for the (?(DEFINE) "condition", which is always
+        false. */
+
+        else if (namelen == 6 && strncmp((char *)name, STRING_DEFINE, 6) == 0)
+          {
+          code[1+LINK_SIZE] = OP_DEF;
+          skipbytes = 1;
+          }
+
+        /* Check for the "name" actually being a subpattern number. We are
+        in the second pass here, so final_bracount is set. */
+
+        else if (recno > 0 && recno <= cd->final_bracount)
+          {
+          PUT2(code, 2+LINK_SIZE, recno);
+          }
+
+        /* Either an unidentified subpattern, or a reference to (?(0) */
+
+        else
+          {
+          *errorcodeptr = (recno == 0)? ERR35: ERR15;
+          goto FAILED;
+          }
+        break;
+
+
+        /* ------------------------------------------------------------ */
+        case CHAR_EQUALS_SIGN:                 /* Positive lookahead */
+        bravalue = OP_ASSERT;
+        ptr++;
+        break;
+
+
+        /* ------------------------------------------------------------ */
+        case CHAR_EXCLAMATION_MARK:            /* Negative lookahead */
+        ptr++;
+        if (*ptr == CHAR_RIGHT_PARENTHESIS)    /* Optimize (?!) */
+          {
+          *code++ = OP_FAIL;
+          previous = NULL;
+          continue;
+          }
+        bravalue = OP_ASSERT_NOT;
+        break;
+
+
+        /* ------------------------------------------------------------ */
+        case CHAR_LESS_THAN_SIGN:              /* Lookbehind or named define */
+        switch (ptr[1])
+          {
+          case CHAR_EQUALS_SIGN:               /* Positive lookbehind */
+          bravalue = OP_ASSERTBACK;
+          ptr += 2;
+          break;
+
+          case CHAR_EXCLAMATION_MARK:          /* Negative lookbehind */
+          bravalue = OP_ASSERTBACK_NOT;
+          ptr += 2;
+          break;
+
+          default:                /* Could be name define, else bad */
+          if ((cd->ctypes[ptr[1]] & ctype_word) != 0) goto DEFINE_NAME;
+          ptr++;                  /* Correct offset for error */
+          *errorcodeptr = ERR24;
+          goto FAILED;
+          }
+        break;
+
+
+        /* ------------------------------------------------------------ */
+        case CHAR_GREATER_THAN_SIGN:           /* One-time brackets */
+        bravalue = OP_ONCE;
+        ptr++;
+        break;
+
+
+        /* ------------------------------------------------------------ */
+        case CHAR_C:                 /* Callout - may be followed by digits; */
+        previous_callout = code;  /* Save for later completion */
+        after_manual_callout = 1; /* Skip one item before completing */
+        *code++ = OP_CALLOUT;
+          {
+          int n = 0;
+          while (g_ascii_isdigit(*(++ptr)) != 0)
+            n = n * 10 + *ptr - CHAR_0;
+          if (*ptr != CHAR_RIGHT_PARENTHESIS)
+            {
+            *errorcodeptr = ERR39;
+            goto FAILED;
+            }
+          if (n > 255)
+            {
+            *errorcodeptr = ERR38;
+            goto FAILED;
+            }
+          *code++ = n;
+          PUT(code, 0, ptr - cd->start_pattern + 1);  /* Pattern offset */
+          PUT(code, LINK_SIZE, 0);                    /* Default length */
+          code += 2 * LINK_SIZE;
+          }
+        previous = NULL;
+        continue;
+
+
+        /* ------------------------------------------------------------ */
+        case CHAR_P:              /* Python-style named subpattern handling */
+        if (*(++ptr) == CHAR_EQUALS_SIGN ||
+            *ptr == CHAR_GREATER_THAN_SIGN)  /* Reference or recursion */
+          {
+          is_recurse = *ptr == CHAR_GREATER_THAN_SIGN;
+          terminator = CHAR_RIGHT_PARENTHESIS;
+          goto NAMED_REF_OR_RECURSE;
+          }
+        else if (*ptr != CHAR_LESS_THAN_SIGN)  /* Test for Python-style defn */
+          {
+          *errorcodeptr = ERR41;
+          goto FAILED;
+          }
+        /* Fall through to handle (?P< as (?< is handled */
+
+
+        /* ------------------------------------------------------------ */
+        DEFINE_NAME:    /* Come here from (?< handling */
+        case CHAR_APOSTROPHE:
+          {
+          terminator = (*ptr == CHAR_LESS_THAN_SIGN)?
+            CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
+          name = ++ptr;
+
+          while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
+          namelen = ptr - name;
+
+          /* In the pre-compile phase, just do a syntax check. */
+
+          if (lengthptr != NULL)
+            {
+            if (*ptr != terminator)
+              {
+              *errorcodeptr = ERR42;
+              goto FAILED;
+              }
+            if (cd->names_found >= MAX_NAME_COUNT)
+              {
+              *errorcodeptr = ERR49;
+              goto FAILED;
+              }
+            if (namelen + 3 > cd->name_entry_size)
+              {
+              cd->name_entry_size = namelen + 3;
+              if (namelen > MAX_NAME_SIZE)
+                {
+                *errorcodeptr = ERR48;
+                goto FAILED;
+                }
+              }
+            }
+
+          /* In the real compile, create the entry in the table, maintaining
+          alphabetical order. Duplicate names for different numbers are
+          permitted only if PCRE_DUPNAMES is set. Duplicate names for the same
+          number are always OK. (An existing number can be re-used if (?|
+          appears in the pattern.) In either event, a duplicate name results in
+          a duplicate entry in the table, even if the number is the same. This
+          is because the number of names, and hence the table size, is computed
+          in the pre-compile, and it affects various numbers and pointers which
+          would all have to be modified, and the compiled code moved down, if
+          duplicates with the same number were omitted from the table. This
+          doesn't seem worth the hassle. However, *different* names for the
+          same number are not permitted. */
+
+          else
+            {
+            BOOL dupname = FALSE;
+            slot = cd->name_table;
+
+            for (i = 0; i < cd->names_found; i++)
+              {
+              int crc = memcmp(name, slot+2, namelen);
+              if (crc == 0)
+                {
+                if (slot[2+namelen] == 0)
+                  {
+                  if (GET2(slot, 0) != cd->bracount + 1 &&
+                      (options & PCRE_DUPNAMES) == 0)
+                    {
+                    *errorcodeptr = ERR43;
+                    goto FAILED;
+                    }
+                  else dupname = TRUE;
+                  }
+                else crc = -1;      /* Current name is a substring */
+                }
+
+              /* Make space in the table and break the loop for an earlier
+              name. For a duplicate or later name, carry on. We do this for
+              duplicates so that in the simple case (when ?(| is not used) they
+              are in order of their numbers. */
+
+              if (crc < 0)
+                {
+                memmove(slot + cd->name_entry_size, slot,
+                  (cd->names_found - i) * cd->name_entry_size);
+                break;
+                }
+
+              /* Continue the loop for a later or duplicate name */
+
+              slot += cd->name_entry_size;
+              }
+
+            /* For non-duplicate names, check for a duplicate number before
+            adding the new name. */
+
+            if (!dupname)
+              {
+              uschar *cslot = cd->name_table;
+              for (i = 0; i < cd->names_found; i++)
+                {
+                if (cslot != slot)
+                  {
+                  if (GET2(cslot, 0) == cd->bracount + 1)
+                    {
+                    *errorcodeptr = ERR65;
+                    goto FAILED;
+                    }
+                  }
+                else i--;
+                cslot += cd->name_entry_size;
+                }
+              }
+
+            PUT2(slot, 0, cd->bracount + 1);
+            memcpy(slot + 2, name, namelen);
+            slot[2+namelen] = 0;
+            }
+          }
+
+        /* In both pre-compile and compile, count the number of names we've
+        encountered. */
+
+        cd->names_found++;
+        ptr++;                    /* Move past > or ' */
+        goto NUMBERED_GROUP;
+
+
+        /* ------------------------------------------------------------ */
+        case CHAR_AMPERSAND:            /* Perl recursion/subroutine syntax */
+        terminator = CHAR_RIGHT_PARENTHESIS;
+        is_recurse = TRUE;
+        /* Fall through */
+
+        /* We come here from the Python syntax above that handles both
+        references (?P=name) and recursion (?P>name), as well as falling
+        through from the Perl recursion syntax (?&name). We also come here from
+        the Perl \k<name> or \k'name' back reference syntax and the \k{name}
+        .NET syntax, and the Oniguruma \g<...> and \g'...' subroutine syntax. */
+
+        NAMED_REF_OR_RECURSE:
+        name = ++ptr;
+        while ((cd->ctypes[*ptr] & ctype_word) != 0) ptr++;
+        namelen = ptr - name;
+
+        /* In the pre-compile phase, do a syntax check and set a dummy
+        reference number. */
+
+        if (lengthptr != NULL)
+          {
+          if (namelen == 0)
+            {
+            *errorcodeptr = ERR62;
+            goto FAILED;
+            }
+          if (*ptr != terminator)
+            {
+            *errorcodeptr = ERR42;
+            goto FAILED;
+            }
+          if (namelen > MAX_NAME_SIZE)
+            {
+            *errorcodeptr = ERR48;
+            goto FAILED;
+            }
+          recno = 0;
+          }
+
+        /* In the real compile, seek the name in the table. We check the name
+        first, and then check that we have reached the end of the name in the
+        table. That way, if the name that is longer than any in the table,
+        the comparison will fail without reading beyond the table entry. */
+
+        else
+          {
+          slot = cd->name_table;
+          for (i = 0; i < cd->names_found; i++)
+            {
+            if (strncmp((char *)name, (char *)slot+2, namelen) == 0 &&
+                slot[2+namelen] == 0)
+              break;
+            slot += cd->name_entry_size;
+            }
+
+          if (i < cd->names_found)         /* Back reference */
+            {
+            recno = GET2(slot, 0);
+            }
+          else if ((recno =                /* Forward back reference */
+                    find_parens(cd, name, namelen,
+                      (options & PCRE_EXTENDED) != 0)) <= 0)
+            {
+            *errorcodeptr = ERR15;
+            goto FAILED;
+            }
+          }
+
+        /* In both phases, we can now go to the code than handles numerical
+        recursion or backreferences. */
+
+        if (is_recurse) goto HANDLE_RECURSION;
+          else goto HANDLE_REFERENCE;
+
+
+        /* ------------------------------------------------------------ */
+        case CHAR_R:              /* Recursion */
+        ptr++;                    /* Same as (?0)      */
+        /* Fall through */
+
+
+        /* ------------------------------------------------------------ */
+        case CHAR_MINUS: case CHAR_PLUS:  /* Recursion or subroutine */
+        case CHAR_0: case CHAR_1: case CHAR_2: case CHAR_3: case CHAR_4:
+        case CHAR_5: case CHAR_6: case CHAR_7: case CHAR_8: case CHAR_9:
+          {
+          const uschar *called;
+          terminator = CHAR_RIGHT_PARENTHESIS;
+
+          /* Come here from the \g<...> and \g'...' code (Oniguruma
+          compatibility). However, the syntax has been checked to ensure that
+          the ... are a (signed) number, so that neither ERR63 nor ERR29 will
+          be called on this path, nor with the jump to OTHER_CHAR_AFTER_QUERY
+          ever be taken. */
+
+          HANDLE_NUMERICAL_RECURSION:
+
+          if ((refsign = *ptr) == CHAR_PLUS)
+            {
+            ptr++;
+            if (g_ascii_isdigit(*ptr) == 0)
+              {
+              *errorcodeptr = ERR63;
+              goto FAILED;
+              }
+            }
+          else if (refsign == CHAR_MINUS)
+            {
+            if (g_ascii_isdigit(ptr[1]) == 0)
+              goto OTHER_CHAR_AFTER_QUERY;
+            ptr++;
+            }
+
+          recno = 0;
+          while(g_ascii_isdigit(*ptr) != 0)
+            recno = recno * 10 + *ptr++ - CHAR_0;
+
+          if (*ptr != terminator)
+            {
+            *errorcodeptr = ERR29;
+            goto FAILED;
+            }
+
+          if (refsign == CHAR_MINUS)
+            {
+            if (recno == 0)
+              {
+              *errorcodeptr = ERR58;
+              goto FAILED;
+              }
+            recno = cd->bracount - recno + 1;
+            if (recno <= 0)
+              {
+              *errorcodeptr = ERR15;
+              goto FAILED;
+              }
+            }
+          else if (refsign == CHAR_PLUS)
+            {
+            if (recno == 0)
+              {
+              *errorcodeptr = ERR58;
+              goto FAILED;
+              }
+            recno += cd->bracount;
+            }
+
+          /* Come here from code above that handles a named recursion */
+
+          HANDLE_RECURSION:
+
+          previous = code;
+          called = cd->start_code;
+
+          /* When we are actually compiling, find the bracket that is being
+          referenced. Temporarily end the regex in case it doesn't exist before
+          this point. If we end up with a forward reference, first check that
+          the bracket does occur later so we can give the error (and position)
+          now. Then remember this forward reference in the workspace so it can
+          be filled in at the end. */
+
+          if (lengthptr == NULL)
+            {
+            *code = OP_END;
+            if (recno != 0)
+              called = _pcre_find_bracket(cd->start_code, utf8, recno);
+
+            /* Forward reference */
+
+            if (called == NULL)
+              {
+              if (find_parens(cd, NULL, recno,
+                    (options & PCRE_EXTENDED) != 0) < 0)
+                {
+                *errorcodeptr = ERR15;
+                goto FAILED;
+                }
+
+              /* Fudge the value of "called" so that when it is inserted as an
+              offset below, what it actually inserted is the reference number
+              of the group. */
+
+              called = cd->start_code + recno;
+              PUTINC(cd->hwm, 0, code + 2 + LINK_SIZE - cd->start_code);
+              }
+
+            /* If not a forward reference, and the subpattern is still open,
+            this is a recursive call. We check to see if this is a left
+            recursion that could loop for ever, and diagnose that case. */
+
+            else if (GET(called, 1) == 0 &&
+                     could_be_empty(called, code, bcptr, utf8, cd))
+              {
+              *errorcodeptr = ERR40;
+              goto FAILED;
+              }
+            }
+
+          /* Insert the recursion/subroutine item, automatically wrapped inside
+          "once" brackets. Set up a "previous group" length so that a
+          subsequent quantifier will work. */
+
+          *code = OP_ONCE;
+          PUT(code, 1, 2 + 2*LINK_SIZE);
+          code += 1 + LINK_SIZE;
+
+          *code = OP_RECURSE;
+          PUT(code, 1, called - cd->start_code);
+          code += 1 + LINK_SIZE;
+
+          *code = OP_KET;
+          PUT(code, 1, 2 + 2*LINK_SIZE);
+          code += 1 + LINK_SIZE;
+
+          length_prevgroup = 3 + 3*LINK_SIZE;
+          }
+
+        /* Can't determine a first byte now */
+
+        if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
+        continue;
+
+
+        /* ------------------------------------------------------------ */
+        default:              /* Other characters: check option setting */
+        OTHER_CHAR_AFTER_QUERY:
+        set = unset = 0;
+        optset = &set;
+
+        while (*ptr != CHAR_RIGHT_PARENTHESIS && *ptr != CHAR_COLON)
+          {
+          switch (*ptr++)
+            {
+            case CHAR_MINUS: optset = &unset; break;
+
+            case CHAR_J:    /* Record that it changed in the external options */
+            *optset |= PCRE_DUPNAMES;
+            cd->external_flags |= PCRE_JCHANGED;
+            break;
+
+            case CHAR_i: *optset |= PCRE_CASELESS; break;
+            case CHAR_m: *optset |= PCRE_MULTILINE; break;
+            case CHAR_s: *optset |= PCRE_DOTALL; break;
+            case CHAR_x: *optset |= PCRE_EXTENDED; break;
+            case CHAR_U: *optset |= PCRE_UNGREEDY; break;
+            case CHAR_X: *optset |= PCRE_EXTRA; break;
+
+            default:  *errorcodeptr = ERR12;
+                      ptr--;    /* Correct the offset */
+                      goto FAILED;
+            }
+          }
+
+        /* Set up the changed option bits, but don't change anything yet. */
+
+        newoptions = (options | set) & (~unset);
+
+        /* If the options ended with ')' this is not the start of a nested
+        group with option changes, so the options change at this level. If this
+        item is right at the start of the pattern, the options can be
+        abstracted and made external in the pre-compile phase, and ignored in
+        the compile phase. This can be helpful when matching -- for instance in
+        caseless checking of required bytes.
+
+        If the code pointer is not (cd->start_code + 1 + LINK_SIZE), we are
+        definitely *not* at the start of the pattern because something has been
+        compiled. In the pre-compile phase, however, the code pointer can have
+        that value after the start, because it gets reset as code is discarded
+        during the pre-compile. However, this can happen only at top level - if
+        we are within parentheses, the starting BRA will still be present. At
+        any parenthesis level, the length value can be used to test if anything
+        has been compiled at that level. Thus, a test for both these conditions
+        is necessary to ensure we correctly detect the start of the pattern in
+        both phases.
+
+        If we are not at the pattern start, compile code to change the ims
+        options if this setting actually changes any of them, and reset the
+        greedy defaults and the case value for firstbyte and reqbyte. */
+
+        if (*ptr == CHAR_RIGHT_PARENTHESIS)
+          {
+          if (code == cd->start_code + 1 + LINK_SIZE &&
+               (lengthptr == NULL || *lengthptr == 2 + 2*LINK_SIZE))
+            {
+            cd->external_options = newoptions;
+            }
+          else
+            {
+            if ((options & PCRE_IMS) != (newoptions & PCRE_IMS))
+              {
+              *code++ = OP_OPT;
+              *code++ = newoptions & PCRE_IMS;
+              }
+            greedy_default = ((newoptions & PCRE_UNGREEDY) != 0);
+            greedy_non_default = greedy_default ^ 1;
+            req_caseopt = ((newoptions & PCRE_CASELESS) != 0)? REQ_CASELESS : 0;
+            }
+
+          /* Change options at this level, and pass them back for use
+          in subsequent branches. When not at the start of the pattern, this
+          information is also necessary so that a resetting item can be
+          compiled at the end of a group (if we are in a group). */
+
+          *optionsptr = options = newoptions;
+          previous = NULL;       /* This item can't be repeated */
+          continue;              /* It is complete */
+          }
+
+        /* If the options ended with ':' we are heading into a nested group
+        with possible change of options. Such groups are non-capturing and are
+        not assertions of any kind. All we need to do is skip over the ':';
+        the newoptions value is handled below. */
+
+        bravalue = OP_BRA;
+        ptr++;
+        }     /* End of switch for character following (? */
+      }       /* End of (? handling */
+
+    /* Opening parenthesis not followed by '?'. If PCRE_NO_AUTO_CAPTURE is set,
+    all unadorned brackets become non-capturing and behave like (?:...)
+    brackets. */
+
+    else if ((options & PCRE_NO_AUTO_CAPTURE) != 0)
+      {
+      bravalue = OP_BRA;
+      }
+
+    /* Else we have a capturing group. */
+
+    else
+      {
+      NUMBERED_GROUP:
+      cd->bracount += 1;
+      PUT2(code, 1+LINK_SIZE, cd->bracount);
+      skipbytes = 2;
+      }
+
+    /* Process nested bracketed regex. Assertions may not be repeated, but
+    other kinds can be. All their opcodes are >= OP_ONCE. We copy code into a
+    non-register variable in order to be able to pass its address because some
+    compilers complain otherwise. Pass in a new setting for the ims options if
+    they have changed. */
+
+    previous = (bravalue >= OP_ONCE)? code : NULL;
+    *code = bravalue;
+    tempcode = code;
+    tempreqvary = cd->req_varyopt;     /* Save value before bracket */
+    length_prevgroup = 0;              /* Initialize for pre-compile phase */
+
+    if (!compile_regex(
+         newoptions,                   /* The complete new option state */
+         options & PCRE_IMS,           /* The previous ims option state */
+         &tempcode,                    /* Where to put code (updated) */
+         &ptr,                         /* Input pointer (updated) */
+         errorcodeptr,                 /* Where to put an error message */
+         (bravalue == OP_ASSERTBACK ||
+          bravalue == OP_ASSERTBACK_NOT), /* TRUE if back assert */
+         reset_bracount,               /* True if (?| group */
+         skipbytes,                    /* Skip over bracket number */
+         &subfirstbyte,                /* For possible first char */
+         &subreqbyte,                  /* For possible last char */
+         bcptr,                        /* Current branch chain */
+         cd,                           /* Tables block */
+         (lengthptr == NULL)? NULL :   /* Actual compile phase */
+           &length_prevgroup           /* Pre-compile phase */
+         ))
+      goto FAILED;
+
+    /* At the end of compiling, code is still pointing to the start of the
+    group, while tempcode has been updated to point past the end of the group
+    and any option resetting that may follow it. The pattern pointer (ptr)
+    is on the bracket. */
+
+    /* If this is a conditional bracket, check that there are no more than
+    two branches in the group, or just one if it's a DEFINE group. We do this
+    in the real compile phase, not in the pre-pass, where the whole group may
+    not be available. */
+
+    if (bravalue == OP_COND && lengthptr == NULL)
+      {
+      uschar *tc = code;
+      int condcount = 0;
+
+      do {
+         condcount++;
+         tc += GET(tc,1);
+         }
+      while (*tc != OP_KET);
+
+      /* A DEFINE group is never obeyed inline (the "condition" is always
+      false). It must have only one branch. */
+
+      if (code[LINK_SIZE+1] == OP_DEF)
+        {
+        if (condcount > 1)
+          {
+          *errorcodeptr = ERR54;
+          goto FAILED;
+          }
+        bravalue = OP_DEF;   /* Just a flag to suppress char handling below */
+        }
+
+      /* A "normal" conditional group. If there is just one branch, we must not
+      make use of its firstbyte or reqbyte, because this is equivalent to an
+      empty second branch. */
+
+      else
+        {
+        if (condcount > 2)
+          {
+          *errorcodeptr = ERR27;
+          goto FAILED;
+          }
+        if (condcount == 1) subfirstbyte = subreqbyte = REQ_NONE;
+        }
+      }
+
+    /* Error if hit end of pattern */
+
+    if (*ptr != CHAR_RIGHT_PARENTHESIS)
+      {
+      *errorcodeptr = ERR14;
+      goto FAILED;
+      }
+
+    /* In the pre-compile phase, update the length by the length of the group,
+    less the brackets at either end. Then reduce the compiled code to just a
+    set of non-capturing brackets so that it doesn't use much memory if it is
+    duplicated by a quantifier.*/
+
+    if (lengthptr != NULL)
+      {
+      if (OFLOW_MAX - *lengthptr < length_prevgroup - 2 - 2*LINK_SIZE)
+        {
+        *errorcodeptr = ERR20;
+        goto FAILED;
+        }
+      *lengthptr += length_prevgroup - 2 - 2*LINK_SIZE;
+      *code++ = OP_BRA;
+      PUTINC(code, 0, 1 + LINK_SIZE);
+      *code++ = OP_KET;
+      PUTINC(code, 0, 1 + LINK_SIZE);
+      break;    /* No need to waste time with special character handling */
+      }
+
+    /* Otherwise update the main code pointer to the end of the group. */
+
+    code = tempcode;
+
+    /* For a DEFINE group, required and first character settings are not
+    relevant. */
+
+    if (bravalue == OP_DEF) break;
+
+    /* Handle updating of the required and first characters for other types of
+    group. Update for normal brackets of all kinds, and conditions with two
+    branches (see code above). If the bracket is followed by a quantifier with
+    zero repeat, we have to back off. Hence the definition of zeroreqbyte and
+    zerofirstbyte outside the main loop so that they can be accessed for the
+    back off. */
+
+    zeroreqbyte = reqbyte;
+    zerofirstbyte = firstbyte;
+    groupsetfirstbyte = FALSE;
+
+    if (bravalue >= OP_ONCE)
+      {
+      /* If we have not yet set a firstbyte in this branch, take it from the
+      subpattern, remembering that it was set here so that a repeat of more
+      than one can replicate it as reqbyte if necessary. If the subpattern has
+      no firstbyte, set "none" for the whole branch. In both cases, a zero
+      repeat forces firstbyte to "none". */
+
+      if (firstbyte == REQ_UNSET)
+        {
+        if (subfirstbyte >= 0)
+          {
+          firstbyte = subfirstbyte;
+          groupsetfirstbyte = TRUE;
+          }
+        else firstbyte = REQ_NONE;
+        zerofirstbyte = REQ_NONE;
+        }
+
+      /* If firstbyte was previously set, convert the subpattern's firstbyte
+      into reqbyte if there wasn't one, using the vary flag that was in
+      existence beforehand. */
+
+      else if (subfirstbyte >= 0 && subreqbyte < 0)
+        subreqbyte = subfirstbyte | tempreqvary;
+
+      /* If the subpattern set a required byte (or set a first byte that isn't
+      really the first byte - see above), set it. */
+
+      if (subreqbyte >= 0) reqbyte = subreqbyte;
+      }
+
+    /* For a forward assertion, we take the reqbyte, if set. This can be
+    helpful if the pattern that follows the assertion doesn't set a different
+    char. For example, it's useful for /(?=abcde).+/. We can't set firstbyte
+    for an assertion, however because it leads to incorrect effect for patterns
+    such as /(?=a)a.+/ when the "real" "a" would then become a reqbyte instead
+    of a firstbyte. This is overcome by a scan at the end if there's no
+    firstbyte, looking for an asserted first char. */
+
+    else if (bravalue == OP_ASSERT && subreqbyte >= 0) reqbyte = subreqbyte;
+    break;     /* End of processing '(' */
+
+
+    /* ===================================================================*/
+    /* Handle metasequences introduced by \. For ones like \d, the ESC_ values
+    are arranged to be the negation of the corresponding OP_values. For the
+    back references, the values are ESC_REF plus the reference number. Only
+    back references and those types that consume a character may be repeated.
+    We can test for values between ESC_b and ESC_Z for the latter; this may
+    have to change if any new ones are ever created. */
+
+    case CHAR_BACKSLASH:
+    tempptr = ptr;
+    c = check_escape(&ptr, errorcodeptr, cd->bracount, options, FALSE);
+    if (*errorcodeptr != 0) goto FAILED;
+
+    if (c < 0)
+      {
+      if (-c == ESC_Q)            /* Handle start of quoted string */
+        {
+        if (ptr[1] == CHAR_BACKSLASH && ptr[2] == CHAR_E)
+          ptr += 2;               /* avoid empty string */
+            else inescq = TRUE;
+        continue;
+        }
+
+      if (-c == ESC_E) continue;  /* Perl ignores an orphan \E */
+
+      /* For metasequences that actually match a character, we disable the
+      setting of a first character if it hasn't already been set. */
+
+      if (firstbyte == REQ_UNSET && -c > ESC_b && -c < ESC_Z)
+        firstbyte = REQ_NONE;
+
+      /* Set values to reset to if this is followed by a zero repeat. */
+
+      zerofirstbyte = firstbyte;
+      zeroreqbyte = reqbyte;
+
+      /* \g<name> or \g'name' is a subroutine call by name and \g<n> or \g'n'
+      is a subroutine call by number (Oniguruma syntax). In fact, the value
+      -ESC_g is returned only for these cases. So we don't need to check for <
+      or ' if the value is -ESC_g. For the Perl syntax \g{n} the value is
+      -ESC_REF+n, and for the Perl syntax \g{name} the result is -ESC_k (as
+      that is a synonym for a named back reference). */
+
+      if (-c == ESC_g)
+        {
+        const uschar *p;
+        save_hwm = cd->hwm;   /* Normally this is set when '(' is read */
+        terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
+          CHAR_GREATER_THAN_SIGN : CHAR_APOSTROPHE;
+
+        /* These two statements stop the compiler for warning about possibly
+        unset variables caused by the jump to HANDLE_NUMERICAL_RECURSION. In
+        fact, because we actually check for a number below, the paths that
+        would actually be in error are never taken. */
+
+        skipbytes = 0;
+        reset_bracount = FALSE;
+
+        /* Test for a name */
+
+        if (ptr[1] != CHAR_PLUS && ptr[1] != CHAR_MINUS)
+          {
+          BOOL isnumber = TRUE;
+          for (p = ptr + 1; *p != 0 && *p != terminator; p++)
+            {
+            if ((cd->ctypes[*p] & ctype_digit) == 0) isnumber = FALSE;
+            if ((cd->ctypes[*p] & ctype_word) == 0) break;
+            }
+          if (*p != terminator)
+            {
+            *errorcodeptr = ERR57;
+            break;
+            }
+          if (isnumber)
+            {
+            ptr++;
+            goto HANDLE_NUMERICAL_RECURSION;
+            }
+          is_recurse = TRUE;
+          goto NAMED_REF_OR_RECURSE;
+          }
+
+        /* Test a signed number in angle brackets or quotes. */
+
+        p = ptr + 2;
+        while (g_ascii_isdigit(*p) != 0) p++;
+        if (*p != terminator)
+          {
+          *errorcodeptr = ERR57;
+          break;
+          }
+        ptr++;
+        goto HANDLE_NUMERICAL_RECURSION;
+        }
+
+      /* \k<name> or \k'name' is a back reference by name (Perl syntax).
+      We also support \k{name} (.NET syntax) */
+
+      if (-c == ESC_k && (ptr[1] == CHAR_LESS_THAN_SIGN ||
+          ptr[1] == CHAR_APOSTROPHE || ptr[1] == CHAR_LEFT_CURLY_BRACKET))
+        {
+        is_recurse = FALSE;
+        terminator = (*(++ptr) == CHAR_LESS_THAN_SIGN)?
+          CHAR_GREATER_THAN_SIGN : (*ptr == CHAR_APOSTROPHE)?
+          CHAR_APOSTROPHE : CHAR_RIGHT_CURLY_BRACKET;
+        goto NAMED_REF_OR_RECURSE;
+        }
+
+      /* Back references are handled specially; must disable firstbyte if
+      not set to cope with cases like (?=(\w+))\1: which would otherwise set
+      ':' later. */
+
+      if (-c >= ESC_REF)
+        {
+        open_capitem *oc;
+        recno = -c - ESC_REF;
+
+        HANDLE_REFERENCE:    /* Come here from named backref handling */
+        if (firstbyte == REQ_UNSET) firstbyte = REQ_NONE;
+        previous = code;
+        *code++ = OP_REF;
+        PUT2INC(code, 0, recno);
+        cd->backref_map |= (recno < 32)? (1 << recno) : 1;
+        if (recno > cd->top_backref) cd->top_backref = recno;
+
+        /* Check to see if this back reference is recursive, that it, it
+        is inside the group that it references. A flag is set so that the
+        group can be made atomic. */
+
+        for (oc = cd->open_caps; oc != NULL; oc = oc->next)
+          {
+          if (oc->number == recno)
+            {
+            oc->flag = TRUE;
+            break;
+            }
+          }
+        }
+
+      /* So are Unicode property matches, if supported. */
+
+#ifdef SUPPORT_UCP
+      else if (-c == ESC_P || -c == ESC_p)
+        {
+        BOOL negated;
+        int pdata;
+        int ptype = get_ucp(&ptr, &negated, &pdata, errorcodeptr);
+        if (ptype < 0) goto FAILED;
+        previous = code;
+        *code++ = ((-c == ESC_p) != negated)? OP_PROP : OP_NOTPROP;
+        *code++ = ptype;
+        *code++ = pdata;
+        }
+#else
+
+      /* If Unicode properties are not supported, \X, \P, and \p are not
+      allowed. */
+
+      else if (-c == ESC_X || -c == ESC_P || -c == ESC_p)
+        {
+        *errorcodeptr = ERR45;
+        goto FAILED;
+        }
+#endif
+
+      /* For the rest (including \X when Unicode properties are supported), we
+      can obtain the OP value by negating the escape value. */
+
+      else
+        {
+        previous = (-c > ESC_b && -c < ESC_Z)? code : NULL;
+        *code++ = -c;
+        }
+      continue;
+      }
+
+    /* We have a data character whose value is in c. In UTF-8 mode it may have
+    a value > 127. We set its representation in the length/buffer, and then
+    handle it as a data character. */
+
+#ifdef SUPPORT_UTF8
+    if (utf8 && c > 127)
+      mclength = _pcre_ord2utf8(c, mcbuffer);
+    else
+#endif
+
+     {
+     mcbuffer[0] = c;
+     mclength = 1;
+     }
+    goto ONE_CHAR;
+
+
+    /* ===================================================================*/
+    /* Handle a literal character. It is guaranteed not to be whitespace or #
+    when the extended flag is set. If we are in UTF-8 mode, it may be a
+    multi-byte literal character. */
+
+    default:
+    NORMAL_CHAR:
+    mclength = 1;
+    mcbuffer[0] = c;
+
+#ifdef SUPPORT_UTF8
+    if (utf8 && c >= 0xc0)
+      {
+      while ((ptr[1] & 0xc0) == 0x80)
+        mcbuffer[mclength++] = *(++ptr);
+      }
+#endif
+
+    /* At this point we have the character's bytes in mcbuffer, and the length
+    in mclength. When not in UTF-8 mode, the length is always 1. */
+
+    ONE_CHAR:
+    previous = code;
+    *code++ = ((options & PCRE_CASELESS) != 0)? OP_CHARNC : OP_CHAR;
+    for (c = 0; c < mclength; c++) *code++ = mcbuffer[c];
+
+    /* Remember if \r or \n were seen */
+
+    if (mcbuffer[0] == CHAR_CR || mcbuffer[0] == CHAR_NL)
+      cd->external_flags |= PCRE_HASCRORLF;
+
+    /* Set the first and required bytes appropriately. If no previous first
+    byte, set it from this character, but revert to none on a zero repeat.
+    Otherwise, leave the firstbyte value alone, and don't change it on a zero
+    repeat. */
+
+    if (firstbyte == REQ_UNSET)
+      {
+      zerofirstbyte = REQ_NONE;
+      zeroreqbyte = reqbyte;
+
+      /* If the character is more than one byte long, we can set firstbyte
+      only if it is not to be matched caselessly. */
+
+      if (mclength == 1 || req_caseopt == 0)
+        {
+        firstbyte = mcbuffer[0] | req_caseopt;
+        if (mclength != 1) reqbyte = code[-1] | cd->req_varyopt;
+        }
+      else firstbyte = reqbyte = REQ_NONE;
+      }
+
+    /* firstbyte was previously set; we can set reqbyte only the length is
+    1 or the matching is caseful. */
+
+    else
+      {
+      zerofirstbyte = firstbyte;
+      zeroreqbyte = reqbyte;
+      if (mclength == 1 || req_caseopt == 0)
+        reqbyte = code[-1] | req_caseopt | cd->req_varyopt;
+      }
+
+    break;            /* End of literal character handling */
+    }
+  }                   /* end of big loop */
+
+
+/* Control never reaches here by falling through, only by a goto for all the
+error states. Pass back the position in the pattern so that it can be displayed
+to the user for diagnosing the error. */
+
+FAILED:
+*ptrptr = ptr;
+return FALSE;
+}
+
+
+
+
+/*************************************************
+*     Compile sequence of alternatives           *
+*************************************************/
+
+/* On entry, ptr is pointing past the bracket character, but on return it
+points to the closing bracket, or vertical bar, or end of string. The code
+variable is pointing at the byte into which the BRA operator has been stored.
+If the ims options are changed at the start (for a (?ims: group) or during any
+branch, we need to insert an OP_OPT item at the start of every following branch
+to ensure they get set correctly at run time, and also pass the new options
+into every subsequent branch compile.
+
+This function is used during the pre-compile phase when we are trying to find
+out the amount of memory needed, as well as during the real compile phase. The
+value of lengthptr distinguishes the two phases.
+
+Arguments:
+  options        option bits, including any changes for this subpattern
+  oldims         previous settings of ims option bits
+  codeptr        -> the address of the current code pointer
+  ptrptr         -> the address of the current pattern pointer
+  errorcodeptr   -> pointer to error code variable
+  lookbehind     TRUE if this is a lookbehind assertion
+  reset_bracount TRUE to reset the count for each branch
+  skipbytes      skip this many bytes at start (for brackets and OP_COND)
+  firstbyteptr   place to put the first required character, or a negative number
+  reqbyteptr     place to put the last required character, or a negative number
+  bcptr          pointer to the chain of currently open branches
+  cd             points to the data block with tables pointers etc.
+  lengthptr      NULL during the real compile phase
+                 points to length accumulator during pre-compile phase
+
+Returns:         TRUE on success
+*/
+
+static BOOL
+compile_regex(int options, int oldims, uschar **codeptr, const uschar **ptrptr,
+  int *errorcodeptr, BOOL lookbehind, BOOL reset_bracount, int skipbytes,
+  int *firstbyteptr, int *reqbyteptr, branch_chain *bcptr, compile_data *cd,
+  int *lengthptr)
+{
+const uschar *ptr = *ptrptr;
+uschar *code = *codeptr;
+uschar *last_branch = code;
+uschar *start_bracket = code;
+uschar *reverse_count = NULL;
+open_capitem capitem;
+int capnumber = 0;
+int firstbyte, reqbyte;
+int branchfirstbyte, branchreqbyte;
+int length;
+int orig_bracount;
+int max_bracount;
+int old_external_options = cd->external_options;
+branch_chain bc;
+
+bc.outer = bcptr;
+bc.current_branch = code;
+
+firstbyte = reqbyte = REQ_UNSET;
+
+/* Accumulate the length for use in the pre-compile phase. Start with the
+length of the BRA and KET and any extra bytes that are required at the
+beginning. We accumulate in a local variable to save frequent testing of
+lenthptr for NULL. We cannot do this by looking at the value of code at the
+start and end of each alternative, because compiled items are discarded during
+the pre-compile phase so that the work space is not exceeded. */
+
+length = 2 + 2*LINK_SIZE + skipbytes;
+
+/* WARNING: If the above line is changed for any reason, you must also change
+the code that abstracts option settings at the start of the pattern and makes
+them global. It tests the value of length for (2 + 2*LINK_SIZE) in the
+pre-compile phase to find out whether anything has yet been compiled or not. */
+
+/* If this is a capturing subpattern, add to the chain of open capturing items
+so that we can detect them if (*ACCEPT) is encountered. This is also used to
+detect groups that contain recursive back references to themselves. */
+
+if (*code == OP_CBRA)
+  {
+  capnumber = GET2(code, 1 + LINK_SIZE);
+  capitem.number = capnumber;
+  capitem.next = cd->open_caps;
+  capitem.flag = FALSE;
+  cd->open_caps = &capitem;
+  }
+
+/* Offset is set zero to mark that this bracket is still open */
+
+PUT(code, 1, 0);
+code += 1 + LINK_SIZE + skipbytes;
+
+/* Loop for each alternative branch */
+
+orig_bracount = max_bracount = cd->bracount;
+for (;;)
+  {
+  /* For a (?| group, reset the capturing bracket count so that each branch
+  uses the same numbers. */
+
+  if (reset_bracount) cd->bracount = orig_bracount;
+
+  /* Handle a change of ims options at the start of the branch */
+
+  if ((options & PCRE_IMS) != oldims)
+    {
+    *code++ = OP_OPT;
+    *code++ = options & PCRE_IMS;
+    length += 2;
+    }
+
+  /* Set up dummy OP_REVERSE if lookbehind assertion */
+
+  if (lookbehind)
+    {
+    *code++ = OP_REVERSE;
+    reverse_count = code;
+    PUTINC(code, 0, 0);
+    length += 1 + LINK_SIZE;
+    }
+
+  /* Now compile the branch; in the pre-compile phase its length gets added
+  into the length. */
+
+  if (!compile_branch(&options, &code, &ptr, errorcodeptr, &branchfirstbyte,
+        &branchreqbyte, &bc, cd, (lengthptr == NULL)? NULL : &length))
+    {
+    *ptrptr = ptr;
+    return FALSE;
+    }
+
+  /* If the external options have changed during this branch, it means that we
+  are at the top level, and a leading option setting has been encountered. We
+  need to re-set the original option values to take account of this so that,
+  during the pre-compile phase, we know to allow for a re-set at the start of
+  subsequent branches. */
+
+  if (old_external_options != cd->external_options)
+    oldims = cd->external_options & PCRE_IMS;
+
+  /* Keep the highest bracket count in case (?| was used and some branch
+  has fewer than the rest. */
+
+  if (cd->bracount > max_bracount) max_bracount = cd->bracount;
+
+  /* In the real compile phase, there is some post-processing to be done. */
+
+  if (lengthptr == NULL)
+    {
+    /* If this is the first branch, the firstbyte and reqbyte values for the
+    branch become the values for the regex. */
+
+    if (*last_branch != OP_ALT)
+      {
+      firstbyte = branchfirstbyte;
+      reqbyte = branchreqbyte;
+      }
+
+    /* If this is not the first branch, the first char and reqbyte have to
+    match the values from all the previous branches, except that if the
+    previous value for reqbyte didn't have REQ_VARY set, it can still match,
+    and we set REQ_VARY for the regex. */
+
+    else
+      {
+      /* If we previously had a firstbyte, but it doesn't match the new branch,
+      we have to abandon the firstbyte for the regex, but if there was
+      previously no reqbyte, it takes on the value of the old firstbyte. */
+
+      if (firstbyte >= 0 && firstbyte != branchfirstbyte)
+        {
+        if (reqbyte < 0) reqbyte = firstbyte;
+        firstbyte = REQ_NONE;
+        }
+
+      /* If we (now or from before) have no firstbyte, a firstbyte from the
+      branch becomes a reqbyte if there isn't a branch reqbyte. */
+
+      if (firstbyte < 0 && branchfirstbyte >= 0 && branchreqbyte < 0)
+          branchreqbyte = branchfirstbyte;
+
+      /* Now ensure that the reqbytes match */
+
+      if ((reqbyte & ~REQ_VARY) != (branchreqbyte & ~REQ_VARY))
+        reqbyte = REQ_NONE;
+      else reqbyte |= branchreqbyte;   /* To "or" REQ_VARY */
+      }
+
+    /* If lookbehind, check that this branch matches a fixed-length string, and
+    put the length into the OP_REVERSE item. Temporarily mark the end of the
+    branch with OP_END. If the branch contains OP_RECURSE, the result is -3
+    because there may be forward references that we can't check here. Set a
+    flag to cause another lookbehind check at the end. Why not do it all at the
+    end? Because common, erroneous checks are picked up here and the offset of
+    the problem can be shown. */
+
+    if (lookbehind)
+      {
+      int fixed_length;
+      *code = OP_END;
+      fixed_length = find_fixedlength(last_branch, options, FALSE, cd);
+      DPRINTF(("fixed length = %d\n", fixed_length));
+      if (fixed_length == -3)
+        {
+        cd->check_lookbehind = TRUE;
+        }
+      else if (fixed_length < 0)
+        {
+        *errorcodeptr = (fixed_length == -2)? ERR36 : ERR25;
+        *ptrptr = ptr;
+        return FALSE;
+        }
+      else { PUT(reverse_count, 0, fixed_length); }
+      }
+    }
+
+  /* Reached end of expression, either ')' or end of pattern. In the real
+  compile phase, go back through the alternative branches and reverse the chain
+  of offsets, with the field in the BRA item now becoming an offset to the
+  first alternative. If there are no alternatives, it points to the end of the
+  group. The length in the terminating ket is always the length of the whole
+  bracketed item. If any of the ims options were changed inside the group,
+  compile a resetting op-code following, except at the very end of the pattern.
+  Return leaving the pointer at the terminating char. */
+
+  if (*ptr != CHAR_VERTICAL_LINE)
+    {
+    if (lengthptr == NULL)
+      {
+      int branch_length = code - last_branch;
+      do
+        {
+        int prev_length = GET(last_branch, 1);
+        PUT(last_branch, 1, branch_length);
+        branch_length = prev_length;
+        last_branch -= branch_length;
+        }
+      while (branch_length > 0);
+      }
+
+    /* Fill in the ket */
+
+    *code = OP_KET;
+    PUT(code, 1, code - start_bracket);
+    code += 1 + LINK_SIZE;
+
+    /* If it was a capturing subpattern, check to see if it contained any
+    recursive back references. If so, we must wrap it in atomic brackets.
+    In any event, remove the block from the chain. */
+
+    if (capnumber > 0)
+      {
+      if (cd->open_caps->flag)
+        {
+        memmove(start_bracket + 1 + LINK_SIZE, start_bracket,
+          code - start_bracket);
+        *start_bracket = OP_ONCE;
+        code += 1 + LINK_SIZE;
+        PUT(start_bracket, 1, code - start_bracket);
+        *code = OP_KET;
+        PUT(code, 1, code - start_bracket);
+        code += 1 + LINK_SIZE;
+        length += 2 + 2*LINK_SIZE;
+        }
+      cd->open_caps = cd->open_caps->next;
+      }
+
+    /* Reset options if needed. */
+
+    if ((options & PCRE_IMS) != oldims && *ptr == CHAR_RIGHT_PARENTHESIS)
+      {
+      *code++ = OP_OPT;
+      *code++ = oldims;
+      length += 2;
+      }
+
+    /* Retain the highest bracket number, in case resetting was used. */
+
+    cd->bracount = max_bracount;
+
+    /* Set values to pass back */
+
+    *codeptr = code;
+    *ptrptr = ptr;
+    *firstbyteptr = firstbyte;
+    *reqbyteptr = reqbyte;
+    if (lengthptr != NULL)
+      {
+      if (OFLOW_MAX - *lengthptr < length)
+        {
+        *errorcodeptr = ERR20;
+        return FALSE;
+        }
+      *lengthptr += length;
+      }
+    return TRUE;
+    }
+
+  /* Another branch follows. In the pre-compile phase, we can move the code
+  pointer back to where it was for the start of the first branch. (That is,
+  pretend that each branch is the only one.)
+
+  In the real compile phase, insert an ALT node. Its length field points back
+  to the previous branch while the bracket remains open. At the end the chain
+  is reversed. It's done like this so that the start of the bracket has a
+  zero offset until it is closed, making it possible to detect recursion. */
+
+  if (lengthptr != NULL)
+    {
+    code = *codeptr + 1 + LINK_SIZE + skipbytes;
+    length += 1 + LINK_SIZE;
+    }
+  else
+    {
+    *code = OP_ALT;
+    PUT(code, 1, code - last_branch);
+    bc.current_branch = last_branch = code;
+    code += 1 + LINK_SIZE;
+    }
+
+  ptr++;
+  }
+/* Control never reaches here */
+}
+
+
+
+
+/*************************************************
+*          Check for anchored expression         *
+*************************************************/
+
+/* Try to find out if this is an anchored regular expression. Consider each
+alternative branch. If they all start with OP_SOD or OP_CIRC, or with a bracket
+all of whose alternatives start with OP_SOD or OP_CIRC (recurse ad lib), then
+it's anchored. However, if this is a multiline pattern, then only OP_SOD
+counts, since OP_CIRC can match in the middle.
+
+We can also consider a regex to be anchored if OP_SOM starts all its branches.
+This is the code for \G, which means "match at start of match position, taking
+into account the match offset".
+
+A branch is also implicitly anchored if it starts with .* and DOTALL is set,
+because that will try the rest of the pattern at all possible matching points,
+so there is no point trying again.... er ....
+
+.... except when the .* appears inside capturing parentheses, and there is a
+subsequent back reference to those parentheses. We haven't enough information
+to catch that case precisely.
+
+At first, the best we could do was to detect when .* was in capturing brackets
+and the highest back reference was greater than or equal to that level.
+However, by keeping a bitmap of the first 31 back references, we can catch some
+of the more common cases more precisely.
+
+Arguments:
+  code           points to start of expression (the bracket)
+  options        points to the options setting
+  bracket_map    a bitmap of which brackets we are inside while testing; this
+                  handles up to substring 31; after that we just have to take
+                  the less precise approach
+  backref_map    the back reference bitmap
+
+Returns:     TRUE or FALSE
+*/
+
+static BOOL
+is_anchored(register const uschar *code, int *options, unsigned int bracket_map,
+  unsigned int backref_map)
+{
+do {
+   const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code],
+     options, PCRE_MULTILINE, FALSE);
+   register int op = *scode;
+
+   /* Non-capturing brackets */
+
+   if (op == OP_BRA)
+     {
+     if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE;
+     }
+
+   /* Capturing brackets */
+
+   else if (op == OP_CBRA)
+     {
+     int n = GET2(scode, 1+LINK_SIZE);
+     int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
+     if (!is_anchored(scode, options, new_map, backref_map)) return FALSE;
+     }
+
+   /* Other brackets */
+
+   else if (op == OP_ASSERT || op == OP_ONCE || op == OP_COND)
+     {
+     if (!is_anchored(scode, options, bracket_map, backref_map)) return FALSE;
+     }
+
+   /* .* is not anchored unless DOTALL is set (which generates OP_ALLANY) and
+   it isn't in brackets that are or may be referenced. */
+
+   else if ((op == OP_TYPESTAR || op == OP_TYPEMINSTAR ||
+             op == OP_TYPEPOSSTAR))
+     {
+     if (scode[1] != OP_ALLANY || (bracket_map & backref_map) != 0)
+       return FALSE;
+     }
+
+   /* Check for explicit anchoring */
+
+   else if (op != OP_SOD && op != OP_SOM &&
+           ((*options & PCRE_MULTILINE) != 0 || op != OP_CIRC))
+     return FALSE;
+   code += GET(code, 1);
+   }
+while (*code == OP_ALT);   /* Loop for each alternative */
+return TRUE;
+}
+
+
+
+/*************************************************
+*         Check for starting with ^ or .*        *
+*************************************************/
+
+/* This is called to find out if every branch starts with ^ or .* so that
+"first char" processing can be done to speed things up in multiline
+matching and for non-DOTALL patterns that start with .* (which must start at
+the beginning or after \n). As in the case of is_anchored() (see above), we
+have to take account of back references to capturing brackets that contain .*
+because in that case we can't make the assumption.
+
+Arguments:
+  code           points to start of expression (the bracket)
+  bracket_map    a bitmap of which brackets we are inside while testing; this
+                  handles up to substring 31; after that we just have to take
+                  the less precise approach
+  backref_map    the back reference bitmap
+
+Returns:         TRUE or FALSE
+*/
+
+static BOOL
+is_startline(const uschar *code, unsigned int bracket_map,
+  unsigned int backref_map)
+{
+do {
+   const uschar *scode = first_significant_code(code + _pcre_OP_lengths[*code],
+     NULL, 0, FALSE);
+   register int op = *scode;
+
+   /* If we are at the start of a conditional assertion group, *both* the
+   conditional assertion *and* what follows the condition must satisfy the test
+   for start of line. Other kinds of condition fail. Note that there may be an
+   auto-callout at the start of a condition. */
+
+   if (op == OP_COND)
+     {
+     scode += 1 + LINK_SIZE;
+     if (*scode == OP_CALLOUT) scode += _pcre_OP_lengths[OP_CALLOUT];
+     switch (*scode)
+       {
+       case OP_CREF:
+       case OP_NCREF:
+       case OP_RREF:
+       case OP_NRREF:
+       case OP_DEF:
+       return FALSE;
+
+       default:     /* Assertion */
+       if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
+       do scode += GET(scode, 1); while (*scode == OP_ALT);
+       scode += 1 + LINK_SIZE;
+       break;
+       }
+     scode = first_significant_code(scode, NULL, 0, FALSE);
+     op = *scode;
+     }
+
+   /* Non-capturing brackets */
+
+   if (op == OP_BRA)
+     {
+     if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
+     }
+
+   /* Capturing brackets */
+
+   else if (op == OP_CBRA)
+     {
+     int n = GET2(scode, 1+LINK_SIZE);
+     int new_map = bracket_map | ((n < 32)? (1 << n) : 1);
+     if (!is_startline(scode, new_map, backref_map)) return FALSE;
+     }
+
+   /* Other brackets */
+
+   else if (op == OP_ASSERT || op == OP_ONCE)
+     {
+     if (!is_startline(scode, bracket_map, backref_map)) return FALSE;
+     }
+
+   /* .* means "start at start or after \n" if it isn't in brackets that
+   may be referenced. */
+
+   else if (op == OP_TYPESTAR || op == OP_TYPEMINSTAR || op == OP_TYPEPOSSTAR)
+     {
+     if (scode[1] != OP_ANY || (bracket_map & backref_map) != 0) return FALSE;
+     }
+
+   /* Check for explicit circumflex */
+
+   else if (op != OP_CIRC) return FALSE;
+
+   /* Move on to the next alternative */
+
+   code += GET(code, 1);
+   }
+while (*code == OP_ALT);  /* Loop for each alternative */
+return TRUE;
+}
+
+
+
+/*************************************************
+*       Check for asserted fixed first char      *
+*************************************************/
+
+/* During compilation, the "first char" settings from forward assertions are
+discarded, because they can cause conflicts with actual literals that follow.
+However, if we end up without a first char setting for an unanchored pattern,
+it is worth scanning the regex to see if there is an initial asserted first
+char. If all branches start with the same asserted char, or with a bracket all
+of whose alternatives start with the same asserted char (recurse ad lib), then
+we return that char, otherwise -1.
+
+Arguments:
+  code       points to start of expression (the bracket)
+  options    pointer to the options (used to check casing changes)
+  inassert   TRUE if in an assertion
+
+Returns:     -1 or the fixed first char
+*/
+
+static int
+find_firstassertedchar(const uschar *code, int *options, BOOL inassert)
+{
+register int c = -1;
+do {
+   int d;
+   const uschar *scode =
+     first_significant_code(code + 1+LINK_SIZE, options, PCRE_CASELESS, TRUE);
+   register int op = *scode;
+
+   switch(op)
+     {
+     default:
+     return -1;
+
+     case OP_BRA:
+     case OP_CBRA:
+     case OP_ASSERT:
+     case OP_ONCE:
+     case OP_COND:
+     if ((d = find_firstassertedchar(scode, options, op == OP_ASSERT)) < 0)
+       return -1;
+     if (c < 0) c = d; else if (c != d) return -1;
+     break;
+
+     case OP_EXACT:       /* Fall through */
+     scode += 2;
+
+     case OP_CHAR:
+     case OP_CHARNC:
+     case OP_PLUS:
+     case OP_MINPLUS:
+     case OP_POSPLUS:
+     if (!inassert) return -1;
+     if (c < 0)
+       {
+       c = scode[1];
+       if ((*options & PCRE_CASELESS) != 0) c |= REQ_CASELESS;
+       }
+     else if (c != scode[1]) return -1;
+     break;
+     }
+
+   code += GET(code, 1);
+   }
+while (*code == OP_ALT);
+return c;
+}
+
+
+
+/*************************************************
+*        Compile a Regular Expression            *
+*************************************************/
+
+/* This function takes a string and returns a pointer to a block of store
+holding a compiled version of the expression. The original API for this
+function had no error code return variable; it is retained for backwards
+compatibility. The new function is given a new name.
+
+Arguments:
+  pattern       the regular expression
+  options       various option bits
+  errorcodeptr  pointer to error code variable (pcre_compile2() only)
+                  can be NULL if you don't want a code value
+  errorptr      pointer to pointer to error text
+  erroroffset   ptr offset in pattern where error was detected
+  tables        pointer to character tables or NULL
+
+Returns:        pointer to compiled data block, or NULL on error,
+                with errorptr and erroroffset set
+*/
+
+#ifdef NOT_USED_IN_GLIB
+
+PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
+pcre_compile(const char *pattern, int options, const char **errorptr,
+  int *erroroffset, const unsigned char *tables)
+{
+return pcre_compile2(pattern, options, NULL, errorptr, erroroffset, tables);
+}
+
+#endif
+
+PCRE_EXP_DEFN pcre * PCRE_CALL_CONVENTION
+pcre_compile2(const char *pattern, int options, int *errorcodeptr,
+  const char **errorptr, int *erroroffset, const unsigned char *tables)
+{
+real_pcre *re;
+int length = 1;  /* For final END opcode */
+int firstbyte, reqbyte, newline;
+int errorcode = 0;
+int skipatstart = 0;
+BOOL utf8 = (options & PCRE_UTF8) != 0;
+size_t size;
+uschar *code;
+const uschar *codestart;
+const uschar *ptr;
+compile_data compile_block;
+compile_data *cd = &compile_block;
+
+/* This space is used for "compiling" into during the first phase, when we are
+computing the amount of memory that is needed. Compiled items are thrown away
+as soon as possible, so that a fairly large buffer should be sufficient for
+this purpose. The same space is used in the second phase for remembering where
+to fill in forward references to subpatterns. */
+
+uschar cworkspace[COMPILE_WORK_SIZE];
+
+/* Set this early so that early errors get offset 0. */
+
+ptr = (const uschar *)pattern;
+
+/* We can't pass back an error message if errorptr is NULL; I guess the best we
+can do is just return NULL, but we can set a code value if there is a code
+pointer. */
+
+if (errorptr == NULL)
+  {
+  if (errorcodeptr != NULL) *errorcodeptr = 99;
+  return NULL;
+  }
+
+*errorptr = NULL;
+if (errorcodeptr != NULL) *errorcodeptr = ERR0;
+
+/* However, we can give a message for this error */
+
+if (erroroffset == NULL)
+  {
+  errorcode = ERR16;
+  goto PCRE_EARLY_ERROR_RETURN2;
+  }
+
+*erroroffset = 0;
+
+/* Set up pointers to the individual character tables */
+
+if (tables == NULL) tables = _pcre_default_tables;
+cd->lcc = tables + lcc_offset;
+cd->fcc = tables + fcc_offset;
+cd->cbits = tables + cbits_offset;
+cd->ctypes = tables + ctypes_offset;
+
+/* Check that all undefined public option bits are zero */
+
+if ((options & ~PUBLIC_COMPILE_OPTIONS) != 0)
+  {
+  errorcode = ERR17;
+  goto PCRE_EARLY_ERROR_RETURN;
+  }
+
+/* Check for global one-time settings at the start of the pattern, and remember
+the offset for later. */
+
+while (ptr[skipatstart] == CHAR_LEFT_PARENTHESIS &&
+       ptr[skipatstart+1] == CHAR_ASTERISK)
+  {
+  int newnl = 0;
+  int newbsr = 0;
+
+  if (strncmp((char *)(ptr+skipatstart+2), STRING_UTF8_RIGHTPAR, 5) == 0)
+    { skipatstart += 7; options |= PCRE_UTF8; continue; }
+
+  if (strncmp((char *)(ptr+skipatstart+2), STRING_CR_RIGHTPAR, 3) == 0)
+    { skipatstart += 5; newnl = PCRE_NEWLINE_CR; }
+  else if (strncmp((char *)(ptr+skipatstart+2), STRING_LF_RIGHTPAR, 3)  == 0)
+    { skipatstart += 5; newnl = PCRE_NEWLINE_LF; }
+  else if (strncmp((char *)(ptr+skipatstart+2), STRING_CRLF_RIGHTPAR, 5)  == 0)
+    { skipatstart += 7; newnl = PCRE_NEWLINE_CR + PCRE_NEWLINE_LF; }
+  else if (strncmp((char *)(ptr+skipatstart+2), STRING_ANY_RIGHTPAR, 4) == 0)
+    { skipatstart += 6; newnl = PCRE_NEWLINE_ANY; }
+  else if (strncmp((char *)(ptr+skipatstart+2), STRING_ANYCRLF_RIGHTPAR, 8) == 0)
+    { skipatstart += 10; newnl = PCRE_NEWLINE_ANYCRLF; }
+
+  else if (strncmp((char *)(ptr+skipatstart+2), STRING_BSR_ANYCRLF_RIGHTPAR, 12) == 0)
+    { skipatstart += 14; newbsr = PCRE_BSR_ANYCRLF; }
+  else if (strncmp((char *)(ptr+skipatstart+2), STRING_BSR_UNICODE_RIGHTPAR, 12) == 0)
+    { skipatstart += 14; newbsr = PCRE_BSR_UNICODE; }
+
+  if (newnl != 0)
+    options = (options & ~PCRE_NEWLINE_BITS) | newnl;
+  else if (newbsr != 0)
+    options = (options & ~(PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) | newbsr;
+  else break;
+  }
+
+/* Can't support UTF8 unless PCRE has been compiled to include the code. */
+
+#ifdef SUPPORT_UTF8
+if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0 &&
+     (*erroroffset = _pcre_valid_utf8((USPTR)pattern, -1)) >= 0)
+  {
+  errorcode = ERR44;
+  goto PCRE_EARLY_ERROR_RETURN2;
+  }
+#else
+if (utf8)
+  {
+  errorcode = ERR32;
+  goto PCRE_EARLY_ERROR_RETURN;
+  }
+#endif
+
+/* Check validity of \R options. */
+
+switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
+  {
+  case 0:
+  case PCRE_BSR_ANYCRLF:
+  case PCRE_BSR_UNICODE:
+  break;
+  default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;
+  }
+
+/* Handle different types of newline. The three bits give seven cases. The
+current code allows for fixed one- or two-byte sequences, plus "any" and
+"anycrlf". */
+
+switch (options & PCRE_NEWLINE_BITS)
+  {
+  case 0: newline = NEWLINE; break;   /* Build-time default */
+  case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
+  case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
+  case PCRE_NEWLINE_CR+
+       PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
+  case PCRE_NEWLINE_ANY: newline = -1; break;
+  case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
+  default: errorcode = ERR56; goto PCRE_EARLY_ERROR_RETURN;
+  }
+
+if (newline == -2)
+  {
+  cd->nltype = NLTYPE_ANYCRLF;
+  }
+else if (newline < 0)
+  {
+  cd->nltype = NLTYPE_ANY;
+  }
+else
+  {
+  cd->nltype = NLTYPE_FIXED;
+  if (newline > 255)
+    {
+    cd->nllen = 2;
+    cd->nl[0] = (newline >> 8) & 255;
+    cd->nl[1] = newline & 255;
+    }
+  else
+    {
+    cd->nllen = 1;
+    cd->nl[0] = newline;
+    }
+  }
+
+/* Maximum back reference and backref bitmap. The bitmap records up to 31 back
+references to help in deciding whether (.*) can be treated as anchored or not.
+*/
+
+cd->top_backref = 0;
+cd->backref_map = 0;
+
+/* Reflect pattern for debugging output */
+
+DPRINTF(("------------------------------------------------------------------\n"));
+DPRINTF(("%s\n", pattern));
+
+/* Pretend to compile the pattern while actually just accumulating the length
+of memory required. This behaviour is triggered by passing a non-NULL final
+argument to compile_regex(). We pass a block of workspace (cworkspace) for it
+to compile parts of the pattern into; the compiled code is discarded when it is
+no longer needed, so hopefully this workspace will never overflow, though there
+is a test for its doing so. */
+
+cd->bracount = cd->final_bracount = 0;
+cd->names_found = 0;
+cd->name_entry_size = 0;
+cd->name_table = NULL;
+cd->start_workspace = cworkspace;
+cd->start_code = cworkspace;
+cd->hwm = cworkspace;
+cd->start_pattern = (const uschar *)pattern;
+cd->end_pattern = (const uschar *)(pattern + strlen(pattern));
+cd->req_varyopt = 0;
+cd->external_options = options;
+cd->external_flags = 0;
+cd->open_caps = NULL;
+
+/* Now do the pre-compile. On error, errorcode will be set non-zero, so we
+don't need to look at the result of the function here. The initial options have
+been put into the cd block so that they can be changed if an option setting is
+found within the regex right at the beginning. Bringing initial option settings
+outside can help speed up starting point checks. */
+
+ptr += skipatstart;
+code = cworkspace;
+*code = OP_BRA;
+(void)compile_regex(cd->external_options, cd->external_options & PCRE_IMS,
+  &code, &ptr, &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd,
+  &length);
+if (errorcode != 0) goto PCRE_EARLY_ERROR_RETURN;
+
+DPRINTF(("end pre-compile: length=%d workspace=%d\n", length,
+  cd->hwm - cworkspace));
+
+if (length > MAX_PATTERN_SIZE)
+  {
+  errorcode = ERR20;
+  goto PCRE_EARLY_ERROR_RETURN;
+  }
+
+/* Compute the size of data block needed and get it, either from malloc or
+externally provided function. Integer overflow should no longer be possible
+because nowadays we limit the maximum value of cd->names_found and
+cd->name_entry_size. */
+
+size = length + sizeof(real_pcre) + cd->names_found * (cd->name_entry_size + 3);
+re = (real_pcre *)(pcre_malloc)(size);
+
+if (re == NULL)
+  {
+  errorcode = ERR21;
+  goto PCRE_EARLY_ERROR_RETURN;
+  }
+
+/* Put in the magic number, and save the sizes, initial options, internal
+flags, and character table pointer. NULL is used for the default character
+tables. The nullpad field is at the end; it's there to help in the case when a
+regex compiled on a system with 4-byte pointers is run on another with 8-byte
+pointers. */
+
+re->magic_number = MAGIC_NUMBER;
+re->size = size;
+re->options = cd->external_options;
+re->flags = cd->external_flags;
+re->dummy1 = 0;
+re->first_byte = 0;
+re->req_byte = 0;
+re->name_table_offset = sizeof(real_pcre);
+re->name_entry_size = cd->name_entry_size;
+re->name_count = cd->names_found;
+re->ref_count = 0;
+re->tables = (tables == _pcre_default_tables)? NULL : tables;
+re->nullpad = NULL;
+
+/* The starting points of the name/number translation table and of the code are
+passed around in the compile data block. The start/end pattern and initial
+options are already set from the pre-compile phase, as is the name_entry_size
+field. Reset the bracket count and the names_found field. Also reset the hwm
+field; this time it's used for remembering forward references to subpatterns.
+*/
+
+cd->final_bracount = cd->bracount;  /* Save for checking forward references */
+cd->bracount = 0;
+cd->names_found = 0;
+cd->name_table = (uschar *)re + re->name_table_offset;
+codestart = cd->name_table + re->name_entry_size * re->name_count;
+cd->start_code = codestart;
+cd->hwm = cworkspace;
+cd->req_varyopt = 0;
+cd->had_accept = FALSE;
+cd->check_lookbehind = FALSE;
+cd->open_caps = NULL;
+
+/* Set up a starting, non-extracting bracket, then compile the expression. On
+error, errorcode will be set non-zero, so we don't need to look at the result
+of the function here. */
+
+ptr = (const uschar *)pattern + skipatstart;
+code = (uschar *)codestart;
+*code = OP_BRA;
+(void)compile_regex(re->options, re->options & PCRE_IMS, &code, &ptr,
+  &errorcode, FALSE, FALSE, 0, &firstbyte, &reqbyte, NULL, cd, NULL);
+re->top_bracket = cd->bracount;
+re->top_backref = cd->top_backref;
+re->flags = cd->external_flags;
+
+if (cd->had_accept) reqbyte = -1;   /* Must disable after (*ACCEPT) */
+
+/* If not reached end of pattern on success, there's an excess bracket. */
+
+if (errorcode == 0 && *ptr != 0) errorcode = ERR22;
+
+/* Fill in the terminating state and check for disastrous overflow, but
+if debugging, leave the test till after things are printed out. */
+
+*code++ = OP_END;
+
+#ifndef PCRE_DEBUG
+if (code - codestart > length) errorcode = ERR23;
+#endif
+
+/* Fill in any forward references that are required. */
+
+while (errorcode == 0 && cd->hwm > cworkspace)
+  {
+  int offset, recno;
+  const uschar *groupptr;
+  cd->hwm -= LINK_SIZE;
+  offset = GET(cd->hwm, 0);
+  recno = GET(codestart, offset);
+  groupptr = _pcre_find_bracket(codestart, utf8, recno);
+  if (groupptr == NULL) errorcode = ERR53;
+    else PUT(((uschar *)codestart), offset, groupptr - codestart);
+  }
+
+/* Give an error if there's back reference to a non-existent capturing
+subpattern. */
+
+if (errorcode == 0 && re->top_backref > re->top_bracket) errorcode = ERR15;
+
+/* If there were any lookbehind assertions that contained OP_RECURSE
+(recursions or subroutine calls), a flag is set for them to be checked here,
+because they may contain forward references. Actual recursions can't be fixed
+length, but subroutine calls can. It is done like this so that those without
+OP_RECURSE that are not fixed length get a diagnosic with a useful offset. The
+exceptional ones forgo this. We scan the pattern to check that they are fixed
+length, and set their lengths. */
+
+if (cd->check_lookbehind)
+  {
+  uschar *cc = (uschar *)codestart;
+
+  /* Loop, searching for OP_REVERSE items, and process those that do not have
+  their length set. (Actually, it will also re-process any that have a length
+  of zero, but that is a pathological case, and it does no harm.) When we find
+  one, we temporarily terminate the branch it is in while we scan it. */
+
+  for (cc = (uschar *)_pcre_find_bracket(codestart, utf8, -1);
+       cc != NULL;
+       cc = (uschar *)_pcre_find_bracket(cc, utf8, -1))
+    {
+    if (GET(cc, 1) == 0)
+      {
+      int fixed_length;
+      uschar *be = cc - 1 - LINK_SIZE + GET(cc, -LINK_SIZE);
+      int end_op = *be;
+      *be = OP_END;
+      fixed_length = find_fixedlength(cc, re->options, TRUE, cd);
+      *be = end_op;
+      DPRINTF(("fixed length = %d\n", fixed_length));
+      if (fixed_length < 0)
+        {
+        errorcode = (fixed_length == -2)? ERR36 : ERR25;
+        break;
+        }
+      PUT(cc, 1, fixed_length);
+      }
+    cc += 1 + LINK_SIZE;
+    }
+  }
+
+/* Failed to compile, or error while post-processing */
+
+if (errorcode != 0)
+  {
+  (pcre_free)(re);
+  PCRE_EARLY_ERROR_RETURN:
+  *erroroffset = ptr - (const uschar *)pattern;
+  PCRE_EARLY_ERROR_RETURN2:
+  *errorptr = find_error_text(errorcode);
+  if (errorcodeptr != NULL) *errorcodeptr = errorcode;
+  return NULL;
+  }
+
+/* If the anchored option was not passed, set the flag if we can determine that
+the pattern is anchored by virtue of ^ characters or \A or anything else (such
+as starting with .* when DOTALL is set).
+
+Otherwise, if we know what the first byte has to be, save it, because that
+speeds up unanchored matches no end. If not, see if we can set the
+PCRE_STARTLINE flag. This is helpful for multiline matches when all branches
+start with ^. and also when all branches start with .* for non-DOTALL matches.
+*/
+
+if ((re->options & PCRE_ANCHORED) == 0)
+  {
+  int temp_options = re->options;   /* May get changed during these scans */
+  if (is_anchored(codestart, &temp_options, 0, cd->backref_map))
+    re->options |= PCRE_ANCHORED;
+  else
+    {
+    if (firstbyte < 0)
+      firstbyte = find_firstassertedchar(codestart, &temp_options, FALSE);
+    if (firstbyte >= 0)   /* Remove caseless flag for non-caseable chars */
+      {
+      int ch = firstbyte & 255;
+      re->first_byte = ((firstbyte & REQ_CASELESS) != 0 &&
+         cd->fcc[ch] == ch)? ch : firstbyte;
+      re->flags |= PCRE_FIRSTSET;
+      }
+    else if (is_startline(codestart, 0, cd->backref_map))
+      re->flags |= PCRE_STARTLINE;
+    }
+  }
+
+/* For an anchored pattern, we use the "required byte" only if it follows a
+variable length item in the regex. Remove the caseless flag for non-caseable
+bytes. */
+
+if (reqbyte >= 0 &&
+     ((re->options & PCRE_ANCHORED) == 0 || (reqbyte & REQ_VARY) != 0))
+  {
+  int ch = reqbyte & 255;
+  re->req_byte = ((reqbyte & REQ_CASELESS) != 0 &&
+    cd->fcc[ch] == ch)? (reqbyte & ~REQ_CASELESS) : reqbyte;
+  re->flags |= PCRE_REQCHSET;
+  }
+
+/* Print out the compiled data if debugging is enabled. This is never the
+case when building a production library. */
+
+#ifdef PCRE_DEBUG
+printf("Length = %d top_bracket = %d top_backref = %d\n",
+  length, re->top_bracket, re->top_backref);
+
+printf("Options=%08x\n", re->options);
+
+if ((re->flags & PCRE_FIRSTSET) != 0)
+  {
+  int ch = re->first_byte & 255;
+  const char *caseless = ((re->first_byte & REQ_CASELESS) == 0)?
+    "" : " (caseless)";
+  if (isprint(ch)) printf("First char = %c%s\n", ch, caseless);
+    else printf("First char = \\x%02x%s\n", ch, caseless);
+  }
+
+if ((re->flags & PCRE_REQCHSET) != 0)
+  {
+  int ch = re->req_byte & 255;
+  const char *caseless = ((re->req_byte & REQ_CASELESS) == 0)?
+    "" : " (caseless)";
+  if (isprint(ch)) printf("Req char = %c%s\n", ch, caseless);
+    else printf("Req char = \\x%02x%s\n", ch, caseless);
+  }
+
+pcre_printint(re, stdout, TRUE);
+
+/* This check is done here in the debugging case so that the code that
+was compiled can be seen. */
+
+if (code - codestart > length)
+  {
+  (pcre_free)(re);
+  *errorptr = find_error_text(ERR23);
+  *erroroffset = ptr - (uschar *)pattern;
+  if (errorcodeptr != NULL) *errorcodeptr = ERR23;
+  return NULL;
+  }
+#endif   /* PCRE_DEBUG */
+
+return (pcre *)re;
+}
+
+/* End of pcre_compile.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_config.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_config.c
new file mode 100644 (file)
index 0000000..78e8560
--- /dev/null
@@ -0,0 +1,128 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2009 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_config(). */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+* Return info about what features are configured *
+*************************************************/
+
+/* This function has an extensible interface so that additional items can be
+added compatibly.
+
+Arguments:
+  what             what information is required
+  where            where to put the information
+
+Returns:           0 if data returned, negative on error
+*/
+
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_config(int what, void *where)
+{
+switch (what)
+  {
+  case PCRE_CONFIG_UTF8:
+#ifdef SUPPORT_UTF8
+  *((int *)where) = 1;
+#else
+  *((int *)where) = 0;
+#endif
+  break;
+
+  case PCRE_CONFIG_UNICODE_PROPERTIES:
+#ifdef SUPPORT_UCP
+  *((int *)where) = 1;
+#else
+  *((int *)where) = 0;
+#endif
+  break;
+
+  case PCRE_CONFIG_NEWLINE:
+  *((int *)where) = NEWLINE;
+  break;
+
+  case PCRE_CONFIG_BSR:
+#ifdef BSR_ANYCRLF
+  *((int *)where) = 1;
+#else
+  *((int *)where) = 0;
+#endif
+  break;
+
+  case PCRE_CONFIG_LINK_SIZE:
+  *((int *)where) = LINK_SIZE;
+  break;
+
+  case PCRE_CONFIG_POSIX_MALLOC_THRESHOLD:
+  *((int *)where) = POSIX_MALLOC_THRESHOLD;
+  break;
+
+  case PCRE_CONFIG_MATCH_LIMIT:
+  *((unsigned long int *)where) = MATCH_LIMIT;
+  break;
+
+  case PCRE_CONFIG_MATCH_LIMIT_RECURSION:
+  *((unsigned long int *)where) = MATCH_LIMIT_RECURSION;
+  break;
+
+  case PCRE_CONFIG_STACKRECURSE:
+#ifdef NO_RECURSE
+  *((int *)where) = 0;
+#else
+  *((int *)where) = 1;
+#endif
+  break;
+
+  default: return PCRE_ERROR_BADOPTION;
+  }
+
+return 0;
+}
+
+/* End of pcre_config.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_dfa_exec.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_dfa_exec.c
new file mode 100644 (file)
index 0000000..c241f5b
--- /dev/null
@@ -0,0 +1,3116 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language (but see
+below for why this module is different).
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2010 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_dfa_exec(), which is an
+alternative matching function that uses a sort of DFA algorithm (not a true
+FSM). This is NOT Perl- compatible, but it has advantages in certain
+applications. */
+
+
+/* NOTE ABOUT PERFORMANCE: A user of this function sent some code that improved
+the performance of his patterns greatly. I could not use it as it stood, as it
+was not thread safe, and made assumptions about pattern sizes. Also, it caused
+test 7 to loop, and test 9 to crash with a segfault.
+
+The issue is the check for duplicate states, which is done by a simple linear
+search up the state list. (Grep for "duplicate" below to find the code.) For
+many patterns, there will never be many states active at one time, so a simple
+linear search is fine. In patterns that have many active states, it might be a
+bottleneck. The suggested code used an indexing scheme to remember which states
+had previously been used for each character, and avoided the linear search when
+it knew there was no chance of a duplicate. This was implemented when adding
+states to the state lists.
+
+I wrote some thread-safe, not-limited code to try something similar at the time
+of checking for duplicates (instead of when adding states), using index vectors
+on the stack. It did give a 13% improvement with one specially constructed
+pattern for certain subject strings, but on other strings and on many of the
+simpler patterns in the test suite it did worse. The major problem, I think,
+was the extra time to initialize the index. This had to be done for each call
+of internal_dfa_exec(). (The supplied patch used a static vector, initialized
+only once - I suspect this was the cause of the problems with the tests.)
+
+Overall, I concluded that the gains in some cases did not outweigh the losses
+in others, so I abandoned this code. */
+
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define NLBLOCK md             /* Block containing newline information */
+#define PSSTART start_subject  /* Field containing processed string start */
+#define PSEND   end_subject    /* Field containing processed string end */
+
+#include "pcre_internal.h"
+
+
+/* For use to indent debugging output */
+
+#define SP "                   "
+
+
+/*************************************************
+*      Code parameters and static tables         *
+*************************************************/
+
+/* These are offsets that are used to turn the OP_TYPESTAR and friends opcodes
+into others, under special conditions. A gap of 20 between the blocks should be
+enough. The resulting opcodes don't have to be less than 256 because they are
+never stored, so we push them well clear of the normal opcodes. */
+
+#define OP_PROP_EXTRA       300
+#define OP_EXTUNI_EXTRA     320
+#define OP_ANYNL_EXTRA      340
+#define OP_HSPACE_EXTRA     360
+#define OP_VSPACE_EXTRA     380
+
+
+/* This table identifies those opcodes that are followed immediately by a
+character that is to be tested in some way. This makes is possible to
+centralize the loading of these characters. In the case of Type * etc, the
+"character" is the opcode for \D, \d, \S, \s, \W, or \w, which will always be a
+small value. Non-zero values in the table are the offsets from the opcode where
+the character is to be found. ***NOTE*** If the start of this table is
+modified, the three tables that follow must also be modified. */
+
+static const uschar coptable[] = {
+  0,                             /* End                                    */
+  0, 0, 0, 0, 0,                 /* \A, \G, \K, \B, \b                     */
+  0, 0, 0, 0, 0, 0,              /* \D, \d, \S, \s, \W, \w                 */
+  0, 0, 0,                       /* Any, AllAny, Anybyte                   */
+  0, 0,                          /* \P, \p                                 */
+  0, 0, 0, 0, 0,                 /* \R, \H, \h, \V, \v                     */
+  0,                             /* \X                                     */
+  0, 0, 0, 0, 0,                 /* \Z, \z, Opt, ^, $                      */
+  1,                             /* Char                                   */
+  1,                             /* Charnc                                 */
+  1,                             /* not                                    */
+  /* Positive single-char repeats                                          */
+  1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */
+  3, 3, 3,                       /* upto, minupto, exact                   */
+  1, 1, 1, 3,                    /* *+, ++, ?+, upto+                      */
+  /* Negative single-char repeats - only for chars < 256                   */
+  1, 1, 1, 1, 1, 1,              /* NOT *, *?, +, +?, ?, ??                */
+  3, 3, 3,                       /* NOT upto, minupto, exact               */
+  1, 1, 1, 3,                    /* NOT *+, ++, ?+, updo+                  */
+  /* Positive type repeats                                                 */
+  1, 1, 1, 1, 1, 1,              /* Type *, *?, +, +?, ?, ??               */
+  3, 3, 3,                       /* Type upto, minupto, exact              */
+  1, 1, 1, 3,                    /* Type *+, ++, ?+, upto+                 */
+  /* Character class & ref repeats                                         */
+  0, 0, 0, 0, 0, 0,              /* *, *?, +, +?, ?, ??                    */
+  0, 0,                          /* CRRANGE, CRMINRANGE                    */
+  0,                             /* CLASS                                  */
+  0,                             /* NCLASS                                 */
+  0,                             /* XCLASS - variable length               */
+  0,                             /* REF                                    */
+  0,                             /* RECURSE                                */
+  0,                             /* CALLOUT                                */
+  0,                             /* Alt                                    */
+  0,                             /* Ket                                    */
+  0,                             /* KetRmax                                */
+  0,                             /* KetRmin                                */
+  0,                             /* Assert                                 */
+  0,                             /* Assert not                             */
+  0,                             /* Assert behind                          */
+  0,                             /* Assert behind not                      */
+  0,                             /* Reverse                                */
+  0, 0, 0, 0,                    /* ONCE, BRA, CBRA, COND                  */
+  0, 0, 0,                       /* SBRA, SCBRA, SCOND                     */
+  0, 0,                          /* CREF, NCREF                            */
+  0, 0,                          /* RREF, NRREF                            */
+  0,                             /* DEF                                    */
+  0, 0,                          /* BRAZERO, BRAMINZERO                    */
+  0, 0, 0, 0,                    /* PRUNE, SKIP, THEN, COMMIT              */
+  0, 0, 0, 0                     /* FAIL, ACCEPT, CLOSE, SKIPZERO          */
+};
+
+/* This table identifies those opcodes that inspect a character. It is used to
+remember the fact that a character could have been inspected when the end of
+the subject is reached. ***NOTE*** If the start of this table is modified, the
+two tables that follow must also be modified. */
+
+static const uschar poptable[] = {
+  0,                             /* End                                    */
+  0, 0, 0, 1, 1,                 /* \A, \G, \K, \B, \b                     */
+  1, 1, 1, 1, 1, 1,              /* \D, \d, \S, \s, \W, \w                 */
+  1, 1, 1,                       /* Any, AllAny, Anybyte                   */
+  1, 1,                          /* \P, \p                                 */
+  1, 1, 1, 1, 1,                 /* \R, \H, \h, \V, \v                     */
+  1,                             /* \X                                     */
+  0, 0, 0, 0, 0,                 /* \Z, \z, Opt, ^, $                      */
+  1,                             /* Char                                   */
+  1,                             /* Charnc                                 */
+  1,                             /* not                                    */
+  /* Positive single-char repeats                                          */
+  1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */
+  1, 1, 1,                       /* upto, minupto, exact                   */
+  1, 1, 1, 1,                    /* *+, ++, ?+, upto+                      */
+  /* Negative single-char repeats - only for chars < 256                   */
+  1, 1, 1, 1, 1, 1,              /* NOT *, *?, +, +?, ?, ??                */
+  1, 1, 1,                       /* NOT upto, minupto, exact               */
+  1, 1, 1, 1,                    /* NOT *+, ++, ?+, upto+                  */
+  /* Positive type repeats                                                 */
+  1, 1, 1, 1, 1, 1,              /* Type *, *?, +, +?, ?, ??               */
+  1, 1, 1,                       /* Type upto, minupto, exact              */
+  1, 1, 1, 1,                    /* Type *+, ++, ?+, upto+                 */
+  /* Character class & ref repeats                                         */
+  1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */
+  1, 1,                          /* CRRANGE, CRMINRANGE                    */
+  1,                             /* CLASS                                  */
+  1,                             /* NCLASS                                 */
+  1,                             /* XCLASS - variable length               */
+  0,                             /* REF                                    */
+  0,                             /* RECURSE                                */
+  0,                             /* CALLOUT                                */
+  0,                             /* Alt                                    */
+  0,                             /* Ket                                    */
+  0,                             /* KetRmax                                */
+  0,                             /* KetRmin                                */
+  0,                             /* Assert                                 */
+  0,                             /* Assert not                             */
+  0,                             /* Assert behind                          */
+  0,                             /* Assert behind not                      */
+  0,                             /* Reverse                                */
+  0, 0, 0, 0,                    /* ONCE, BRA, CBRA, COND                  */
+  0, 0, 0,                       /* SBRA, SCBRA, SCOND                     */
+  0, 0,                          /* CREF, NCREF                            */
+  0, 0,                          /* RREF, NRREF                            */
+  0,                             /* DEF                                    */
+  0, 0,                          /* BRAZERO, BRAMINZERO                    */
+  0, 0, 0, 0,                    /* PRUNE, SKIP, THEN, COMMIT              */
+  0, 0, 0, 0                     /* FAIL, ACCEPT, CLOSE, SKIPZERO          */
+};
+
+/* These 2 tables allow for compact code for testing for \D, \d, \S, \s, \W,
+and \w */
+
+static const uschar toptable1[] = {
+  0, 0, 0, 0, 0, 0,
+  ctype_digit, ctype_digit,
+  ctype_space, ctype_space,
+  ctype_word,  ctype_word,
+  0, 0                            /* OP_ANY, OP_ALLANY */
+};
+
+static const uschar toptable2[] = {
+  0, 0, 0, 0, 0, 0,
+  ctype_digit, 0,
+  ctype_space, 0,
+  ctype_word,  0,
+  1, 1                            /* OP_ANY, OP_ALLANY */
+};
+
+
+/* Structure for holding data about a particular state, which is in effect the
+current data for an active path through the match tree. It must consist
+entirely of ints because the working vector we are passed, and which we put
+these structures in, is a vector of ints. */
+
+typedef struct stateblock {
+  int offset;                     /* Offset to opcode */
+  int count;                      /* Count for repeats */
+  int ims;                        /* ims flag bits */
+  int data;                       /* Some use extra data */
+} stateblock;
+
+#define INTS_PER_STATEBLOCK  (sizeof(stateblock)/sizeof(int))
+
+
+#ifdef PCRE_DEBUG
+/*************************************************
+*             Print character string             *
+*************************************************/
+
+/* Character string printing function for debugging.
+
+Arguments:
+  p            points to string
+  length       number of bytes
+  f            where to print
+
+Returns:       nothing
+*/
+
+static void
+pchars(unsigned char *p, int length, FILE *f)
+{
+int c;
+while (length-- > 0)
+  {
+  if (isprint(c = *(p++)))
+    fprintf(f, "%c", c);
+  else
+    fprintf(f, "\\x%02x", c);
+  }
+}
+#endif
+
+
+
+/*************************************************
+*    Execute a Regular Expression - DFA engine   *
+*************************************************/
+
+/* This internal function applies a compiled pattern to a subject string,
+starting at a given point, using a DFA engine. This function is called from the
+external one, possibly multiple times if the pattern is not anchored. The
+function calls itself recursively for some kinds of subpattern.
+
+Arguments:
+  md                the match_data block with fixed information
+  this_start_code   the opening bracket of this subexpression's code
+  current_subject   where we currently are in the subject string
+  start_offset      start offset in the subject string
+  offsets           vector to contain the matching string offsets
+  offsetcount       size of same
+  workspace         vector of workspace
+  wscount           size of same
+  ims               the current ims flags
+  rlevel            function call recursion level
+  recursing         regex recursive call level
+
+Returns:            > 0 => number of match offset pairs placed in offsets
+                    = 0 => offsets overflowed; longest matches are present
+                     -1 => failed to match
+                   < -1 => some kind of unexpected problem
+
+The following macros are used for adding states to the two state vectors (one
+for the current character, one for the following character). */
+
+#define ADD_ACTIVE(x,y) \
+  if (active_count++ < wscount) \
+    { \
+    next_active_state->offset = (x); \
+    next_active_state->count  = (y); \
+    next_active_state->ims    = ims; \
+    next_active_state++; \
+    DPRINTF(("%.*sADD_ACTIVE(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
+    } \
+  else return PCRE_ERROR_DFA_WSSIZE
+
+#define ADD_ACTIVE_DATA(x,y,z) \
+  if (active_count++ < wscount) \
+    { \
+    next_active_state->offset = (x); \
+    next_active_state->count  = (y); \
+    next_active_state->ims    = ims; \
+    next_active_state->data   = (z); \
+    next_active_state++; \
+    DPRINTF(("%.*sADD_ACTIVE_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
+    } \
+  else return PCRE_ERROR_DFA_WSSIZE
+
+#define ADD_NEW(x,y) \
+  if (new_count++ < wscount) \
+    { \
+    next_new_state->offset = (x); \
+    next_new_state->count  = (y); \
+    next_new_state->ims    = ims; \
+    next_new_state++; \
+    DPRINTF(("%.*sADD_NEW(%d,%d)\n", rlevel*2-2, SP, (x), (y))); \
+    } \
+  else return PCRE_ERROR_DFA_WSSIZE
+
+#define ADD_NEW_DATA(x,y,z) \
+  if (new_count++ < wscount) \
+    { \
+    next_new_state->offset = (x); \
+    next_new_state->count  = (y); \
+    next_new_state->ims    = ims; \
+    next_new_state->data   = (z); \
+    next_new_state++; \
+    DPRINTF(("%.*sADD_NEW_DATA(%d,%d,%d)\n", rlevel*2-2, SP, (x), (y), (z))); \
+    } \
+  else return PCRE_ERROR_DFA_WSSIZE
+
+/* And now, here is the code */
+
+static int
+internal_dfa_exec(
+  dfa_match_data *md,
+  const uschar *this_start_code,
+  const uschar *current_subject,
+  int start_offset,
+  int *offsets,
+  int offsetcount,
+  int *workspace,
+  int wscount,
+  int ims,
+  int  rlevel,
+  int  recursing)
+{
+stateblock *active_states, *new_states, *temp_states;
+stateblock *next_active_state, *next_new_state;
+
+const uschar *ctypes, *lcc, *fcc;
+const uschar *ptr;
+const uschar *end_code, *first_op;
+
+int active_count, new_count, match_count;
+
+/* Some fields in the md block are frequently referenced, so we load them into
+independent variables in the hope that this will perform better. */
+
+const uschar *start_subject = md->start_subject;
+const uschar *end_subject = md->end_subject;
+const uschar *start_code = md->start_code;
+
+#ifdef SUPPORT_UTF8
+BOOL utf8 = (md->poptions & PCRE_UTF8) != 0;
+#else
+BOOL utf8 = FALSE;
+#endif
+
+rlevel++;
+offsetcount &= (-2);
+
+wscount -= 2;
+wscount = (wscount - (wscount % (INTS_PER_STATEBLOCK * 2))) /
+          (2 * INTS_PER_STATEBLOCK);
+
+DPRINTF(("\n%.*s---------------------\n"
+  "%.*sCall to internal_dfa_exec f=%d r=%d\n",
+  rlevel*2-2, SP, rlevel*2-2, SP, rlevel, recursing));
+
+ctypes = md->tables + ctypes_offset;
+lcc = md->tables + lcc_offset;
+fcc = md->tables + fcc_offset;
+
+match_count = PCRE_ERROR_NOMATCH;   /* A negative number */
+
+active_states = (stateblock *)(workspace + 2);
+next_new_state = new_states = active_states + wscount;
+new_count = 0;
+
+first_op = this_start_code + 1 + LINK_SIZE +
+  ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0);
+
+/* The first thing in any (sub) pattern is a bracket of some sort. Push all
+the alternative states onto the list, and find out where the end is. This
+makes is possible to use this function recursively, when we want to stop at a
+matching internal ket rather than at the end.
+
+If the first opcode in the first alternative is OP_REVERSE, we are dealing with
+a backward assertion. In that case, we have to find out the maximum amount to
+move back, and set up each alternative appropriately. */
+
+if (*first_op == OP_REVERSE)
+  {
+  int max_back = 0;
+  int gone_back;
+
+  end_code = this_start_code;
+  do
+    {
+    int back = GET(end_code, 2+LINK_SIZE);
+    if (back > max_back) max_back = back;
+    end_code += GET(end_code, 1);
+    }
+  while (*end_code == OP_ALT);
+
+  /* If we can't go back the amount required for the longest lookbehind
+  pattern, go back as far as we can; some alternatives may still be viable. */
+
+#ifdef SUPPORT_UTF8
+  /* In character mode we have to step back character by character */
+
+  if (utf8)
+    {
+    for (gone_back = 0; gone_back < max_back; gone_back++)
+      {
+      if (current_subject <= start_subject) break;
+      current_subject--;
+      while (current_subject > start_subject &&
+             (*current_subject & 0xc0) == 0x80)
+        current_subject--;
+      }
+    }
+  else
+#endif
+
+  /* In byte-mode we can do this quickly. */
+
+    {
+    gone_back = (current_subject - max_back < start_subject)?
+      current_subject - start_subject : max_back;
+    current_subject -= gone_back;
+    }
+
+  /* Save the earliest consulted character */
+
+  if (current_subject < md->start_used_ptr)
+    md->start_used_ptr = current_subject;
+
+  /* Now we can process the individual branches. */
+
+  end_code = this_start_code;
+  do
+    {
+    int back = GET(end_code, 2+LINK_SIZE);
+    if (back <= gone_back)
+      {
+      int bstate = end_code - start_code + 2 + 2*LINK_SIZE;
+      ADD_NEW_DATA(-bstate, 0, gone_back - back);
+      }
+    end_code += GET(end_code, 1);
+    }
+  while (*end_code == OP_ALT);
+ }
+
+/* This is the code for a "normal" subpattern (not a backward assertion). The
+start of a whole pattern is always one of these. If we are at the top level,
+we may be asked to restart matching from the same point that we reached for a
+previous partial match. We still have to scan through the top-level branches to
+find the end state. */
+
+else
+  {
+  end_code = this_start_code;
+
+  /* Restarting */
+
+  if (rlevel == 1 && (md->moptions & PCRE_DFA_RESTART) != 0)
+    {
+    do { end_code += GET(end_code, 1); } while (*end_code == OP_ALT);
+    new_count = workspace[1];
+    if (!workspace[0])
+      memcpy(new_states, active_states, new_count * sizeof(stateblock));
+    }
+
+  /* Not restarting */
+
+  else
+    {
+    int length = 1 + LINK_SIZE +
+      ((*this_start_code == OP_CBRA || *this_start_code == OP_SCBRA)? 2:0);
+    do
+      {
+      ADD_NEW(end_code - start_code + length, 0);
+      end_code += GET(end_code, 1);
+      length = 1 + LINK_SIZE;
+      }
+    while (*end_code == OP_ALT);
+    }
+  }
+
+workspace[0] = 0;    /* Bit indicating which vector is current */
+
+DPRINTF(("%.*sEnd state = %d\n", rlevel*2-2, SP, end_code - start_code));
+
+/* Loop for scanning the subject */
+
+ptr = current_subject;
+for (;;)
+  {
+  int i, j;
+  int clen, dlen;
+  unsigned int c, d;
+  int forced_fail = 0;
+  BOOL could_continue = FALSE;
+
+  /* Make the new state list into the active state list and empty the
+  new state list. */
+
+  temp_states = active_states;
+  active_states = new_states;
+  new_states = temp_states;
+  active_count = new_count;
+  new_count = 0;
+
+  workspace[0] ^= 1;              /* Remember for the restarting feature */
+  workspace[1] = active_count;
+
+#ifdef PCRE_DEBUG
+  printf("%.*sNext character: rest of subject = \"", rlevel*2-2, SP);
+  pchars((uschar *)ptr, strlen((char *)ptr), stdout);
+  printf("\"\n");
+
+  printf("%.*sActive states: ", rlevel*2-2, SP);
+  for (i = 0; i < active_count; i++)
+    printf("%d/%d ", active_states[i].offset, active_states[i].count);
+  printf("\n");
+#endif
+
+  /* Set the pointers for adding new states */
+
+  next_active_state = active_states + active_count;
+  next_new_state = new_states;
+
+  /* Load the current character from the subject outside the loop, as many
+  different states may want to look at it, and we assume that at least one
+  will. */
+
+  if (ptr < end_subject)
+    {
+    clen = 1;        /* Number of bytes in the character */
+#ifdef SUPPORT_UTF8
+    if (utf8) { GETCHARLEN(c, ptr, clen); } else
+#endif  /* SUPPORT_UTF8 */
+    c = *ptr;
+    }
+  else
+    {
+    clen = 0;        /* This indicates the end of the subject */
+    c = NOTACHAR;    /* This value should never actually be used */
+    }
+
+  /* Scan up the active states and act on each one. The result of an action
+  may be to add more states to the currently active list (e.g. on hitting a
+  parenthesis) or it may be to put states on the new list, for considering
+  when we move the character pointer on. */
+
+  for (i = 0; i < active_count; i++)
+    {
+    stateblock *current_state = active_states + i;
+    const uschar *code;
+    int state_offset = current_state->offset;
+    int count, codevalue, rrc;
+
+#ifdef PCRE_DEBUG
+    printf ("%.*sProcessing state %d c=", rlevel*2-2, SP, state_offset);
+    if (clen == 0) printf("EOL\n");
+      else if (c > 32 && c < 127) printf("'%c'\n", c);
+        else printf("0x%02x\n", c);
+#endif
+
+    /* This variable is referred to implicity in the ADD_xxx macros. */
+
+    ims = current_state->ims;
+
+    /* A negative offset is a special case meaning "hold off going to this
+    (negated) state until the number of characters in the data field have
+    been skipped". */
+
+    if (state_offset < 0)
+      {
+      if (current_state->data > 0)
+        {
+        DPRINTF(("%.*sSkipping this character\n", rlevel*2-2, SP));
+        ADD_NEW_DATA(state_offset, current_state->count,
+          current_state->data - 1);
+        continue;
+        }
+      else
+        {
+        current_state->offset = state_offset = -state_offset;
+        }
+      }
+
+    /* Check for a duplicate state with the same count, and skip if found.
+    See the note at the head of this module about the possibility of improving
+    performance here. */
+
+    for (j = 0; j < i; j++)
+      {
+      if (active_states[j].offset == state_offset &&
+          active_states[j].count == current_state->count)
+        {
+        DPRINTF(("%.*sDuplicate state: skipped\n", rlevel*2-2, SP));
+        goto NEXT_ACTIVE_STATE;
+        }
+      }
+
+    /* The state offset is the offset to the opcode */
+
+    code = start_code + state_offset;
+    codevalue = *code;
+
+    /* If this opcode inspects a character, but we are at the end of the
+    subject, remember the fact for use when testing for a partial match. */
+
+    if (clen == 0 && poptable[codevalue] != 0)
+      could_continue = TRUE;
+
+    /* If this opcode is followed by an inline character, load it. It is
+    tempting to test for the presence of a subject character here, but that
+    is wrong, because sometimes zero repetitions of the subject are
+    permitted.
+
+    We also use this mechanism for opcodes such as OP_TYPEPLUS that take an
+    argument that is not a data character - but is always one byte long. We
+    have to take special action to deal with  \P, \p, \H, \h, \V, \v and \X in
+    this case. To keep the other cases fast, convert these ones to new opcodes.
+    */
+
+    if (coptable[codevalue] > 0)
+      {
+      dlen = 1;
+#ifdef SUPPORT_UTF8
+      if (utf8) { GETCHARLEN(d, (code + coptable[codevalue]), dlen); } else
+#endif  /* SUPPORT_UTF8 */
+      d = code[coptable[codevalue]];
+      if (codevalue >= OP_TYPESTAR)
+        {
+        switch(d)
+          {
+          case OP_ANYBYTE: return PCRE_ERROR_DFA_UITEM;
+          case OP_NOTPROP:
+          case OP_PROP: codevalue += OP_PROP_EXTRA; break;
+          case OP_ANYNL: codevalue += OP_ANYNL_EXTRA; break;
+          case OP_EXTUNI: codevalue += OP_EXTUNI_EXTRA; break;
+          case OP_NOT_HSPACE:
+          case OP_HSPACE: codevalue += OP_HSPACE_EXTRA; break;
+          case OP_NOT_VSPACE:
+          case OP_VSPACE: codevalue += OP_VSPACE_EXTRA; break;
+          default: break;
+          }
+        }
+      }
+    else
+      {
+      dlen = 0;         /* Not strictly necessary, but compilers moan */
+      d = NOTACHAR;     /* if these variables are not set. */
+      }
+
+
+    /* Now process the individual opcodes */
+
+    switch (codevalue)
+      {
+/* ========================================================================== */
+      /* These cases are never obeyed. This is a fudge that causes a compile-
+      time error if the vectors coptable or poptable, which are indexed by
+      opcode, are not the correct length. It seems to be the only way to do
+      such a check at compile time, as the sizeof() operator does not work
+      in the C preprocessor. */
+
+      case OP_TABLE_LENGTH:
+      case OP_TABLE_LENGTH +
+        ((sizeof(coptable) == OP_TABLE_LENGTH) &&
+         (sizeof(poptable) == OP_TABLE_LENGTH)):
+      break;
+
+/* ========================================================================== */
+      /* Reached a closing bracket. If not at the end of the pattern, carry
+      on with the next opcode. Otherwise, unless we have an empty string and
+      PCRE_NOTEMPTY is set, or PCRE_NOTEMPTY_ATSTART is set and we are at the
+      start of the subject, save the match data, shifting up all previous
+      matches so we always have the longest first. */
+
+      case OP_KET:
+      case OP_KETRMIN:
+      case OP_KETRMAX:
+      if (code != end_code)
+        {
+        ADD_ACTIVE(state_offset + 1 + LINK_SIZE, 0);
+        if (codevalue != OP_KET)
+          {
+          ADD_ACTIVE(state_offset - GET(code, 1), 0);
+          }
+        }
+      else
+        {
+        if (ptr > current_subject ||
+            ((md->moptions & PCRE_NOTEMPTY) == 0 &&
+              ((md->moptions & PCRE_NOTEMPTY_ATSTART) == 0 ||
+                current_subject > start_subject + md->start_offset)))
+          {
+          if (match_count < 0) match_count = (offsetcount >= 2)? 1 : 0;
+            else if (match_count > 0 && ++match_count * 2 >= offsetcount)
+              match_count = 0;
+          count = ((match_count == 0)? offsetcount : match_count * 2) - 2;
+          if (count > 0) memmove(offsets + 2, offsets, count * sizeof(int));
+          if (offsetcount >= 2)
+            {
+            offsets[0] = current_subject - start_subject;
+            offsets[1] = ptr - start_subject;
+            DPRINTF(("%.*sSet matched string = \"%.*s\"\n", rlevel*2-2, SP,
+              offsets[1] - offsets[0], current_subject));
+            }
+          if ((md->moptions & PCRE_DFA_SHORTEST) != 0)
+            {
+            DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
+              "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel,
+              match_count, rlevel*2-2, SP));
+            return match_count;
+            }
+          }
+        }
+      break;
+
+/* ========================================================================== */
+      /* These opcodes add to the current list of states without looking
+      at the current character. */
+
+      /*-----------------------------------------------------------------*/
+      case OP_ALT:
+      do { code += GET(code, 1); } while (*code == OP_ALT);
+      ADD_ACTIVE(code - start_code, 0);
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_BRA:
+      case OP_SBRA:
+      do
+        {
+        ADD_ACTIVE(code - start_code + 1 + LINK_SIZE, 0);
+        code += GET(code, 1);
+        }
+      while (*code == OP_ALT);
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_CBRA:
+      case OP_SCBRA:
+      ADD_ACTIVE(code - start_code + 3 + LINK_SIZE,  0);
+      code += GET(code, 1);
+      while (*code == OP_ALT)
+        {
+        ADD_ACTIVE(code - start_code + 1 + LINK_SIZE,  0);
+        code += GET(code, 1);
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_BRAZERO:
+      case OP_BRAMINZERO:
+      ADD_ACTIVE(state_offset + 1, 0);
+      code += 1 + GET(code, 2);
+      while (*code == OP_ALT) code += GET(code, 1);
+      ADD_ACTIVE(code - start_code + 1 + LINK_SIZE, 0);
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_SKIPZERO:
+      code += 1 + GET(code, 2);
+      while (*code == OP_ALT) code += GET(code, 1);
+      ADD_ACTIVE(code - start_code + 1 + LINK_SIZE, 0);
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_CIRC:
+      if ((ptr == start_subject && (md->moptions & PCRE_NOTBOL) == 0) ||
+          ((ims & PCRE_MULTILINE) != 0 &&
+            ptr != end_subject &&
+            WAS_NEWLINE(ptr)))
+        { ADD_ACTIVE(state_offset + 1, 0); }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_EOD:
+      if (ptr >= end_subject) { ADD_ACTIVE(state_offset + 1, 0); }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_OPT:
+      ims = code[1];
+      ADD_ACTIVE(state_offset + 2, 0);
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_SOD:
+      if (ptr == start_subject) { ADD_ACTIVE(state_offset + 1, 0); }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_SOM:
+      if (ptr == start_subject + start_offset) { ADD_ACTIVE(state_offset + 1, 0); }
+      break;
+
+
+/* ========================================================================== */
+      /* These opcodes inspect the next subject character, and sometimes
+      the previous one as well, but do not have an argument. The variable
+      clen contains the length of the current character and is zero if we are
+      at the end of the subject. */
+
+      /*-----------------------------------------------------------------*/
+      case OP_ANY:
+      if (clen > 0 && !IS_NEWLINE(ptr))
+        { ADD_NEW(state_offset + 1, 0); }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_ALLANY:
+      if (clen > 0)
+        { ADD_NEW(state_offset + 1, 0); }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_EODN:
+      if (clen == 0 || (IS_NEWLINE(ptr) && ptr == end_subject - md->nllen))
+        { ADD_ACTIVE(state_offset + 1, 0); }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_DOLL:
+      if ((md->moptions & PCRE_NOTEOL) == 0)
+        {
+        if (clen == 0 ||
+            ((md->poptions & PCRE_DOLLAR_ENDONLY) == 0 && IS_NEWLINE(ptr) &&
+               ((ims & PCRE_MULTILINE) != 0 || ptr == end_subject - md->nllen)
+            ))
+          { ADD_ACTIVE(state_offset + 1, 0); }
+        }
+      else if ((ims & PCRE_MULTILINE) != 0 && IS_NEWLINE(ptr))
+        { ADD_ACTIVE(state_offset + 1, 0); }
+      break;
+
+      /*-----------------------------------------------------------------*/
+
+      case OP_DIGIT:
+      case OP_WHITESPACE:
+      case OP_WORDCHAR:
+      if (clen > 0 && c < 256 &&
+            ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0)
+        { ADD_NEW(state_offset + 1, 0); }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_NOT_DIGIT:
+      case OP_NOT_WHITESPACE:
+      case OP_NOT_WORDCHAR:
+      if (clen > 0 && (c >= 256 ||
+            ((ctypes[c] & toptable1[codevalue]) ^ toptable2[codevalue]) != 0))
+        { ADD_NEW(state_offset + 1, 0); }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_WORD_BOUNDARY:
+      case OP_NOT_WORD_BOUNDARY:
+        {
+        int left_word, right_word;
+
+        if (ptr > start_subject)
+          {
+          const uschar *temp = ptr - 1;
+          if (temp < md->start_used_ptr) md->start_used_ptr = temp;
+#ifdef SUPPORT_UTF8
+          if (utf8) BACKCHAR(temp);
+#endif
+          GETCHARTEST(d, temp);
+          left_word = d < 256 && (ctypes[d] & ctype_word) != 0;
+          }
+        else left_word = 0;
+
+        if (clen > 0)
+          right_word = c < 256 && (ctypes[c] & ctype_word) != 0;
+        else right_word = 0;
+
+        if ((left_word == right_word) == (codevalue == OP_NOT_WORD_BOUNDARY))
+          { ADD_ACTIVE(state_offset + 1, 0); }
+        }
+      break;
+
+
+      /*-----------------------------------------------------------------*/
+      /* Check the next character by Unicode property. We will get here only
+      if the support is in the binary; otherwise a compile-time error occurs.
+      */
+
+#ifdef SUPPORT_UCP
+      case OP_PROP:
+      case OP_NOTPROP:
+      if (clen > 0)
+        {
+        BOOL OK;
+        int chartype = UCD_CHARTYPE(c);
+        switch(code[1])
+          {
+          case PT_ANY:
+          OK = TRUE;
+          break;
+
+          case PT_LAMP:
+          OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
+          break;
+
+          case PT_GC:
+          OK = _pcre_ucp_gentype[chartype] == code[2];
+          break;
+
+          case PT_PC:
+          OK = chartype == code[2];
+          break;
+
+          case PT_SC:
+          OK = UCD_SCRIPT(c) == code[2];
+          break;
+
+          /* Should never occur, but keep compilers from grumbling. */
+
+          default:
+          OK = codevalue != OP_PROP;
+          break;
+          }
+
+        if (OK == (codevalue == OP_PROP)) { ADD_NEW(state_offset + 3, 0); }
+        }
+      break;
+#endif
+
+
+
+/* ========================================================================== */
+      /* These opcodes likewise inspect the subject character, but have an
+      argument that is not a data character. It is one of these opcodes:
+      OP_ANY, OP_ALLANY, OP_DIGIT, OP_NOT_DIGIT, OP_WHITESPACE, OP_NOT_SPACE,
+      OP_WORDCHAR, OP_NOT_WORDCHAR. The value is loaded into d. */
+
+      case OP_TYPEPLUS:
+      case OP_TYPEMINPLUS:
+      case OP_TYPEPOSPLUS:
+      count = current_state->count;  /* Already matched */
+      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+      if (clen > 0)
+        {
+        if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+            (c < 256 &&
+              (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+          {
+          if (count > 0 && codevalue == OP_TYPEPOSPLUS)
+            {
+            active_count--;            /* Remove non-match possibility */
+            next_active_state--;
+            }
+          count++;
+          ADD_NEW(state_offset, count);
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_TYPEQUERY:
+      case OP_TYPEMINQUERY:
+      case OP_TYPEPOSQUERY:
+      ADD_ACTIVE(state_offset + 2, 0);
+      if (clen > 0)
+        {
+        if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+            (c < 256 &&
+              (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+          {
+          if (codevalue == OP_TYPEPOSQUERY)
+            {
+            active_count--;            /* Remove non-match possibility */
+            next_active_state--;
+            }
+          ADD_NEW(state_offset + 2, 0);
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_TYPESTAR:
+      case OP_TYPEMINSTAR:
+      case OP_TYPEPOSSTAR:
+      ADD_ACTIVE(state_offset + 2, 0);
+      if (clen > 0)
+        {
+        if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+            (c < 256 &&
+              (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+          {
+          if (codevalue == OP_TYPEPOSSTAR)
+            {
+            active_count--;            /* Remove non-match possibility */
+            next_active_state--;
+            }
+          ADD_NEW(state_offset, 0);
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_TYPEEXACT:
+      count = current_state->count;  /* Number already matched */
+      if (clen > 0)
+        {
+        if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+            (c < 256 &&
+              (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+          {
+          if (++count >= GET2(code, 1))
+            { ADD_NEW(state_offset + 4, 0); }
+          else
+            { ADD_NEW(state_offset, count); }
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_TYPEUPTO:
+      case OP_TYPEMINUPTO:
+      case OP_TYPEPOSUPTO:
+      ADD_ACTIVE(state_offset + 4, 0);
+      count = current_state->count;  /* Number already matched */
+      if (clen > 0)
+        {
+        if ((c >= 256 && d != OP_DIGIT && d != OP_WHITESPACE && d != OP_WORDCHAR) ||
+            (c < 256 &&
+              (d != OP_ANY || !IS_NEWLINE(ptr)) &&
+              ((ctypes[c] & toptable1[d]) ^ toptable2[d]) != 0))
+          {
+          if (codevalue == OP_TYPEPOSUPTO)
+            {
+            active_count--;           /* Remove non-match possibility */
+            next_active_state--;
+            }
+          if (++count >= GET2(code, 1))
+            { ADD_NEW(state_offset + 4, 0); }
+          else
+            { ADD_NEW(state_offset, count); }
+          }
+        }
+      break;
+
+/* ========================================================================== */
+      /* These are virtual opcodes that are used when something like
+      OP_TYPEPLUS has OP_PROP, OP_NOTPROP, OP_ANYNL, or OP_EXTUNI as its
+      argument. It keeps the code above fast for the other cases. The argument
+      is in the d variable. */
+
+#ifdef SUPPORT_UCP
+      case OP_PROP_EXTRA + OP_TYPEPLUS:
+      case OP_PROP_EXTRA + OP_TYPEMINPLUS:
+      case OP_PROP_EXTRA + OP_TYPEPOSPLUS:
+      count = current_state->count;           /* Already matched */
+      if (count > 0) { ADD_ACTIVE(state_offset + 4, 0); }
+      if (clen > 0)
+        {
+        BOOL OK;
+        int chartype = UCD_CHARTYPE(c);
+        switch(code[2])
+          {
+          case PT_ANY:
+          OK = TRUE;
+          break;
+
+          case PT_LAMP:
+          OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
+          break;
+
+          case PT_GC:
+          OK = _pcre_ucp_gentype[chartype] == code[3];
+          break;
+
+          case PT_PC:
+          OK = chartype == code[3];
+          break;
+
+          case PT_SC:
+          OK = UCD_SCRIPT(c) == code[3];
+          break;
+
+          /* Should never occur, but keep compilers from grumbling. */
+
+          default:
+          OK = codevalue != OP_PROP;
+          break;
+          }
+
+        if (OK == (d == OP_PROP))
+          {
+          if (count > 0 && codevalue == OP_PROP_EXTRA + OP_TYPEPOSPLUS)
+            {
+            active_count--;           /* Remove non-match possibility */
+            next_active_state--;
+            }
+          count++;
+          ADD_NEW(state_offset, count);
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_EXTUNI_EXTRA + OP_TYPEPLUS:
+      case OP_EXTUNI_EXTRA + OP_TYPEMINPLUS:
+      case OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS:
+      count = current_state->count;  /* Already matched */
+      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+      if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
+        {
+        const uschar *nptr = ptr + clen;
+        int ncount = 0;
+        if (count > 0 && codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSPLUS)
+          {
+          active_count--;           /* Remove non-match possibility */
+          next_active_state--;
+          }
+        while (nptr < end_subject)
+          {
+          int nd;
+          int ndlen = 1;
+          GETCHARLEN(nd, nptr, ndlen);
+          if (UCD_CATEGORY(nd) != ucp_M) break;
+          ncount++;
+          nptr += ndlen;
+          }
+        count++;
+        ADD_NEW_DATA(-state_offset, count, ncount);
+        }
+      break;
+#endif
+
+      /*-----------------------------------------------------------------*/
+      case OP_ANYNL_EXTRA + OP_TYPEPLUS:
+      case OP_ANYNL_EXTRA + OP_TYPEMINPLUS:
+      case OP_ANYNL_EXTRA + OP_TYPEPOSPLUS:
+      count = current_state->count;  /* Already matched */
+      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+      if (clen > 0)
+        {
+        int ncount = 0;
+        switch (c)
+          {
+          case 0x000b:
+          case 0x000c:
+          case 0x0085:
+          case 0x2028:
+          case 0x2029:
+          if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
+          goto ANYNL01;
+
+          case 0x000d:
+          if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
+          /* Fall through */
+
+          ANYNL01:
+          case 0x000a:
+          if (count > 0 && codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSPLUS)
+            {
+            active_count--;           /* Remove non-match possibility */
+            next_active_state--;
+            }
+          count++;
+          ADD_NEW_DATA(-state_offset, count, ncount);
+          break;
+
+          default:
+          break;
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_VSPACE_EXTRA + OP_TYPEPLUS:
+      case OP_VSPACE_EXTRA + OP_TYPEMINPLUS:
+      case OP_VSPACE_EXTRA + OP_TYPEPOSPLUS:
+      count = current_state->count;  /* Already matched */
+      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+      if (clen > 0)
+        {
+        BOOL OK;
+        switch (c)
+          {
+          case 0x000a:
+          case 0x000b:
+          case 0x000c:
+          case 0x000d:
+          case 0x0085:
+          case 0x2028:
+          case 0x2029:
+          OK = TRUE;
+          break;
+
+          default:
+          OK = FALSE;
+          break;
+          }
+
+        if (OK == (d == OP_VSPACE))
+          {
+          if (count > 0 && codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSPLUS)
+            {
+            active_count--;           /* Remove non-match possibility */
+            next_active_state--;
+            }
+          count++;
+          ADD_NEW_DATA(-state_offset, count, 0);
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_HSPACE_EXTRA + OP_TYPEPLUS:
+      case OP_HSPACE_EXTRA + OP_TYPEMINPLUS:
+      case OP_HSPACE_EXTRA + OP_TYPEPOSPLUS:
+      count = current_state->count;  /* Already matched */
+      if (count > 0) { ADD_ACTIVE(state_offset + 2, 0); }
+      if (clen > 0)
+        {
+        BOOL OK;
+        switch (c)
+          {
+          case 0x09:      /* HT */
+          case 0x20:      /* SPACE */
+          case 0xa0:      /* NBSP */
+          case 0x1680:    /* OGHAM SPACE MARK */
+          case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
+          case 0x2000:    /* EN QUAD */
+          case 0x2001:    /* EM QUAD */
+          case 0x2002:    /* EN SPACE */
+          case 0x2003:    /* EM SPACE */
+          case 0x2004:    /* THREE-PER-EM SPACE */
+          case 0x2005:    /* FOUR-PER-EM SPACE */
+          case 0x2006:    /* SIX-PER-EM SPACE */
+          case 0x2007:    /* FIGURE SPACE */
+          case 0x2008:    /* PUNCTUATION SPACE */
+          case 0x2009:    /* THIN SPACE */
+          case 0x200A:    /* HAIR SPACE */
+          case 0x202f:    /* NARROW NO-BREAK SPACE */
+          case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
+          case 0x3000:    /* IDEOGRAPHIC SPACE */
+          OK = TRUE;
+          break;
+
+          default:
+          OK = FALSE;
+          break;
+          }
+
+        if (OK == (d == OP_HSPACE))
+          {
+          if (count > 0 && codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSPLUS)
+            {
+            active_count--;           /* Remove non-match possibility */
+            next_active_state--;
+            }
+          count++;
+          ADD_NEW_DATA(-state_offset, count, 0);
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+#ifdef SUPPORT_UCP
+      case OP_PROP_EXTRA + OP_TYPEQUERY:
+      case OP_PROP_EXTRA + OP_TYPEMINQUERY:
+      case OP_PROP_EXTRA + OP_TYPEPOSQUERY:
+      count = 4;
+      goto QS1;
+
+      case OP_PROP_EXTRA + OP_TYPESTAR:
+      case OP_PROP_EXTRA + OP_TYPEMINSTAR:
+      case OP_PROP_EXTRA + OP_TYPEPOSSTAR:
+      count = 0;
+
+      QS1:
+
+      ADD_ACTIVE(state_offset + 4, 0);
+      if (clen > 0)
+        {
+        BOOL OK;
+        int chartype = UCD_CHARTYPE(c);
+        switch(code[2])
+          {
+          case PT_ANY:
+          OK = TRUE;
+          break;
+
+          case PT_LAMP:
+          OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
+          break;
+
+          case PT_GC:
+          OK = _pcre_ucp_gentype[chartype] == code[3];
+          break;
+
+          case PT_PC:
+          OK = chartype == code[3];
+          break;
+
+          case PT_SC:
+          OK = UCD_SCRIPT(c) == code[3];
+          break;
+
+          /* Should never occur, but keep compilers from grumbling. */
+
+          default:
+          OK = codevalue != OP_PROP;
+          break;
+          }
+
+        if (OK == (d == OP_PROP))
+          {
+          if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSSTAR ||
+              codevalue == OP_PROP_EXTRA + OP_TYPEPOSQUERY)
+            {
+            active_count--;           /* Remove non-match possibility */
+            next_active_state--;
+            }
+          ADD_NEW(state_offset + count, 0);
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_EXTUNI_EXTRA + OP_TYPEQUERY:
+      case OP_EXTUNI_EXTRA + OP_TYPEMINQUERY:
+      case OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY:
+      count = 2;
+      goto QS2;
+
+      case OP_EXTUNI_EXTRA + OP_TYPESTAR:
+      case OP_EXTUNI_EXTRA + OP_TYPEMINSTAR:
+      case OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR:
+      count = 0;
+
+      QS2:
+
+      ADD_ACTIVE(state_offset + 2, 0);
+      if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
+        {
+        const uschar *nptr = ptr + clen;
+        int ncount = 0;
+        if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSSTAR ||
+            codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSQUERY)
+          {
+          active_count--;           /* Remove non-match possibility */
+          next_active_state--;
+          }
+        while (nptr < end_subject)
+          {
+          int nd;
+          int ndlen = 1;
+          GETCHARLEN(nd, nptr, ndlen);
+          if (UCD_CATEGORY(nd) != ucp_M) break;
+          ncount++;
+          nptr += ndlen;
+          }
+        ADD_NEW_DATA(-(state_offset + count), 0, ncount);
+        }
+      break;
+#endif
+
+      /*-----------------------------------------------------------------*/
+      case OP_ANYNL_EXTRA + OP_TYPEQUERY:
+      case OP_ANYNL_EXTRA + OP_TYPEMINQUERY:
+      case OP_ANYNL_EXTRA + OP_TYPEPOSQUERY:
+      count = 2;
+      goto QS3;
+
+      case OP_ANYNL_EXTRA + OP_TYPESTAR:
+      case OP_ANYNL_EXTRA + OP_TYPEMINSTAR:
+      case OP_ANYNL_EXTRA + OP_TYPEPOSSTAR:
+      count = 0;
+
+      QS3:
+      ADD_ACTIVE(state_offset + 2, 0);
+      if (clen > 0)
+        {
+        int ncount = 0;
+        switch (c)
+          {
+          case 0x000b:
+          case 0x000c:
+          case 0x0085:
+          case 0x2028:
+          case 0x2029:
+          if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
+          goto ANYNL02;
+
+          case 0x000d:
+          if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
+          /* Fall through */
+
+          ANYNL02:
+          case 0x000a:
+          if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSSTAR ||
+              codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSQUERY)
+            {
+            active_count--;           /* Remove non-match possibility */
+            next_active_state--;
+            }
+          ADD_NEW_DATA(-(state_offset + count), 0, ncount);
+          break;
+
+          default:
+          break;
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_VSPACE_EXTRA + OP_TYPEQUERY:
+      case OP_VSPACE_EXTRA + OP_TYPEMINQUERY:
+      case OP_VSPACE_EXTRA + OP_TYPEPOSQUERY:
+      count = 2;
+      goto QS4;
+
+      case OP_VSPACE_EXTRA + OP_TYPESTAR:
+      case OP_VSPACE_EXTRA + OP_TYPEMINSTAR:
+      case OP_VSPACE_EXTRA + OP_TYPEPOSSTAR:
+      count = 0;
+
+      QS4:
+      ADD_ACTIVE(state_offset + 2, 0);
+      if (clen > 0)
+        {
+        BOOL OK;
+        switch (c)
+          {
+          case 0x000a:
+          case 0x000b:
+          case 0x000c:
+          case 0x000d:
+          case 0x0085:
+          case 0x2028:
+          case 0x2029:
+          OK = TRUE;
+          break;
+
+          default:
+          OK = FALSE;
+          break;
+          }
+        if (OK == (d == OP_VSPACE))
+          {
+          if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSSTAR ||
+              codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSQUERY)
+            {
+            active_count--;           /* Remove non-match possibility */
+            next_active_state--;
+            }
+          ADD_NEW_DATA(-(state_offset + count), 0, 0);
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_HSPACE_EXTRA + OP_TYPEQUERY:
+      case OP_HSPACE_EXTRA + OP_TYPEMINQUERY:
+      case OP_HSPACE_EXTRA + OP_TYPEPOSQUERY:
+      count = 2;
+      goto QS5;
+
+      case OP_HSPACE_EXTRA + OP_TYPESTAR:
+      case OP_HSPACE_EXTRA + OP_TYPEMINSTAR:
+      case OP_HSPACE_EXTRA + OP_TYPEPOSSTAR:
+      count = 0;
+
+      QS5:
+      ADD_ACTIVE(state_offset + 2, 0);
+      if (clen > 0)
+        {
+        BOOL OK;
+        switch (c)
+          {
+          case 0x09:      /* HT */
+          case 0x20:      /* SPACE */
+          case 0xa0:      /* NBSP */
+          case 0x1680:    /* OGHAM SPACE MARK */
+          case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
+          case 0x2000:    /* EN QUAD */
+          case 0x2001:    /* EM QUAD */
+          case 0x2002:    /* EN SPACE */
+          case 0x2003:    /* EM SPACE */
+          case 0x2004:    /* THREE-PER-EM SPACE */
+          case 0x2005:    /* FOUR-PER-EM SPACE */
+          case 0x2006:    /* SIX-PER-EM SPACE */
+          case 0x2007:    /* FIGURE SPACE */
+          case 0x2008:    /* PUNCTUATION SPACE */
+          case 0x2009:    /* THIN SPACE */
+          case 0x200A:    /* HAIR SPACE */
+          case 0x202f:    /* NARROW NO-BREAK SPACE */
+          case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
+          case 0x3000:    /* IDEOGRAPHIC SPACE */
+          OK = TRUE;
+          break;
+
+          default:
+          OK = FALSE;
+          break;
+          }
+
+        if (OK == (d == OP_HSPACE))
+          {
+          if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSSTAR ||
+              codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSQUERY)
+            {
+            active_count--;           /* Remove non-match possibility */
+            next_active_state--;
+            }
+          ADD_NEW_DATA(-(state_offset + count), 0, 0);
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+#ifdef SUPPORT_UCP
+      case OP_PROP_EXTRA + OP_TYPEEXACT:
+      case OP_PROP_EXTRA + OP_TYPEUPTO:
+      case OP_PROP_EXTRA + OP_TYPEMINUPTO:
+      case OP_PROP_EXTRA + OP_TYPEPOSUPTO:
+      if (codevalue != OP_PROP_EXTRA + OP_TYPEEXACT)
+        { ADD_ACTIVE(state_offset + 6, 0); }
+      count = current_state->count;  /* Number already matched */
+      if (clen > 0)
+        {
+        BOOL OK;
+        int chartype = UCD_CHARTYPE(c);
+        switch(code[4])
+          {
+          case PT_ANY:
+          OK = TRUE;
+          break;
+
+          case PT_LAMP:
+          OK = chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt;
+          break;
+
+          case PT_GC:
+          OK = _pcre_ucp_gentype[chartype] == code[5];
+          break;
+
+          case PT_PC:
+          OK = chartype == code[5];
+          break;
+
+          case PT_SC:
+          OK = UCD_SCRIPT(c) == code[5];
+          break;
+
+          /* Should never occur, but keep compilers from grumbling. */
+
+          default:
+          OK = codevalue != OP_PROP;
+          break;
+          }
+
+        if (OK == (d == OP_PROP))
+          {
+          if (codevalue == OP_PROP_EXTRA + OP_TYPEPOSUPTO)
+            {
+            active_count--;           /* Remove non-match possibility */
+            next_active_state--;
+            }
+          if (++count >= GET2(code, 1))
+            { ADD_NEW(state_offset + 6, 0); }
+          else
+            { ADD_NEW(state_offset, count); }
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_EXTUNI_EXTRA + OP_TYPEEXACT:
+      case OP_EXTUNI_EXTRA + OP_TYPEUPTO:
+      case OP_EXTUNI_EXTRA + OP_TYPEMINUPTO:
+      case OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO:
+      if (codevalue != OP_EXTUNI_EXTRA + OP_TYPEEXACT)
+        { ADD_ACTIVE(state_offset + 4, 0); }
+      count = current_state->count;  /* Number already matched */
+      if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
+        {
+        const uschar *nptr = ptr + clen;
+        int ncount = 0;
+        if (codevalue == OP_EXTUNI_EXTRA + OP_TYPEPOSUPTO)
+          {
+          active_count--;           /* Remove non-match possibility */
+          next_active_state--;
+          }
+        while (nptr < end_subject)
+          {
+          int nd;
+          int ndlen = 1;
+          GETCHARLEN(nd, nptr, ndlen);
+          if (UCD_CATEGORY(nd) != ucp_M) break;
+          ncount++;
+          nptr += ndlen;
+          }
+        if (++count >= GET2(code, 1))
+          { ADD_NEW_DATA(-(state_offset + 4), 0, ncount); }
+        else
+          { ADD_NEW_DATA(-state_offset, count, ncount); }
+        }
+      break;
+#endif
+
+      /*-----------------------------------------------------------------*/
+      case OP_ANYNL_EXTRA + OP_TYPEEXACT:
+      case OP_ANYNL_EXTRA + OP_TYPEUPTO:
+      case OP_ANYNL_EXTRA + OP_TYPEMINUPTO:
+      case OP_ANYNL_EXTRA + OP_TYPEPOSUPTO:
+      if (codevalue != OP_ANYNL_EXTRA + OP_TYPEEXACT)
+        { ADD_ACTIVE(state_offset + 4, 0); }
+      count = current_state->count;  /* Number already matched */
+      if (clen > 0)
+        {
+        int ncount = 0;
+        switch (c)
+          {
+          case 0x000b:
+          case 0x000c:
+          case 0x0085:
+          case 0x2028:
+          case 0x2029:
+          if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
+          goto ANYNL03;
+
+          case 0x000d:
+          if (ptr + 1 < end_subject && ptr[1] == 0x0a) ncount = 1;
+          /* Fall through */
+
+          ANYNL03:
+          case 0x000a:
+          if (codevalue == OP_ANYNL_EXTRA + OP_TYPEPOSUPTO)
+            {
+            active_count--;           /* Remove non-match possibility */
+            next_active_state--;
+            }
+          if (++count >= GET2(code, 1))
+            { ADD_NEW_DATA(-(state_offset + 4), 0, ncount); }
+          else
+            { ADD_NEW_DATA(-state_offset, count, ncount); }
+          break;
+
+          default:
+          break;
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_VSPACE_EXTRA + OP_TYPEEXACT:
+      case OP_VSPACE_EXTRA + OP_TYPEUPTO:
+      case OP_VSPACE_EXTRA + OP_TYPEMINUPTO:
+      case OP_VSPACE_EXTRA + OP_TYPEPOSUPTO:
+      if (codevalue != OP_VSPACE_EXTRA + OP_TYPEEXACT)
+        { ADD_ACTIVE(state_offset + 4, 0); }
+      count = current_state->count;  /* Number already matched */
+      if (clen > 0)
+        {
+        BOOL OK;
+        switch (c)
+          {
+          case 0x000a:
+          case 0x000b:
+          case 0x000c:
+          case 0x000d:
+          case 0x0085:
+          case 0x2028:
+          case 0x2029:
+          OK = TRUE;
+          break;
+
+          default:
+          OK = FALSE;
+          }
+
+        if (OK == (d == OP_VSPACE))
+          {
+          if (codevalue == OP_VSPACE_EXTRA + OP_TYPEPOSUPTO)
+            {
+            active_count--;           /* Remove non-match possibility */
+            next_active_state--;
+            }
+          if (++count >= GET2(code, 1))
+            { ADD_NEW_DATA(-(state_offset + 4), 0, 0); }
+          else
+            { ADD_NEW_DATA(-state_offset, count, 0); }
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_HSPACE_EXTRA + OP_TYPEEXACT:
+      case OP_HSPACE_EXTRA + OP_TYPEUPTO:
+      case OP_HSPACE_EXTRA + OP_TYPEMINUPTO:
+      case OP_HSPACE_EXTRA + OP_TYPEPOSUPTO:
+      if (codevalue != OP_HSPACE_EXTRA + OP_TYPEEXACT)
+        { ADD_ACTIVE(state_offset + 4, 0); }
+      count = current_state->count;  /* Number already matched */
+      if (clen > 0)
+        {
+        BOOL OK;
+        switch (c)
+          {
+          case 0x09:      /* HT */
+          case 0x20:      /* SPACE */
+          case 0xa0:      /* NBSP */
+          case 0x1680:    /* OGHAM SPACE MARK */
+          case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
+          case 0x2000:    /* EN QUAD */
+          case 0x2001:    /* EM QUAD */
+          case 0x2002:    /* EN SPACE */
+          case 0x2003:    /* EM SPACE */
+          case 0x2004:    /* THREE-PER-EM SPACE */
+          case 0x2005:    /* FOUR-PER-EM SPACE */
+          case 0x2006:    /* SIX-PER-EM SPACE */
+          case 0x2007:    /* FIGURE SPACE */
+          case 0x2008:    /* PUNCTUATION SPACE */
+          case 0x2009:    /* THIN SPACE */
+          case 0x200A:    /* HAIR SPACE */
+          case 0x202f:    /* NARROW NO-BREAK SPACE */
+          case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
+          case 0x3000:    /* IDEOGRAPHIC SPACE */
+          OK = TRUE;
+          break;
+
+          default:
+          OK = FALSE;
+          break;
+          }
+
+        if (OK == (d == OP_HSPACE))
+          {
+          if (codevalue == OP_HSPACE_EXTRA + OP_TYPEPOSUPTO)
+            {
+            active_count--;           /* Remove non-match possibility */
+            next_active_state--;
+            }
+          if (++count >= GET2(code, 1))
+            { ADD_NEW_DATA(-(state_offset + 4), 0, 0); }
+          else
+            { ADD_NEW_DATA(-state_offset, count, 0); }
+          }
+        }
+      break;
+
+/* ========================================================================== */
+      /* These opcodes are followed by a character that is usually compared
+      to the current subject character; it is loaded into d. We still get
+      here even if there is no subject character, because in some cases zero
+      repetitions are permitted. */
+
+      /*-----------------------------------------------------------------*/
+      case OP_CHAR:
+      if (clen > 0 && c == d) { ADD_NEW(state_offset + dlen + 1, 0); }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_CHARNC:
+      if (clen == 0) break;
+
+#ifdef SUPPORT_UTF8
+      if (utf8)
+        {
+        if (c == d) { ADD_NEW(state_offset + dlen + 1, 0); } else
+          {
+          unsigned int othercase;
+          if (c < 128) othercase = fcc[c]; else
+
+          /* If we have Unicode property support, we can use it to test the
+          other case of the character. */
+
+#ifdef SUPPORT_UCP
+          othercase = UCD_OTHERCASE(c);
+#else
+          othercase = NOTACHAR;
+#endif
+
+          if (d == othercase) { ADD_NEW(state_offset + dlen + 1, 0); }
+          }
+        }
+      else
+#endif  /* SUPPORT_UTF8 */
+
+      /* Non-UTF-8 mode */
+        {
+        if (lcc[c] == lcc[d]) { ADD_NEW(state_offset + 2, 0); }
+        }
+      break;
+
+
+#ifdef SUPPORT_UCP
+      /*-----------------------------------------------------------------*/
+      /* This is a tricky one because it can match more than one character.
+      Find out how many characters to skip, and then set up a negative state
+      to wait for them to pass before continuing. */
+
+      case OP_EXTUNI:
+      if (clen > 0 && UCD_CATEGORY(c) != ucp_M)
+        {
+        const uschar *nptr = ptr + clen;
+        int ncount = 0;
+        while (nptr < end_subject)
+          {
+          int nclen = 1;
+          GETCHARLEN(c, nptr, nclen);
+          if (UCD_CATEGORY(c) != ucp_M) break;
+          ncount++;
+          nptr += nclen;
+          }
+        ADD_NEW_DATA(-(state_offset + 1), 0, ncount);
+        }
+      break;
+#endif
+
+      /*-----------------------------------------------------------------*/
+      /* This is a tricky like EXTUNI because it too can match more than one
+      character (when CR is followed by LF). In this case, set up a negative
+      state to wait for one character to pass before continuing. */
+
+      case OP_ANYNL:
+      if (clen > 0) switch(c)
+        {
+        case 0x000b:
+        case 0x000c:
+        case 0x0085:
+        case 0x2028:
+        case 0x2029:
+        if ((md->moptions & PCRE_BSR_ANYCRLF) != 0) break;
+
+        case 0x000a:
+        ADD_NEW(state_offset + 1, 0);
+        break;
+
+        case 0x000d:
+        if (ptr + 1 < end_subject && ptr[1] == 0x0a)
+          {
+          ADD_NEW_DATA(-(state_offset + 1), 0, 1);
+          }
+        else
+          {
+          ADD_NEW(state_offset + 1, 0);
+          }
+        break;
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_NOT_VSPACE:
+      if (clen > 0) switch(c)
+        {
+        case 0x000a:
+        case 0x000b:
+        case 0x000c:
+        case 0x000d:
+        case 0x0085:
+        case 0x2028:
+        case 0x2029:
+        break;
+
+        default:
+        ADD_NEW(state_offset + 1, 0);
+        break;
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_VSPACE:
+      if (clen > 0) switch(c)
+        {
+        case 0x000a:
+        case 0x000b:
+        case 0x000c:
+        case 0x000d:
+        case 0x0085:
+        case 0x2028:
+        case 0x2029:
+        ADD_NEW(state_offset + 1, 0);
+        break;
+
+        default: break;
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_NOT_HSPACE:
+      if (clen > 0) switch(c)
+        {
+        case 0x09:      /* HT */
+        case 0x20:      /* SPACE */
+        case 0xa0:      /* NBSP */
+        case 0x1680:    /* OGHAM SPACE MARK */
+        case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
+        case 0x2000:    /* EN QUAD */
+        case 0x2001:    /* EM QUAD */
+        case 0x2002:    /* EN SPACE */
+        case 0x2003:    /* EM SPACE */
+        case 0x2004:    /* THREE-PER-EM SPACE */
+        case 0x2005:    /* FOUR-PER-EM SPACE */
+        case 0x2006:    /* SIX-PER-EM SPACE */
+        case 0x2007:    /* FIGURE SPACE */
+        case 0x2008:    /* PUNCTUATION SPACE */
+        case 0x2009:    /* THIN SPACE */
+        case 0x200A:    /* HAIR SPACE */
+        case 0x202f:    /* NARROW NO-BREAK SPACE */
+        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
+        case 0x3000:    /* IDEOGRAPHIC SPACE */
+        break;
+
+        default:
+        ADD_NEW(state_offset + 1, 0);
+        break;
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_HSPACE:
+      if (clen > 0) switch(c)
+        {
+        case 0x09:      /* HT */
+        case 0x20:      /* SPACE */
+        case 0xa0:      /* NBSP */
+        case 0x1680:    /* OGHAM SPACE MARK */
+        case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
+        case 0x2000:    /* EN QUAD */
+        case 0x2001:    /* EM QUAD */
+        case 0x2002:    /* EN SPACE */
+        case 0x2003:    /* EM SPACE */
+        case 0x2004:    /* THREE-PER-EM SPACE */
+        case 0x2005:    /* FOUR-PER-EM SPACE */
+        case 0x2006:    /* SIX-PER-EM SPACE */
+        case 0x2007:    /* FIGURE SPACE */
+        case 0x2008:    /* PUNCTUATION SPACE */
+        case 0x2009:    /* THIN SPACE */
+        case 0x200A:    /* HAIR SPACE */
+        case 0x202f:    /* NARROW NO-BREAK SPACE */
+        case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
+        case 0x3000:    /* IDEOGRAPHIC SPACE */
+        ADD_NEW(state_offset + 1, 0);
+        break;
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      /* Match a negated single character. This is only used for one-byte
+      characters, that is, we know that d < 256. The character we are
+      checking (c) can be multibyte. */
+
+      case OP_NOT:
+      if (clen > 0)
+        {
+        unsigned int otherd = ((ims & PCRE_CASELESS) != 0)? fcc[d] : d;
+        if (c != d && c != otherd) { ADD_NEW(state_offset + dlen + 1, 0); }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_PLUS:
+      case OP_MINPLUS:
+      case OP_POSPLUS:
+      case OP_NOTPLUS:
+      case OP_NOTMINPLUS:
+      case OP_NOTPOSPLUS:
+      count = current_state->count;  /* Already matched */
+      if (count > 0) { ADD_ACTIVE(state_offset + dlen + 1, 0); }
+      if (clen > 0)
+        {
+        unsigned int otherd = NOTACHAR;
+        if ((ims & PCRE_CASELESS) != 0)
+          {
+#ifdef SUPPORT_UTF8
+          if (utf8 && d >= 128)
+            {
+#ifdef SUPPORT_UCP
+            otherd = UCD_OTHERCASE(d);
+#endif  /* SUPPORT_UCP */
+            }
+          else
+#endif  /* SUPPORT_UTF8 */
+          otherd = fcc[d];
+          }
+        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+          {
+          if (count > 0 &&
+              (codevalue == OP_POSPLUS || codevalue == OP_NOTPOSPLUS))
+            {
+            active_count--;             /* Remove non-match possibility */
+            next_active_state--;
+            }
+          count++;
+          ADD_NEW(state_offset, count);
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_QUERY:
+      case OP_MINQUERY:
+      case OP_POSQUERY:
+      case OP_NOTQUERY:
+      case OP_NOTMINQUERY:
+      case OP_NOTPOSQUERY:
+      ADD_ACTIVE(state_offset + dlen + 1, 0);
+      if (clen > 0)
+        {
+        unsigned int otherd = NOTACHAR;
+        if ((ims & PCRE_CASELESS) != 0)
+          {
+#ifdef SUPPORT_UTF8
+          if (utf8 && d >= 128)
+            {
+#ifdef SUPPORT_UCP
+            otherd = UCD_OTHERCASE(d);
+#endif  /* SUPPORT_UCP */
+            }
+          else
+#endif  /* SUPPORT_UTF8 */
+          otherd = fcc[d];
+          }
+        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+          {
+          if (codevalue == OP_POSQUERY || codevalue == OP_NOTPOSQUERY)
+            {
+            active_count--;            /* Remove non-match possibility */
+            next_active_state--;
+            }
+          ADD_NEW(state_offset + dlen + 1, 0);
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_STAR:
+      case OP_MINSTAR:
+      case OP_POSSTAR:
+      case OP_NOTSTAR:
+      case OP_NOTMINSTAR:
+      case OP_NOTPOSSTAR:
+      ADD_ACTIVE(state_offset + dlen + 1, 0);
+      if (clen > 0)
+        {
+        unsigned int otherd = NOTACHAR;
+        if ((ims & PCRE_CASELESS) != 0)
+          {
+#ifdef SUPPORT_UTF8
+          if (utf8 && d >= 128)
+            {
+#ifdef SUPPORT_UCP
+            otherd = UCD_OTHERCASE(d);
+#endif  /* SUPPORT_UCP */
+            }
+          else
+#endif  /* SUPPORT_UTF8 */
+          otherd = fcc[d];
+          }
+        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+          {
+          if (codevalue == OP_POSSTAR || codevalue == OP_NOTPOSSTAR)
+            {
+            active_count--;            /* Remove non-match possibility */
+            next_active_state--;
+            }
+          ADD_NEW(state_offset, 0);
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_EXACT:
+      case OP_NOTEXACT:
+      count = current_state->count;  /* Number already matched */
+      if (clen > 0)
+        {
+        unsigned int otherd = NOTACHAR;
+        if ((ims & PCRE_CASELESS) != 0)
+          {
+#ifdef SUPPORT_UTF8
+          if (utf8 && d >= 128)
+            {
+#ifdef SUPPORT_UCP
+            otherd = UCD_OTHERCASE(d);
+#endif  /* SUPPORT_UCP */
+            }
+          else
+#endif  /* SUPPORT_UTF8 */
+          otherd = fcc[d];
+          }
+        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+          {
+          if (++count >= GET2(code, 1))
+            { ADD_NEW(state_offset + dlen + 3, 0); }
+          else
+            { ADD_NEW(state_offset, count); }
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_UPTO:
+      case OP_MINUPTO:
+      case OP_POSUPTO:
+      case OP_NOTUPTO:
+      case OP_NOTMINUPTO:
+      case OP_NOTPOSUPTO:
+      ADD_ACTIVE(state_offset + dlen + 3, 0);
+      count = current_state->count;  /* Number already matched */
+      if (clen > 0)
+        {
+        unsigned int otherd = NOTACHAR;
+        if ((ims & PCRE_CASELESS) != 0)
+          {
+#ifdef SUPPORT_UTF8
+          if (utf8 && d >= 128)
+            {
+#ifdef SUPPORT_UCP
+            otherd = UCD_OTHERCASE(d);
+#endif  /* SUPPORT_UCP */
+            }
+          else
+#endif  /* SUPPORT_UTF8 */
+          otherd = fcc[d];
+          }
+        if ((c == d || c == otherd) == (codevalue < OP_NOTSTAR))
+          {
+          if (codevalue == OP_POSUPTO || codevalue == OP_NOTPOSUPTO)
+            {
+            active_count--;             /* Remove non-match possibility */
+            next_active_state--;
+            }
+          if (++count >= GET2(code, 1))
+            { ADD_NEW(state_offset + dlen + 3, 0); }
+          else
+            { ADD_NEW(state_offset, count); }
+          }
+        }
+      break;
+
+
+/* ========================================================================== */
+      /* These are the class-handling opcodes */
+
+      case OP_CLASS:
+      case OP_NCLASS:
+      case OP_XCLASS:
+        {
+        BOOL isinclass = FALSE;
+        int next_state_offset;
+        const uschar *ecode;
+
+        /* For a simple class, there is always just a 32-byte table, and we
+        can set isinclass from it. */
+
+        if (codevalue != OP_XCLASS)
+          {
+          ecode = code + 33;
+          if (clen > 0)
+            {
+            isinclass = (c > 255)? (codevalue == OP_NCLASS) :
+              ((code[1 + c/8] & (1 << (c&7))) != 0);
+            }
+          }
+
+        /* An extended class may have a table or a list of single characters,
+        ranges, or both, and it may be positive or negative. There's a
+        function that sorts all this out. */
+
+        else
+         {
+         ecode = code + GET(code, 1);
+         if (clen > 0) isinclass = _pcre_xclass(c, code + 1 + LINK_SIZE);
+         }
+
+        /* At this point, isinclass is set for all kinds of class, and ecode
+        points to the byte after the end of the class. If there is a
+        quantifier, this is where it will be. */
+
+        next_state_offset = ecode - start_code;
+
+        switch (*ecode)
+          {
+          case OP_CRSTAR:
+          case OP_CRMINSTAR:
+          ADD_ACTIVE(next_state_offset + 1, 0);
+          if (isinclass) { ADD_NEW(state_offset, 0); }
+          break;
+
+          case OP_CRPLUS:
+          case OP_CRMINPLUS:
+          count = current_state->count;  /* Already matched */
+          if (count > 0) { ADD_ACTIVE(next_state_offset + 1, 0); }
+          if (isinclass) { count++; ADD_NEW(state_offset, count); }
+          break;
+
+          case OP_CRQUERY:
+          case OP_CRMINQUERY:
+          ADD_ACTIVE(next_state_offset + 1, 0);
+          if (isinclass) { ADD_NEW(next_state_offset + 1, 0); }
+          break;
+
+          case OP_CRRANGE:
+          case OP_CRMINRANGE:
+          count = current_state->count;  /* Already matched */
+          if (count >= GET2(ecode, 1))
+            { ADD_ACTIVE(next_state_offset + 5, 0); }
+          if (isinclass)
+            {
+            int max = GET2(ecode, 3);
+            if (++count >= max && max != 0)   /* Max 0 => no limit */
+              { ADD_NEW(next_state_offset + 5, 0); }
+            else
+              { ADD_NEW(state_offset, count); }
+            }
+          break;
+
+          default:
+          if (isinclass) { ADD_NEW(next_state_offset, 0); }
+          break;
+          }
+        }
+      break;
+
+/* ========================================================================== */
+      /* These are the opcodes for fancy brackets of various kinds. We have
+      to use recursion in order to handle them. The "always failing" assertion
+      (?!) is optimised to OP_FAIL when compiling, so we have to support that,
+      though the other "backtracking verbs" are not supported. */
+
+      case OP_FAIL:
+      forced_fail++;    /* Count FAILs for multiple states */
+      break;
+
+      case OP_ASSERT:
+      case OP_ASSERT_NOT:
+      case OP_ASSERTBACK:
+      case OP_ASSERTBACK_NOT:
+        {
+        int rc;
+        int local_offsets[2];
+        int local_workspace[1000];
+        const uschar *endasscode = code + GET(code, 1);
+
+        while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
+
+        rc = internal_dfa_exec(
+          md,                                   /* static match data */
+          code,                                 /* this subexpression's code */
+          ptr,                                  /* where we currently are */
+          ptr - start_subject,                  /* start offset */
+          local_offsets,                        /* offset vector */
+          sizeof(local_offsets)/sizeof(int),    /* size of same */
+          local_workspace,                      /* workspace vector */
+          sizeof(local_workspace)/sizeof(int),  /* size of same */
+          ims,                                  /* the current ims flags */
+          rlevel,                               /* function recursion level */
+          recursing);                           /* pass on regex recursion */
+
+        if (rc == PCRE_ERROR_DFA_UITEM) return rc;
+        if ((rc >= 0) == (codevalue == OP_ASSERT || codevalue == OP_ASSERTBACK))
+            { ADD_ACTIVE(endasscode + LINK_SIZE + 1 - start_code, 0); }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_COND:
+      case OP_SCOND:
+        {
+        int local_offsets[1000];
+        int local_workspace[1000];
+        int codelink = GET(code, 1);
+        int condcode;
+
+        /* Because of the way auto-callout works during compile, a callout item
+        is inserted between OP_COND and an assertion condition. This does not
+        happen for the other conditions. */
+
+        if (code[LINK_SIZE+1] == OP_CALLOUT)
+          {
+          rrc = 0;
+          if (pcre_callout != NULL)
+            {
+            pcre_callout_block cb;
+            cb.version          = 1;   /* Version 1 of the callout block */
+            cb.callout_number   = code[LINK_SIZE+2];
+            cb.offset_vector    = offsets;
+            cb.subject          = (PCRE_SPTR)start_subject;
+            cb.subject_length   = end_subject - start_subject;
+            cb.start_match      = current_subject - start_subject;
+            cb.current_position = ptr - start_subject;
+            cb.pattern_position = GET(code, LINK_SIZE + 3);
+            cb.next_item_length = GET(code, 3 + 2*LINK_SIZE);
+            cb.capture_top      = 1;
+            cb.capture_last     = -1;
+            cb.callout_data     = md->callout_data;
+            if ((rrc = (*pcre_callout)(&cb)) < 0) return rrc;   /* Abandon */
+            }
+          if (rrc > 0) break;                      /* Fail this thread */
+          code += _pcre_OP_lengths[OP_CALLOUT];    /* Skip callout data */
+          }
+
+        condcode = code[LINK_SIZE+1];
+
+        /* Back reference conditions are not supported */
+
+        if (condcode == OP_CREF || condcode == OP_NCREF)
+          return PCRE_ERROR_DFA_UCOND;
+
+        /* The DEFINE condition is always false */
+
+        if (condcode == OP_DEF)
+          { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
+
+        /* The only supported version of OP_RREF is for the value RREF_ANY,
+        which means "test if in any recursion". We can't test for specifically
+        recursed groups. */
+
+        else if (condcode == OP_RREF || condcode == OP_NRREF)
+          {
+          int value = GET2(code, LINK_SIZE+2);
+          if (value != RREF_ANY) return PCRE_ERROR_DFA_UCOND;
+          if (recursing > 0)
+            { ADD_ACTIVE(state_offset + LINK_SIZE + 4, 0); }
+          else { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
+          }
+
+        /* Otherwise, the condition is an assertion */
+
+        else
+          {
+          int rc;
+          const uschar *asscode = code + LINK_SIZE + 1;
+          const uschar *endasscode = asscode + GET(asscode, 1);
+
+          while (*endasscode == OP_ALT) endasscode += GET(endasscode, 1);
+
+          rc = internal_dfa_exec(
+            md,                                   /* fixed match data */
+            asscode,                              /* this subexpression's code */
+            ptr,                                  /* where we currently are */
+            ptr - start_subject,                  /* start offset */
+            local_offsets,                        /* offset vector */
+            sizeof(local_offsets)/sizeof(int),    /* size of same */
+            local_workspace,                      /* workspace vector */
+            sizeof(local_workspace)/sizeof(int),  /* size of same */
+            ims,                                  /* the current ims flags */
+            rlevel,                               /* function recursion level */
+            recursing);                           /* pass on regex recursion */
+
+          if (rc == PCRE_ERROR_DFA_UITEM) return rc;
+          if ((rc >= 0) ==
+                (condcode == OP_ASSERT || condcode == OP_ASSERTBACK))
+            { ADD_ACTIVE(endasscode + LINK_SIZE + 1 - start_code, 0); }
+          else
+            { ADD_ACTIVE(state_offset + codelink + LINK_SIZE + 1, 0); }
+          }
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_RECURSE:
+        {
+        int local_offsets[1000];
+        int local_workspace[1000];
+        int rc;
+
+        DPRINTF(("%.*sStarting regex recursion %d\n", rlevel*2-2, SP,
+          recursing + 1));
+
+        rc = internal_dfa_exec(
+          md,                                   /* fixed match data */
+          start_code + GET(code, 1),            /* this subexpression's code */
+          ptr,                                  /* where we currently are */
+          ptr - start_subject,                  /* start offset */
+          local_offsets,                        /* offset vector */
+          sizeof(local_offsets)/sizeof(int),    /* size of same */
+          local_workspace,                      /* workspace vector */
+          sizeof(local_workspace)/sizeof(int),  /* size of same */
+          ims,                                  /* the current ims flags */
+          rlevel,                               /* function recursion level */
+          recursing + 1);                       /* regex recurse level */
+
+        DPRINTF(("%.*sReturn from regex recursion %d: rc=%d\n", rlevel*2-2, SP,
+          recursing + 1, rc));
+
+        /* Ran out of internal offsets */
+
+        if (rc == 0) return PCRE_ERROR_DFA_RECURSE;
+
+        /* For each successful matched substring, set up the next state with a
+        count of characters to skip before trying it. Note that the count is in
+        characters, not bytes. */
+
+        if (rc > 0)
+          {
+          for (rc = rc*2 - 2; rc >= 0; rc -= 2)
+            {
+            const uschar *p = start_subject + local_offsets[rc];
+            const uschar *pp = start_subject + local_offsets[rc+1];
+            int charcount = local_offsets[rc+1] - local_offsets[rc];
+            while (p < pp) if ((*p++ & 0xc0) == 0x80) charcount--;
+            if (charcount > 0)
+              {
+              ADD_NEW_DATA(-(state_offset + LINK_SIZE + 1), 0, (charcount - 1));
+              }
+            else
+              {
+              ADD_ACTIVE(state_offset + LINK_SIZE + 1, 0);
+              }
+            }
+          }
+        else if (rc != PCRE_ERROR_NOMATCH) return rc;
+        }
+      break;
+
+      /*-----------------------------------------------------------------*/
+      case OP_ONCE:
+        {
+        int local_offsets[2];
+        int local_workspace[1000];
+
+        int rc = internal_dfa_exec(
+          md,                                   /* fixed match data */
+          code,                                 /* this subexpression's code */
+          ptr,                                  /* where we currently are */
+          ptr - start_subject,                  /* start offset */
+          local_offsets,                        /* offset vector */
+          sizeof(local_offsets)/sizeof(int),    /* size of same */
+          local_workspace,                      /* workspace vector */
+          sizeof(local_workspace)/sizeof(int),  /* size of same */
+          ims,                                  /* the current ims flags */
+          rlevel,                               /* function recursion level */
+          recursing);                           /* pass on regex recursion */
+
+        if (rc >= 0)
+          {
+          const uschar *end_subpattern = code;
+          int charcount = local_offsets[1] - local_offsets[0];
+          int next_state_offset, repeat_state_offset;
+
+          do { end_subpattern += GET(end_subpattern, 1); }
+            while (*end_subpattern == OP_ALT);
+          next_state_offset = end_subpattern - start_code + LINK_SIZE + 1;
+
+          /* If the end of this subpattern is KETRMAX or KETRMIN, we must
+          arrange for the repeat state also to be added to the relevant list.
+          Calculate the offset, or set -1 for no repeat. */
+
+          repeat_state_offset = (*end_subpattern == OP_KETRMAX ||
+                                 *end_subpattern == OP_KETRMIN)?
+            end_subpattern - start_code - GET(end_subpattern, 1) : -1;
+
+          /* If we have matched an empty string, add the next state at the
+          current character pointer. This is important so that the duplicate
+          checking kicks in, which is what breaks infinite loops that match an
+          empty string. */
+
+          if (charcount == 0)
+            {
+            ADD_ACTIVE(next_state_offset, 0);
+            }
+
+          /* Optimization: if there are no more active states, and there
+          are no new states yet set up, then skip over the subject string
+          right here, to save looping. Otherwise, set up the new state to swing
+          into action when the end of the substring is reached. */
+
+          else if (i + 1 >= active_count && new_count == 0)
+            {
+            ptr += charcount;
+            clen = 0;
+            ADD_NEW(next_state_offset, 0);
+
+            /* If we are adding a repeat state at the new character position,
+            we must fudge things so that it is the only current state.
+            Otherwise, it might be a duplicate of one we processed before, and
+            that would cause it to be skipped. */
+
+            if (repeat_state_offset >= 0)
+              {
+              next_active_state = active_states;
+              active_count = 0;
+              i = -1;
+              ADD_ACTIVE(repeat_state_offset, 0);
+              }
+            }
+          else
+            {
+            const uschar *p = start_subject + local_offsets[0];
+            const uschar *pp = start_subject + local_offsets[1];
+            while (p < pp) if ((*p++ & 0xc0) == 0x80) charcount--;
+            ADD_NEW_DATA(-next_state_offset, 0, (charcount - 1));
+            if (repeat_state_offset >= 0)
+              { ADD_NEW_DATA(-repeat_state_offset, 0, (charcount - 1)); }
+            }
+
+          }
+        else if (rc != PCRE_ERROR_NOMATCH) return rc;
+        }
+      break;
+
+
+/* ========================================================================== */
+      /* Handle callouts */
+
+      case OP_CALLOUT:
+      rrc = 0;
+      if (pcre_callout != NULL)
+        {
+        pcre_callout_block cb;
+        cb.version          = 1;   /* Version 1 of the callout block */
+        cb.callout_number   = code[1];
+        cb.offset_vector    = offsets;
+        cb.subject          = (PCRE_SPTR)start_subject;
+        cb.subject_length   = end_subject - start_subject;
+        cb.start_match      = current_subject - start_subject;
+        cb.current_position = ptr - start_subject;
+        cb.pattern_position = GET(code, 2);
+        cb.next_item_length = GET(code, 2 + LINK_SIZE);
+        cb.capture_top      = 1;
+        cb.capture_last     = -1;
+        cb.callout_data     = md->callout_data;
+        if ((rrc = (*pcre_callout)(&cb)) < 0) return rrc;   /* Abandon */
+        }
+      if (rrc == 0)
+        { ADD_ACTIVE(state_offset + _pcre_OP_lengths[OP_CALLOUT], 0); }
+      break;
+
+
+/* ========================================================================== */
+      default:        /* Unsupported opcode */
+      return PCRE_ERROR_DFA_UITEM;
+      }
+
+    NEXT_ACTIVE_STATE: continue;
+
+    }      /* End of loop scanning active states */
+
+  /* We have finished the processing at the current subject character. If no
+  new states have been set for the next character, we have found all the
+  matches that we are going to find. If we are at the top level and partial
+  matching has been requested, check for appropriate conditions.
+
+  The "forced_ fail" variable counts the number of (*F) encountered for the
+  character. If it is equal to the original active_count (saved in
+  workspace[1]) it means that (*F) was found on every active state. In this
+  case we don't want to give a partial match.
+
+  The "could_continue" variable is true if a state could have continued but
+  for the fact that the end of the subject was reached. */
+
+  if (new_count <= 0)
+    {
+    if (rlevel == 1 &&                               /* Top level, and */
+        could_continue &&                            /* Some could go on */
+        forced_fail != workspace[1] &&               /* Not all forced fail & */
+        (                                            /* either... */
+        (md->moptions & PCRE_PARTIAL_HARD) != 0      /* Hard partial */
+        ||                                           /* or... */
+        ((md->moptions & PCRE_PARTIAL_SOFT) != 0 &&  /* Soft partial and */
+         match_count < 0)                            /* no matches */
+        ) &&                                         /* And... */
+        ptr >= end_subject &&                     /* Reached end of subject */
+        ptr > current_subject)                    /* Matched non-empty string */
+      {
+      if (offsetcount >= 2)
+        {
+        offsets[0] = md->start_used_ptr - start_subject;
+        offsets[1] = end_subject - start_subject;
+        }
+      match_count = PCRE_ERROR_PARTIAL;
+      }
+
+    DPRINTF(("%.*sEnd of internal_dfa_exec %d: returning %d\n"
+      "%.*s---------------------\n\n", rlevel*2-2, SP, rlevel, match_count,
+      rlevel*2-2, SP));
+    break;        /* In effect, "return", but see the comment below */
+    }
+
+  /* One or more states are active for the next character. */
+
+  ptr += clen;    /* Advance to next subject character */
+  }               /* Loop to move along the subject string */
+
+/* Control gets here from "break" a few lines above. We do it this way because
+if we use "return" above, we have compiler trouble. Some compilers warn if
+there's nothing here because they think the function doesn't return a value. On
+the other hand, if we put a dummy statement here, some more clever compilers
+complain that it can't be reached. Sigh. */
+
+return match_count;
+}
+
+
+
+
+/*************************************************
+*    Execute a Regular Expression - DFA engine   *
+*************************************************/
+
+/* This external function applies a compiled re to a subject string using a DFA
+engine. This function calls the internal function multiple times if the pattern
+is not anchored.
+
+Arguments:
+  argument_re     points to the compiled expression
+  extra_data      points to extra data or is NULL
+  subject         points to the subject string
+  length          length of subject string (may contain binary zeros)
+  start_offset    where to start in the subject string
+  options         option bits
+  offsets         vector of match offsets
+  offsetcount     size of same
+  workspace       workspace vector
+  wscount         size of same
+
+Returns:          > 0 => number of match offset pairs placed in offsets
+                  = 0 => offsets overflowed; longest matches are present
+                   -1 => failed to match
+                 < -1 => some kind of unexpected problem
+*/
+
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_dfa_exec(const pcre *argument_re, const pcre_extra *extra_data,
+  const char *subject, int length, int start_offset, int options, int *offsets,
+  int offsetcount, int *workspace, int wscount)
+{
+real_pcre *re = (real_pcre *)argument_re;
+dfa_match_data match_block;
+dfa_match_data *md = &match_block;
+BOOL utf8, anchored, startline, firstline;
+const uschar *current_subject, *end_subject, *lcc;
+
+pcre_study_data internal_study;
+const pcre_study_data *study = NULL;
+real_pcre internal_re;
+
+const uschar *req_byte_ptr;
+const uschar *start_bits = NULL;
+BOOL first_byte_caseless = FALSE;
+BOOL req_byte_caseless = FALSE;
+int first_byte = -1;
+int req_byte = -1;
+int req_byte2 = -1;
+int newline;
+
+/* Plausibility checks */
+
+if ((options & ~PUBLIC_DFA_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
+if (re == NULL || subject == NULL || workspace == NULL ||
+   (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
+if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
+if (wscount < 20) return PCRE_ERROR_DFA_WSSIZE;
+
+/* We need to find the pointer to any study data before we test for byte
+flipping, so we scan the extra_data block first. This may set two fields in the
+match block, so we must initialize them beforehand. However, the other fields
+in the match block must not be set until after the byte flipping. */
+
+md->tables = re->tables;
+md->callout_data = NULL;
+
+if (extra_data != NULL)
+  {
+  unsigned int flags = extra_data->flags;
+  if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
+    study = (const pcre_study_data *)extra_data->study_data;
+  if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0) return PCRE_ERROR_DFA_UMLIMIT;
+  if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
+    return PCRE_ERROR_DFA_UMLIMIT;
+  if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
+    md->callout_data = extra_data->callout_data;
+  if ((flags & PCRE_EXTRA_TABLES) != 0)
+    md->tables = extra_data->tables;
+  }
+
+/* Check that the first field in the block is the magic number. If it is not,
+test for a regex that was compiled on a host of opposite endianness. If this is
+the case, flipped values are put in internal_re and internal_study if there was
+study data too. */
+
+if (re->magic_number != MAGIC_NUMBER)
+  {
+  re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
+  if (re == NULL) return PCRE_ERROR_BADMAGIC;
+  if (study != NULL) study = &internal_study;
+  }
+
+/* Set some local values */
+
+current_subject = (const unsigned char *)subject + start_offset;
+end_subject = (const unsigned char *)subject + length;
+req_byte_ptr = current_subject - 1;
+
+#ifdef SUPPORT_UTF8
+utf8 = (re->options & PCRE_UTF8) != 0;
+#else
+utf8 = FALSE;
+#endif
+
+anchored = (options & (PCRE_ANCHORED|PCRE_DFA_RESTART)) != 0 ||
+  (re->options & PCRE_ANCHORED) != 0;
+
+/* The remaining fixed data for passing around. */
+
+md->start_code = (const uschar *)argument_re +
+    re->name_table_offset + re->name_count * re->name_entry_size;
+md->start_subject = (const unsigned char *)subject;
+md->end_subject = end_subject;
+md->start_offset = start_offset;
+md->moptions = options;
+md->poptions = re->options;
+
+/* If the BSR option is not set at match time, copy what was set
+at compile time. */
+
+if ((md->moptions & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) == 0)
+  {
+  if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
+    md->moptions |= re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE);
+#ifdef BSR_ANYCRLF
+  else md->moptions |= PCRE_BSR_ANYCRLF;
+#endif
+  }
+
+/* Handle different types of newline. The three bits give eight cases. If
+nothing is set at run time, whatever was used at compile time applies. */
+
+switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options : (pcre_uint32)options) &
+         PCRE_NEWLINE_BITS)
+  {
+  case 0: newline = NEWLINE; break;   /* Compile-time default */
+  case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
+  case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
+  case PCRE_NEWLINE_CR+
+       PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
+  case PCRE_NEWLINE_ANY: newline = -1; break;
+  case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
+  default: return PCRE_ERROR_BADNEWLINE;
+  }
+
+if (newline == -2)
+  {
+  md->nltype = NLTYPE_ANYCRLF;
+  }
+else if (newline < 0)
+  {
+  md->nltype = NLTYPE_ANY;
+  }
+else
+  {
+  md->nltype = NLTYPE_FIXED;
+  if (newline > 255)
+    {
+    md->nllen = 2;
+    md->nl[0] = (newline >> 8) & 255;
+    md->nl[1] = newline & 255;
+    }
+  else
+    {
+    md->nllen = 1;
+    md->nl[0] = newline;
+    }
+  }
+
+/* Check a UTF-8 string if required. Unfortunately there's no way of passing
+back the character offset. */
+
+#ifdef SUPPORT_UTF8
+if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
+  {
+  if (_pcre_valid_utf8((uschar *)subject, length) >= 0)
+    return PCRE_ERROR_BADUTF8;
+  if (start_offset > 0 && start_offset < length)
+    {
+    int tb = ((uschar *)subject)[start_offset];
+    if (tb > 127)
+      {
+      tb &= 0xc0;
+      if (tb != 0 && tb != 0xc0) return PCRE_ERROR_BADUTF8_OFFSET;
+      }
+    }
+  }
+#endif
+
+/* If the exec call supplied NULL for tables, use the inbuilt ones. This
+is a feature that makes it possible to save compiled regex and re-use them
+in other programs later. */
+
+if (md->tables == NULL) md->tables = _pcre_default_tables;
+
+/* The lower casing table and the "must be at the start of a line" flag are
+used in a loop when finding where to start. */
+
+lcc = md->tables + lcc_offset;
+startline = (re->flags & PCRE_STARTLINE) != 0;
+firstline = (re->options & PCRE_FIRSTLINE) != 0;
+
+/* Set up the first character to match, if available. The first_byte value is
+never set for an anchored regular expression, but the anchoring may be forced
+at run time, so we have to test for anchoring. The first char may be unset for
+an unanchored pattern, of course. If there's no first char and the pattern was
+studied, there may be a bitmap of possible first characters. */
+
+if (!anchored)
+  {
+  if ((re->flags & PCRE_FIRSTSET) != 0)
+    {
+    first_byte = re->first_byte & 255;
+    if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)
+      first_byte = lcc[first_byte];
+    }
+  else
+    {
+    if (!startline && study != NULL &&
+         (study->flags & PCRE_STUDY_MAPPED) != 0)
+      start_bits = study->start_bits;
+    }
+  }
+
+/* For anchored or unanchored matches, there may be a "last known required
+character" set. */
+
+if ((re->flags & PCRE_REQCHSET) != 0)
+  {
+  req_byte = re->req_byte & 255;
+  req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0;
+  req_byte2 = (md->tables + fcc_offset)[req_byte];  /* case flipped */
+  }
+
+/* Call the main matching function, looping for a non-anchored regex after a
+failed match. If not restarting, perform certain optimizations at the start of
+a match. */
+
+for (;;)
+  {
+  int rc;
+
+  if ((options & PCRE_DFA_RESTART) == 0)
+    {
+    const uschar *save_end_subject = end_subject;
+
+    /* If firstline is TRUE, the start of the match is constrained to the first
+    line of a multiline string. Implement this by temporarily adjusting
+    end_subject so that we stop scanning at a newline. If the match fails at
+    the newline, later code breaks this loop. */
+
+    if (firstline)
+      {
+      USPTR t = current_subject;
+#ifdef SUPPORT_UTF8
+      if (utf8)
+        {
+        while (t < md->end_subject && !IS_NEWLINE(t))
+          {
+          t++;
+          while (t < end_subject && (*t & 0xc0) == 0x80) t++;
+          }
+        }
+      else
+#endif
+      while (t < md->end_subject && !IS_NEWLINE(t)) t++;
+      end_subject = t;
+      }
+
+    /* There are some optimizations that avoid running the match if a known
+    starting point is not found. However, there is an option that disables
+    these, for testing and for ensuring that all callouts do actually occur. */
+
+    if ((options & PCRE_NO_START_OPTIMIZE) == 0)
+      {
+      /* Advance to a known first byte. */
+
+      if (first_byte >= 0)
+        {
+        if (first_byte_caseless)
+          while (current_subject < end_subject &&
+                 lcc[*current_subject] != first_byte)
+            current_subject++;
+        else
+          while (current_subject < end_subject &&
+                 *current_subject != first_byte)
+            current_subject++;
+        }
+
+      /* Or to just after a linebreak for a multiline match if possible */
+
+      else if (startline)
+        {
+        if (current_subject > md->start_subject + start_offset)
+          {
+#ifdef SUPPORT_UTF8
+          if (utf8)
+            {
+            while (current_subject < end_subject &&
+                   !WAS_NEWLINE(current_subject))
+              {
+              current_subject++;
+              while(current_subject < end_subject &&
+                    (*current_subject & 0xc0) == 0x80)
+                current_subject++;
+              }
+            }
+          else
+#endif
+          while (current_subject < end_subject && !WAS_NEWLINE(current_subject))
+            current_subject++;
+
+          /* If we have just passed a CR and the newline option is ANY or
+          ANYCRLF, and we are now at a LF, advance the match position by one
+          more character. */
+
+          if (current_subject[-1] == CHAR_CR &&
+               (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
+               current_subject < end_subject &&
+               *current_subject == CHAR_NL)
+            current_subject++;
+          }
+        }
+
+      /* Or to a non-unique first char after study */
+
+      else if (start_bits != NULL)
+        {
+        while (current_subject < end_subject)
+          {
+          register unsigned int c = *current_subject;
+          if ((start_bits[c/8] & (1 << (c&7))) == 0) current_subject++;
+            else break;
+          }
+        }
+      }
+
+    /* Restore fudged end_subject */
+
+    end_subject = save_end_subject;
+
+    /* The following two optimizations are disabled for partial matching or if
+    disabling is explicitly requested (and of course, by the test above, this
+    code is not obeyed when restarting after a partial match). */
+
+    if ((options & PCRE_NO_START_OPTIMIZE) == 0 &&
+        (options & (PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT)) == 0)
+      {
+      /* If the pattern was studied, a minimum subject length may be set. This
+      is a lower bound; no actual string of that length may actually match the
+      pattern. Although the value is, strictly, in characters, we treat it as
+      bytes to avoid spending too much time in this optimization. */
+
+      if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 &&
+          (pcre_uint32)(end_subject - current_subject) < study->minlength)
+        return PCRE_ERROR_NOMATCH;
+
+      /* If req_byte is set, we know that that character must appear in the
+      subject for the match to succeed. If the first character is set, req_byte
+      must be later in the subject; otherwise the test starts at the match
+      point. This optimization can save a huge amount of work in patterns with
+      nested unlimited repeats that aren't going to match. Writing separate
+      code for cased/caseless versions makes it go faster, as does using an
+      autoincrement and backing off on a match.
+
+      HOWEVER: when the subject string is very, very long, searching to its end
+      can take a long time, and give bad performance on quite ordinary
+      patterns. This showed up when somebody was matching /^C/ on a 32-megabyte
+      string... so we don't do this when the string is sufficiently long. */
+
+      if (req_byte >= 0 && end_subject - current_subject < REQ_BYTE_MAX)
+        {
+        register const uschar *p = current_subject + ((first_byte >= 0)? 1 : 0);
+
+        /* We don't need to repeat the search if we haven't yet reached the
+        place we found it at last time. */
+
+        if (p > req_byte_ptr)
+          {
+          if (req_byte_caseless)
+            {
+            while (p < end_subject)
+              {
+              register int pp = *p++;
+              if (pp == req_byte || pp == req_byte2) { p--; break; }
+              }
+            }
+          else
+            {
+            while (p < end_subject)
+              {
+              if (*p++ == req_byte) { p--; break; }
+              }
+            }
+
+          /* If we can't find the required character, break the matching loop,
+          which will cause a return or PCRE_ERROR_NOMATCH. */
+
+          if (p >= end_subject) break;
+
+          /* If we have found the required character, save the point where we
+          found it, so that we don't search again next time round the loop if
+          the start hasn't passed this character yet. */
+
+          req_byte_ptr = p;
+          }
+        }
+      }
+    }   /* End of optimizations that are done when not restarting */
+
+  /* OK, now we can do the business */
+
+  md->start_used_ptr = current_subject;
+
+  rc = internal_dfa_exec(
+    md,                                /* fixed match data */
+    md->start_code,                    /* this subexpression's code */
+    current_subject,                   /* where we currently are */
+    start_offset,                      /* start offset in subject */
+    offsets,                           /* offset vector */
+    offsetcount,                       /* size of same */
+    workspace,                         /* workspace vector */
+    wscount,                           /* size of same */
+    re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL), /* ims flags */
+    0,                                 /* function recurse level */
+    0);                                /* regex recurse level */
+
+  /* Anything other than "no match" means we are done, always; otherwise, carry
+  on only if not anchored. */
+
+  if (rc != PCRE_ERROR_NOMATCH || anchored) return rc;
+
+  /* Advance to the next subject character unless we are at the end of a line
+  and firstline is set. */
+
+  if (firstline && IS_NEWLINE(current_subject)) break;
+  current_subject++;
+  if (utf8)
+    {
+    while (current_subject < end_subject && (*current_subject & 0xc0) == 0x80)
+      current_subject++;
+    }
+  if (current_subject > end_subject) break;
+
+  /* If we have just passed a CR and we are now at a LF, and the pattern does
+  not contain any explicit matches for \r or \n, and the newline option is CRLF
+  or ANY or ANYCRLF, advance the match position by one more character. */
+
+  if (current_subject[-1] == CHAR_CR &&
+      current_subject < end_subject &&
+      *current_subject == CHAR_NL &&
+      (re->flags & PCRE_HASCRORLF) == 0 &&
+        (md->nltype == NLTYPE_ANY ||
+         md->nltype == NLTYPE_ANYCRLF ||
+         md->nllen == 2))
+    current_subject++;
+
+  }   /* "Bumpalong" loop */
+
+return PCRE_ERROR_NOMATCH;
+}
+
+/* End of pcre_dfa_exec.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_exec.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_exec.c
new file mode 100644 (file)
index 0000000..0a44fcc
--- /dev/null
@@ -0,0 +1,5825 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2010 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains pcre_exec(), the externally visible function that does
+pattern matching using an NFA algorithm, trying to mimic Perl as closely as
+possible. There are also some static supporting functions. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#define NLBLOCK md             /* Block containing newline information */
+#define PSSTART start_subject  /* Field containing processed string start */
+#define PSEND   end_subject    /* Field containing processed string end */
+
+#include "pcre_internal.h"
+
+/* Undefine some potentially clashing cpp symbols */
+
+#undef min
+#undef max
+
+/* Flag bits for the match() function */
+
+#define match_condassert     0x01  /* Called to check a condition assertion */
+#define match_cbegroup       0x02  /* Could-be-empty unlimited repeat group */
+
+/* Non-error returns from the match() function. Error returns are externally
+defined PCRE_ERROR_xxx codes, which are all negative. */
+
+#define MATCH_MATCH        1
+#define MATCH_NOMATCH      0
+
+/* Special internal returns from the match() function. Make them sufficiently
+negative to avoid the external error codes. */
+
+#define MATCH_COMMIT       (-999)
+#define MATCH_PRUNE        (-998)
+#define MATCH_SKIP         (-997)
+#define MATCH_THEN         (-996)
+
+/* Maximum number of ints of offset to save on the stack for recursive calls.
+If the offset vector is bigger, malloc is used. This should be a multiple of 3,
+because the offset vector is always a multiple of 3 long. */
+
+#define REC_STACK_SAVE_MAX 30
+
+/* Min and max values for the common repeats; for the maxima, 0 => infinity */
+
+static const char rep_min[] = { 0, 0, 1, 1, 0, 0 };
+static const char rep_max[] = { 0, 0, 0, 0, 1, 1 };
+
+
+
+#ifdef PCRE_DEBUG
+/*************************************************
+*        Debugging function to print chars       *
+*************************************************/
+
+/* Print a sequence of chars in printable format, stopping at the end of the
+subject if the requested.
+
+Arguments:
+  p           points to characters
+  length      number to print
+  is_subject  TRUE if printing from within md->start_subject
+  md          pointer to matching data block, if is_subject is TRUE
+
+Returns:     nothing
+*/
+
+static void
+pchars(const uschar *p, int length, BOOL is_subject, match_data *md)
+{
+unsigned int c;
+if (is_subject && length > md->end_subject - p) length = md->end_subject - p;
+while (length-- > 0)
+  if (isprint(c = *(p++))) printf("%c", c); else printf("\\x%02x", c);
+}
+#endif
+
+
+
+/*************************************************
+*          Match a back-reference                *
+*************************************************/
+
+/* If a back reference hasn't been set, the length that is passed is greater
+than the number of characters left in the string, so the match fails.
+
+Arguments:
+  offset      index into the offset vector
+  eptr        points into the subject
+  length      length to be matched
+  md          points to match data block
+  ims         the ims flags
+
+Returns:      TRUE if matched
+*/
+
+static BOOL
+match_ref(int offset, register USPTR eptr, int length, match_data *md,
+  unsigned long int ims)
+{
+USPTR p = md->start_subject + md->offset_vector[offset];
+
+#ifdef PCRE_DEBUG
+if (eptr >= md->end_subject)
+  printf("matching subject <null>");
+else
+  {
+  printf("matching subject ");
+  pchars(eptr, length, TRUE, md);
+  }
+printf(" against backref ");
+pchars(p, length, FALSE, md);
+printf("\n");
+#endif
+
+/* Always fail if not enough characters left */
+
+if (length > md->end_subject - eptr) return FALSE;
+
+/* Separate the caseless case for speed. In UTF-8 mode we can only do this
+properly if Unicode properties are supported. Otherwise, we can check only
+ASCII characters. */
+
+if ((ims & PCRE_CASELESS) != 0)
+  {
+#ifdef SUPPORT_UTF8
+#ifdef SUPPORT_UCP
+  if (md->utf8)
+    {
+    USPTR endptr = eptr + length;
+    while (eptr < endptr)
+      {
+      int c, d;
+      GETCHARINC(c, eptr);
+      GETCHARINC(d, p);
+      if (c != d && c != UCD_OTHERCASE(d)) return FALSE;
+      }
+    }
+  else
+#endif
+#endif
+
+  /* The same code works when not in UTF-8 mode and in UTF-8 mode when there
+  is no UCP support. */
+
+  while (length-- > 0)
+    { if (md->lcc[*p++] != md->lcc[*eptr++]) return FALSE; }
+  }
+
+/* In the caseful case, we can just compare the bytes, whether or not we
+are in UTF-8 mode. */
+
+else
+  { while (length-- > 0) if (*p++ != *eptr++) return FALSE; }
+
+return TRUE;
+}
+
+
+
+/***************************************************************************
+****************************************************************************
+                   RECURSION IN THE match() FUNCTION
+
+The match() function is highly recursive, though not every recursive call
+increases the recursive depth. Nevertheless, some regular expressions can cause
+it to recurse to a great depth. I was writing for Unix, so I just let it call
+itself recursively. This uses the stack for saving everything that has to be
+saved for a recursive call. On Unix, the stack can be large, and this works
+fine.
+
+It turns out that on some non-Unix-like systems there are problems with
+programs that use a lot of stack. (This despite the fact that every last chip
+has oodles of memory these days, and techniques for extending the stack have
+been known for decades.) So....
+
+There is a fudge, triggered by defining NO_RECURSE, which avoids recursive
+calls by keeping local variables that need to be preserved in blocks of memory
+obtained from malloc() instead instead of on the stack. Macros are used to
+achieve this so that the actual code doesn't look very different to what it
+always used to.
+
+The original heap-recursive code used longjmp(). However, it seems that this
+can be very slow on some operating systems. Following a suggestion from Stan
+Switzer, the use of longjmp() has been abolished, at the cost of having to
+provide a unique number for each call to RMATCH. There is no way of generating
+a sequence of numbers at compile time in C. I have given them names, to make
+them stand out more clearly.
+
+Crude tests on x86 Linux show a small speedup of around 5-8%. However, on
+FreeBSD, avoiding longjmp() more than halves the time taken to run the standard
+tests. Furthermore, not using longjmp() means that local dynamic variables
+don't have indeterminate values; this has meant that the frame size can be
+reduced because the result can be "passed back" by straight setting of the
+variable instead of being passed in the frame.
+****************************************************************************
+***************************************************************************/
+
+/* Numbers for RMATCH calls. When this list is changed, the code at HEAP_RETURN
+below must be updated in sync.  */
+
+enum { RM1=1, RM2,  RM3,  RM4,  RM5,  RM6,  RM7,  RM8,  RM9,  RM10,
+       RM11,  RM12, RM13, RM14, RM15, RM16, RM17, RM18, RM19, RM20,
+       RM21,  RM22, RM23, RM24, RM25, RM26, RM27, RM28, RM29, RM30,
+       RM31,  RM32, RM33, RM34, RM35, RM36, RM37, RM38, RM39, RM40,
+       RM41,  RM42, RM43, RM44, RM45, RM46, RM47, RM48, RM49, RM50,
+       RM51,  RM52, RM53, RM54 };
+
+/* These versions of the macros use the stack, as normal. There are debugging
+versions and production versions. Note that the "rw" argument of RMATCH isn't
+actually used in this definition. */
+
+#ifndef NO_RECURSE
+#define REGISTER register
+
+#ifdef PCRE_DEBUG
+#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
+  { \
+  printf("match() called in line %d\n", __LINE__); \
+  rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1); \
+  printf("to line %d\n", __LINE__); \
+  }
+#define RRETURN(ra) \
+  { \
+  printf("match() returned %d from line %d ", ra, __LINE__); \
+  return ra; \
+  }
+#else
+#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw) \
+  rrc = match(ra,rb,mstart,markptr,rc,rd,re,rf,rg,rdepth+1)
+#define RRETURN(ra) return ra
+#endif
+
+#else
+
+
+/* These versions of the macros manage a private stack on the heap. Note that
+the "rd" argument of RMATCH isn't actually used in this definition. It's the md
+argument of match(), which never changes. */
+
+#define REGISTER
+
+#define RMATCH(ra,rb,rc,rd,re,rf,rg,rw)\
+  {\
+  heapframe *newframe = (pcre_stack_malloc)(sizeof(heapframe));\
+  frame->Xwhere = rw; \
+  newframe->Xeptr = ra;\
+  newframe->Xecode = rb;\
+  newframe->Xmstart = mstart;\
+  newframe->Xmarkptr = markptr;\
+  newframe->Xoffset_top = rc;\
+  newframe->Xims = re;\
+  newframe->Xeptrb = rf;\
+  newframe->Xflags = rg;\
+  newframe->Xrdepth = frame->Xrdepth + 1;\
+  newframe->Xprevframe = frame;\
+  frame = newframe;\
+  DPRINTF(("restarting from line %d\n", __LINE__));\
+  goto HEAP_RECURSE;\
+  L_##rw:\
+  DPRINTF(("jumped back to line %d\n", __LINE__));\
+  }
+
+#define RRETURN(ra)\
+  {\
+  heapframe *newframe = frame;\
+  frame = newframe->Xprevframe;\
+  (pcre_stack_free)(newframe);\
+  if (frame != NULL)\
+    {\
+    rrc = ra;\
+    goto HEAP_RETURN;\
+    }\
+  return ra;\
+  }
+
+
+/* Structure for remembering the local variables in a private frame */
+
+typedef struct heapframe {
+  struct heapframe *Xprevframe;
+
+  /* Function arguments that may change */
+
+  USPTR Xeptr;
+  const uschar *Xecode;
+  USPTR Xmstart;
+  USPTR Xmarkptr;
+  int Xoffset_top;
+  long int Xims;
+  eptrblock *Xeptrb;
+  int Xflags;
+  unsigned int Xrdepth;
+
+  /* Function local variables */
+
+  USPTR Xcallpat;
+#ifdef SUPPORT_UTF8
+  USPTR Xcharptr;
+#endif
+  USPTR Xdata;
+  USPTR Xnext;
+  USPTR Xpp;
+  USPTR Xprev;
+  USPTR Xsaved_eptr;
+
+  recursion_info Xnew_recursive;
+
+  BOOL Xcur_is_word;
+  BOOL Xcondition;
+  BOOL Xprev_is_word;
+
+  unsigned long int Xoriginal_ims;
+
+#ifdef SUPPORT_UCP
+  int Xprop_type;
+  int Xprop_value;
+  int Xprop_fail_result;
+  int Xprop_category;
+  int Xprop_chartype;
+  int Xprop_script;
+  int Xoclength;
+  uschar Xocchars[8];
+#endif
+
+  int Xcodelink;
+  int Xctype;
+  unsigned int Xfc;
+  int Xfi;
+  int Xlength;
+  int Xmax;
+  int Xmin;
+  int Xnumber;
+  int Xoffset;
+  int Xop;
+  int Xsave_capture_last;
+  int Xsave_offset1, Xsave_offset2, Xsave_offset3;
+  int Xstacksave[REC_STACK_SAVE_MAX];
+
+  eptrblock Xnewptrb;
+
+  /* Where to jump back to */
+
+  int Xwhere;
+
+} heapframe;
+
+#endif
+
+
+/***************************************************************************
+***************************************************************************/
+
+
+
+/*************************************************
+*         Match from current position            *
+*************************************************/
+
+/* This function is called recursively in many circumstances. Whenever it
+returns a negative (error) response, the outer incarnation must also return the
+same response. */
+
+/* These macros pack up tests that are used for partial matching, and which
+appears several times in the code. We set the "hit end" flag if the pointer is
+at the end of the subject and also past the start of the subject (i.e.
+something has been matched). For hard partial matching, we then return
+immediately. The second one is used when we already know we are past the end of
+the subject. */
+
+#define CHECK_PARTIAL()\
+  if (md->partial != 0 && eptr >= md->end_subject && eptr > mstart)\
+    {\
+    md->hitend = TRUE;\
+    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);\
+    }
+
+#define SCHECK_PARTIAL()\
+  if (md->partial != 0 && eptr > mstart)\
+    {\
+    md->hitend = TRUE;\
+    if (md->partial > 1) RRETURN(PCRE_ERROR_PARTIAL);\
+    }
+
+
+/* Performance note: It might be tempting to extract commonly used fields from
+the md structure (e.g. utf8, end_subject) into individual variables to improve
+performance. Tests using gcc on a SPARC disproved this; in the first case, it
+made performance worse.
+
+Arguments:
+   eptr        pointer to current character in subject
+   ecode       pointer to current position in compiled code
+   mstart      pointer to the current match start position (can be modified
+                 by encountering \K)
+   markptr     pointer to the most recent MARK name, or NULL
+   offset_top  current top pointer
+   md          pointer to "static" info for the match
+   ims         current /i, /m, and /s options
+   eptrb       pointer to chain of blocks containing eptr at start of
+                 brackets - for testing for empty matches
+   flags       can contain
+                 match_condassert - this is an assertion condition
+                 match_cbegroup - this is the start of an unlimited repeat
+                   group that can match an empty string
+   rdepth      the recursion depth
+
+Returns:       MATCH_MATCH if matched            )  these values are >= 0
+               MATCH_NOMATCH if failed to match  )
+               a negative PCRE_ERROR_xxx value if aborted by an error condition
+                 (e.g. stopped by repeated call or recursion limit)
+*/
+
+static int
+match(REGISTER USPTR eptr, REGISTER const uschar *ecode, USPTR mstart, USPTR
+  markptr, int offset_top, match_data *md, unsigned long int ims,
+  eptrblock *eptrb, int flags, unsigned int rdepth)
+{
+/* These variables do not need to be preserved over recursion in this function,
+so they can be ordinary variables in all cases. Mark some of them with
+"register" because they are used a lot in loops. */
+
+register int  rrc;         /* Returns from recursive calls */
+register int  i;           /* Used for loops not involving calls to RMATCH() */
+register unsigned int c;   /* Character values not kept over RMATCH() calls */
+register BOOL utf8;        /* Local copy of UTF-8 flag for speed */
+
+BOOL minimize, possessive; /* Quantifier options */
+int condcode;
+
+/* When recursion is not being used, all "local" variables that have to be
+preserved over calls to RMATCH() are part of a "frame" which is obtained from
+heap storage. Set up the top-level frame here; others are obtained from the
+heap whenever RMATCH() does a "recursion". See the macro definitions above. */
+
+#ifdef NO_RECURSE
+heapframe *frame = (pcre_stack_malloc)(sizeof(heapframe));
+frame->Xprevframe = NULL;            /* Marks the top level */
+
+/* Copy in the original argument variables */
+
+frame->Xeptr = eptr;
+frame->Xecode = ecode;
+frame->Xmstart = mstart;
+frame->Xmarkptr = markptr;
+frame->Xoffset_top = offset_top;
+frame->Xims = ims;
+frame->Xeptrb = eptrb;
+frame->Xflags = flags;
+frame->Xrdepth = rdepth;
+
+/* This is where control jumps back to to effect "recursion" */
+
+HEAP_RECURSE:
+
+/* Macros make the argument variables come from the current frame */
+
+#define eptr               frame->Xeptr
+#define ecode              frame->Xecode
+#define mstart             frame->Xmstart
+#define markptr            frame->Xmarkptr
+#define offset_top         frame->Xoffset_top
+#define ims                frame->Xims
+#define eptrb              frame->Xeptrb
+#define flags              frame->Xflags
+#define rdepth             frame->Xrdepth
+
+/* Ditto for the local variables */
+
+#ifdef SUPPORT_UTF8
+#define charptr            frame->Xcharptr
+#endif
+#define callpat            frame->Xcallpat
+#define codelink           frame->Xcodelink
+#define data               frame->Xdata
+#define next               frame->Xnext
+#define pp                 frame->Xpp
+#define prev               frame->Xprev
+#define saved_eptr         frame->Xsaved_eptr
+
+#define new_recursive      frame->Xnew_recursive
+
+#define cur_is_word        frame->Xcur_is_word
+#define condition          frame->Xcondition
+#define prev_is_word       frame->Xprev_is_word
+
+#define original_ims       frame->Xoriginal_ims
+
+#ifdef SUPPORT_UCP
+#define prop_type          frame->Xprop_type
+#define prop_value         frame->Xprop_value
+#define prop_fail_result   frame->Xprop_fail_result
+#define prop_category      frame->Xprop_category
+#define prop_chartype      frame->Xprop_chartype
+#define prop_script        frame->Xprop_script
+#define oclength           frame->Xoclength
+#define occhars            frame->Xocchars
+#endif
+
+#define ctype              frame->Xctype
+#define fc                 frame->Xfc
+#define fi                 frame->Xfi
+#define length             frame->Xlength
+#define max                frame->Xmax
+#define min                frame->Xmin
+#define number             frame->Xnumber
+#define offset             frame->Xoffset
+#define op                 frame->Xop
+#define save_capture_last  frame->Xsave_capture_last
+#define save_offset1       frame->Xsave_offset1
+#define save_offset2       frame->Xsave_offset2
+#define save_offset3       frame->Xsave_offset3
+#define stacksave          frame->Xstacksave
+
+#define newptrb            frame->Xnewptrb
+
+/* When recursion is being used, local variables are allocated on the stack and
+get preserved during recursion in the normal way. In this environment, fi and
+i, and fc and c, can be the same variables. */
+
+#else         /* NO_RECURSE not defined */
+#define fi i
+#define fc c
+
+
+#ifdef SUPPORT_UTF8                /* Many of these variables are used only  */
+const uschar *charptr;             /* in small blocks of the code. My normal */
+#endif                             /* style of coding would have declared    */
+const uschar *callpat;             /* them within each of those blocks.      */
+const uschar *data;                /* However, in order to accommodate the   */
+const uschar *next;                /* version of this code that uses an      */
+USPTR         pp;                  /* external "stack" implemented on the    */
+const uschar *prev;                /* heap, it is easier to declare them all */
+USPTR         saved_eptr;          /* here, so the declarations can be cut   */
+                                   /* out in a block. The only declarations  */
+recursion_info new_recursive;      /* within blocks below are for variables  */
+                                   /* that do not have to be preserved over  */
+BOOL cur_is_word;                  /* a recursive call to RMATCH().          */
+BOOL condition;
+BOOL prev_is_word;
+
+unsigned long int original_ims;
+
+#ifdef SUPPORT_UCP
+int prop_type;
+int prop_value;
+int prop_fail_result;
+int prop_category;
+int prop_chartype;
+int prop_script;
+int oclength;
+uschar occhars[8];
+#endif
+
+int codelink;
+int ctype;
+int length;
+int max;
+int min;
+int number;
+int offset;
+int op;
+int save_capture_last;
+int save_offset1, save_offset2, save_offset3;
+int stacksave[REC_STACK_SAVE_MAX];
+
+eptrblock newptrb;
+#endif     /* NO_RECURSE */
+
+/* These statements are here to stop the compiler complaining about unitialized
+variables. */
+
+#ifdef SUPPORT_UCP
+prop_value = 0;
+prop_fail_result = 0;
+#endif
+
+
+/* This label is used for tail recursion, which is used in a few cases even
+when NO_RECURSE is not defined, in order to reduce the amount of stack that is
+used. Thanks to Ian Taylor for noticing this possibility and sending the
+original patch. */
+
+TAIL_RECURSE:
+
+/* OK, now we can get on with the real code of the function. Recursive calls
+are specified by the macro RMATCH and RRETURN is used to return. When
+NO_RECURSE is *not* defined, these just turn into a recursive call to match()
+and a "return", respectively (possibly with some debugging if PCRE_DEBUG is
+defined). However, RMATCH isn't like a function call because it's quite a
+complicated macro. It has to be used in one particular way. This shouldn't,
+however, impact performance when true recursion is being used. */
+
+#ifdef SUPPORT_UTF8
+utf8 = md->utf8;       /* Local copy of the flag */
+#else
+utf8 = FALSE;
+#endif
+
+/* First check that we haven't called match() too many times, or that we
+haven't exceeded the recursive call limit. */
+
+if (md->match_call_count++ >= md->match_limit) RRETURN(PCRE_ERROR_MATCHLIMIT);
+if (rdepth >= md->match_limit_recursion) RRETURN(PCRE_ERROR_RECURSIONLIMIT);
+
+original_ims = ims;    /* Save for resetting on ')' */
+
+/* At the start of a group with an unlimited repeat that may match an empty
+string, the match_cbegroup flag is set. When this is the case, add the current
+subject pointer to the chain of such remembered pointers, to be checked when we
+hit the closing ket, in order to break infinite loops that match no characters.
+When match() is called in other circumstances, don't add to the chain. The
+match_cbegroup flag must NOT be used with tail recursion, because the memory
+block that is used is on the stack, so a new one may be required for each
+match(). */
+
+if ((flags & match_cbegroup) != 0)
+  {
+  newptrb.epb_saved_eptr = eptr;
+  newptrb.epb_prev = eptrb;
+  eptrb = &newptrb;
+  }
+
+/* Now start processing the opcodes. */
+
+for (;;)
+  {
+  minimize = possessive = FALSE;
+  op = *ecode;
+
+  switch(op)
+    {
+    case OP_FAIL:
+    RRETURN(MATCH_NOMATCH);
+
+    case OP_PRUNE:
+    RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
+      ims, eptrb, flags, RM51);
+    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+    RRETURN(MATCH_PRUNE);
+
+    case OP_COMMIT:
+    RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
+      ims, eptrb, flags, RM52);
+    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+    RRETURN(MATCH_COMMIT);
+
+    case OP_SKIP:
+    RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
+      ims, eptrb, flags, RM53);
+    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+    md->start_match_ptr = eptr;   /* Pass back current position */
+    RRETURN(MATCH_SKIP);
+
+    case OP_THEN:
+    RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
+      ims, eptrb, flags, RM54);
+    if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+    RRETURN(MATCH_THEN);
+
+    /* Handle a capturing bracket. If there is space in the offset vector, save
+    the current subject position in the working slot at the top of the vector.
+    We mustn't change the current values of the data slot, because they may be
+    set from a previous iteration of this group, and be referred to by a
+    reference inside the group.
+
+    If the bracket fails to match, we need to restore this value and also the
+    values of the final offsets, in case they were set by a previous iteration
+    of the same bracket.
+
+    If there isn't enough space in the offset vector, treat this as if it were
+    a non-capturing bracket. Don't worry about setting the flag for the error
+    case here; that is handled in the code for KET. */
+
+    case OP_CBRA:
+    case OP_SCBRA:
+    number = GET2(ecode, 1+LINK_SIZE);
+    offset = number << 1;
+
+#ifdef PCRE_DEBUG
+    printf("start bracket %d\n", number);
+    printf("subject=");
+    pchars(eptr, 16, TRUE, md);
+    printf("\n");
+#endif
+
+    if (offset < md->offset_max)
+      {
+      save_offset1 = md->offset_vector[offset];
+      save_offset2 = md->offset_vector[offset+1];
+      save_offset3 = md->offset_vector[md->offset_end - number];
+      save_capture_last = md->capture_last;
+
+      DPRINTF(("saving %d %d %d\n", save_offset1, save_offset2, save_offset3));
+      md->offset_vector[md->offset_end - number] = eptr - md->start_subject;
+
+      flags = (op == OP_SCBRA)? match_cbegroup : 0;
+      do
+        {
+        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md,
+          ims, eptrb, flags, RM1);
+        if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+        md->capture_last = save_capture_last;
+        ecode += GET(ecode, 1);
+        }
+      while (*ecode == OP_ALT);
+
+      DPRINTF(("bracket %d failed\n", number));
+
+      md->offset_vector[offset] = save_offset1;
+      md->offset_vector[offset+1] = save_offset2;
+      md->offset_vector[md->offset_end - number] = save_offset3;
+
+      RRETURN(MATCH_NOMATCH);
+      }
+
+    /* FALL THROUGH ... Insufficient room for saving captured contents. Treat
+    as a non-capturing bracket. */
+
+    /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+    /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+
+    DPRINTF(("insufficient capture room: treat as non-capturing\n"));
+
+    /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+    /* VVVVVVVVVVVVVVVVVVVVVVVVV */
+
+    /* Non-capturing bracket. Loop for all the alternatives. When we get to the
+    final alternative within the brackets, we would return the result of a
+    recursive call to match() whatever happened. We can reduce stack usage by
+    turning this into a tail recursion, except in the case when match_cbegroup
+    is set.*/
+
+    case OP_BRA:
+    case OP_SBRA:
+    DPRINTF(("start non-capturing bracket\n"));
+    flags = (op >= OP_SBRA)? match_cbegroup : 0;
+    for (;;)
+      {
+      if (ecode[GET(ecode, 1)] != OP_ALT)   /* Final alternative */
+        {
+        if (flags == 0)    /* Not a possibly empty group */
+          {
+          ecode += _pcre_OP_lengths[*ecode];
+          DPRINTF(("bracket 0 tail recursion\n"));
+          goto TAIL_RECURSE;
+          }
+
+        /* Possibly empty group; can't use tail recursion. */
+
+        RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
+          eptrb, flags, RM48);
+        RRETURN(rrc);
+        }
+
+      /* For non-final alternatives, continue the loop for a NOMATCH result;
+      otherwise return. */
+
+      RMATCH(eptr, ecode + _pcre_OP_lengths[*ecode], offset_top, md, ims,
+        eptrb, flags, RM2);
+      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+      ecode += GET(ecode, 1);
+      }
+    /* Control never reaches here. */
+
+    /* Conditional group: compilation checked that there are no more than
+    two branches. If the condition is false, skipping the first branch takes us
+    past the end if there is only one branch, but that's OK because that is
+    exactly what going to the ket would do. As there is only one branch to be
+    obeyed, we can use tail recursion to avoid using another stack frame. */
+
+    case OP_COND:
+    case OP_SCOND:
+    codelink= GET(ecode, 1);
+
+    /* Because of the way auto-callout works during compile, a callout item is
+    inserted between OP_COND and an assertion condition. */
+
+    if (ecode[LINK_SIZE+1] == OP_CALLOUT)
+      {
+      if (pcre_callout != NULL)
+        {
+        pcre_callout_block cb;
+        cb.version          = 1;   /* Version 1 of the callout block */
+        cb.callout_number   = ecode[LINK_SIZE+2];
+        cb.offset_vector    = md->offset_vector;
+        cb.subject          = (PCRE_SPTR)md->start_subject;
+        cb.subject_length   = md->end_subject - md->start_subject;
+        cb.start_match      = mstart - md->start_subject;
+        cb.current_position = eptr - md->start_subject;
+        cb.pattern_position = GET(ecode, LINK_SIZE + 3);
+        cb.next_item_length = GET(ecode, 3 + 2*LINK_SIZE);
+        cb.capture_top      = offset_top/2;
+        cb.capture_last     = md->capture_last;
+        cb.callout_data     = md->callout_data;
+        if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);
+        if (rrc < 0) RRETURN(rrc);
+        }
+      ecode += _pcre_OP_lengths[OP_CALLOUT];
+      }
+
+    condcode = ecode[LINK_SIZE+1];
+
+    /* Now see what the actual condition is */
+
+    if (condcode == OP_RREF || condcode == OP_NRREF)    /* Recursion test */
+      {
+      if (md->recursive == NULL)                /* Not recursing => FALSE */
+        {
+        condition = FALSE;
+        ecode += GET(ecode, 1);
+        }
+      else
+        {
+        int recno = GET2(ecode, LINK_SIZE + 2);   /* Recursion group number*/
+        condition =  (recno == RREF_ANY || recno == md->recursive->group_num);
+
+        /* If the test is for recursion into a specific subpattern, and it is
+        false, but the test was set up by name, scan the table to see if the
+        name refers to any other numbers, and test them. The condition is true
+        if any one is set. */
+
+        if (!condition && condcode == OP_NRREF && recno != RREF_ANY)
+          {
+          uschar *slotA = md->name_table;
+          for (i = 0; i < md->name_count; i++)
+            {
+            if (GET2(slotA, 0) == recno) break;
+            slotA += md->name_entry_size;
+            }
+
+          /* Found a name for the number - there can be only one; duplicate
+          names for different numbers are allowed, but not vice versa. First
+          scan down for duplicates. */
+
+          if (i < md->name_count)
+            {
+            uschar *slotB = slotA;
+            while (slotB > md->name_table)
+              {
+              slotB -= md->name_entry_size;
+              if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
+                {
+                condition = GET2(slotB, 0) == md->recursive->group_num;
+                if (condition) break;
+                }
+              else break;
+              }
+
+            /* Scan up for duplicates */
+
+            if (!condition)
+              {
+              slotB = slotA;
+              for (i++; i < md->name_count; i++)
+                {
+                slotB += md->name_entry_size;
+                if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
+                  {
+                  condition = GET2(slotB, 0) == md->recursive->group_num;
+                  if (condition) break;
+                  }
+                else break;
+                }
+              }
+            }
+          }
+
+        /* Chose branch according to the condition */
+
+        ecode += condition? 3 : GET(ecode, 1);
+        }
+      }
+
+    else if (condcode == OP_CREF || condcode == OP_NCREF)  /* Group used test */
+      {
+      offset = GET2(ecode, LINK_SIZE+2) << 1;  /* Doubled ref number */
+      condition = offset < offset_top && md->offset_vector[offset] >= 0;
+
+      /* If the numbered capture is unset, but the reference was by name,
+      scan the table to see if the name refers to any other numbers, and test
+      them. The condition is true if any one is set. This is tediously similar
+      to the code above, but not close enough to try to amalgamate. */
+
+      if (!condition && condcode == OP_NCREF)
+        {
+        int refno = offset >> 1;
+        uschar *slotA = md->name_table;
+
+        for (i = 0; i < md->name_count; i++)
+          {
+          if (GET2(slotA, 0) == refno) break;
+          slotA += md->name_entry_size;
+          }
+
+        /* Found a name for the number - there can be only one; duplicate names
+        for different numbers are allowed, but not vice versa. First scan down
+        for duplicates. */
+
+        if (i < md->name_count)
+          {
+          uschar *slotB = slotA;
+          while (slotB > md->name_table)
+            {
+            slotB -= md->name_entry_size;
+            if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
+              {
+              offset = GET2(slotB, 0) << 1;
+              condition = offset < offset_top &&
+                md->offset_vector[offset] >= 0;
+              if (condition) break;
+              }
+            else break;
+            }
+
+          /* Scan up for duplicates */
+
+          if (!condition)
+            {
+            slotB = slotA;
+            for (i++; i < md->name_count; i++)
+              {
+              slotB += md->name_entry_size;
+              if (strcmp((char *)slotA + 2, (char *)slotB + 2) == 0)
+                {
+                offset = GET2(slotB, 0) << 1;
+                condition = offset < offset_top &&
+                  md->offset_vector[offset] >= 0;
+                if (condition) break;
+                }
+              else break;
+              }
+            }
+          }
+        }
+
+      /* Chose branch according to the condition */
+
+      ecode += condition? 3 : GET(ecode, 1);
+      }
+
+    else if (condcode == OP_DEF)     /* DEFINE - always false */
+      {
+      condition = FALSE;
+      ecode += GET(ecode, 1);
+      }
+
+    /* The condition is an assertion. Call match() to evaluate it - setting
+    the final argument match_condassert causes it to stop at the end of an
+    assertion. */
+
+    else
+      {
+      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL,
+          match_condassert, RM3);
+      if (rrc == MATCH_MATCH)
+        {
+        condition = TRUE;
+        ecode += 1 + LINK_SIZE + GET(ecode, LINK_SIZE + 2);
+        while (*ecode == OP_ALT) ecode += GET(ecode, 1);
+        }
+      else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
+        {
+        RRETURN(rrc);         /* Need braces because of following else */
+        }
+      else
+        {
+        condition = FALSE;
+        ecode += codelink;
+        }
+      }
+
+    /* We are now at the branch that is to be obeyed. As there is only one,
+    we can use tail recursion to avoid using another stack frame, except when
+    match_cbegroup is required for an unlimited repeat of a possibly empty
+    group. If the second alternative doesn't exist, we can just plough on. */
+
+    if (condition || *ecode == OP_ALT)
+      {
+      ecode += 1 + LINK_SIZE;
+      if (op == OP_SCOND)        /* Possibly empty group */
+        {
+        RMATCH(eptr, ecode, offset_top, md, ims, eptrb, match_cbegroup, RM49);
+        RRETURN(rrc);
+        }
+      else                       /* Group must match something */
+        {
+        flags = 0;
+        goto TAIL_RECURSE;
+        }
+      }
+    else                         /* Condition false & no alternative */
+      {
+      ecode += 1 + LINK_SIZE;
+      }
+    break;
+
+
+    /* Before OP_ACCEPT there may be any number of OP_CLOSE opcodes,
+    to close any currently open capturing brackets. */
+
+    case OP_CLOSE:
+    number = GET2(ecode, 1);
+    offset = number << 1;
+
+#ifdef PCRE_DEBUG
+      printf("end bracket %d at *ACCEPT", number);
+      printf("\n");
+#endif
+
+    md->capture_last = number;
+    if (offset >= md->offset_max) md->offset_overflow = TRUE; else
+      {
+      md->offset_vector[offset] =
+        md->offset_vector[md->offset_end - number];
+      md->offset_vector[offset+1] = eptr - md->start_subject;
+      if (offset_top <= offset) offset_top = offset + 2;
+      }
+    ecode += 3;
+    break;
+
+
+    /* End of the pattern, either real or forced. If we are in a top-level
+    recursion, we should restore the offsets appropriately and continue from
+    after the call. */
+
+    case OP_ACCEPT:
+    case OP_END:
+    if (md->recursive != NULL && md->recursive->group_num == 0)
+      {
+      recursion_info *rec = md->recursive;
+      DPRINTF(("End of pattern in a (?0) recursion\n"));
+      md->recursive = rec->prevrec;
+      memmove(md->offset_vector, rec->offset_save,
+        rec->saved_max * sizeof(int));
+      offset_top = rec->save_offset_top;
+      ims = original_ims;
+      ecode = rec->after_call;
+      break;
+      }
+
+    /* Otherwise, if we have matched an empty string, fail if PCRE_NOTEMPTY is
+    set, or if PCRE_NOTEMPTY_ATSTART is set and we have matched at the start of
+    the subject. In both cases, backtracking will then try other alternatives,
+    if any. */
+
+    if (eptr == mstart &&
+        (md->notempty ||
+          (md->notempty_atstart &&
+            mstart == md->start_subject + md->start_offset)))
+      RRETURN(MATCH_NOMATCH);
+
+    /* Otherwise, we have a match. */
+
+    md->end_match_ptr = eptr;           /* Record where we ended */
+    md->end_offset_top = offset_top;    /* and how many extracts were taken */
+    md->start_match_ptr = mstart;       /* and the start (\K can modify) */
+    RRETURN(MATCH_MATCH);
+
+    /* Change option settings */
+
+    case OP_OPT:
+    ims = ecode[1];
+    ecode += 2;
+    DPRINTF(("ims set to %02lx\n", ims));
+    break;
+
+    /* Assertion brackets. Check the alternative branches in turn - the
+    matching won't pass the KET for an assertion. If any one branch matches,
+    the assertion is true. Lookbehind assertions have an OP_REVERSE item at the
+    start of each branch to move the current point backwards, so the code at
+    this level is identical to the lookahead case. */
+
+    case OP_ASSERT:
+    case OP_ASSERTBACK:
+    do
+      {
+      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
+        RM4);
+      if (rrc == MATCH_MATCH)
+        {
+        mstart = md->start_match_ptr;   /* In case \K reset it */
+        break;
+        }
+      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+      ecode += GET(ecode, 1);
+      }
+    while (*ecode == OP_ALT);
+    if (*ecode == OP_KET) RRETURN(MATCH_NOMATCH);
+
+    /* If checking an assertion for a condition, return MATCH_MATCH. */
+
+    if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH);
+
+    /* Continue from after the assertion, updating the offsets high water
+    mark, since extracts may have been taken during the assertion. */
+
+    do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+    ecode += 1 + LINK_SIZE;
+    offset_top = md->end_offset_top;
+    continue;
+
+    /* Negative assertion: all branches must fail to match. Encountering SKIP,
+    PRUNE, or COMMIT means we must assume failure without checking subsequent
+    branches. */
+
+    case OP_ASSERT_NOT:
+    case OP_ASSERTBACK_NOT:
+    do
+      {
+      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, NULL, 0,
+        RM5);
+      if (rrc == MATCH_MATCH) RRETURN(MATCH_NOMATCH);
+      if (rrc == MATCH_SKIP || rrc == MATCH_PRUNE || rrc == MATCH_COMMIT)
+        {
+        do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+        break;
+        }
+      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+      ecode += GET(ecode,1);
+      }
+    while (*ecode == OP_ALT);
+
+    if ((flags & match_condassert) != 0) RRETURN(MATCH_MATCH);
+
+    ecode += 1 + LINK_SIZE;
+    continue;
+
+    /* Move the subject pointer back. This occurs only at the start of
+    each branch of a lookbehind assertion. If we are too close to the start to
+    move back, this match function fails. When working with UTF-8 we move
+    back a number of characters, not bytes. */
+
+    case OP_REVERSE:
+#ifdef SUPPORT_UTF8
+    if (utf8)
+      {
+      i = GET(ecode, 1);
+      while (i-- > 0)
+        {
+        eptr--;
+        if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
+        BACKCHAR(eptr);
+        }
+      }
+    else
+#endif
+
+    /* No UTF-8 support, or not in UTF-8 mode: count is byte count */
+
+      {
+      eptr -= GET(ecode, 1);
+      if (eptr < md->start_subject) RRETURN(MATCH_NOMATCH);
+      }
+
+    /* Save the earliest consulted character, then skip to next op code */
+
+    if (eptr < md->start_used_ptr) md->start_used_ptr = eptr;
+    ecode += 1 + LINK_SIZE;
+    break;
+
+    /* The callout item calls an external function, if one is provided, passing
+    details of the match so far. This is mainly for debugging, though the
+    function is able to force a failure. */
+
+    case OP_CALLOUT:
+    if (pcre_callout != NULL)
+      {
+      pcre_callout_block cb;
+      cb.version          = 1;   /* Version 1 of the callout block */
+      cb.callout_number   = ecode[1];
+      cb.offset_vector    = md->offset_vector;
+      cb.subject          = (PCRE_SPTR)md->start_subject;
+      cb.subject_length   = md->end_subject - md->start_subject;
+      cb.start_match      = mstart - md->start_subject;
+      cb.current_position = eptr - md->start_subject;
+      cb.pattern_position = GET(ecode, 2);
+      cb.next_item_length = GET(ecode, 2 + LINK_SIZE);
+      cb.capture_top      = offset_top/2;
+      cb.capture_last     = md->capture_last;
+      cb.callout_data     = md->callout_data;
+      if ((rrc = (*pcre_callout)(&cb)) > 0) RRETURN(MATCH_NOMATCH);
+      if (rrc < 0) RRETURN(rrc);
+      }
+    ecode += 2 + 2*LINK_SIZE;
+    break;
+
+    /* Recursion either matches the current regex, or some subexpression. The
+    offset data is the offset to the starting bracket from the start of the
+    whole pattern. (This is so that it works from duplicated subpatterns.)
+
+    If there are any capturing brackets started but not finished, we have to
+    save their starting points and reinstate them after the recursion. However,
+    we don't know how many such there are (offset_top records the completed
+    total) so we just have to save all the potential data. There may be up to
+    65535 such values, which is too large to put on the stack, but using malloc
+    for small numbers seems expensive. As a compromise, the stack is used when
+    there are no more than REC_STACK_SAVE_MAX values to store; otherwise malloc
+    is used. A problem is what to do if the malloc fails ... there is no way of
+    returning to the top level with an error. Save the top REC_STACK_SAVE_MAX
+    values on the stack, and accept that the rest may be wrong.
+
+    There are also other values that have to be saved. We use a chained
+    sequence of blocks that actually live on the stack. Thanks to Robin Houston
+    for the original version of this logic. */
+
+    case OP_RECURSE:
+      {
+      callpat = md->start_code + GET(ecode, 1);
+      new_recursive.group_num = (callpat == md->start_code)? 0 :
+        GET2(callpat, 1 + LINK_SIZE);
+
+      /* Add to "recursing stack" */
+
+      new_recursive.prevrec = md->recursive;
+      md->recursive = &new_recursive;
+
+      /* Find where to continue from afterwards */
+
+      ecode += 1 + LINK_SIZE;
+      new_recursive.after_call = ecode;
+
+      /* Now save the offset data. */
+
+      new_recursive.saved_max = md->offset_end;
+      if (new_recursive.saved_max <= REC_STACK_SAVE_MAX)
+        new_recursive.offset_save = stacksave;
+      else
+        {
+        new_recursive.offset_save =
+          (int *)(pcre_malloc)(new_recursive.saved_max * sizeof(int));
+        if (new_recursive.offset_save == NULL) RRETURN(PCRE_ERROR_NOMEMORY);
+        }
+
+      memcpy(new_recursive.offset_save, md->offset_vector,
+            new_recursive.saved_max * sizeof(int));
+      new_recursive.save_offset_top = offset_top;
+
+      /* OK, now we can do the recursion. For each top-level alternative we
+      restore the offset and recursion data. */
+
+      DPRINTF(("Recursing into group %d\n", new_recursive.group_num));
+      flags = (*callpat >= OP_SBRA)? match_cbegroup : 0;
+      do
+        {
+        RMATCH(eptr, callpat + _pcre_OP_lengths[*callpat], offset_top,
+          md, ims, eptrb, flags, RM6);
+        if (rrc == MATCH_MATCH)
+          {
+          DPRINTF(("Recursion matched\n"));
+          md->recursive = new_recursive.prevrec;
+          if (new_recursive.offset_save != stacksave)
+            (pcre_free)(new_recursive.offset_save);
+          RRETURN(MATCH_MATCH);
+          }
+        else if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN)
+          {
+          DPRINTF(("Recursion gave error %d\n", rrc));
+          if (new_recursive.offset_save != stacksave)
+            (pcre_free)(new_recursive.offset_save);
+          RRETURN(rrc);
+          }
+
+        md->recursive = &new_recursive;
+        memcpy(md->offset_vector, new_recursive.offset_save,
+            new_recursive.saved_max * sizeof(int));
+        callpat += GET(callpat, 1);
+        }
+      while (*callpat == OP_ALT);
+
+      DPRINTF(("Recursion didn't match\n"));
+      md->recursive = new_recursive.prevrec;
+      if (new_recursive.offset_save != stacksave)
+        (pcre_free)(new_recursive.offset_save);
+      RRETURN(MATCH_NOMATCH);
+      }
+    /* Control never reaches here */
+
+    /* "Once" brackets are like assertion brackets except that after a match,
+    the point in the subject string is not moved back. Thus there can never be
+    a move back into the brackets. Friedl calls these "atomic" subpatterns.
+    Check the alternative branches in turn - the matching won't pass the KET
+    for this kind of subpattern. If any one branch matches, we carry on as at
+    the end of a normal bracket, leaving the subject pointer, but resetting
+    the start-of-match value in case it was changed by \K. */
+
+    case OP_ONCE:
+    prev = ecode;
+    saved_eptr = eptr;
+
+    do
+      {
+      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM7);
+      if (rrc == MATCH_MATCH)
+        {
+        mstart = md->start_match_ptr;
+        break;
+        }
+      if (rrc != MATCH_NOMATCH && rrc != MATCH_THEN) RRETURN(rrc);
+      ecode += GET(ecode,1);
+      }
+    while (*ecode == OP_ALT);
+
+    /* If hit the end of the group (which could be repeated), fail */
+
+    if (*ecode != OP_ONCE && *ecode != OP_ALT) RRETURN(MATCH_NOMATCH);
+
+    /* Continue as from after the assertion, updating the offsets high water
+    mark, since extracts may have been taken. */
+
+    do ecode += GET(ecode, 1); while (*ecode == OP_ALT);
+
+    offset_top = md->end_offset_top;
+    eptr = md->end_match_ptr;
+
+    /* For a non-repeating ket, just continue at this level. This also
+    happens for a repeating ket if no characters were matched in the group.
+    This is the forcible breaking of infinite loops as implemented in Perl
+    5.005. If there is an options reset, it will get obeyed in the normal
+    course of events. */
+
+    if (*ecode == OP_KET || eptr == saved_eptr)
+      {
+      ecode += 1+LINK_SIZE;
+      break;
+      }
+
+    /* The repeating kets try the rest of the pattern or restart from the
+    preceding bracket, in the appropriate order. The second "call" of match()
+    uses tail recursion, to avoid using another stack frame. We need to reset
+    any options that changed within the bracket before re-running it, so
+    check the next opcode. */
+
+    if (ecode[1+LINK_SIZE] == OP_OPT)
+      {
+      ims = (ims & ~PCRE_IMS) | ecode[4];
+      DPRINTF(("ims set to %02lx at group repeat\n", ims));
+      }
+
+    if (*ecode == OP_KETRMIN)
+      {
+      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM8);
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      ecode = prev;
+      flags = 0;
+      goto TAIL_RECURSE;
+      }
+    else  /* OP_KETRMAX */
+      {
+      RMATCH(eptr, prev, offset_top, md, ims, eptrb, match_cbegroup, RM9);
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      ecode += 1 + LINK_SIZE;
+      flags = 0;
+      goto TAIL_RECURSE;
+      }
+    /* Control never gets here */
+
+    /* An alternation is the end of a branch; scan along to find the end of the
+    bracketed group and go to there. */
+
+    case OP_ALT:
+    do ecode += GET(ecode,1); while (*ecode == OP_ALT);
+    break;
+
+    /* BRAZERO, BRAMINZERO and SKIPZERO occur just before a bracket group,
+    indicating that it may occur zero times. It may repeat infinitely, or not
+    at all - i.e. it could be ()* or ()? or even (){0} in the pattern. Brackets
+    with fixed upper repeat limits are compiled as a number of copies, with the
+    optional ones preceded by BRAZERO or BRAMINZERO. */
+
+    case OP_BRAZERO:
+      {
+      next = ecode+1;
+      RMATCH(eptr, next, offset_top, md, ims, eptrb, 0, RM10);
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      do next += GET(next,1); while (*next == OP_ALT);
+      ecode = next + 1 + LINK_SIZE;
+      }
+    break;
+
+    case OP_BRAMINZERO:
+      {
+      next = ecode+1;
+      do next += GET(next, 1); while (*next == OP_ALT);
+      RMATCH(eptr, next + 1+LINK_SIZE, offset_top, md, ims, eptrb, 0, RM11);
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      ecode++;
+      }
+    break;
+
+    case OP_SKIPZERO:
+      {
+      next = ecode+1;
+      do next += GET(next,1); while (*next == OP_ALT);
+      ecode = next + 1 + LINK_SIZE;
+      }
+    break;
+
+    /* End of a group, repeated or non-repeating. */
+
+    case OP_KET:
+    case OP_KETRMIN:
+    case OP_KETRMAX:
+    prev = ecode - GET(ecode, 1);
+
+    /* If this was a group that remembered the subject start, in order to break
+    infinite repeats of empty string matches, retrieve the subject start from
+    the chain. Otherwise, set it NULL. */
+
+    if (*prev >= OP_SBRA)
+      {
+      saved_eptr = eptrb->epb_saved_eptr;   /* Value at start of group */
+      eptrb = eptrb->epb_prev;              /* Backup to previous group */
+      }
+    else saved_eptr = NULL;
+
+    /* If we are at the end of an assertion group or an atomic group, stop
+    matching and return MATCH_MATCH, but record the current high water mark for
+    use by positive assertions. We also need to record the match start in case
+    it was changed by \K. */
+
+    if (*prev == OP_ASSERT || *prev == OP_ASSERT_NOT ||
+        *prev == OP_ASSERTBACK || *prev == OP_ASSERTBACK_NOT ||
+        *prev == OP_ONCE)
+      {
+      md->end_match_ptr = eptr;      /* For ONCE */
+      md->end_offset_top = offset_top;
+      md->start_match_ptr = mstart;
+      RRETURN(MATCH_MATCH);
+      }
+
+    /* For capturing groups we have to check the group number back at the start
+    and if necessary complete handling an extraction by setting the offsets and
+    bumping the high water mark. Note that whole-pattern recursion is coded as
+    a recurse into group 0, so it won't be picked up here. Instead, we catch it
+    when the OP_END is reached. Other recursion is handled here. */
+
+    if (*prev == OP_CBRA || *prev == OP_SCBRA)
+      {
+      number = GET2(prev, 1+LINK_SIZE);
+      offset = number << 1;
+
+#ifdef PCRE_DEBUG
+      printf("end bracket %d", number);
+      printf("\n");
+#endif
+
+      md->capture_last = number;
+      if (offset >= md->offset_max) md->offset_overflow = TRUE; else
+        {
+        md->offset_vector[offset] =
+          md->offset_vector[md->offset_end - number];
+        md->offset_vector[offset+1] = eptr - md->start_subject;
+        if (offset_top <= offset) offset_top = offset + 2;
+        }
+
+      /* Handle a recursively called group. Restore the offsets
+      appropriately and continue from after the call. */
+
+      if (md->recursive != NULL && md->recursive->group_num == number)
+        {
+        recursion_info *rec = md->recursive;
+        DPRINTF(("Recursion (%d) succeeded - continuing\n", number));
+        md->recursive = rec->prevrec;
+        memcpy(md->offset_vector, rec->offset_save,
+          rec->saved_max * sizeof(int));
+        offset_top = rec->save_offset_top;
+        ecode = rec->after_call;
+        ims = original_ims;
+        break;
+        }
+      }
+
+    /* For both capturing and non-capturing groups, reset the value of the ims
+    flags, in case they got changed during the group. */
+
+    ims = original_ims;
+    DPRINTF(("ims reset to %02lx\n", ims));
+
+    /* For a non-repeating ket, just continue at this level. This also
+    happens for a repeating ket if no characters were matched in the group.
+    This is the forcible breaking of infinite loops as implemented in Perl
+    5.005. If there is an options reset, it will get obeyed in the normal
+    course of events. */
+
+    if (*ecode == OP_KET || eptr == saved_eptr)
+      {
+      ecode += 1 + LINK_SIZE;
+      break;
+      }
+
+    /* The repeating kets try the rest of the pattern or restart from the
+    preceding bracket, in the appropriate order. In the second case, we can use
+    tail recursion to avoid using another stack frame, unless we have an
+    unlimited repeat of a group that can match an empty string. */
+
+    flags = (*prev >= OP_SBRA)? match_cbegroup : 0;
+
+    if (*ecode == OP_KETRMIN)
+      {
+      RMATCH(eptr, ecode + 1 + LINK_SIZE, offset_top, md, ims, eptrb, 0, RM12);
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      if (flags != 0)    /* Could match an empty string */
+        {
+        RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM50);
+        RRETURN(rrc);
+        }
+      ecode = prev;
+      goto TAIL_RECURSE;
+      }
+    else  /* OP_KETRMAX */
+      {
+      RMATCH(eptr, prev, offset_top, md, ims, eptrb, flags, RM13);
+      if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+      ecode += 1 + LINK_SIZE;
+      flags = 0;
+      goto TAIL_RECURSE;
+      }
+    /* Control never gets here */
+
+    /* Start of subject unless notbol, or after internal newline if multiline */
+
+    case OP_CIRC:
+    if (md->notbol && eptr == md->start_subject) RRETURN(MATCH_NOMATCH);
+    if ((ims & PCRE_MULTILINE) != 0)
+      {
+      if (eptr != md->start_subject &&
+          (eptr == md->end_subject || !WAS_NEWLINE(eptr)))
+        RRETURN(MATCH_NOMATCH);
+      ecode++;
+      break;
+      }
+    /* ... else fall through */
+
+    /* Start of subject assertion */
+
+    case OP_SOD:
+    if (eptr != md->start_subject) RRETURN(MATCH_NOMATCH);
+    ecode++;
+    break;
+
+    /* Start of match assertion */
+
+    case OP_SOM:
+    if (eptr != md->start_subject + md->start_offset) RRETURN(MATCH_NOMATCH);
+    ecode++;
+    break;
+
+    /* Reset the start of match point */
+
+    case OP_SET_SOM:
+    mstart = eptr;
+    ecode++;
+    break;
+
+    /* Assert before internal newline if multiline, or before a terminating
+    newline unless endonly is set, else end of subject unless noteol is set. */
+
+    case OP_DOLL:
+    if ((ims & PCRE_MULTILINE) != 0)
+      {
+      if (eptr < md->end_subject)
+        { if (!IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH); }
+      else
+        { if (md->noteol) RRETURN(MATCH_NOMATCH); }
+      ecode++;
+      break;
+      }
+    else
+      {
+      if (md->noteol) RRETURN(MATCH_NOMATCH);
+      if (!md->endonly)
+        {
+        if (eptr != md->end_subject &&
+            (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
+          RRETURN(MATCH_NOMATCH);
+        ecode++;
+        break;
+        }
+      }
+    /* ... else fall through for endonly */
+
+    /* End of subject assertion (\z) */
+
+    case OP_EOD:
+    if (eptr < md->end_subject) RRETURN(MATCH_NOMATCH);
+    ecode++;
+    break;
+
+    /* End of subject or ending \n assertion (\Z) */
+
+    case OP_EODN:
+    if (eptr != md->end_subject &&
+        (!IS_NEWLINE(eptr) || eptr != md->end_subject - md->nllen))
+      RRETURN(MATCH_NOMATCH);
+    ecode++;
+    break;
+
+    /* Word boundary assertions */
+
+    case OP_NOT_WORD_BOUNDARY:
+    case OP_WORD_BOUNDARY:
+      {
+
+      /* Find out if the previous and current characters are "word" characters.
+      It takes a bit more work in UTF-8 mode. Characters > 255 are assumed to
+      be "non-word" characters. Remember the earliest consulted character for
+      partial matching. */
+
+#ifdef SUPPORT_UTF8
+      if (utf8)
+        {
+        if (eptr == md->start_subject) prev_is_word = FALSE; else
+          {
+          USPTR lastptr = eptr - 1;
+          while((*lastptr & 0xc0) == 0x80) lastptr--;
+          if (lastptr < md->start_used_ptr) md->start_used_ptr = lastptr;
+          GETCHAR(c, lastptr);
+          prev_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
+          }
+        if (eptr >= md->end_subject)
+          {
+          SCHECK_PARTIAL();
+          cur_is_word = FALSE;
+          }
+        else
+          {
+          GETCHAR(c, eptr);
+          cur_is_word = c < 256 && (md->ctypes[c] & ctype_word) != 0;
+          }
+        }
+      else
+#endif
+
+      /* Not in UTF-8 mode */
+
+        {
+        if (eptr == md->start_subject) prev_is_word = FALSE; else
+          {
+          if (eptr <= md->start_used_ptr) md->start_used_ptr = eptr - 1;
+          prev_is_word = ((md->ctypes[eptr[-1]] & ctype_word) != 0);
+          }
+        if (eptr >= md->end_subject)
+          {
+          SCHECK_PARTIAL();
+          cur_is_word = FALSE;
+          }
+        else cur_is_word = ((md->ctypes[*eptr] & ctype_word) != 0);
+        }
+
+      /* Now see if the situation is what we want */
+
+      if ((*ecode++ == OP_WORD_BOUNDARY)?
+           cur_is_word == prev_is_word : cur_is_word != prev_is_word)
+        RRETURN(MATCH_NOMATCH);
+      }
+    break;
+
+    /* Match a single character type; inline for speed */
+
+    case OP_ANY:
+    if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+    /* Fall through */
+
+    case OP_ALLANY:
+    if (eptr++ >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    if (utf8) while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
+    ecode++;
+    break;
+
+    /* Match a single byte, even in UTF-8 mode. This opcode really does match
+    any byte, even newline, independent of the setting of PCRE_DOTALL. */
+
+    case OP_ANYBYTE:
+    if (eptr++ >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    ecode++;
+    break;
+
+    case OP_NOT_DIGIT:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(c, eptr);
+    if (
+#ifdef SUPPORT_UTF8
+       c < 256 &&
+#endif
+       (md->ctypes[c] & ctype_digit) != 0
+       )
+      RRETURN(MATCH_NOMATCH);
+    ecode++;
+    break;
+
+    case OP_DIGIT:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(c, eptr);
+    if (
+#ifdef SUPPORT_UTF8
+       c >= 256 ||
+#endif
+       (md->ctypes[c] & ctype_digit) == 0
+       )
+      RRETURN(MATCH_NOMATCH);
+    ecode++;
+    break;
+
+    case OP_NOT_WHITESPACE:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(c, eptr);
+    if (
+#ifdef SUPPORT_UTF8
+       c < 256 &&
+#endif
+       (md->ctypes[c] & ctype_space) != 0
+       )
+      RRETURN(MATCH_NOMATCH);
+    ecode++;
+    break;
+
+    case OP_WHITESPACE:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(c, eptr);
+    if (
+#ifdef SUPPORT_UTF8
+       c >= 256 ||
+#endif
+       (md->ctypes[c] & ctype_space) == 0
+       )
+      RRETURN(MATCH_NOMATCH);
+    ecode++;
+    break;
+
+    case OP_NOT_WORDCHAR:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(c, eptr);
+    if (
+#ifdef SUPPORT_UTF8
+       c < 256 &&
+#endif
+       (md->ctypes[c] & ctype_word) != 0
+       )
+      RRETURN(MATCH_NOMATCH);
+    ecode++;
+    break;
+
+    case OP_WORDCHAR:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(c, eptr);
+    if (
+#ifdef SUPPORT_UTF8
+       c >= 256 ||
+#endif
+       (md->ctypes[c] & ctype_word) == 0
+       )
+      RRETURN(MATCH_NOMATCH);
+    ecode++;
+    break;
+
+    case OP_ANYNL:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(c, eptr);
+    switch(c)
+      {
+      default: RRETURN(MATCH_NOMATCH);
+      case 0x000d:
+      if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+      break;
+
+      case 0x000a:
+      break;
+
+      case 0x000b:
+      case 0x000c:
+      case 0x0085:
+      case 0x2028:
+      case 0x2029:
+      if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+      break;
+      }
+    ecode++;
+    break;
+
+    case OP_NOT_HSPACE:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(c, eptr);
+    switch(c)
+      {
+      default: break;
+      case 0x09:      /* HT */
+      case 0x20:      /* SPACE */
+      case 0xa0:      /* NBSP */
+      case 0x1680:    /* OGHAM SPACE MARK */
+      case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
+      case 0x2000:    /* EN QUAD */
+      case 0x2001:    /* EM QUAD */
+      case 0x2002:    /* EN SPACE */
+      case 0x2003:    /* EM SPACE */
+      case 0x2004:    /* THREE-PER-EM SPACE */
+      case 0x2005:    /* FOUR-PER-EM SPACE */
+      case 0x2006:    /* SIX-PER-EM SPACE */
+      case 0x2007:    /* FIGURE SPACE */
+      case 0x2008:    /* PUNCTUATION SPACE */
+      case 0x2009:    /* THIN SPACE */
+      case 0x200A:    /* HAIR SPACE */
+      case 0x202f:    /* NARROW NO-BREAK SPACE */
+      case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
+      case 0x3000:    /* IDEOGRAPHIC SPACE */
+      RRETURN(MATCH_NOMATCH);
+      }
+    ecode++;
+    break;
+
+    case OP_HSPACE:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(c, eptr);
+    switch(c)
+      {
+      default: RRETURN(MATCH_NOMATCH);
+      case 0x09:      /* HT */
+      case 0x20:      /* SPACE */
+      case 0xa0:      /* NBSP */
+      case 0x1680:    /* OGHAM SPACE MARK */
+      case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
+      case 0x2000:    /* EN QUAD */
+      case 0x2001:    /* EM QUAD */
+      case 0x2002:    /* EN SPACE */
+      case 0x2003:    /* EM SPACE */
+      case 0x2004:    /* THREE-PER-EM SPACE */
+      case 0x2005:    /* FOUR-PER-EM SPACE */
+      case 0x2006:    /* SIX-PER-EM SPACE */
+      case 0x2007:    /* FIGURE SPACE */
+      case 0x2008:    /* PUNCTUATION SPACE */
+      case 0x2009:    /* THIN SPACE */
+      case 0x200A:    /* HAIR SPACE */
+      case 0x202f:    /* NARROW NO-BREAK SPACE */
+      case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
+      case 0x3000:    /* IDEOGRAPHIC SPACE */
+      break;
+      }
+    ecode++;
+    break;
+
+    case OP_NOT_VSPACE:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(c, eptr);
+    switch(c)
+      {
+      default: break;
+      case 0x0a:      /* LF */
+      case 0x0b:      /* VT */
+      case 0x0c:      /* FF */
+      case 0x0d:      /* CR */
+      case 0x85:      /* NEL */
+      case 0x2028:    /* LINE SEPARATOR */
+      case 0x2029:    /* PARAGRAPH SEPARATOR */
+      RRETURN(MATCH_NOMATCH);
+      }
+    ecode++;
+    break;
+
+    case OP_VSPACE:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(c, eptr);
+    switch(c)
+      {
+      default: RRETURN(MATCH_NOMATCH);
+      case 0x0a:      /* LF */
+      case 0x0b:      /* VT */
+      case 0x0c:      /* FF */
+      case 0x0d:      /* CR */
+      case 0x85:      /* NEL */
+      case 0x2028:    /* LINE SEPARATOR */
+      case 0x2029:    /* PARAGRAPH SEPARATOR */
+      break;
+      }
+    ecode++;
+    break;
+
+#ifdef SUPPORT_UCP
+    /* Check the next character by Unicode property. We will get here only
+    if the support is in the binary; otherwise a compile-time error occurs. */
+
+    case OP_PROP:
+    case OP_NOTPROP:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(c, eptr);
+      {
+      int chartype = UCD_CHARTYPE(c);
+      switch(ecode[1])
+        {
+        case PT_ANY:
+        if (op == OP_NOTPROP) RRETURN(MATCH_NOMATCH);
+        break;
+
+        case PT_LAMP:
+        if ((chartype == ucp_Lu ||
+             chartype == ucp_Ll ||
+             chartype == ucp_Lt) == (op == OP_NOTPROP))
+          RRETURN(MATCH_NOMATCH);
+         break;
+
+        case PT_GC:
+        if ((ecode[2] != _pcre_ucp_gentype[chartype]) == (op == OP_PROP))
+          RRETURN(MATCH_NOMATCH);
+        break;
+
+        case PT_PC:
+        if ((ecode[2] != chartype) == (op == OP_PROP))
+          RRETURN(MATCH_NOMATCH);
+        break;
+
+        case PT_SC:
+        if ((ecode[2] != UCD_SCRIPT(c)) == (op == OP_PROP))
+          RRETURN(MATCH_NOMATCH);
+        break;
+
+        default:
+        RRETURN(PCRE_ERROR_INTERNAL);
+        }
+
+      ecode += 3;
+      }
+    break;
+
+    /* Match an extended Unicode sequence. We will get here only if the support
+    is in the binary; otherwise a compile-time error occurs. */
+
+    case OP_EXTUNI:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    GETCHARINCTEST(c, eptr);
+      {
+      int category = UCD_CATEGORY(c);
+      if (category == ucp_M) RRETURN(MATCH_NOMATCH);
+      while (eptr < md->end_subject)
+        {
+        int len = 1;
+        if (!utf8) c = *eptr; else
+          {
+          GETCHARLEN(c, eptr, len);
+          }
+        category = UCD_CATEGORY(c);
+        if (category != ucp_M) break;
+        eptr += len;
+        }
+      }
+    ecode++;
+    break;
+#endif
+
+
+    /* Match a back reference, possibly repeatedly. Look past the end of the
+    item to see if there is repeat information following. The code is similar
+    to that for character classes, but repeated for efficiency. Then obey
+    similar code to character type repeats - written out again for speed.
+    However, if the referenced string is the empty string, always treat
+    it as matched, any number of times (otherwise there could be infinite
+    loops). */
+
+    case OP_REF:
+      {
+      offset = GET2(ecode, 1) << 1;               /* Doubled ref number */
+      ecode += 3;
+
+      /* If the reference is unset, there are two possibilities:
+
+      (a) In the default, Perl-compatible state, set the length to be longer
+      than the amount of subject left; this ensures that every attempt at a
+      match fails. We can't just fail here, because of the possibility of
+      quantifiers with zero minima.
+
+      (b) If the JavaScript compatibility flag is set, set the length to zero
+      so that the back reference matches an empty string.
+
+      Otherwise, set the length to the length of what was matched by the
+      referenced subpattern. */
+
+      if (offset >= offset_top || md->offset_vector[offset] < 0)
+        length = (md->jscript_compat)? 0 : md->end_subject - eptr + 1;
+      else
+        length = md->offset_vector[offset+1] - md->offset_vector[offset];
+
+      /* Set up for repetition, or handle the non-repeated case */
+
+      switch (*ecode)
+        {
+        case OP_CRSTAR:
+        case OP_CRMINSTAR:
+        case OP_CRPLUS:
+        case OP_CRMINPLUS:
+        case OP_CRQUERY:
+        case OP_CRMINQUERY:
+        c = *ecode++ - OP_CRSTAR;
+        minimize = (c & 1) != 0;
+        min = rep_min[c];                 /* Pick up values from tables; */
+        max = rep_max[c];                 /* zero for max => infinity */
+        if (max == 0) max = INT_MAX;
+        break;
+
+        case OP_CRRANGE:
+        case OP_CRMINRANGE:
+        minimize = (*ecode == OP_CRMINRANGE);
+        min = GET2(ecode, 1);
+        max = GET2(ecode, 3);
+        if (max == 0) max = INT_MAX;
+        ecode += 5;
+        break;
+
+        default:               /* No repeat follows */
+        if (!match_ref(offset, eptr, length, md, ims))
+          {
+          CHECK_PARTIAL();
+          RRETURN(MATCH_NOMATCH);
+          }
+        eptr += length;
+        continue;              /* With the main loop */
+        }
+
+      /* If the length of the reference is zero, just continue with the
+      main loop. */
+
+      if (length == 0) continue;
+
+      /* First, ensure the minimum number of matches are present. We get back
+      the length of the reference string explicitly rather than passing the
+      address of eptr, so that eptr can be a register variable. */
+
+      for (i = 1; i <= min; i++)
+        {
+        if (!match_ref(offset, eptr, length, md, ims))
+          {
+          CHECK_PARTIAL();
+          RRETURN(MATCH_NOMATCH);
+          }
+        eptr += length;
+        }
+
+      /* If min = max, continue at the same level without recursion.
+      They are not both allowed to be zero. */
+
+      if (min == max) continue;
+
+      /* If minimizing, keep trying and advancing the pointer */
+
+      if (minimize)
+        {
+        for (fi = min;; fi++)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM14);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (fi >= max) RRETURN(MATCH_NOMATCH);
+          if (!match_ref(offset, eptr, length, md, ims))
+            {
+            CHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          eptr += length;
+          }
+        /* Control never gets here */
+        }
+
+      /* If maximizing, find the longest string and work backwards */
+
+      else
+        {
+        pp = eptr;
+        for (i = min; i < max; i++)
+          {
+          if (!match_ref(offset, eptr, length, md, ims))
+            {
+            CHECK_PARTIAL();
+            break;
+            }
+          eptr += length;
+          }
+        while (eptr >= pp)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM15);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          eptr -= length;
+          }
+        RRETURN(MATCH_NOMATCH);
+        }
+      }
+    /* Control never gets here */
+
+    /* Match a bit-mapped character class, possibly repeatedly. This op code is
+    used when all the characters in the class have values in the range 0-255,
+    and either the matching is caseful, or the characters are in the range
+    0-127 when UTF-8 processing is enabled. The only difference between
+    OP_CLASS and OP_NCLASS occurs when a data character outside the range is
+    encountered.
+
+    First, look past the end of the item to see if there is repeat information
+    following. Then obey similar code to character type repeats - written out
+    again for speed. */
+
+    case OP_NCLASS:
+    case OP_CLASS:
+      {
+      data = ecode + 1;                /* Save for matching */
+      ecode += 33;                     /* Advance past the item */
+
+      switch (*ecode)
+        {
+        case OP_CRSTAR:
+        case OP_CRMINSTAR:
+        case OP_CRPLUS:
+        case OP_CRMINPLUS:
+        case OP_CRQUERY:
+        case OP_CRMINQUERY:
+        c = *ecode++ - OP_CRSTAR;
+        minimize = (c & 1) != 0;
+        min = rep_min[c];                 /* Pick up values from tables; */
+        max = rep_max[c];                 /* zero for max => infinity */
+        if (max == 0) max = INT_MAX;
+        break;
+
+        case OP_CRRANGE:
+        case OP_CRMINRANGE:
+        minimize = (*ecode == OP_CRMINRANGE);
+        min = GET2(ecode, 1);
+        max = GET2(ecode, 3);
+        if (max == 0) max = INT_MAX;
+        ecode += 5;
+        break;
+
+        default:               /* No repeat follows */
+        min = max = 1;
+        break;
+        }
+
+      /* First, ensure the minimum number of matches are present. */
+
+#ifdef SUPPORT_UTF8
+      /* UTF-8 mode */
+      if (utf8)
+        {
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINC(c, eptr);
+          if (c > 255)
+            {
+            if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+            }
+          else
+            {
+            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+            }
+          }
+        }
+      else
+#endif
+      /* Not UTF-8 mode */
+        {
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          c = *eptr++;
+          if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+          }
+        }
+
+      /* If max == min we can continue with the main loop without the
+      need to recurse. */
+
+      if (min == max) continue;
+
+      /* If minimizing, keep testing the rest of the expression and advancing
+      the pointer while it matches the class. */
+
+      if (minimize)
+        {
+#ifdef SUPPORT_UTF8
+        /* UTF-8 mode */
+        if (utf8)
+          {
+          for (fi = min;; fi++)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM16);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINC(c, eptr);
+            if (c > 255)
+              {
+              if (op == OP_CLASS) RRETURN(MATCH_NOMATCH);
+              }
+            else
+              {
+              if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+              }
+            }
+          }
+        else
+#endif
+        /* Not UTF-8 mode */
+          {
+          for (fi = min;; fi++)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM17);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            c = *eptr++;
+            if ((data[c/8] & (1 << (c&7))) == 0) RRETURN(MATCH_NOMATCH);
+            }
+          }
+        /* Control never gets here */
+        }
+
+      /* If maximizing, find the longest possible run, then work backwards. */
+
+      else
+        {
+        pp = eptr;
+
+#ifdef SUPPORT_UTF8
+        /* UTF-8 mode */
+        if (utf8)
+          {
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            if (c > 255)
+              {
+              if (op == OP_CLASS) break;
+              }
+            else
+              {
+              if ((data[c/8] & (1 << (c&7))) == 0) break;
+              }
+            eptr += len;
+            }
+          for (;;)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM18);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (eptr-- == pp) break;        /* Stop if tried at original pos */
+            BACKCHAR(eptr);
+            }
+          }
+        else
+#endif
+          /* Not UTF-8 mode */
+          {
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            c = *eptr;
+            if ((data[c/8] & (1 << (c&7))) == 0) break;
+            eptr++;
+            }
+          while (eptr >= pp)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM19);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            eptr--;
+            }
+          }
+
+        RRETURN(MATCH_NOMATCH);
+        }
+      }
+    /* Control never gets here */
+
+
+    /* Match an extended character class. This opcode is encountered only
+    when UTF-8 mode mode is supported. Nevertheless, we may not be in UTF-8
+    mode, because Unicode properties are supported in non-UTF-8 mode. */
+
+#ifdef SUPPORT_UTF8
+    case OP_XCLASS:
+      {
+      data = ecode + 1 + LINK_SIZE;                /* Save for matching */
+      ecode += GET(ecode, 1);                      /* Advance past the item */
+
+      switch (*ecode)
+        {
+        case OP_CRSTAR:
+        case OP_CRMINSTAR:
+        case OP_CRPLUS:
+        case OP_CRMINPLUS:
+        case OP_CRQUERY:
+        case OP_CRMINQUERY:
+        c = *ecode++ - OP_CRSTAR;
+        minimize = (c & 1) != 0;
+        min = rep_min[c];                 /* Pick up values from tables; */
+        max = rep_max[c];                 /* zero for max => infinity */
+        if (max == 0) max = INT_MAX;
+        break;
+
+        case OP_CRRANGE:
+        case OP_CRMINRANGE:
+        minimize = (*ecode == OP_CRMINRANGE);
+        min = GET2(ecode, 1);
+        max = GET2(ecode, 3);
+        if (max == 0) max = INT_MAX;
+        ecode += 5;
+        break;
+
+        default:               /* No repeat follows */
+        min = max = 1;
+        break;
+        }
+
+      /* First, ensure the minimum number of matches are present. */
+
+      for (i = 1; i <= min; i++)
+        {
+        if (eptr >= md->end_subject)
+          {
+          SCHECK_PARTIAL();
+          RRETURN(MATCH_NOMATCH);
+          }
+        GETCHARINCTEST(c, eptr);
+        if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
+        }
+
+      /* If max == min we can continue with the main loop without the
+      need to recurse. */
+
+      if (min == max) continue;
+
+      /* If minimizing, keep testing the rest of the expression and advancing
+      the pointer while it matches the class. */
+
+      if (minimize)
+        {
+        for (fi = min;; fi++)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM20);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (fi >= max) RRETURN(MATCH_NOMATCH);
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINCTEST(c, eptr);
+          if (!_pcre_xclass(c, data)) RRETURN(MATCH_NOMATCH);
+          }
+        /* Control never gets here */
+        }
+
+      /* If maximizing, find the longest possible run, then work backwards. */
+
+      else
+        {
+        pp = eptr;
+        for (i = min; i < max; i++)
+          {
+          int len = 1;
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            break;
+            }
+          GETCHARLENTEST(c, eptr, len);
+          if (!_pcre_xclass(c, data)) break;
+          eptr += len;
+          }
+        for(;;)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM21);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (eptr-- == pp) break;        /* Stop if tried at original pos */
+          if (utf8) BACKCHAR(eptr);
+          }
+        RRETURN(MATCH_NOMATCH);
+        }
+
+      /* Control never gets here */
+      }
+#endif    /* End of XCLASS */
+
+    /* Match a single character, casefully */
+
+    case OP_CHAR:
+#ifdef SUPPORT_UTF8
+    if (utf8)
+      {
+      length = 1;
+      ecode++;
+      GETCHARLEN(fc, ecode, length);
+      if (length > md->end_subject - eptr)
+        {
+        CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
+        RRETURN(MATCH_NOMATCH);
+        }
+      while (length-- > 0) if (*ecode++ != *eptr++) RRETURN(MATCH_NOMATCH);
+      }
+    else
+#endif
+
+    /* Non-UTF-8 mode */
+      {
+      if (md->end_subject - eptr < 1)
+        {
+        SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
+        RRETURN(MATCH_NOMATCH);
+        }
+      if (ecode[1] != *eptr++) RRETURN(MATCH_NOMATCH);
+      ecode += 2;
+      }
+    break;
+
+    /* Match a single character, caselessly */
+
+    case OP_CHARNC:
+#ifdef SUPPORT_UTF8
+    if (utf8)
+      {
+      length = 1;
+      ecode++;
+      GETCHARLEN(fc, ecode, length);
+
+      if (length > md->end_subject - eptr)
+        {
+        CHECK_PARTIAL();             /* Not SCHECK_PARTIAL() */
+        RRETURN(MATCH_NOMATCH);
+        }
+
+      /* If the pattern character's value is < 128, we have only one byte, and
+      can use the fast lookup table. */
+
+      if (fc < 128)
+        {
+        if (md->lcc[*ecode++] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
+        }
+
+      /* Otherwise we must pick up the subject character */
+
+      else
+        {
+        unsigned int dc;
+        GETCHARINC(dc, eptr);
+        ecode += length;
+
+        /* If we have Unicode property support, we can use it to test the other
+        case of the character, if there is one. */
+
+        if (fc != dc)
+          {
+#ifdef SUPPORT_UCP
+          if (dc != UCD_OTHERCASE(fc))
+#endif
+            RRETURN(MATCH_NOMATCH);
+          }
+        }
+      }
+    else
+#endif   /* SUPPORT_UTF8 */
+
+    /* Non-UTF-8 mode */
+      {
+      if (md->end_subject - eptr < 1)
+        {
+        SCHECK_PARTIAL();            /* This one can use SCHECK_PARTIAL() */
+        RRETURN(MATCH_NOMATCH);
+        }
+      if (md->lcc[ecode[1]] != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
+      ecode += 2;
+      }
+    break;
+
+    /* Match a single character repeatedly. */
+
+    case OP_EXACT:
+    min = max = GET2(ecode, 1);
+    ecode += 3;
+    goto REPEATCHAR;
+
+    case OP_POSUPTO:
+    possessive = TRUE;
+    /* Fall through */
+
+    case OP_UPTO:
+    case OP_MINUPTO:
+    min = 0;
+    max = GET2(ecode, 1);
+    minimize = *ecode == OP_MINUPTO;
+    ecode += 3;
+    goto REPEATCHAR;
+
+    case OP_POSSTAR:
+    possessive = TRUE;
+    min = 0;
+    max = INT_MAX;
+    ecode++;
+    goto REPEATCHAR;
+
+    case OP_POSPLUS:
+    possessive = TRUE;
+    min = 1;
+    max = INT_MAX;
+    ecode++;
+    goto REPEATCHAR;
+
+    case OP_POSQUERY:
+    possessive = TRUE;
+    min = 0;
+    max = 1;
+    ecode++;
+    goto REPEATCHAR;
+
+    case OP_STAR:
+    case OP_MINSTAR:
+    case OP_PLUS:
+    case OP_MINPLUS:
+    case OP_QUERY:
+    case OP_MINQUERY:
+    c = *ecode++ - OP_STAR;
+    minimize = (c & 1) != 0;
+
+    min = rep_min[c];                 /* Pick up values from tables; */
+    max = rep_max[c];                 /* zero for max => infinity */
+    if (max == 0) max = INT_MAX;
+
+    /* Common code for all repeated single-character matches. */
+
+    REPEATCHAR:
+#ifdef SUPPORT_UTF8
+    if (utf8)
+      {
+      length = 1;
+      charptr = ecode;
+      GETCHARLEN(fc, ecode, length);
+      ecode += length;
+
+      /* Handle multibyte character matching specially here. There is
+      support for caseless matching if UCP support is present. */
+
+      if (length > 1)
+        {
+#ifdef SUPPORT_UCP
+        unsigned int othercase;
+        if ((ims & PCRE_CASELESS) != 0 &&
+            (othercase = UCD_OTHERCASE(fc)) != fc)
+          oclength = _pcre_ord2utf8(othercase, occhars);
+        else oclength = 0;
+#endif  /* SUPPORT_UCP */
+
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr <= md->end_subject - length &&
+            memcmp(eptr, charptr, length) == 0) eptr += length;
+#ifdef SUPPORT_UCP
+          else if (oclength > 0 &&
+                   eptr <= md->end_subject - oclength &&
+                   memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
+#endif  /* SUPPORT_UCP */
+          else
+            {
+            CHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          }
+
+        if (min == max) continue;
+
+        if (minimize)
+          {
+          for (fi = min;; fi++)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM22);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
+            if (eptr <= md->end_subject - length &&
+              memcmp(eptr, charptr, length) == 0) eptr += length;
+#ifdef SUPPORT_UCP
+            else if (oclength > 0 &&
+                     eptr <= md->end_subject - oclength &&
+                     memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
+#endif  /* SUPPORT_UCP */
+            else
+              {
+              CHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            }
+          /* Control never gets here */
+          }
+
+        else  /* Maximize */
+          {
+          pp = eptr;
+          for (i = min; i < max; i++)
+            {
+            if (eptr <= md->end_subject - length &&
+                memcmp(eptr, charptr, length) == 0) eptr += length;
+#ifdef SUPPORT_UCP
+            else if (oclength > 0 &&
+                     eptr <= md->end_subject - oclength &&
+                     memcmp(eptr, occhars, oclength) == 0) eptr += oclength;
+#endif  /* SUPPORT_UCP */
+            else
+              {
+              CHECK_PARTIAL();
+              break;
+              }
+            }
+
+          if (possessive) continue;
+
+          for(;;)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM23);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (eptr == pp) { RRETURN(MATCH_NOMATCH); }
+#ifdef SUPPORT_UCP
+            eptr--;
+            BACKCHAR(eptr);
+#else   /* without SUPPORT_UCP */
+            eptr -= length;
+#endif  /* SUPPORT_UCP */
+            }
+          }
+        /* Control never gets here */
+        }
+
+      /* If the length of a UTF-8 character is 1, we fall through here, and
+      obey the code as for non-UTF-8 characters below, though in this case the
+      value of fc will always be < 128. */
+      }
+    else
+#endif  /* SUPPORT_UTF8 */
+
+    /* When not in UTF-8 mode, load a single-byte character. */
+
+    fc = *ecode++;
+
+    /* The value of fc at this point is always less than 256, though we may or
+    may not be in UTF-8 mode. The code is duplicated for the caseless and
+    caseful cases, for speed, since matching characters is likely to be quite
+    common. First, ensure the minimum number of matches are present. If min =
+    max, continue at the same level without recursing. Otherwise, if
+    minimizing, keep trying the rest of the expression and advancing one
+    matching character if failing, up to the maximum. Alternatively, if
+    maximizing, find the maximum number of characters and work backwards. */
+
+    DPRINTF(("matching %c{%d,%d} against subject %.*s\n", fc, min, max,
+      max, eptr));
+
+    if ((ims & PCRE_CASELESS) != 0)
+      {
+      fc = md->lcc[fc];
+      for (i = 1; i <= min; i++)
+        {
+        if (eptr >= md->end_subject)
+          {
+          SCHECK_PARTIAL();
+          RRETURN(MATCH_NOMATCH);
+          }
+        if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
+        }
+      if (min == max) continue;
+      if (minimize)
+        {
+        for (fi = min;; fi++)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM24);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (fi >= max) RRETURN(MATCH_NOMATCH);
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (fc != md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
+          }
+        /* Control never gets here */
+        }
+      else  /* Maximize */
+        {
+        pp = eptr;
+        for (i = min; i < max; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            break;
+            }
+          if (fc != md->lcc[*eptr]) break;
+          eptr++;
+          }
+
+        if (possessive) continue;
+
+        while (eptr >= pp)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM25);
+          eptr--;
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          }
+        RRETURN(MATCH_NOMATCH);
+        }
+      /* Control never gets here */
+      }
+
+    /* Caseful comparisons (includes all multi-byte characters) */
+
+    else
+      {
+      for (i = 1; i <= min; i++)
+        {
+        if (eptr >= md->end_subject)
+          {
+          SCHECK_PARTIAL();
+          RRETURN(MATCH_NOMATCH);
+          }
+        if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
+        }
+
+      if (min == max) continue;
+
+      if (minimize)
+        {
+        for (fi = min;; fi++)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM26);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (fi >= max) RRETURN(MATCH_NOMATCH);
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (fc != *eptr++) RRETURN(MATCH_NOMATCH);
+          }
+        /* Control never gets here */
+        }
+      else  /* Maximize */
+        {
+        pp = eptr;
+        for (i = min; i < max; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            break;
+            }
+          if (fc != *eptr) break;
+          eptr++;
+          }
+        if (possessive) continue;
+
+        while (eptr >= pp)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM27);
+          eptr--;
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          }
+        RRETURN(MATCH_NOMATCH);
+        }
+      }
+    /* Control never gets here */
+
+    /* Match a negated single one-byte character. The character we are
+    checking can be multibyte. */
+
+    case OP_NOT:
+    if (eptr >= md->end_subject)
+      {
+      SCHECK_PARTIAL();
+      RRETURN(MATCH_NOMATCH);
+      }
+    ecode++;
+    GETCHARINCTEST(c, eptr);
+    if ((ims & PCRE_CASELESS) != 0)
+      {
+#ifdef SUPPORT_UTF8
+      if (c < 256)
+#endif
+      c = md->lcc[c];
+      if (md->lcc[*ecode++] == c) RRETURN(MATCH_NOMATCH);
+      }
+    else
+      {
+      if (*ecode++ == c) RRETURN(MATCH_NOMATCH);
+      }
+    break;
+
+    /* Match a negated single one-byte character repeatedly. This is almost a
+    repeat of the code for a repeated single character, but I haven't found a
+    nice way of commoning these up that doesn't require a test of the
+    positive/negative option for each character match. Maybe that wouldn't add
+    very much to the time taken, but character matching *is* what this is all
+    about... */
+
+    case OP_NOTEXACT:
+    min = max = GET2(ecode, 1);
+    ecode += 3;
+    goto REPEATNOTCHAR;
+
+    case OP_NOTUPTO:
+    case OP_NOTMINUPTO:
+    min = 0;
+    max = GET2(ecode, 1);
+    minimize = *ecode == OP_NOTMINUPTO;
+    ecode += 3;
+    goto REPEATNOTCHAR;
+
+    case OP_NOTPOSSTAR:
+    possessive = TRUE;
+    min = 0;
+    max = INT_MAX;
+    ecode++;
+    goto REPEATNOTCHAR;
+
+    case OP_NOTPOSPLUS:
+    possessive = TRUE;
+    min = 1;
+    max = INT_MAX;
+    ecode++;
+    goto REPEATNOTCHAR;
+
+    case OP_NOTPOSQUERY:
+    possessive = TRUE;
+    min = 0;
+    max = 1;
+    ecode++;
+    goto REPEATNOTCHAR;
+
+    case OP_NOTPOSUPTO:
+    possessive = TRUE;
+    min = 0;
+    max = GET2(ecode, 1);
+    ecode += 3;
+    goto REPEATNOTCHAR;
+
+    case OP_NOTSTAR:
+    case OP_NOTMINSTAR:
+    case OP_NOTPLUS:
+    case OP_NOTMINPLUS:
+    case OP_NOTQUERY:
+    case OP_NOTMINQUERY:
+    c = *ecode++ - OP_NOTSTAR;
+    minimize = (c & 1) != 0;
+    min = rep_min[c];                 /* Pick up values from tables; */
+    max = rep_max[c];                 /* zero for max => infinity */
+    if (max == 0) max = INT_MAX;
+
+    /* Common code for all repeated single-byte matches. */
+
+    REPEATNOTCHAR:
+    fc = *ecode++;
+
+    /* The code is duplicated for the caseless and caseful cases, for speed,
+    since matching characters is likely to be quite common. First, ensure the
+    minimum number of matches are present. If min = max, continue at the same
+    level without recursing. Otherwise, if minimizing, keep trying the rest of
+    the expression and advancing one matching character if failing, up to the
+    maximum. Alternatively, if maximizing, find the maximum number of
+    characters and work backwards. */
+
+    DPRINTF(("negative matching %c{%d,%d} against subject %.*s\n", fc, min, max,
+      max, eptr));
+
+    if ((ims & PCRE_CASELESS) != 0)
+      {
+      fc = md->lcc[fc];
+
+#ifdef SUPPORT_UTF8
+      /* UTF-8 mode */
+      if (utf8)
+        {
+        register unsigned int d;
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINC(d, eptr);
+          if (d < 256) d = md->lcc[d];
+          if (fc == d) RRETURN(MATCH_NOMATCH);
+          }
+        }
+      else
+#endif
+
+      /* Not UTF-8 mode */
+        {
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
+          }
+        }
+
+      if (min == max) continue;
+
+      if (minimize)
+        {
+#ifdef SUPPORT_UTF8
+        /* UTF-8 mode */
+        if (utf8)
+          {
+          register unsigned int d;
+          for (fi = min;; fi++)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM28);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINC(d, eptr);
+            if (d < 256) d = md->lcc[d];
+            if (fc == d) RRETURN(MATCH_NOMATCH);
+            }
+          }
+        else
+#endif
+        /* Not UTF-8 mode */
+          {
+          for (fi = min;; fi++)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM29);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            if (fc == md->lcc[*eptr++]) RRETURN(MATCH_NOMATCH);
+            }
+          }
+        /* Control never gets here */
+        }
+
+      /* Maximize case */
+
+      else
+        {
+        pp = eptr;
+
+#ifdef SUPPORT_UTF8
+        /* UTF-8 mode */
+        if (utf8)
+          {
+          register unsigned int d;
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(d, eptr, len);
+            if (d < 256) d = md->lcc[d];
+            if (fc == d) break;
+            eptr += len;
+            }
+        if (possessive) continue;
+        for(;;)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM30);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (eptr-- == pp) break;        /* Stop if tried at original pos */
+            BACKCHAR(eptr);
+            }
+          }
+        else
+#endif
+        /* Not UTF-8 mode */
+          {
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            if (fc == md->lcc[*eptr]) break;
+            eptr++;
+            }
+          if (possessive) continue;
+          while (eptr >= pp)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM31);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            eptr--;
+            }
+          }
+
+        RRETURN(MATCH_NOMATCH);
+        }
+      /* Control never gets here */
+      }
+
+    /* Caseful comparisons */
+
+    else
+      {
+#ifdef SUPPORT_UTF8
+      /* UTF-8 mode */
+      if (utf8)
+        {
+        register unsigned int d;
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINC(d, eptr);
+          if (fc == d) RRETURN(MATCH_NOMATCH);
+          }
+        }
+      else
+#endif
+      /* Not UTF-8 mode */
+        {
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
+          }
+        }
+
+      if (min == max) continue;
+
+      if (minimize)
+        {
+#ifdef SUPPORT_UTF8
+        /* UTF-8 mode */
+        if (utf8)
+          {
+          register unsigned int d;
+          for (fi = min;; fi++)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM32);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINC(d, eptr);
+            if (fc == d) RRETURN(MATCH_NOMATCH);
+            }
+          }
+        else
+#endif
+        /* Not UTF-8 mode */
+          {
+          for (fi = min;; fi++)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM33);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            if (fc == *eptr++) RRETURN(MATCH_NOMATCH);
+            }
+          }
+        /* Control never gets here */
+        }
+
+      /* Maximize case */
+
+      else
+        {
+        pp = eptr;
+
+#ifdef SUPPORT_UTF8
+        /* UTF-8 mode */
+        if (utf8)
+          {
+          register unsigned int d;
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(d, eptr, len);
+            if (fc == d) break;
+            eptr += len;
+            }
+          if (possessive) continue;
+          for(;;)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM34);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (eptr-- == pp) break;        /* Stop if tried at original pos */
+            BACKCHAR(eptr);
+            }
+          }
+        else
+#endif
+        /* Not UTF-8 mode */
+          {
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            if (fc == *eptr) break;
+            eptr++;
+            }
+          if (possessive) continue;
+          while (eptr >= pp)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM35);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            eptr--;
+            }
+          }
+
+        RRETURN(MATCH_NOMATCH);
+        }
+      }
+    /* Control never gets here */
+
+    /* Match a single character type repeatedly; several different opcodes
+    share code. This is very similar to the code for single characters, but we
+    repeat it in the interests of efficiency. */
+
+    case OP_TYPEEXACT:
+    min = max = GET2(ecode, 1);
+    minimize = TRUE;
+    ecode += 3;
+    goto REPEATTYPE;
+
+    case OP_TYPEUPTO:
+    case OP_TYPEMINUPTO:
+    min = 0;
+    max = GET2(ecode, 1);
+    minimize = *ecode == OP_TYPEMINUPTO;
+    ecode += 3;
+    goto REPEATTYPE;
+
+    case OP_TYPEPOSSTAR:
+    possessive = TRUE;
+    min = 0;
+    max = INT_MAX;
+    ecode++;
+    goto REPEATTYPE;
+
+    case OP_TYPEPOSPLUS:
+    possessive = TRUE;
+    min = 1;
+    max = INT_MAX;
+    ecode++;
+    goto REPEATTYPE;
+
+    case OP_TYPEPOSQUERY:
+    possessive = TRUE;
+    min = 0;
+    max = 1;
+    ecode++;
+    goto REPEATTYPE;
+
+    case OP_TYPEPOSUPTO:
+    possessive = TRUE;
+    min = 0;
+    max = GET2(ecode, 1);
+    ecode += 3;
+    goto REPEATTYPE;
+
+    case OP_TYPESTAR:
+    case OP_TYPEMINSTAR:
+    case OP_TYPEPLUS:
+    case OP_TYPEMINPLUS:
+    case OP_TYPEQUERY:
+    case OP_TYPEMINQUERY:
+    c = *ecode++ - OP_TYPESTAR;
+    minimize = (c & 1) != 0;
+    min = rep_min[c];                 /* Pick up values from tables; */
+    max = rep_max[c];                 /* zero for max => infinity */
+    if (max == 0) max = INT_MAX;
+
+    /* Common code for all repeated single character type matches. Note that
+    in UTF-8 mode, '.' matches a character of any length, but for the other
+    character types, the valid characters are all one-byte long. */
+
+    REPEATTYPE:
+    ctype = *ecode++;      /* Code for the character type */
+
+#ifdef SUPPORT_UCP
+    if (ctype == OP_PROP || ctype == OP_NOTPROP)
+      {
+      prop_fail_result = ctype == OP_NOTPROP;
+      prop_type = *ecode++;
+      prop_value = *ecode++;
+      }
+    else prop_type = -1;
+#endif
+
+    /* First, ensure the minimum number of matches are present. Use inline
+    code for maximizing the speed, and do the type test once at the start
+    (i.e. keep it out of the loop). Separate the UTF-8 code completely as that
+    is tidier. Also separate the UCP code, which can be the same for both UTF-8
+    and single-bytes. */
+
+    if (min > 0)
+      {
+#ifdef SUPPORT_UCP
+      if (prop_type >= 0)
+        {
+        switch(prop_type)
+          {
+          case PT_ANY:
+          if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+          for (i = 1; i <= min; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINCTEST(c, eptr);
+            }
+          break;
+
+          case PT_LAMP:
+          for (i = 1; i <= min; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINCTEST(c, eptr);
+            prop_chartype = UCD_CHARTYPE(c);
+            if ((prop_chartype == ucp_Lu ||
+                 prop_chartype == ucp_Ll ||
+                 prop_chartype == ucp_Lt) == prop_fail_result)
+              RRETURN(MATCH_NOMATCH);
+            }
+          break;
+
+          case PT_GC:
+          for (i = 1; i <= min; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINCTEST(c, eptr);
+            prop_category = UCD_CATEGORY(c);
+            if ((prop_category == prop_value) == prop_fail_result)
+              RRETURN(MATCH_NOMATCH);
+            }
+          break;
+
+          case PT_PC:
+          for (i = 1; i <= min; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINCTEST(c, eptr);
+            prop_chartype = UCD_CHARTYPE(c);
+            if ((prop_chartype == prop_value) == prop_fail_result)
+              RRETURN(MATCH_NOMATCH);
+            }
+          break;
+
+          case PT_SC:
+          for (i = 1; i <= min; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINCTEST(c, eptr);
+            prop_script = UCD_SCRIPT(c);
+            if ((prop_script == prop_value) == prop_fail_result)
+              RRETURN(MATCH_NOMATCH);
+            }
+          break;
+
+          default:
+          RRETURN(PCRE_ERROR_INTERNAL);
+          }
+        }
+
+      /* Match extended Unicode sequences. We will get here only if the
+      support is in the binary; otherwise a compile-time error occurs. */
+
+      else if (ctype == OP_EXTUNI)
+        {
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINCTEST(c, eptr);
+          prop_category = UCD_CATEGORY(c);
+          if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
+          while (eptr < md->end_subject)
+            {
+            int len = 1;
+            if (!utf8) c = *eptr;
+              else { GETCHARLEN(c, eptr, len); }
+            prop_category = UCD_CATEGORY(c);
+            if (prop_category != ucp_M) break;
+            eptr += len;
+            }
+          }
+        }
+
+      else
+#endif     /* SUPPORT_UCP */
+
+/* Handle all other cases when the coding is UTF-8 */
+
+#ifdef SUPPORT_UTF8
+      if (utf8) switch(ctype)
+        {
+        case OP_ANY:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+          eptr++;
+          while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
+          }
+        break;
+
+        case OP_ALLANY:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          eptr++;
+          while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
+          }
+        break;
+
+        case OP_ANYBYTE:
+        if (eptr > md->end_subject - min) RRETURN(MATCH_NOMATCH);
+        eptr += min;
+        break;
+
+        case OP_ANYNL:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINC(c, eptr);
+          switch(c)
+            {
+            default: RRETURN(MATCH_NOMATCH);
+            case 0x000d:
+            if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+            break;
+
+            case 0x000a:
+            break;
+
+            case 0x000b:
+            case 0x000c:
+            case 0x0085:
+            case 0x2028:
+            case 0x2029:
+            if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+            break;
+            }
+          }
+        break;
+
+        case OP_NOT_HSPACE:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINC(c, eptr);
+          switch(c)
+            {
+            default: break;
+            case 0x09:      /* HT */
+            case 0x20:      /* SPACE */
+            case 0xa0:      /* NBSP */
+            case 0x1680:    /* OGHAM SPACE MARK */
+            case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
+            case 0x2000:    /* EN QUAD */
+            case 0x2001:    /* EM QUAD */
+            case 0x2002:    /* EN SPACE */
+            case 0x2003:    /* EM SPACE */
+            case 0x2004:    /* THREE-PER-EM SPACE */
+            case 0x2005:    /* FOUR-PER-EM SPACE */
+            case 0x2006:    /* SIX-PER-EM SPACE */
+            case 0x2007:    /* FIGURE SPACE */
+            case 0x2008:    /* PUNCTUATION SPACE */
+            case 0x2009:    /* THIN SPACE */
+            case 0x200A:    /* HAIR SPACE */
+            case 0x202f:    /* NARROW NO-BREAK SPACE */
+            case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
+            case 0x3000:    /* IDEOGRAPHIC SPACE */
+            RRETURN(MATCH_NOMATCH);
+            }
+          }
+        break;
+
+        case OP_HSPACE:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINC(c, eptr);
+          switch(c)
+            {
+            default: RRETURN(MATCH_NOMATCH);
+            case 0x09:      /* HT */
+            case 0x20:      /* SPACE */
+            case 0xa0:      /* NBSP */
+            case 0x1680:    /* OGHAM SPACE MARK */
+            case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
+            case 0x2000:    /* EN QUAD */
+            case 0x2001:    /* EM QUAD */
+            case 0x2002:    /* EN SPACE */
+            case 0x2003:    /* EM SPACE */
+            case 0x2004:    /* THREE-PER-EM SPACE */
+            case 0x2005:    /* FOUR-PER-EM SPACE */
+            case 0x2006:    /* SIX-PER-EM SPACE */
+            case 0x2007:    /* FIGURE SPACE */
+            case 0x2008:    /* PUNCTUATION SPACE */
+            case 0x2009:    /* THIN SPACE */
+            case 0x200A:    /* HAIR SPACE */
+            case 0x202f:    /* NARROW NO-BREAK SPACE */
+            case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
+            case 0x3000:    /* IDEOGRAPHIC SPACE */
+            break;
+            }
+          }
+        break;
+
+        case OP_NOT_VSPACE:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINC(c, eptr);
+          switch(c)
+            {
+            default: break;
+            case 0x0a:      /* LF */
+            case 0x0b:      /* VT */
+            case 0x0c:      /* FF */
+            case 0x0d:      /* CR */
+            case 0x85:      /* NEL */
+            case 0x2028:    /* LINE SEPARATOR */
+            case 0x2029:    /* PARAGRAPH SEPARATOR */
+            RRETURN(MATCH_NOMATCH);
+            }
+          }
+        break;
+
+        case OP_VSPACE:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINC(c, eptr);
+          switch(c)
+            {
+            default: RRETURN(MATCH_NOMATCH);
+            case 0x0a:      /* LF */
+            case 0x0b:      /* VT */
+            case 0x0c:      /* FF */
+            case 0x0d:      /* CR */
+            case 0x85:      /* NEL */
+            case 0x2028:    /* LINE SEPARATOR */
+            case 0x2029:    /* PARAGRAPH SEPARATOR */
+            break;
+            }
+          }
+        break;
+
+        case OP_NOT_DIGIT:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINC(c, eptr);
+          if (c < 128 && (md->ctypes[c] & ctype_digit) != 0)
+            RRETURN(MATCH_NOMATCH);
+          }
+        break;
+
+        case OP_DIGIT:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_digit) == 0)
+            RRETURN(MATCH_NOMATCH);
+          /* No need to skip more bytes - we know it's a 1-byte character */
+          }
+        break;
+
+        case OP_NOT_WHITESPACE:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (*eptr < 128 && (md->ctypes[*eptr] & ctype_space) != 0)
+            RRETURN(MATCH_NOMATCH);
+          while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
+          }
+        break;
+
+        case OP_WHITESPACE:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_space) == 0)
+            RRETURN(MATCH_NOMATCH);
+          /* No need to skip more bytes - we know it's a 1-byte character */
+          }
+        break;
+
+        case OP_NOT_WORDCHAR:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (*eptr < 128 && (md->ctypes[*eptr] & ctype_word) != 0)
+            RRETURN(MATCH_NOMATCH);
+          while (++eptr < md->end_subject && (*eptr & 0xc0) == 0x80);
+          }
+        break;
+
+        case OP_WORDCHAR:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (*eptr >= 128 || (md->ctypes[*eptr++] & ctype_word) == 0)
+            RRETURN(MATCH_NOMATCH);
+          /* No need to skip more bytes - we know it's a 1-byte character */
+          }
+        break;
+
+        default:
+        RRETURN(PCRE_ERROR_INTERNAL);
+        }  /* End switch(ctype) */
+
+      else
+#endif     /* SUPPORT_UTF8 */
+
+      /* Code for the non-UTF-8 case for minimum matching of operators other
+      than OP_PROP and OP_NOTPROP. */
+
+      switch(ctype)
+        {
+        case OP_ANY:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (IS_NEWLINE(eptr)) RRETURN(MATCH_NOMATCH);
+          eptr++;
+          }
+        break;
+
+        case OP_ALLANY:
+        if (eptr > md->end_subject - min)
+          {
+          SCHECK_PARTIAL();
+          RRETURN(MATCH_NOMATCH);
+          }
+        eptr += min;
+        break;
+
+        case OP_ANYBYTE:
+        if (eptr > md->end_subject - min)
+          {
+          SCHECK_PARTIAL();
+          RRETURN(MATCH_NOMATCH);
+          }
+        eptr += min;
+        break;
+
+        case OP_ANYNL:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          switch(*eptr++)
+            {
+            default: RRETURN(MATCH_NOMATCH);
+            case 0x000d:
+            if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+            break;
+            case 0x000a:
+            break;
+
+            case 0x000b:
+            case 0x000c:
+            case 0x0085:
+            if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+            break;
+            }
+          }
+        break;
+
+        case OP_NOT_HSPACE:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          switch(*eptr++)
+            {
+            default: break;
+            case 0x09:      /* HT */
+            case 0x20:      /* SPACE */
+            case 0xa0:      /* NBSP */
+            RRETURN(MATCH_NOMATCH);
+            }
+          }
+        break;
+
+        case OP_HSPACE:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          switch(*eptr++)
+            {
+            default: RRETURN(MATCH_NOMATCH);
+            case 0x09:      /* HT */
+            case 0x20:      /* SPACE */
+            case 0xa0:      /* NBSP */
+            break;
+            }
+          }
+        break;
+
+        case OP_NOT_VSPACE:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          switch(*eptr++)
+            {
+            default: break;
+            case 0x0a:      /* LF */
+            case 0x0b:      /* VT */
+            case 0x0c:      /* FF */
+            case 0x0d:      /* CR */
+            case 0x85:      /* NEL */
+            RRETURN(MATCH_NOMATCH);
+            }
+          }
+        break;
+
+        case OP_VSPACE:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          switch(*eptr++)
+            {
+            default: RRETURN(MATCH_NOMATCH);
+            case 0x0a:      /* LF */
+            case 0x0b:      /* VT */
+            case 0x0c:      /* FF */
+            case 0x0d:      /* CR */
+            case 0x85:      /* NEL */
+            break;
+            }
+          }
+        break;
+
+        case OP_NOT_DIGIT:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if ((md->ctypes[*eptr++] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
+          }
+        break;
+
+        case OP_DIGIT:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if ((md->ctypes[*eptr++] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
+          }
+        break;
+
+        case OP_NOT_WHITESPACE:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if ((md->ctypes[*eptr++] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
+          }
+        break;
+
+        case OP_WHITESPACE:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if ((md->ctypes[*eptr++] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
+          }
+        break;
+
+        case OP_NOT_WORDCHAR:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if ((md->ctypes[*eptr++] & ctype_word) != 0)
+            RRETURN(MATCH_NOMATCH);
+          }
+        break;
+
+        case OP_WORDCHAR:
+        for (i = 1; i <= min; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if ((md->ctypes[*eptr++] & ctype_word) == 0)
+            RRETURN(MATCH_NOMATCH);
+          }
+        break;
+
+        default:
+        RRETURN(PCRE_ERROR_INTERNAL);
+        }
+      }
+
+    /* If min = max, continue at the same level without recursing */
+
+    if (min == max) continue;
+
+    /* If minimizing, we have to test the rest of the pattern before each
+    subsequent match. Again, separate the UTF-8 case for speed, and also
+    separate the UCP cases. */
+
+    if (minimize)
+      {
+#ifdef SUPPORT_UCP
+      if (prop_type >= 0)
+        {
+        switch(prop_type)
+          {
+          case PT_ANY:
+          for (fi = min;; fi++)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM36);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINC(c, eptr);
+            if (prop_fail_result) RRETURN(MATCH_NOMATCH);
+            }
+          /* Control never gets here */
+
+          case PT_LAMP:
+          for (fi = min;; fi++)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM37);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINC(c, eptr);
+            prop_chartype = UCD_CHARTYPE(c);
+            if ((prop_chartype == ucp_Lu ||
+                 prop_chartype == ucp_Ll ||
+                 prop_chartype == ucp_Lt) == prop_fail_result)
+              RRETURN(MATCH_NOMATCH);
+            }
+          /* Control never gets here */
+
+          case PT_GC:
+          for (fi = min;; fi++)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM38);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINC(c, eptr);
+            prop_category = UCD_CATEGORY(c);
+            if ((prop_category == prop_value) == prop_fail_result)
+              RRETURN(MATCH_NOMATCH);
+            }
+          /* Control never gets here */
+
+          case PT_PC:
+          for (fi = min;; fi++)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM39);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINC(c, eptr);
+            prop_chartype = UCD_CHARTYPE(c);
+            if ((prop_chartype == prop_value) == prop_fail_result)
+              RRETURN(MATCH_NOMATCH);
+            }
+          /* Control never gets here */
+
+          case PT_SC:
+          for (fi = min;; fi++)
+            {
+            RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM40);
+            if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+            if (fi >= max) RRETURN(MATCH_NOMATCH);
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              RRETURN(MATCH_NOMATCH);
+              }
+            GETCHARINC(c, eptr);
+            prop_script = UCD_SCRIPT(c);
+            if ((prop_script == prop_value) == prop_fail_result)
+              RRETURN(MATCH_NOMATCH);
+            }
+          /* Control never gets here */
+
+          default:
+          RRETURN(PCRE_ERROR_INTERNAL);
+          }
+        }
+
+      /* Match extended Unicode sequences. We will get here only if the
+      support is in the binary; otherwise a compile-time error occurs. */
+
+      else if (ctype == OP_EXTUNI)
+        {
+        for (fi = min;; fi++)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM41);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (fi >= max) RRETURN(MATCH_NOMATCH);
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          GETCHARINCTEST(c, eptr);
+          prop_category = UCD_CATEGORY(c);
+          if (prop_category == ucp_M) RRETURN(MATCH_NOMATCH);
+          while (eptr < md->end_subject)
+            {
+            int len = 1;
+            if (!utf8) c = *eptr;
+              else { GETCHARLEN(c, eptr, len); }
+            prop_category = UCD_CATEGORY(c);
+            if (prop_category != ucp_M) break;
+            eptr += len;
+            }
+          }
+        }
+
+      else
+#endif     /* SUPPORT_UCP */
+
+#ifdef SUPPORT_UTF8
+      /* UTF-8 mode */
+      if (utf8)
+        {
+        for (fi = min;; fi++)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM42);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (fi >= max) RRETURN(MATCH_NOMATCH);
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (ctype == OP_ANY && IS_NEWLINE(eptr))
+            RRETURN(MATCH_NOMATCH);
+          GETCHARINC(c, eptr);
+          switch(ctype)
+            {
+            case OP_ANY:        /* This is the non-NL case */
+            case OP_ALLANY:
+            case OP_ANYBYTE:
+            break;
+
+            case OP_ANYNL:
+            switch(c)
+              {
+              default: RRETURN(MATCH_NOMATCH);
+              case 0x000d:
+              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+              break;
+              case 0x000a:
+              break;
+
+              case 0x000b:
+              case 0x000c:
+              case 0x0085:
+              case 0x2028:
+              case 0x2029:
+              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+              break;
+              }
+            break;
+
+            case OP_NOT_HSPACE:
+            switch(c)
+              {
+              default: break;
+              case 0x09:      /* HT */
+              case 0x20:      /* SPACE */
+              case 0xa0:      /* NBSP */
+              case 0x1680:    /* OGHAM SPACE MARK */
+              case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
+              case 0x2000:    /* EN QUAD */
+              case 0x2001:    /* EM QUAD */
+              case 0x2002:    /* EN SPACE */
+              case 0x2003:    /* EM SPACE */
+              case 0x2004:    /* THREE-PER-EM SPACE */
+              case 0x2005:    /* FOUR-PER-EM SPACE */
+              case 0x2006:    /* SIX-PER-EM SPACE */
+              case 0x2007:    /* FIGURE SPACE */
+              case 0x2008:    /* PUNCTUATION SPACE */
+              case 0x2009:    /* THIN SPACE */
+              case 0x200A:    /* HAIR SPACE */
+              case 0x202f:    /* NARROW NO-BREAK SPACE */
+              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
+              case 0x3000:    /* IDEOGRAPHIC SPACE */
+              RRETURN(MATCH_NOMATCH);
+              }
+            break;
+
+            case OP_HSPACE:
+            switch(c)
+              {
+              default: RRETURN(MATCH_NOMATCH);
+              case 0x09:      /* HT */
+              case 0x20:      /* SPACE */
+              case 0xa0:      /* NBSP */
+              case 0x1680:    /* OGHAM SPACE MARK */
+              case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
+              case 0x2000:    /* EN QUAD */
+              case 0x2001:    /* EM QUAD */
+              case 0x2002:    /* EN SPACE */
+              case 0x2003:    /* EM SPACE */
+              case 0x2004:    /* THREE-PER-EM SPACE */
+              case 0x2005:    /* FOUR-PER-EM SPACE */
+              case 0x2006:    /* SIX-PER-EM SPACE */
+              case 0x2007:    /* FIGURE SPACE */
+              case 0x2008:    /* PUNCTUATION SPACE */
+              case 0x2009:    /* THIN SPACE */
+              case 0x200A:    /* HAIR SPACE */
+              case 0x202f:    /* NARROW NO-BREAK SPACE */
+              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
+              case 0x3000:    /* IDEOGRAPHIC SPACE */
+              break;
+              }
+            break;
+
+            case OP_NOT_VSPACE:
+            switch(c)
+              {
+              default: break;
+              case 0x0a:      /* LF */
+              case 0x0b:      /* VT */
+              case 0x0c:      /* FF */
+              case 0x0d:      /* CR */
+              case 0x85:      /* NEL */
+              case 0x2028:    /* LINE SEPARATOR */
+              case 0x2029:    /* PARAGRAPH SEPARATOR */
+              RRETURN(MATCH_NOMATCH);
+              }
+            break;
+
+            case OP_VSPACE:
+            switch(c)
+              {
+              default: RRETURN(MATCH_NOMATCH);
+              case 0x0a:      /* LF */
+              case 0x0b:      /* VT */
+              case 0x0c:      /* FF */
+              case 0x0d:      /* CR */
+              case 0x85:      /* NEL */
+              case 0x2028:    /* LINE SEPARATOR */
+              case 0x2029:    /* PARAGRAPH SEPARATOR */
+              break;
+              }
+            break;
+
+            case OP_NOT_DIGIT:
+            if (c < 256 && (md->ctypes[c] & ctype_digit) != 0)
+              RRETURN(MATCH_NOMATCH);
+            break;
+
+            case OP_DIGIT:
+            if (c >= 256 || (md->ctypes[c] & ctype_digit) == 0)
+              RRETURN(MATCH_NOMATCH);
+            break;
+
+            case OP_NOT_WHITESPACE:
+            if (c < 256 && (md->ctypes[c] & ctype_space) != 0)
+              RRETURN(MATCH_NOMATCH);
+            break;
+
+            case OP_WHITESPACE:
+            if  (c >= 256 || (md->ctypes[c] & ctype_space) == 0)
+              RRETURN(MATCH_NOMATCH);
+            break;
+
+            case OP_NOT_WORDCHAR:
+            if (c < 256 && (md->ctypes[c] & ctype_word) != 0)
+              RRETURN(MATCH_NOMATCH);
+            break;
+
+            case OP_WORDCHAR:
+            if (c >= 256 || (md->ctypes[c] & ctype_word) == 0)
+              RRETURN(MATCH_NOMATCH);
+            break;
+
+            default:
+            RRETURN(PCRE_ERROR_INTERNAL);
+            }
+          }
+        }
+      else
+#endif
+      /* Not UTF-8 mode */
+        {
+        for (fi = min;; fi++)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM43);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (fi >= max) RRETURN(MATCH_NOMATCH);
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            RRETURN(MATCH_NOMATCH);
+            }
+          if (ctype == OP_ANY && IS_NEWLINE(eptr))
+            RRETURN(MATCH_NOMATCH);
+          c = *eptr++;
+          switch(ctype)
+            {
+            case OP_ANY:     /* This is the non-NL case */
+            case OP_ALLANY:
+            case OP_ANYBYTE:
+            break;
+
+            case OP_ANYNL:
+            switch(c)
+              {
+              default: RRETURN(MATCH_NOMATCH);
+              case 0x000d:
+              if (eptr < md->end_subject && *eptr == 0x0a) eptr++;
+              break;
+
+              case 0x000a:
+              break;
+
+              case 0x000b:
+              case 0x000c:
+              case 0x0085:
+              if (md->bsr_anycrlf) RRETURN(MATCH_NOMATCH);
+              break;
+              }
+            break;
+
+            case OP_NOT_HSPACE:
+            switch(c)
+              {
+              default: break;
+              case 0x09:      /* HT */
+              case 0x20:      /* SPACE */
+              case 0xa0:      /* NBSP */
+              RRETURN(MATCH_NOMATCH);
+              }
+            break;
+
+            case OP_HSPACE:
+            switch(c)
+              {
+              default: RRETURN(MATCH_NOMATCH);
+              case 0x09:      /* HT */
+              case 0x20:      /* SPACE */
+              case 0xa0:      /* NBSP */
+              break;
+              }
+            break;
+
+            case OP_NOT_VSPACE:
+            switch(c)
+              {
+              default: break;
+              case 0x0a:      /* LF */
+              case 0x0b:      /* VT */
+              case 0x0c:      /* FF */
+              case 0x0d:      /* CR */
+              case 0x85:      /* NEL */
+              RRETURN(MATCH_NOMATCH);
+              }
+            break;
+
+            case OP_VSPACE:
+            switch(c)
+              {
+              default: RRETURN(MATCH_NOMATCH);
+              case 0x0a:      /* LF */
+              case 0x0b:      /* VT */
+              case 0x0c:      /* FF */
+              case 0x0d:      /* CR */
+              case 0x85:      /* NEL */
+              break;
+              }
+            break;
+
+            case OP_NOT_DIGIT:
+            if ((md->ctypes[c] & ctype_digit) != 0) RRETURN(MATCH_NOMATCH);
+            break;
+
+            case OP_DIGIT:
+            if ((md->ctypes[c] & ctype_digit) == 0) RRETURN(MATCH_NOMATCH);
+            break;
+
+            case OP_NOT_WHITESPACE:
+            if ((md->ctypes[c] & ctype_space) != 0) RRETURN(MATCH_NOMATCH);
+            break;
+
+            case OP_WHITESPACE:
+            if  ((md->ctypes[c] & ctype_space) == 0) RRETURN(MATCH_NOMATCH);
+            break;
+
+            case OP_NOT_WORDCHAR:
+            if ((md->ctypes[c] & ctype_word) != 0) RRETURN(MATCH_NOMATCH);
+            break;
+
+            case OP_WORDCHAR:
+            if ((md->ctypes[c] & ctype_word) == 0) RRETURN(MATCH_NOMATCH);
+            break;
+
+            default:
+            RRETURN(PCRE_ERROR_INTERNAL);
+            }
+          }
+        }
+      /* Control never gets here */
+      }
+
+    /* If maximizing, it is worth using inline code for speed, doing the type
+    test once at the start (i.e. keep it out of the loop). Again, keep the
+    UTF-8 and UCP stuff separate. */
+
+    else
+      {
+      pp = eptr;  /* Remember where we started */
+
+#ifdef SUPPORT_UCP
+      if (prop_type >= 0)
+        {
+        switch(prop_type)
+          {
+          case PT_ANY:
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            if (prop_fail_result) break;
+            eptr+= len;
+            }
+          break;
+
+          case PT_LAMP:
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            prop_chartype = UCD_CHARTYPE(c);
+            if ((prop_chartype == ucp_Lu ||
+                 prop_chartype == ucp_Ll ||
+                 prop_chartype == ucp_Lt) == prop_fail_result)
+              break;
+            eptr+= len;
+            }
+          break;
+
+          case PT_GC:
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            prop_category = UCD_CATEGORY(c);
+            if ((prop_category == prop_value) == prop_fail_result)
+              break;
+            eptr+= len;
+            }
+          break;
+
+          case PT_PC:
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            prop_chartype = UCD_CHARTYPE(c);
+            if ((prop_chartype == prop_value) == prop_fail_result)
+              break;
+            eptr+= len;
+            }
+          break;
+
+          case PT_SC:
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            prop_script = UCD_SCRIPT(c);
+            if ((prop_script == prop_value) == prop_fail_result)
+              break;
+            eptr+= len;
+            }
+          break;
+          }
+
+        /* eptr is now past the end of the maximum run */
+
+        if (possessive) continue;
+        for(;;)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM44);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (eptr-- == pp) break;        /* Stop if tried at original pos */
+          if (utf8) BACKCHAR(eptr);
+          }
+        }
+
+      /* Match extended Unicode sequences. We will get here only if the
+      support is in the binary; otherwise a compile-time error occurs. */
+
+      else if (ctype == OP_EXTUNI)
+        {
+        for (i = min; i < max; i++)
+          {
+          if (eptr >= md->end_subject)
+            {
+            SCHECK_PARTIAL();
+            break;
+            }
+          GETCHARINCTEST(c, eptr);
+          prop_category = UCD_CATEGORY(c);
+          if (prop_category == ucp_M) break;
+          while (eptr < md->end_subject)
+            {
+            int len = 1;
+            if (!utf8) c = *eptr; else
+              {
+              GETCHARLEN(c, eptr, len);
+              }
+            prop_category = UCD_CATEGORY(c);
+            if (prop_category != ucp_M) break;
+            eptr += len;
+            }
+          }
+
+        /* eptr is now past the end of the maximum run */
+
+        if (possessive) continue;
+
+        for(;;)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM45);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (eptr-- == pp) break;        /* Stop if tried at original pos */
+          for (;;)                        /* Move back over one extended */
+            {
+            int len = 1;
+            if (!utf8) c = *eptr; else
+              {
+              BACKCHAR(eptr);
+              GETCHARLEN(c, eptr, len);
+              }
+            prop_category = UCD_CATEGORY(c);
+            if (prop_category != ucp_M) break;
+            eptr--;
+            }
+          }
+        }
+
+      else
+#endif   /* SUPPORT_UCP */
+
+#ifdef SUPPORT_UTF8
+      /* UTF-8 mode */
+
+      if (utf8)
+        {
+        switch(ctype)
+          {
+          case OP_ANY:
+          if (max < INT_MAX)
+            {
+            for (i = min; i < max; i++)
+              {
+              if (eptr >= md->end_subject)
+                {
+                SCHECK_PARTIAL();
+                break;
+                }
+              if (IS_NEWLINE(eptr)) break;
+              eptr++;
+              while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
+              }
+            }
+
+          /* Handle unlimited UTF-8 repeat */
+
+          else
+            {
+            for (i = min; i < max; i++)
+              {
+              if (eptr >= md->end_subject)
+                {
+                SCHECK_PARTIAL();
+                break;
+                }
+              if (IS_NEWLINE(eptr)) break;
+              eptr++;
+              while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
+              }
+            }
+          break;
+
+          case OP_ALLANY:
+          if (max < INT_MAX)
+            {
+            for (i = min; i < max; i++)
+              {
+              if (eptr >= md->end_subject)
+                {
+                SCHECK_PARTIAL();
+                break;
+                }
+              eptr++;
+              while (eptr < md->end_subject && (*eptr & 0xc0) == 0x80) eptr++;
+              }
+            }
+          else eptr = md->end_subject;   /* Unlimited UTF-8 repeat */
+          break;
+
+          /* The byte case is the same as non-UTF8 */
+
+          case OP_ANYBYTE:
+          c = max - min;
+          if (c > (unsigned int)(md->end_subject - eptr))
+            {
+            eptr = md->end_subject;
+            SCHECK_PARTIAL();
+            }
+          else eptr += c;
+          break;
+
+          case OP_ANYNL:
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            if (c == 0x000d)
+              {
+              if (++eptr >= md->end_subject) break;
+              if (*eptr == 0x000a) eptr++;
+              }
+            else
+              {
+              if (c != 0x000a &&
+                  (md->bsr_anycrlf ||
+                   (c != 0x000b && c != 0x000c &&
+                    c != 0x0085 && c != 0x2028 && c != 0x2029)))
+                break;
+              eptr += len;
+              }
+            }
+          break;
+
+          case OP_NOT_HSPACE:
+          case OP_HSPACE:
+          for (i = min; i < max; i++)
+            {
+            BOOL gotspace;
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            switch(c)
+              {
+              default: gotspace = FALSE; break;
+              case 0x09:      /* HT */
+              case 0x20:      /* SPACE */
+              case 0xa0:      /* NBSP */
+              case 0x1680:    /* OGHAM SPACE MARK */
+              case 0x180e:    /* MONGOLIAN VOWEL SEPARATOR */
+              case 0x2000:    /* EN QUAD */
+              case 0x2001:    /* EM QUAD */
+              case 0x2002:    /* EN SPACE */
+              case 0x2003:    /* EM SPACE */
+              case 0x2004:    /* THREE-PER-EM SPACE */
+              case 0x2005:    /* FOUR-PER-EM SPACE */
+              case 0x2006:    /* SIX-PER-EM SPACE */
+              case 0x2007:    /* FIGURE SPACE */
+              case 0x2008:    /* PUNCTUATION SPACE */
+              case 0x2009:    /* THIN SPACE */
+              case 0x200A:    /* HAIR SPACE */
+              case 0x202f:    /* NARROW NO-BREAK SPACE */
+              case 0x205f:    /* MEDIUM MATHEMATICAL SPACE */
+              case 0x3000:    /* IDEOGRAPHIC SPACE */
+              gotspace = TRUE;
+              break;
+              }
+            if (gotspace == (ctype == OP_NOT_HSPACE)) break;
+            eptr += len;
+            }
+          break;
+
+          case OP_NOT_VSPACE:
+          case OP_VSPACE:
+          for (i = min; i < max; i++)
+            {
+            BOOL gotspace;
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            switch(c)
+              {
+              default: gotspace = FALSE; break;
+              case 0x0a:      /* LF */
+              case 0x0b:      /* VT */
+              case 0x0c:      /* FF */
+              case 0x0d:      /* CR */
+              case 0x85:      /* NEL */
+              case 0x2028:    /* LINE SEPARATOR */
+              case 0x2029:    /* PARAGRAPH SEPARATOR */
+              gotspace = TRUE;
+              break;
+              }
+            if (gotspace == (ctype == OP_NOT_VSPACE)) break;
+            eptr += len;
+            }
+          break;
+
+          case OP_NOT_DIGIT:
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            if (c < 256 && (md->ctypes[c] & ctype_digit) != 0) break;
+            eptr+= len;
+            }
+          break;
+
+          case OP_DIGIT:
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            if (c >= 256 ||(md->ctypes[c] & ctype_digit) == 0) break;
+            eptr+= len;
+            }
+          break;
+
+          case OP_NOT_WHITESPACE:
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            if (c < 256 && (md->ctypes[c] & ctype_space) != 0) break;
+            eptr+= len;
+            }
+          break;
+
+          case OP_WHITESPACE:
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            if (c >= 256 ||(md->ctypes[c] & ctype_space) == 0) break;
+            eptr+= len;
+            }
+          break;
+
+          case OP_NOT_WORDCHAR:
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            if (c < 256 && (md->ctypes[c] & ctype_word) != 0) break;
+            eptr+= len;
+            }
+          break;
+
+          case OP_WORDCHAR:
+          for (i = min; i < max; i++)
+            {
+            int len = 1;
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            GETCHARLEN(c, eptr, len);
+            if (c >= 256 || (md->ctypes[c] & ctype_word) == 0) break;
+            eptr+= len;
+            }
+          break;
+
+          default:
+          RRETURN(PCRE_ERROR_INTERNAL);
+          }
+
+        /* eptr is now past the end of the maximum run */
+
+        if (possessive) continue;
+        for(;;)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM46);
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          if (eptr-- == pp) break;        /* Stop if tried at original pos */
+          BACKCHAR(eptr);
+          }
+        }
+      else
+#endif  /* SUPPORT_UTF8 */
+
+      /* Not UTF-8 mode */
+        {
+        switch(ctype)
+          {
+          case OP_ANY:
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            if (IS_NEWLINE(eptr)) break;
+            eptr++;
+            }
+          break;
+
+          case OP_ALLANY:
+          case OP_ANYBYTE:
+          c = max - min;
+          if (c > (unsigned int)(md->end_subject - eptr))
+            {
+            eptr = md->end_subject;
+            SCHECK_PARTIAL();
+            }
+          else eptr += c;
+          break;
+
+          case OP_ANYNL:
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            c = *eptr;
+            if (c == 0x000d)
+              {
+              if (++eptr >= md->end_subject) break;
+              if (*eptr == 0x000a) eptr++;
+              }
+            else
+              {
+              if (c != 0x000a &&
+                  (md->bsr_anycrlf ||
+                    (c != 0x000b && c != 0x000c && c != 0x0085)))
+                break;
+              eptr++;
+              }
+            }
+          break;
+
+          case OP_NOT_HSPACE:
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            c = *eptr;
+            if (c == 0x09 || c == 0x20 || c == 0xa0) break;
+            eptr++;
+            }
+          break;
+
+          case OP_HSPACE:
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            c = *eptr;
+            if (c != 0x09 && c != 0x20 && c != 0xa0) break;
+            eptr++;
+            }
+          break;
+
+          case OP_NOT_VSPACE:
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            c = *eptr;
+            if (c == 0x0a || c == 0x0b || c == 0x0c || c == 0x0d || c == 0x85)
+              break;
+            eptr++;
+            }
+          break;
+
+          case OP_VSPACE:
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            c = *eptr;
+            if (c != 0x0a && c != 0x0b && c != 0x0c && c != 0x0d && c != 0x85)
+              break;
+            eptr++;
+            }
+          break;
+
+          case OP_NOT_DIGIT:
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            if ((md->ctypes[*eptr] & ctype_digit) != 0) break;
+            eptr++;
+            }
+          break;
+
+          case OP_DIGIT:
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            if ((md->ctypes[*eptr] & ctype_digit) == 0) break;
+            eptr++;
+            }
+          break;
+
+          case OP_NOT_WHITESPACE:
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            if ((md->ctypes[*eptr] & ctype_space) != 0) break;
+            eptr++;
+            }
+          break;
+
+          case OP_WHITESPACE:
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            if ((md->ctypes[*eptr] & ctype_space) == 0) break;
+            eptr++;
+            }
+          break;
+
+          case OP_NOT_WORDCHAR:
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            if ((md->ctypes[*eptr] & ctype_word) != 0) break;
+            eptr++;
+            }
+          break;
+
+          case OP_WORDCHAR:
+          for (i = min; i < max; i++)
+            {
+            if (eptr >= md->end_subject)
+              {
+              SCHECK_PARTIAL();
+              break;
+              }
+            if ((md->ctypes[*eptr] & ctype_word) == 0) break;
+            eptr++;
+            }
+          break;
+
+          default:
+          RRETURN(PCRE_ERROR_INTERNAL);
+          }
+
+        /* eptr is now past the end of the maximum run */
+
+        if (possessive) continue;
+        while (eptr >= pp)
+          {
+          RMATCH(eptr, ecode, offset_top, md, ims, eptrb, 0, RM47);
+          eptr--;
+          if (rrc != MATCH_NOMATCH) RRETURN(rrc);
+          }
+        }
+
+      /* Get here if we can't make it match with any permitted repetitions */
+
+      RRETURN(MATCH_NOMATCH);
+      }
+    /* Control never gets here */
+
+    /* There's been some horrible disaster. Arrival here can only mean there is
+    something seriously wrong in the code above or the OP_xxx definitions. */
+
+    default:
+    DPRINTF(("Unknown opcode %d\n", *ecode));
+    RRETURN(PCRE_ERROR_UNKNOWN_OPCODE);
+    }
+
+  /* Do not stick any code in here without much thought; it is assumed
+  that "continue" in the code above comes out to here to repeat the main
+  loop. */
+
+  }             /* End of main loop */
+/* Control never reaches here */
+
+
+/* When compiling to use the heap rather than the stack for recursive calls to
+match(), the RRETURN() macro jumps here. The number that is saved in
+frame->Xwhere indicates which label we actually want to return to. */
+
+#ifdef NO_RECURSE
+#define LBL(val) case val: goto L_RM##val;
+HEAP_RETURN:
+switch (frame->Xwhere)
+  {
+  LBL( 1) LBL( 2) LBL( 3) LBL( 4) LBL( 5) LBL( 6) LBL( 7) LBL( 8)
+  LBL( 9) LBL(10) LBL(11) LBL(12) LBL(13) LBL(14) LBL(15) LBL(17)
+  LBL(19) LBL(24) LBL(25) LBL(26) LBL(27) LBL(29) LBL(31) LBL(33)
+  LBL(35) LBL(43) LBL(47) LBL(48) LBL(49) LBL(50) LBL(51) LBL(52)
+  LBL(53) LBL(54)
+#ifdef SUPPORT_UTF8
+  LBL(16) LBL(18) LBL(20) LBL(21) LBL(22) LBL(23) LBL(28) LBL(30)
+  LBL(32) LBL(34) LBL(42) LBL(46)
+#ifdef SUPPORT_UCP
+  LBL(36) LBL(37) LBL(38) LBL(39) LBL(40) LBL(41) LBL(44) LBL(45)
+#endif  /* SUPPORT_UCP */
+#endif  /* SUPPORT_UTF8 */
+  default:
+  DPRINTF(("jump error in pcre match: label %d non-existent\n", frame->Xwhere));
+  return PCRE_ERROR_INTERNAL;
+  }
+#undef LBL
+#endif  /* NO_RECURSE */
+}
+
+
+/***************************************************************************
+****************************************************************************
+                   RECURSION IN THE match() FUNCTION
+
+Undefine all the macros that were defined above to handle this. */
+
+#ifdef NO_RECURSE
+#undef eptr
+#undef ecode
+#undef mstart
+#undef offset_top
+#undef ims
+#undef eptrb
+#undef flags
+
+#undef callpat
+#undef charptr
+#undef data
+#undef next
+#undef pp
+#undef prev
+#undef saved_eptr
+
+#undef new_recursive
+
+#undef cur_is_word
+#undef condition
+#undef prev_is_word
+
+#undef original_ims
+
+#undef ctype
+#undef length
+#undef max
+#undef min
+#undef number
+#undef offset
+#undef op
+#undef save_capture_last
+#undef save_offset1
+#undef save_offset2
+#undef save_offset3
+#undef stacksave
+
+#undef newptrb
+
+#endif
+
+/* These two are defined as macros in both cases */
+
+#undef fc
+#undef fi
+
+/***************************************************************************
+***************************************************************************/
+
+
+
+/*************************************************
+*         Execute a Regular Expression           *
+*************************************************/
+
+/* This function applies a compiled re to a subject string and picks out
+portions of the string if it matches. Two elements in the vector are set for
+each substring: the offsets to the start and end of the substring.
+
+Arguments:
+  argument_re     points to the compiled expression
+  extra_data      points to extra data or is NULL
+  subject         points to the subject string
+  length          length of subject string (may contain binary zeros)
+  start_offset    where to start in the subject string
+  options         option bits
+  offsets         points to a vector of ints to be filled in with offsets
+  offsetcount     the number of elements in the vector
+
+Returns:          > 0 => success; value is the number of elements filled in
+                  = 0 => success, but offsets is not big enough
+                   -1 => failed to match
+                 < -1 => some kind of unexpected problem
+*/
+
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_exec(const pcre *argument_re, const pcre_extra *extra_data,
+  PCRE_SPTR subject, int length, int start_offset, int options, int *offsets,
+  int offsetcount)
+{
+int rc, resetcount, ocount;
+int first_byte = -1;
+int req_byte = -1;
+int req_byte2 = -1;
+int newline;
+unsigned long int ims;
+BOOL using_temporary_offsets = FALSE;
+BOOL anchored;
+BOOL startline;
+BOOL firstline;
+BOOL first_byte_caseless = FALSE;
+BOOL req_byte_caseless = FALSE;
+BOOL utf8;
+match_data match_block;
+match_data *md = &match_block;
+const uschar *tables;
+const uschar *start_bits = NULL;
+USPTR start_match = (USPTR)subject + start_offset;
+USPTR end_subject;
+USPTR start_partial = NULL;
+USPTR req_byte_ptr = start_match - 1;
+
+pcre_study_data internal_study;
+const pcre_study_data *study;
+
+real_pcre internal_re;
+const real_pcre *external_re = (const real_pcre *)argument_re;
+const real_pcre *re = external_re;
+
+/* Plausibility checks */
+
+if ((options & ~PUBLIC_EXEC_OPTIONS) != 0) return PCRE_ERROR_BADOPTION;
+if (re == NULL || subject == NULL ||
+   (offsets == NULL && offsetcount > 0)) return PCRE_ERROR_NULL;
+if (offsetcount < 0) return PCRE_ERROR_BADCOUNT;
+
+/* This information is for finding all the numbers associated with a given
+name, for condition testing. */
+
+md->name_table = (uschar *)re + re->name_table_offset;
+md->name_count = re->name_count;
+md->name_entry_size = re->name_entry_size;
+
+/* Fish out the optional data from the extra_data structure, first setting
+the default values. */
+
+study = NULL;
+md->match_limit = MATCH_LIMIT;
+md->match_limit_recursion = MATCH_LIMIT_RECURSION;
+md->callout_data = NULL;
+
+/* The table pointer is always in native byte order. */
+
+tables = external_re->tables;
+
+if (extra_data != NULL)
+  {
+  register unsigned int flags = extra_data->flags;
+  if ((flags & PCRE_EXTRA_STUDY_DATA) != 0)
+    study = (const pcre_study_data *)extra_data->study_data;
+  if ((flags & PCRE_EXTRA_MATCH_LIMIT) != 0)
+    md->match_limit = extra_data->match_limit;
+  if ((flags & PCRE_EXTRA_MATCH_LIMIT_RECURSION) != 0)
+    md->match_limit_recursion = extra_data->match_limit_recursion;
+  if ((flags & PCRE_EXTRA_CALLOUT_DATA) != 0)
+    md->callout_data = extra_data->callout_data;
+  if ((flags & PCRE_EXTRA_TABLES) != 0) tables = extra_data->tables;
+  }
+
+/* If the exec call supplied NULL for tables, use the inbuilt ones. This
+is a feature that makes it possible to save compiled regex and re-use them
+in other programs later. */
+
+if (tables == NULL) tables = _pcre_default_tables;
+
+/* Check that the first field in the block is the magic number. If it is not,
+test for a regex that was compiled on a host of opposite endianness. If this is
+the case, flipped values are put in internal_re and internal_study if there was
+study data too. */
+
+if (re->magic_number != MAGIC_NUMBER)
+  {
+  re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
+  if (re == NULL) return PCRE_ERROR_BADMAGIC;
+  if (study != NULL) study = &internal_study;
+  }
+
+/* Set up other data */
+
+anchored = ((re->options | options) & PCRE_ANCHORED) != 0;
+startline = (re->flags & PCRE_STARTLINE) != 0;
+firstline = (re->options & PCRE_FIRSTLINE) != 0;
+
+/* The code starts after the real_pcre block and the capture name table. */
+
+md->start_code = (const uschar *)external_re + re->name_table_offset +
+  re->name_count * re->name_entry_size;
+
+md->start_subject = (USPTR)subject;
+md->start_offset = start_offset;
+md->end_subject = md->start_subject + length;
+end_subject = md->end_subject;
+
+md->endonly = (re->options & PCRE_DOLLAR_ENDONLY) != 0;
+utf8 = md->utf8 = (re->options & PCRE_UTF8) != 0;
+md->jscript_compat = (re->options & PCRE_JAVASCRIPT_COMPAT) != 0;
+
+md->notbol = (options & PCRE_NOTBOL) != 0;
+md->noteol = (options & PCRE_NOTEOL) != 0;
+md->notempty = (options & PCRE_NOTEMPTY) != 0;
+md->notempty_atstart = (options & PCRE_NOTEMPTY_ATSTART) != 0;
+md->partial = ((options & PCRE_PARTIAL_HARD) != 0)? 2 :
+              ((options & PCRE_PARTIAL_SOFT) != 0)? 1 : 0;
+md->hitend = FALSE;
+
+md->recursive = NULL;                   /* No recursion at top level */
+
+md->lcc = tables + lcc_offset;
+md->ctypes = tables + ctypes_offset;
+
+/* Handle different \R options. */
+
+switch (options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE))
+  {
+  case 0:
+  if ((re->options & (PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE)) != 0)
+    md->bsr_anycrlf = (re->options & PCRE_BSR_ANYCRLF) != 0;
+  else
+#ifdef BSR_ANYCRLF
+  md->bsr_anycrlf = TRUE;
+#else
+  md->bsr_anycrlf = FALSE;
+#endif
+  break;
+
+  case PCRE_BSR_ANYCRLF:
+  md->bsr_anycrlf = TRUE;
+  break;
+
+  case PCRE_BSR_UNICODE:
+  md->bsr_anycrlf = FALSE;
+  break;
+
+  default: return PCRE_ERROR_BADNEWLINE;
+  }
+
+/* Handle different types of newline. The three bits give eight cases. If
+nothing is set at run time, whatever was used at compile time applies. */
+
+switch ((((options & PCRE_NEWLINE_BITS) == 0)? re->options :
+        (pcre_uint32)options) & PCRE_NEWLINE_BITS)
+  {
+  case 0: newline = NEWLINE; break;   /* Compile-time default */
+  case PCRE_NEWLINE_CR: newline = CHAR_CR; break;
+  case PCRE_NEWLINE_LF: newline = CHAR_NL; break;
+  case PCRE_NEWLINE_CR+
+       PCRE_NEWLINE_LF: newline = (CHAR_CR << 8) | CHAR_NL; break;
+  case PCRE_NEWLINE_ANY: newline = -1; break;
+  case PCRE_NEWLINE_ANYCRLF: newline = -2; break;
+  default: return PCRE_ERROR_BADNEWLINE;
+  }
+
+if (newline == -2)
+  {
+  md->nltype = NLTYPE_ANYCRLF;
+  }
+else if (newline < 0)
+  {
+  md->nltype = NLTYPE_ANY;
+  }
+else
+  {
+  md->nltype = NLTYPE_FIXED;
+  if (newline > 255)
+    {
+    md->nllen = 2;
+    md->nl[0] = (newline >> 8) & 255;
+    md->nl[1] = newline & 255;
+    }
+  else
+    {
+    md->nllen = 1;
+    md->nl[0] = newline;
+    }
+  }
+
+/* Partial matching was originally supported only for a restricted set of
+regexes; from release 8.00 there are no restrictions, but the bits are still
+defined (though never set). So there's no harm in leaving this code. */
+
+if (md->partial && (re->flags & PCRE_NOPARTIAL) != 0)
+  return PCRE_ERROR_BADPARTIAL;
+
+/* Check a UTF-8 string if required. Unfortunately there's no way of passing
+back the character offset. */
+
+#ifdef SUPPORT_UTF8
+if (utf8 && (options & PCRE_NO_UTF8_CHECK) == 0)
+  {
+  if (_pcre_valid_utf8((USPTR)subject, length) >= 0)
+    return PCRE_ERROR_BADUTF8;
+  if (start_offset > 0 && start_offset < length)
+    {
+    int tb = ((USPTR)subject)[start_offset];
+    if (tb > 127)
+      {
+      tb &= 0xc0;
+      if (tb != 0 && tb != 0xc0) return PCRE_ERROR_BADUTF8_OFFSET;
+      }
+    }
+  }
+#endif
+
+/* The ims options can vary during the matching as a result of the presence
+of (?ims) items in the pattern. They are kept in a local variable so that
+restoring at the exit of a group is easy. */
+
+ims = re->options & (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL);
+
+/* If the expression has got more back references than the offsets supplied can
+hold, we get a temporary chunk of working store to use during the matching.
+Otherwise, we can use the vector supplied, rounding down its size to a multiple
+of 3. */
+
+ocount = offsetcount - (offsetcount % 3);
+
+if (re->top_backref > 0 && re->top_backref >= ocount/3)
+  {
+  ocount = re->top_backref * 3 + 3;
+  md->offset_vector = (int *)(pcre_malloc)(ocount * sizeof(int));
+  if (md->offset_vector == NULL) return PCRE_ERROR_NOMEMORY;
+  using_temporary_offsets = TRUE;
+  DPRINTF(("Got memory to hold back references\n"));
+  }
+else md->offset_vector = offsets;
+
+md->offset_end = ocount;
+md->offset_max = (2*ocount)/3;
+md->offset_overflow = FALSE;
+md->capture_last = -1;
+
+/* Compute the minimum number of offsets that we need to reset each time. Doing
+this makes a huge difference to execution time when there aren't many brackets
+in the pattern. */
+
+resetcount = 2 + re->top_bracket * 2;
+if (resetcount > offsetcount) resetcount = ocount;
+
+/* Reset the working variable associated with each extraction. These should
+never be used unless previously set, but they get saved and restored, and so we
+initialize them to avoid reading uninitialized locations. */
+
+if (md->offset_vector != NULL)
+  {
+  register int *iptr = md->offset_vector + ocount;
+  register int *iend = iptr - resetcount/2 + 1;
+  while (--iptr >= iend) *iptr = -1;
+  }
+
+/* Set up the first character to match, if available. The first_byte value is
+never set for an anchored regular expression, but the anchoring may be forced
+at run time, so we have to test for anchoring. The first char may be unset for
+an unanchored pattern, of course. If there's no first char and the pattern was
+studied, there may be a bitmap of possible first characters. */
+
+if (!anchored)
+  {
+  if ((re->flags & PCRE_FIRSTSET) != 0)
+    {
+    first_byte = re->first_byte & 255;
+    if ((first_byte_caseless = ((re->first_byte & REQ_CASELESS) != 0)) == TRUE)
+      first_byte = md->lcc[first_byte];
+    }
+  else
+    if (!startline && study != NULL &&
+      (study->flags & PCRE_STUDY_MAPPED) != 0)
+        start_bits = study->start_bits;
+  }
+
+/* For anchored or unanchored matches, there may be a "last known required
+character" set. */
+
+if ((re->flags & PCRE_REQCHSET) != 0)
+  {
+  req_byte = re->req_byte & 255;
+  req_byte_caseless = (re->req_byte & REQ_CASELESS) != 0;
+  req_byte2 = (tables + fcc_offset)[req_byte];  /* case flipped */
+  }
+
+
+/* ==========================================================================*/
+
+/* Loop for handling unanchored repeated matching attempts; for anchored regexs
+the loop runs just once. */
+
+for(;;)
+  {
+  USPTR save_end_subject = end_subject;
+  USPTR new_start_match;
+
+  /* Reset the maximum number of extractions we might see. */
+
+  if (md->offset_vector != NULL)
+    {
+    register int *iptr = md->offset_vector;
+    register int *iend = iptr + resetcount;
+    while (iptr < iend) *iptr++ = -1;
+    }
+
+  /* If firstline is TRUE, the start of the match is constrained to the first
+  line of a multiline string. That is, the match must be before or at the first
+  newline. Implement this by temporarily adjusting end_subject so that we stop
+  scanning at a newline. If the match fails at the newline, later code breaks
+  this loop. */
+
+  if (firstline)
+    {
+    USPTR t = start_match;
+#ifdef SUPPORT_UTF8
+    if (utf8)
+      {
+      while (t < md->end_subject && !IS_NEWLINE(t))
+        {
+        t++;
+        while (t < end_subject && (*t & 0xc0) == 0x80) t++;
+        }
+      }
+    else
+#endif
+    while (t < md->end_subject && !IS_NEWLINE(t)) t++;
+    end_subject = t;
+    }
+
+  /* There are some optimizations that avoid running the match if a known
+  starting point is not found, or if a known later character is not present.
+  However, there is an option that disables these, for testing and for ensuring
+  that all callouts do actually occur. */
+
+  if ((options & PCRE_NO_START_OPTIMIZE) == 0)
+    {
+    /* Advance to a unique first byte if there is one. */
+
+    if (first_byte >= 0)
+      {
+      if (first_byte_caseless)
+        while (start_match < end_subject && md->lcc[*start_match] != first_byte)
+          start_match++;
+      else
+        while (start_match < end_subject && *start_match != first_byte)
+          start_match++;
+      }
+
+    /* Or to just after a linebreak for a multiline match */
+
+    else if (startline)
+      {
+      if (start_match > md->start_subject + start_offset)
+        {
+#ifdef SUPPORT_UTF8
+        if (utf8)
+          {
+          while (start_match < end_subject && !WAS_NEWLINE(start_match))
+            {
+            start_match++;
+            while(start_match < end_subject && (*start_match & 0xc0) == 0x80)
+              start_match++;
+            }
+          }
+        else
+#endif
+        while (start_match < end_subject && !WAS_NEWLINE(start_match))
+          start_match++;
+
+        /* If we have just passed a CR and the newline option is ANY or ANYCRLF,
+        and we are now at a LF, advance the match position by one more character.
+        */
+
+        if (start_match[-1] == CHAR_CR &&
+             (md->nltype == NLTYPE_ANY || md->nltype == NLTYPE_ANYCRLF) &&
+             start_match < end_subject &&
+             *start_match == CHAR_NL)
+          start_match++;
+        }
+      }
+
+    /* Or to a non-unique first byte after study */
+
+    else if (start_bits != NULL)
+      {
+      while (start_match < end_subject)
+        {
+        register unsigned int c = *start_match;
+        if ((start_bits[c/8] & (1 << (c&7))) == 0) start_match++;
+          else break;
+        }
+      }
+    }   /* Starting optimizations */
+
+  /* Restore fudged end_subject */
+
+  end_subject = save_end_subject;
+
+  /* The following two optimizations are disabled for partial matching or if
+  disabling is explicitly requested. */
+
+  if ((options & PCRE_NO_START_OPTIMIZE) == 0 && !md->partial)
+    {
+    /* If the pattern was studied, a minimum subject length may be set. This is
+    a lower bound; no actual string of that length may actually match the
+    pattern. Although the value is, strictly, in characters, we treat it as
+    bytes to avoid spending too much time in this optimization. */
+
+    if (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0 &&
+        (pcre_uint32)(end_subject - start_match) < study->minlength)
+      {
+      rc = MATCH_NOMATCH;
+      break;
+      }
+
+    /* If req_byte is set, we know that that character must appear in the
+    subject for the match to succeed. If the first character is set, req_byte
+    must be later in the subject; otherwise the test starts at the match point.
+    This optimization can save a huge amount of backtracking in patterns with
+    nested unlimited repeats that aren't going to match. Writing separate code
+    for cased/caseless versions makes it go faster, as does using an
+    autoincrement and backing off on a match.
+
+    HOWEVER: when the subject string is very, very long, searching to its end
+    can take a long time, and give bad performance on quite ordinary patterns.
+    This showed up when somebody was matching something like /^\d+C/ on a
+    32-megabyte string... so we don't do this when the string is sufficiently
+    long. */
+
+    if (req_byte >= 0 && end_subject - start_match < REQ_BYTE_MAX)
+      {
+      register USPTR p = start_match + ((first_byte >= 0)? 1 : 0);
+
+      /* We don't need to repeat the search if we haven't yet reached the
+      place we found it at last time. */
+
+      if (p > req_byte_ptr)
+        {
+        if (req_byte_caseless)
+          {
+          while (p < end_subject)
+            {
+            register int pp = *p++;
+            if (pp == req_byte || pp == req_byte2) { p--; break; }
+            }
+          }
+        else
+          {
+          while (p < end_subject)
+            {
+            if (*p++ == req_byte) { p--; break; }
+            }
+          }
+
+        /* If we can't find the required character, break the matching loop,
+        forcing a match failure. */
+
+        if (p >= end_subject)
+          {
+          rc = MATCH_NOMATCH;
+          break;
+          }
+
+        /* If we have found the required character, save the point where we
+        found it, so that we don't search again next time round the loop if
+        the start hasn't passed this character yet. */
+
+        req_byte_ptr = p;
+        }
+      }
+    }
+
+#ifdef PCRE_DEBUG  /* Sigh. Some compilers never learn. */
+  printf(">>>> Match against: ");
+  pchars(start_match, end_subject - start_match, TRUE, md);
+  printf("\n");
+#endif
+
+  /* OK, we can now run the match. If "hitend" is set afterwards, remember the
+  first starting point for which a partial match was found. */
+
+  md->start_match_ptr = start_match;
+  md->start_used_ptr = start_match;
+  md->match_call_count = 0;
+  rc = match(start_match, md->start_code, start_match, NULL, 2, md, ims, NULL,
+    0, 0);
+  if (md->hitend && start_partial == NULL) start_partial = md->start_used_ptr;
+
+  switch(rc)
+    {
+    /* NOMATCH and PRUNE advance by one character. THEN at this level acts
+    exactly like PRUNE. */
+
+    case MATCH_NOMATCH:
+    case MATCH_PRUNE:
+    case MATCH_THEN:
+    new_start_match = start_match + 1;
+#ifdef SUPPORT_UTF8
+    if (utf8)
+      while(new_start_match < end_subject && (*new_start_match & 0xc0) == 0x80)
+        new_start_match++;
+#endif
+    break;
+
+    /* SKIP passes back the next starting point explicitly. */
+
+    case MATCH_SKIP:
+    new_start_match = md->start_match_ptr;
+    break;
+
+    /* COMMIT disables the bumpalong, but otherwise behaves as NOMATCH. */
+
+    case MATCH_COMMIT:
+    rc = MATCH_NOMATCH;
+    goto ENDLOOP;
+
+    /* Any other return is either a match, or some kind of error. */
+
+    default:
+    goto ENDLOOP;
+    }
+
+  /* Control reaches here for the various types of "no match at this point"
+  result. Reset the code to MATCH_NOMATCH for subsequent checking. */
+
+  rc = MATCH_NOMATCH;
+
+  /* If PCRE_FIRSTLINE is set, the match must happen before or at the first
+  newline in the subject (though it may continue over the newline). Therefore,
+  if we have just failed to match, starting at a newline, do not continue. */
+
+  if (firstline && IS_NEWLINE(start_match)) break;
+
+  /* Advance to new matching position */
+
+  start_match = new_start_match;
+
+  /* Break the loop if the pattern is anchored or if we have passed the end of
+  the subject. */
+
+  if (anchored || start_match > end_subject) break;
+
+  /* If we have just passed a CR and we are now at a LF, and the pattern does
+  not contain any explicit matches for \r or \n, and the newline option is CRLF
+  or ANY or ANYCRLF, advance the match position by one more character. */
+
+  if (start_match[-1] == CHAR_CR &&
+      start_match < end_subject &&
+      *start_match == CHAR_NL &&
+      (re->flags & PCRE_HASCRORLF) == 0 &&
+        (md->nltype == NLTYPE_ANY ||
+         md->nltype == NLTYPE_ANYCRLF ||
+         md->nllen == 2))
+    start_match++;
+
+  }   /* End of for(;;) "bumpalong" loop */
+
+/* ==========================================================================*/
+
+/* We reach here when rc is not MATCH_NOMATCH, or if one of the stopping
+conditions is true:
+
+(1) The pattern is anchored or the match was failed by (*COMMIT);
+
+(2) We are past the end of the subject;
+
+(3) PCRE_FIRSTLINE is set and we have failed to match at a newline, because
+    this option requests that a match occur at or before the first newline in
+    the subject.
+
+When we have a match and the offset vector is big enough to deal with any
+backreferences, captured substring offsets will already be set up. In the case
+where we had to get some local store to hold offsets for backreference
+processing, copy those that we can. In this case there need not be overflow if
+certain parts of the pattern were not used, even though there are more
+capturing parentheses than vector slots. */
+
+ENDLOOP:
+
+if (rc == MATCH_MATCH)
+  {
+  if (using_temporary_offsets)
+    {
+    if (offsetcount >= 4)
+      {
+      memcpy(offsets + 2, md->offset_vector + 2,
+        (offsetcount - 2) * sizeof(int));
+      DPRINTF(("Copied offsets from temporary memory\n"));
+      }
+    if (md->end_offset_top > offsetcount) md->offset_overflow = TRUE;
+    DPRINTF(("Freeing temporary memory\n"));
+    (pcre_free)(md->offset_vector);
+    }
+
+  /* Set the return code to the number of captured strings, or 0 if there are
+  too many to fit into the vector. */
+
+  rc = md->offset_overflow? 0 : md->end_offset_top/2;
+
+  /* If there is space, set up the whole thing as substring 0. The value of
+  md->start_match_ptr might be modified if \K was encountered on the success
+  matching path. */
+
+  if (offsetcount < 2) rc = 0; else
+    {
+    offsets[0] = md->start_match_ptr - md->start_subject;
+    offsets[1] = md->end_match_ptr - md->start_subject;
+    }
+
+  DPRINTF((">>>> returning %d\n", rc));
+  return rc;
+  }
+
+/* Control gets here if there has been an error, or if the overall match
+attempt has failed at all permitted starting positions. */
+
+if (using_temporary_offsets)
+  {
+  DPRINTF(("Freeing temporary memory\n"));
+  (pcre_free)(md->offset_vector);
+  }
+
+if (rc != MATCH_NOMATCH && rc != PCRE_ERROR_PARTIAL)
+  {
+  DPRINTF((">>>> error: returning %d\n", rc));
+  return rc;
+  }
+else if (start_partial != NULL)
+  {
+  DPRINTF((">>>> returning PCRE_ERROR_PARTIAL\n"));
+  if (offsetcount > 1)
+    {
+    offsets[0] = start_partial - (USPTR)subject;
+    offsets[1] = end_subject - (USPTR)subject;
+    }
+  return PCRE_ERROR_PARTIAL;
+  }
+else
+  {
+  DPRINTF((">>>> returning PCRE_ERROR_NOMATCH\n"));
+  return PCRE_ERROR_NOMATCH;
+  }
+}
+
+/* End of pcre_exec.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_fullinfo.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_fullinfo.c
new file mode 100644 (file)
index 0000000..6b8d789
--- /dev/null
@@ -0,0 +1,174 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2009 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_fullinfo(), which returns
+information about a compiled pattern. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+*        Return info about compiled pattern      *
+*************************************************/
+
+/* This is a newer "info" function which has an extensible interface so
+that additional items can be added compatibly.
+
+Arguments:
+  argument_re      points to compiled code
+  extra_data       points extra data, or NULL
+  what             what information is required
+  where            where to put the information
+
+Returns:           0 if data returned, negative on error
+*/
+
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_fullinfo(const pcre *argument_re, const pcre_extra *extra_data, int what,
+  void *where)
+{
+real_pcre internal_re;
+pcre_study_data internal_study;
+const real_pcre *re = (const real_pcre *)argument_re;
+const pcre_study_data *study = NULL;
+
+if (re == NULL || where == NULL) return PCRE_ERROR_NULL;
+
+if (extra_data != NULL && (extra_data->flags & PCRE_EXTRA_STUDY_DATA) != 0)
+  study = (const pcre_study_data *)extra_data->study_data;
+
+if (re->magic_number != MAGIC_NUMBER)
+  {
+  re = _pcre_try_flipped(re, &internal_re, study, &internal_study);
+  if (re == NULL) return PCRE_ERROR_BADMAGIC;
+  if (study != NULL) study = &internal_study;
+  }
+
+switch (what)
+  {
+  case PCRE_INFO_OPTIONS:
+  *((unsigned long int *)where) = re->options & PUBLIC_COMPILE_OPTIONS;
+  break;
+
+  case PCRE_INFO_SIZE:
+  *((size_t *)where) = re->size;
+  break;
+
+  case PCRE_INFO_STUDYSIZE:
+  *((size_t *)where) = (study == NULL)? 0 : study->size;
+  break;
+
+  case PCRE_INFO_CAPTURECOUNT:
+  *((int *)where) = re->top_bracket;
+  break;
+
+  case PCRE_INFO_BACKREFMAX:
+  *((int *)where) = re->top_backref;
+  break;
+
+  case PCRE_INFO_FIRSTBYTE:
+  *((int *)where) =
+    ((re->flags & PCRE_FIRSTSET) != 0)? re->first_byte :
+    ((re->flags & PCRE_STARTLINE) != 0)? -1 : -2;
+  break;
+
+  /* Make sure we pass back the pointer to the bit vector in the external
+  block, not the internal copy (with flipped integer fields). */
+
+  case PCRE_INFO_FIRSTTABLE:
+  *((const uschar **)where) =
+    (study != NULL && (study->flags & PCRE_STUDY_MAPPED) != 0)?
+      ((const pcre_study_data *)extra_data->study_data)->start_bits : NULL;
+  break;
+
+  case PCRE_INFO_MINLENGTH:
+  *((int *)where) =
+    (study != NULL && (study->flags & PCRE_STUDY_MINLEN) != 0)?
+      study->minlength : -1;
+  break;
+
+  case PCRE_INFO_LASTLITERAL:
+  *((int *)where) =
+    ((re->flags & PCRE_REQCHSET) != 0)? re->req_byte : -1;
+  break;
+
+  case PCRE_INFO_NAMEENTRYSIZE:
+  *((int *)where) = re->name_entry_size;
+  break;
+
+  case PCRE_INFO_NAMECOUNT:
+  *((int *)where) = re->name_count;
+  break;
+
+  case PCRE_INFO_NAMETABLE:
+  *((const uschar **)where) = (const uschar *)re + re->name_table_offset;
+  break;
+
+  case PCRE_INFO_DEFAULT_TABLES:
+  *((const uschar **)where) = (const uschar *)(_pcre_default_tables);
+  break;
+
+  /* From release 8.00 this will always return TRUE because NOPARTIAL is
+  no longer ever set (the restrictions have been removed). */
+
+  case PCRE_INFO_OKPARTIAL:
+  *((int *)where) = (re->flags & PCRE_NOPARTIAL) == 0;
+  break;
+
+  case PCRE_INFO_JCHANGED:
+  *((int *)where) = (re->flags & PCRE_JCHANGED) != 0;
+  break;
+
+  case PCRE_INFO_HASCRORLF:
+  *((int *)where) = (re->flags & PCRE_HASCRORLF) != 0;
+  break;
+
+  default: return PCRE_ERROR_BADOPTION;
+  }
+
+return 0;
+}
+
+/* End of pcre_fullinfo.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_get.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_get.c
new file mode 100644 (file)
index 0000000..837e2f6
--- /dev/null
@@ -0,0 +1,468 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2008 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains some convenience functions for extracting substrings
+from the subject string after a regex match has succeeded. The original idea
+for these functions came from Scott Wimer. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+*           Find number for named string         *
+*************************************************/
+
+/* This function is used by the get_first_set() function below, as well
+as being generally available. It assumes that names are unique.
+
+Arguments:
+  code        the compiled regex
+  stringname  the name whose number is required
+
+Returns:      the number of the named parentheses, or a negative number
+                (PCRE_ERROR_NOSUBSTRING) if not found
+*/
+
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_stringnumber(const pcre *code, const char *stringname)
+{
+int rc;
+int entrysize;
+int top, bot;
+uschar *nametable;
+
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
+  return rc;
+if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
+
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
+  return rc;
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
+  return rc;
+
+bot = 0;
+while (top > bot)
+  {
+  int mid = (top + bot) / 2;
+  uschar *entry = nametable + entrysize*mid;
+  int c = strcmp(stringname, (char *)(entry + 2));
+  if (c == 0) return (entry[0] << 8) + entry[1];
+  if (c > 0) bot = mid + 1; else top = mid;
+  }
+
+return PCRE_ERROR_NOSUBSTRING;
+}
+
+
+
+/*************************************************
+*     Find (multiple) entries for named string   *
+*************************************************/
+
+/* This is used by the get_first_set() function below, as well as being
+generally available. It is used when duplicated names are permitted.
+
+Arguments:
+  code        the compiled regex
+  stringname  the name whose entries required
+  firstptr    where to put the pointer to the first entry
+  lastptr     where to put the pointer to the last entry
+
+Returns:      the length of each entry, or a negative number
+                (PCRE_ERROR_NOSUBSTRING) if not found
+*/
+
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_stringtable_entries(const pcre *code, const char *stringname,
+  char **firstptr, char **lastptr)
+{
+int rc;
+int entrysize;
+int top, bot;
+uschar *nametable, *lastentry;
+
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMECOUNT, &top)) != 0)
+  return rc;
+if (top <= 0) return PCRE_ERROR_NOSUBSTRING;
+
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMEENTRYSIZE, &entrysize)) != 0)
+  return rc;
+if ((rc = pcre_fullinfo(code, NULL, PCRE_INFO_NAMETABLE, &nametable)) != 0)
+  return rc;
+
+lastentry = nametable + entrysize * (top - 1);
+bot = 0;
+while (top > bot)
+  {
+  int mid = (top + bot) / 2;
+  uschar *entry = nametable + entrysize*mid;
+  int c = strcmp(stringname, (char *)(entry + 2));
+  if (c == 0)
+    {
+    uschar *first = entry;
+    uschar *last = entry;
+    while (first > nametable)
+      {
+      if (strcmp(stringname, (char *)(first - entrysize + 2)) != 0) break;
+      first -= entrysize;
+      }
+    while (last < lastentry)
+      {
+      if (strcmp(stringname, (char *)(last + entrysize + 2)) != 0) break;
+      last += entrysize;
+      }
+    *firstptr = (char *)first;
+    *lastptr = (char *)last;
+    return entrysize;
+    }
+  if (c > 0) bot = mid + 1; else top = mid;
+  }
+
+return PCRE_ERROR_NOSUBSTRING;
+}
+
+
+#ifdef NOT_USED_IN_GLIB
+
+/*************************************************
+*    Find first set of multiple named strings    *
+*************************************************/
+
+/* This function allows for duplicate names in the table of named substrings.
+It returns the number of the first one that was set in a pattern match.
+
+Arguments:
+  code         the compiled regex
+  stringname   the name of the capturing substring
+  ovector      the vector of matched substrings
+
+Returns:       the number of the first that is set,
+               or the number of the last one if none are set,
+               or a negative number on error
+*/
+
+static int
+get_first_set(const pcre *code, const char *stringname, int *ovector)
+{
+const real_pcre *re = (const real_pcre *)code;
+int entrysize;
+char *first, *last;
+uschar *entry;
+if ((re->options & PCRE_DUPNAMES) == 0 && (re->flags & PCRE_JCHANGED) == 0)
+  return pcre_get_stringnumber(code, stringname);
+entrysize = pcre_get_stringtable_entries(code, stringname, &first, &last);
+if (entrysize <= 0) return entrysize;
+for (entry = (uschar *)first; entry <= (uschar *)last; entry += entrysize)
+  {
+  int n = (entry[0] << 8) + entry[1];
+  if (ovector[n*2] >= 0) return n;
+  }
+return (first[0] << 8) + first[1];
+}
+
+
+
+
+/*************************************************
+*      Copy captured string to given buffer      *
+*************************************************/
+
+/* This function copies a single captured substring into a given buffer.
+Note that we use memcpy() rather than strncpy() in case there are binary zeros
+in the string.
+
+Arguments:
+  subject        the subject string that was matched
+  ovector        pointer to the offsets table
+  stringcount    the number of substrings that were captured
+                   (i.e. the yield of the pcre_exec call, unless
+                   that was zero, in which case it should be 1/3
+                   of the offset table size)
+  stringnumber   the number of the required substring
+  buffer         where to put the substring
+  size           the size of the buffer
+
+Returns:         if successful:
+                   the length of the copied string, not including the zero
+                   that is put on the end; can be zero
+                 if not successful:
+                   PCRE_ERROR_NOMEMORY (-6) buffer too small
+                   PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
+*/
+
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_copy_substring(const char *subject, int *ovector, int stringcount,
+  int stringnumber, char *buffer, int size)
+{
+int yield;
+if (stringnumber < 0 || stringnumber >= stringcount)
+  return PCRE_ERROR_NOSUBSTRING;
+stringnumber *= 2;
+yield = ovector[stringnumber+1] - ovector[stringnumber];
+if (size < yield + 1) return PCRE_ERROR_NOMEMORY;
+memcpy(buffer, subject + ovector[stringnumber], yield);
+buffer[yield] = 0;
+return yield;
+}
+
+
+
+/*************************************************
+*   Copy named captured string to given buffer   *
+*************************************************/
+
+/* This function copies a single captured substring into a given buffer,
+identifying it by name. If the regex permits duplicate names, the first
+substring that is set is chosen.
+
+Arguments:
+  code           the compiled regex
+  subject        the subject string that was matched
+  ovector        pointer to the offsets table
+  stringcount    the number of substrings that were captured
+                   (i.e. the yield of the pcre_exec call, unless
+                   that was zero, in which case it should be 1/3
+                   of the offset table size)
+  stringname     the name of the required substring
+  buffer         where to put the substring
+  size           the size of the buffer
+
+Returns:         if successful:
+                   the length of the copied string, not including the zero
+                   that is put on the end; can be zero
+                 if not successful:
+                   PCRE_ERROR_NOMEMORY (-6) buffer too small
+                   PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
+*/
+
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_copy_named_substring(const pcre *code, const char *subject, int *ovector,
+  int stringcount, const char *stringname, char *buffer, int size)
+{
+int n = get_first_set(code, stringname, ovector);
+if (n <= 0) return n;
+return pcre_copy_substring(subject, ovector, stringcount, n, buffer, size);
+}
+
+
+
+/*************************************************
+*      Copy all captured strings to new store    *
+*************************************************/
+
+/* This function gets one chunk of store and builds a list of pointers and all
+of the captured substrings in it. A NULL pointer is put on the end of the list.
+
+Arguments:
+  subject        the subject string that was matched
+  ovector        pointer to the offsets table
+  stringcount    the number of substrings that were captured
+                   (i.e. the yield of the pcre_exec call, unless
+                   that was zero, in which case it should be 1/3
+                   of the offset table size)
+  listptr        set to point to the list of pointers
+
+Returns:         if successful: 0
+                 if not successful:
+                   PCRE_ERROR_NOMEMORY (-6) failed to get store
+*/
+
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_substring_list(const char *subject, int *ovector, int stringcount,
+  const char ***listptr)
+{
+int i;
+int size = sizeof(char *);
+int double_count = stringcount * 2;
+char **stringlist;
+char *p;
+
+for (i = 0; i < double_count; i += 2)
+  size += sizeof(char *) + ovector[i+1] - ovector[i] + 1;
+
+stringlist = (char **)(pcre_malloc)(size);
+if (stringlist == NULL) return PCRE_ERROR_NOMEMORY;
+
+*listptr = (const char **)stringlist;
+p = (char *)(stringlist + stringcount + 1);
+
+for (i = 0; i < double_count; i += 2)
+  {
+  int len = ovector[i+1] - ovector[i];
+  memcpy(p, subject + ovector[i], len);
+  *stringlist++ = p;
+  p += len;
+  *p++ = 0;
+  }
+
+*stringlist = NULL;
+return 0;
+}
+
+
+
+/*************************************************
+*   Free store obtained by get_substring_list    *
+*************************************************/
+
+/* This function exists for the benefit of people calling PCRE from non-C
+programs that can call its functions, but not free() or (pcre_free)() directly.
+
+Argument:   the result of a previous pcre_get_substring_list()
+Returns:    nothing
+*/
+
+PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
+pcre_free_substring_list(const char **pointer)
+{
+(pcre_free)((void *)pointer);
+}
+
+
+
+/*************************************************
+*      Copy captured string to new store         *
+*************************************************/
+
+/* This function copies a single captured substring into a piece of new
+store
+
+Arguments:
+  subject        the subject string that was matched
+  ovector        pointer to the offsets table
+  stringcount    the number of substrings that were captured
+                   (i.e. the yield of the pcre_exec call, unless
+                   that was zero, in which case it should be 1/3
+                   of the offset table size)
+  stringnumber   the number of the required substring
+  stringptr      where to put a pointer to the substring
+
+Returns:         if successful:
+                   the length of the string, not including the zero that
+                   is put on the end; can be zero
+                 if not successful:
+                   PCRE_ERROR_NOMEMORY (-6) failed to get store
+                   PCRE_ERROR_NOSUBSTRING (-7) substring not present
+*/
+
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_substring(const char *subject, int *ovector, int stringcount,
+  int stringnumber, const char **stringptr)
+{
+int yield;
+char *substring;
+if (stringnumber < 0 || stringnumber >= stringcount)
+  return PCRE_ERROR_NOSUBSTRING;
+stringnumber *= 2;
+yield = ovector[stringnumber+1] - ovector[stringnumber];
+substring = (char *)(pcre_malloc)(yield + 1);
+if (substring == NULL) return PCRE_ERROR_NOMEMORY;
+memcpy(substring, subject + ovector[stringnumber], yield);
+substring[yield] = 0;
+*stringptr = substring;
+return yield;
+}
+
+
+
+/*************************************************
+*   Copy named captured string to new store      *
+*************************************************/
+
+/* This function copies a single captured substring, identified by name, into
+new store. If the regex permits duplicate names, the first substring that is
+set is chosen.
+
+Arguments:
+  code           the compiled regex
+  subject        the subject string that was matched
+  ovector        pointer to the offsets table
+  stringcount    the number of substrings that were captured
+                   (i.e. the yield of the pcre_exec call, unless
+                   that was zero, in which case it should be 1/3
+                   of the offset table size)
+  stringname     the name of the required substring
+  stringptr      where to put the pointer
+
+Returns:         if successful:
+                   the length of the copied string, not including the zero
+                   that is put on the end; can be zero
+                 if not successful:
+                   PCRE_ERROR_NOMEMORY (-6) couldn't get memory
+                   PCRE_ERROR_NOSUBSTRING (-7) no such captured substring
+*/
+
+PCRE_EXP_DEFN int PCRE_CALL_CONVENTION
+pcre_get_named_substring(const pcre *code, const char *subject, int *ovector,
+  int stringcount, const char *stringname, const char **stringptr)
+{
+int n = get_first_set(code, stringname, ovector);
+if (n <= 0) return n;
+return pcre_get_substring(subject, ovector, stringcount, n, stringptr);
+}
+
+
+
+
+/*************************************************
+*       Free store obtained by get_substring     *
+*************************************************/
+
+/* This function exists for the benefit of people calling PCRE from non-C
+programs that can call its functions, but not free() or (pcre_free)() directly.
+
+Argument:   the result of a previous pcre_get_substring()
+Returns:    nothing
+*/
+
+PCRE_EXP_DEFN void PCRE_CALL_CONVENTION
+pcre_free_substring(const char *pointer)
+{
+(pcre_free)((void *)pointer);
+}
+
+#endif
+
+/* End of pcre_get.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_globals.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_globals.c
new file mode 100644 (file)
index 0000000..18d30cf
--- /dev/null
@@ -0,0 +1,76 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2008 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains global variables that are exported by the PCRE library.
+PCRE is thread-clean and doesn't use any global variables in the normal sense.
+However, it calls memory allocation and freeing functions via the four
+indirections below, and it can optionally do callouts, using the fifth
+indirection. These values can be changed by the caller, but are shared between
+all threads.
+
+For MS Visual Studio and Symbian OS, there are problems in initializing these
+variables to non-local functions. In these cases, therefore, an indirection via
+a local function is used.
+
+Also, when compiling for Virtual Pascal, things are done differently, and
+global variables are not used. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#if defined _MSC_VER || defined  __SYMBIAN32__
+static void* LocalPcreMalloc(size_t aSize)
+  {
+  return malloc(aSize);
+  }
+static void LocalPcreFree(void* aPtr)
+  {
+  free(aPtr);
+  }
+PCRE_EXP_DATA_DEFN int   (*pcre_callout)(pcre_callout_block *) = NULL;
+
+#elif !defined VPCOMPAT
+PCRE_EXP_DATA_DEFN int   (*pcre_callout)(pcre_callout_block *) = NULL;
+#endif
+
+/* End of pcre_globals.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_internal.h b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_internal.h
new file mode 100644 (file)
index 0000000..7c7412f
--- /dev/null
@@ -0,0 +1,1798 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2010 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+/* This header contains definitions that are shared between the different
+modules, but which are not relevant to the exported API. This includes some
+functions whose names all begin with "_pcre_". */
+
+#ifndef PCRE_INTERNAL_H
+#define PCRE_INTERNAL_H
+
+/* Define PCRE_DEBUG to get debugging output on stdout. */
+
+#if 0
+#define PCRE_DEBUG
+#endif
+
+/* We do not support both EBCDIC and UTF-8 at the same time. The "configure"
+script prevents both being selected, but not everybody uses "configure". */
+
+#if defined EBCDIC && defined SUPPORT_UTF8
+#error The use of both EBCDIC and SUPPORT_UTF8 is not supported.
+#endif
+
+/* If SUPPORT_UCP is defined, SUPPORT_UTF8 must also be defined. The
+"configure" script ensures this, but not everybody uses "configure". */
+
+#if defined SUPPORT_UCP && !defined SUPPORT_UTF8
+#define SUPPORT_UTF8 1
+#endif
+
+/* Use a macro for debugging printing, 'cause that eliminates the use of #ifdef
+inline, and there are *still* stupid compilers about that don't like indented
+pre-processor statements, or at least there were when I first wrote this. After
+all, it had only been about 10 years then...
+
+It turns out that the Mac Debugging.h header also defines the macro DPRINTF, so
+be absolutely sure we get our version. */
+
+#undef DPRINTF
+#ifdef PCRE_DEBUG
+#define DPRINTF(p) printf p
+#else
+#define DPRINTF(p) /* Nothing */
+#endif
+
+
+/* Standard C headers plus the external interface definition. The only time
+setjmp and stdarg are used is when NO_RECURSE is set. */
+
+#include <ctype.h>
+#include <limits.h>
+#include <stddef.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+/* When compiling a DLL for Windows, the exported symbols have to be declared
+using some MS magic. I found some useful information on this web page:
+http://msdn2.microsoft.com/en-us/library/y4h7bcy6(VS.80).aspx. According to the
+information there, using __declspec(dllexport) without "extern" we have a
+definition; with "extern" we have a declaration. The settings here override the
+setting in pcre.h (which is included below); it defines only PCRE_EXP_DECL,
+which is all that is needed for applications (they just import the symbols). We
+use:
+
+  PCRE_EXP_DECL       for declarations
+  PCRE_EXP_DEFN       for definitions of exported functions
+  PCRE_EXP_DATA_DEFN  for definitions of exported variables
+
+The reason for the two DEFN macros is that in non-Windows environments, one
+does not want to have "extern" before variable definitions because it leads to
+compiler warnings. So we distinguish between functions and variables. In
+Windows, the two should always be the same.
+
+The reason for wrapping this in #ifndef PCRE_EXP_DECL is so that pcretest,
+which is an application, but needs to import this file in order to "peek" at
+internals, can #include pcre.h first to get an application's-eye view.
+
+In principle, people compiling for non-Windows, non-Unix-like (i.e. uncommon,
+special-purpose environments) might want to stick other stuff in front of
+exported symbols. That's why, in the non-Windows case, we set PCRE_EXP_DEFN and
+PCRE_EXP_DATA_DEFN only if they are not already set. */
+
+#ifndef PCRE_EXP_DECL
+#  ifdef _WIN32
+#    ifndef PCRE_STATIC
+#      define PCRE_EXP_DECL       extern __declspec(dllexport)
+#      define PCRE_EXP_DEFN       __declspec(dllexport)
+#      define PCRE_EXP_DATA_DEFN  __declspec(dllexport)
+#    else
+#      define PCRE_EXP_DECL       extern
+#      define PCRE_EXP_DEFN
+#      define PCRE_EXP_DATA_DEFN
+#    endif
+#  else
+#    ifdef __cplusplus
+#      define PCRE_EXP_DECL       extern "C"
+#    else
+#      define PCRE_EXP_DECL       extern
+#    endif
+#    ifndef PCRE_EXP_DEFN
+#      define PCRE_EXP_DEFN       PCRE_EXP_DECL
+#    endif
+#    ifndef PCRE_EXP_DATA_DEFN
+#      define PCRE_EXP_DATA_DEFN
+#    endif
+#  endif
+#endif
+
+/* When compiling with the MSVC compiler, it is sometimes necessary to include
+a "calling convention" before exported function names. (This is secondhand
+information; I know nothing about MSVC myself). For example, something like
+
+  void __cdecl function(....)
+
+might be needed. In order so make this easy, all the exported functions have
+PCRE_CALL_CONVENTION just before their names. It is rarely needed; if not
+set, we ensure here that it has no effect. */
+
+#ifndef PCRE_CALL_CONVENTION
+#define PCRE_CALL_CONVENTION
+#endif
+
+/* We need to have types that specify unsigned 16-bit and 32-bit integers. We
+cannot determine these outside the compilation (e.g. by running a program as
+part of "configure") because PCRE is often cross-compiled for use on other
+systems. Instead we make use of the maximum sizes that are available at
+preprocessor time in standard C environments. */
+
+#if USHRT_MAX == 65535
+  typedef unsigned short pcre_uint16;
+  typedef short pcre_int16;
+#elif UINT_MAX == 65535
+  typedef unsigned int pcre_uint16;
+  typedef int pcre_int16;
+#else
+  #error Cannot determine a type for 16-bit unsigned integers
+#endif
+
+#if UINT_MAX == 4294967295
+  typedef unsigned int pcre_uint32;
+  typedef int pcre_int32;
+#elif ULONG_MAX == 4294967295
+  typedef unsigned long int pcre_uint32;
+  typedef long int pcre_int32;
+#else
+  #error Cannot determine a type for 32-bit unsigned integers
+#endif
+
+/* When checking for integer overflow in pcre_compile(), we need to handle
+large integers. If a 64-bit integer type is available, we can use that.
+Otherwise we have to cast to double, which of course requires floating point
+arithmetic. Handle this by defining a macro for the appropriate type. If
+stdint.h is available, include it; it may define INT64_MAX. Systems that do not
+have stdint.h (e.g. Solaris) may have inttypes.h. The macro int64_t may be set
+by "configure". */
+
+#if HAVE_STDINT_H
+#include <stdint.h>
+#elif HAVE_INTTYPES_H
+#include <inttypes.h>
+#endif
+
+#if defined INT64_MAX || defined int64_t
+#define INT64_OR_DOUBLE int64_t
+#else
+#define INT64_OR_DOUBLE double
+#endif
+
+/* All character handling must be done as unsigned characters. Otherwise there
+are problems with top-bit-set characters and functions such as isspace().
+However, we leave the interface to the outside world as char *, because that
+should make things easier for callers. We define a short type for unsigned char
+to save lots of typing. I tried "uchar", but it causes problems on Digital
+Unix, where it is defined in sys/types, so use "uschar" instead. */
+
+typedef unsigned char uschar;
+
+/* This is an unsigned int value that no character can ever have. UTF-8
+characters only go up to 0x7fffffff (though Unicode doesn't go beyond
+0x0010ffff). */
+
+#define NOTACHAR 0xffffffff
+
+/* PCRE is able to support several different kinds of newline (CR, LF, CRLF,
+"any" and "anycrlf" at present). The following macros are used to package up
+testing for newlines. NLBLOCK, PSSTART, and PSEND are defined in the various
+modules to indicate in which datablock the parameters exist, and what the
+start/end of string field names are. */
+
+#define NLTYPE_FIXED    0     /* Newline is a fixed length string */
+#define NLTYPE_ANY      1     /* Newline is any Unicode line ending */
+#define NLTYPE_ANYCRLF  2     /* Newline is CR, LF, or CRLF */
+
+/* This macro checks for a newline at the given position */
+
+#define IS_NEWLINE(p) \
+  ((NLBLOCK->nltype != NLTYPE_FIXED)? \
+    ((p) < NLBLOCK->PSEND && \
+     _pcre_is_newline((p), NLBLOCK->nltype, NLBLOCK->PSEND, &(NLBLOCK->nllen),\
+       utf8)) \
+    : \
+    ((p) <= NLBLOCK->PSEND - NLBLOCK->nllen && \
+     (p)[0] == NLBLOCK->nl[0] && \
+     (NLBLOCK->nllen == 1 || (p)[1] == NLBLOCK->nl[1]) \
+    ) \
+  )
+
+/* This macro checks for a newline immediately preceding the given position */
+
+#define WAS_NEWLINE(p) \
+  ((NLBLOCK->nltype != NLTYPE_FIXED)? \
+    ((p) > NLBLOCK->PSSTART && \
+     _pcre_was_newline((p), NLBLOCK->nltype, NLBLOCK->PSSTART, \
+       &(NLBLOCK->nllen), utf8)) \
+    : \
+    ((p) >= NLBLOCK->PSSTART + NLBLOCK->nllen && \
+     (p)[-NLBLOCK->nllen] == NLBLOCK->nl[0] && \
+     (NLBLOCK->nllen == 1 || (p)[-NLBLOCK->nllen+1] == NLBLOCK->nl[1]) \
+    ) \
+  )
+
+/* When PCRE is compiled as a C++ library, the subject pointer can be replaced
+with a custom type. This makes it possible, for example, to allow pcre_exec()
+to process subject strings that are discontinuous by using a smart pointer
+class. It must always be possible to inspect all of the subject string in
+pcre_exec() because of the way it backtracks. Two macros are required in the
+normal case, for sign-unspecified and unsigned char pointers. The former is
+used for the external interface and appears in pcre.h, which is why its name
+must begin with PCRE_. */
+
+#ifdef CUSTOM_SUBJECT_PTR
+#define PCRE_SPTR CUSTOM_SUBJECT_PTR
+#define USPTR CUSTOM_SUBJECT_PTR
+#else
+#define PCRE_SPTR const char *
+#define USPTR const unsigned char *
+#endif
+
+
+
+/* Include the public PCRE header and the definitions of UCP character property
+values. */
+
+#include "pcre.h"
+#include "ucp.h"
+
+/* When compiling for use with the Virtual Pascal compiler, these functions
+need to have their names changed. PCRE must be compiled with the -DVPCOMPAT
+option on the command line. */
+
+#ifdef VPCOMPAT
+#define strlen(s)        _strlen(s)
+#define strncmp(s1,s2,m) _strncmp(s1,s2,m)
+#define memcmp(s,c,n)    _memcmp(s,c,n)
+#define memcpy(d,s,n)    _memcpy(d,s,n)
+#define memmove(d,s,n)   _memmove(d,s,n)
+#define memset(s,c,n)    _memset(s,c,n)
+#else  /* VPCOMPAT */
+
+/* To cope with SunOS4 and other systems that lack memmove() but have bcopy(),
+define a macro for memmove() if HAVE_MEMMOVE is false, provided that HAVE_BCOPY
+is set. Otherwise, include an emulating function for those systems that have
+neither (there some non-Unix environments where this is the case). */
+
+#ifndef HAVE_MEMMOVE
+#undef  memmove        /* some systems may have a macro */
+#ifdef HAVE_BCOPY
+#define memmove(a, b, c) bcopy(b, a, c)
+#else  /* HAVE_BCOPY */
+static void *
+pcre_memmove(void *d, const void *s, size_t n)
+{
+size_t i;
+unsigned char *dest = (unsigned char *)d;
+const unsigned char *src = (const unsigned char *)s;
+if (dest > src)
+  {
+  dest += n;
+  src += n;
+  for (i = 0; i < n; ++i) *(--dest) = *(--src);
+  return (void *)dest;
+  }
+else
+  {
+  for (i = 0; i < n; ++i) *dest++ = *src++;
+  return (void *)(dest - n);
+  }
+}
+#define memmove(a, b, c) pcre_memmove(a, b, c)
+#endif   /* not HAVE_BCOPY */
+#endif   /* not HAVE_MEMMOVE */
+#endif   /* not VPCOMPAT */
+
+
+/* PCRE keeps offsets in its compiled code as 2-byte quantities (always stored
+in big-endian order) by default. These are used, for example, to link from the
+start of a subpattern to its alternatives and its end. The use of 2 bytes per
+offset limits the size of the compiled regex to around 64K, which is big enough
+for almost everybody. However, I received a request for an even bigger limit.
+For this reason, and also to make the code easier to maintain, the storing and
+loading of offsets from the byte string is now handled by the macros that are
+defined here.
+
+The macros are controlled by the value of LINK_SIZE. This defaults to 2 in
+the config.h file, but can be overridden by using -D on the command line. This
+is automated on Unix systems via the "configure" command. */
+
+#if LINK_SIZE == 2
+
+#define PUT(a,n,d)   \
+  (a[n] = (d) >> 8), \
+  (a[(n)+1] = (d) & 255)
+
+#define GET(a,n) \
+  (((a)[n] << 8) | (a)[(n)+1])
+
+#define MAX_PATTERN_SIZE (1 << 16)
+
+
+#elif LINK_SIZE == 3
+
+#define PUT(a,n,d)       \
+  (a[n] = (d) >> 16),    \
+  (a[(n)+1] = (d) >> 8), \
+  (a[(n)+2] = (d) & 255)
+
+#define GET(a,n) \
+  (((a)[n] << 16) | ((a)[(n)+1] << 8) | (a)[(n)+2])
+
+#define MAX_PATTERN_SIZE (1 << 24)
+
+
+#elif LINK_SIZE == 4
+
+#define PUT(a,n,d)        \
+  (a[n] = (d) >> 24),     \
+  (a[(n)+1] = (d) >> 16), \
+  (a[(n)+2] = (d) >> 8),  \
+  (a[(n)+3] = (d) & 255)
+
+#define GET(a,n) \
+  (((a)[n] << 24) | ((a)[(n)+1] << 16) | ((a)[(n)+2] << 8) | (a)[(n)+3])
+
+#define MAX_PATTERN_SIZE (1 << 30)   /* Keep it positive */
+
+
+#else
+#error LINK_SIZE must be either 2, 3, or 4
+#endif
+
+
+/* Convenience macro defined in terms of the others */
+
+#define PUTINC(a,n,d)   PUT(a,n,d), a += LINK_SIZE
+
+
+/* PCRE uses some other 2-byte quantities that do not change when the size of
+offsets changes. There are used for repeat counts and for other things such as
+capturing parenthesis numbers in back references. */
+
+#define PUT2(a,n,d)   \
+  a[n] = (d) >> 8; \
+  a[(n)+1] = (d) & 255
+
+#define GET2(a,n) \
+  (((a)[n] << 8) | (a)[(n)+1])
+
+#define PUT2INC(a,n,d)  PUT2(a,n,d), a += 2
+
+
+/* When UTF-8 encoding is being used, a character is no longer just a single
+byte. The macros for character handling generate simple sequences when used in
+byte-mode, and more complicated ones for UTF-8 characters. BACKCHAR should
+never be called in byte mode. To make sure it can never even appear when UTF-8
+support is omitted, we don't even define it. */
+
+#ifndef SUPPORT_UTF8
+#define GETCHAR(c, eptr) c = *eptr;
+#define GETCHARTEST(c, eptr) c = *eptr;
+#define GETCHARINC(c, eptr) c = *eptr++;
+#define GETCHARINCTEST(c, eptr) c = *eptr++;
+#define GETCHARLEN(c, eptr, len) c = *eptr;
+/* #define BACKCHAR(eptr) */
+
+#else   /* SUPPORT_UTF8 */
+
+/* Get the next UTF-8 character, not advancing the pointer. This is called when
+we know we are in UTF-8 mode. */
+
+#define GETCHAR(c, eptr) \
+  c = *eptr; \
+  if (c >= 0xc0) \
+    { \
+    int gcii; \
+    int gcaa = _pcre_utf8_table4[c & 0x3f];  /* Number of additional bytes */ \
+    int gcss = 6*gcaa; \
+    c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
+    for (gcii = 1; gcii <= gcaa; gcii++) \
+      { \
+      gcss -= 6; \
+      c |= (eptr[gcii] & 0x3f) << gcss; \
+      } \
+    }
+
+/* Get the next UTF-8 character, testing for UTF-8 mode, and not advancing the
+pointer. */
+
+#define GETCHARTEST(c, eptr) \
+  c = *eptr; \
+  if (utf8 && c >= 0xc0) \
+    { \
+    int gcii; \
+    int gcaa = _pcre_utf8_table4[c & 0x3f];  /* Number of additional bytes */ \
+    int gcss = 6*gcaa; \
+    c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
+    for (gcii = 1; gcii <= gcaa; gcii++) \
+      { \
+      gcss -= 6; \
+      c |= (eptr[gcii] & 0x3f) << gcss; \
+      } \
+    }
+
+/* Get the next UTF-8 character, advancing the pointer. This is called when we
+know we are in UTF-8 mode. */
+
+#define GETCHARINC(c, eptr) \
+  c = *eptr++; \
+  if (c >= 0xc0) \
+    { \
+    int gcaa = _pcre_utf8_table4[c & 0x3f];  /* Number of additional bytes */ \
+    int gcss = 6*gcaa; \
+    c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
+    while (gcaa-- > 0) \
+      { \
+      gcss -= 6; \
+      c |= (*eptr++ & 0x3f) << gcss; \
+      } \
+    }
+
+/* Get the next character, testing for UTF-8 mode, and advancing the pointer */
+
+#define GETCHARINCTEST(c, eptr) \
+  c = *eptr++; \
+  if (utf8 && c >= 0xc0) \
+    { \
+    int gcaa = _pcre_utf8_table4[c & 0x3f];  /* Number of additional bytes */ \
+    int gcss = 6*gcaa; \
+    c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
+    while (gcaa-- > 0) \
+      { \
+      gcss -= 6; \
+      c |= (*eptr++ & 0x3f) << gcss; \
+      } \
+    }
+
+/* Get the next UTF-8 character, not advancing the pointer, incrementing length
+if there are extra bytes. This is called when we know we are in UTF-8 mode. */
+
+#define GETCHARLEN(c, eptr, len) \
+  c = *eptr; \
+  if (c >= 0xc0) \
+    { \
+    int gcii; \
+    int gcaa = _pcre_utf8_table4[c & 0x3f];  /* Number of additional bytes */ \
+    int gcss = 6*gcaa; \
+    c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
+    for (gcii = 1; gcii <= gcaa; gcii++) \
+      { \
+      gcss -= 6; \
+      c |= (eptr[gcii] & 0x3f) << gcss; \
+      } \
+    len += gcaa; \
+    }
+
+/* Get the next UTF-8 character, testing for UTF-8 mode, not advancing the
+pointer, incrementing length if there are extra bytes. This is called when we
+know we are in UTF-8 mode. */
+
+#define GETCHARLENTEST(c, eptr, len) \
+  c = *eptr; \
+  if (utf8 && c >= 0xc0) \
+    { \
+    int gcii; \
+    int gcaa = _pcre_utf8_table4[c & 0x3f];  /* Number of additional bytes */ \
+    int gcss = 6*gcaa; \
+    c = (c & _pcre_utf8_table3[gcaa]) << gcss; \
+    for (gcii = 1; gcii <= gcaa; gcii++) \
+      { \
+      gcss -= 6; \
+      c |= (eptr[gcii] & 0x3f) << gcss; \
+      } \
+    len += gcaa; \
+    }
+
+/* If the pointer is not at the start of a character, move it back until
+it is. This is called only in UTF-8 mode - we don't put a test within the macro
+because almost all calls are already within a block of UTF-8 only code. */
+
+#define BACKCHAR(eptr) while((*eptr & 0xc0) == 0x80) eptr--
+
+#endif
+
+
+/* In case there is no definition of offsetof() provided - though any proper
+Standard C system should have one. */
+
+#ifndef offsetof
+#define offsetof(p_type,field) ((size_t)&(((p_type *)0)->field))
+#endif
+
+
+/* These are the public options that can change during matching. */
+
+#define PCRE_IMS (PCRE_CASELESS|PCRE_MULTILINE|PCRE_DOTALL)
+
+/* Private flags containing information about the compiled regex. They used to
+live at the top end of the options word, but that got almost full, so now they
+are in a 16-bit flags word. From release 8.00, PCRE_NOPARTIAL is unused, as
+the restrictions on partial matching have been lifted. It remains for backwards
+compatibility. */
+
+#define PCRE_NOPARTIAL     0x0001  /* can't use partial with this regex */
+#define PCRE_FIRSTSET      0x0002  /* first_byte is set */
+#define PCRE_REQCHSET      0x0004  /* req_byte is set */
+#define PCRE_STARTLINE     0x0008  /* start after \n for multiline */
+#define PCRE_JCHANGED      0x0010  /* j option used in regex */
+#define PCRE_HASCRORLF     0x0020  /* explicit \r or \n in pattern */
+
+/* Options for the "extra" block produced by pcre_study(). */
+
+#define PCRE_STUDY_MAPPED   0x01     /* a map of starting chars exists */
+#define PCRE_STUDY_MINLEN   0x02     /* a minimum length field exists */
+
+/* Masks for identifying the public options that are permitted at compile
+time, run time, or study time, respectively. */
+
+#define PCRE_NEWLINE_BITS (PCRE_NEWLINE_CR|PCRE_NEWLINE_LF|PCRE_NEWLINE_ANY| \
+                           PCRE_NEWLINE_ANYCRLF)
+
+#define PUBLIC_COMPILE_OPTIONS \
+  (PCRE_CASELESS|PCRE_EXTENDED|PCRE_ANCHORED|PCRE_MULTILINE| \
+   PCRE_DOTALL|PCRE_DOLLAR_ENDONLY|PCRE_EXTRA|PCRE_UNGREEDY|PCRE_UTF8| \
+   PCRE_NO_AUTO_CAPTURE|PCRE_NO_UTF8_CHECK|PCRE_AUTO_CALLOUT|PCRE_FIRSTLINE| \
+   PCRE_DUPNAMES|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
+   PCRE_JAVASCRIPT_COMPAT)
+
+#define PUBLIC_EXEC_OPTIONS \
+  (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
+   PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_NEWLINE_BITS| \
+   PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE|PCRE_NO_START_OPTIMIZE)
+
+#define PUBLIC_DFA_EXEC_OPTIONS \
+  (PCRE_ANCHORED|PCRE_NOTBOL|PCRE_NOTEOL|PCRE_NOTEMPTY|PCRE_NOTEMPTY_ATSTART| \
+   PCRE_NO_UTF8_CHECK|PCRE_PARTIAL_HARD|PCRE_PARTIAL_SOFT|PCRE_DFA_SHORTEST| \
+   PCRE_DFA_RESTART|PCRE_NEWLINE_BITS|PCRE_BSR_ANYCRLF|PCRE_BSR_UNICODE| \
+   PCRE_NO_START_OPTIMIZE)
+
+#define PUBLIC_STUDY_OPTIONS 0   /* None defined */
+
+/* Magic number to provide a small check against being handed junk. Also used
+to detect whether a pattern was compiled on a host of different endianness. */
+
+#define MAGIC_NUMBER  0x50435245UL   /* 'PCRE' */
+
+/* Negative values for the firstchar and reqchar variables */
+
+#define REQ_UNSET (-2)
+#define REQ_NONE  (-1)
+
+/* The maximum remaining length of subject we are prepared to search for a
+req_byte match. */
+
+#define REQ_BYTE_MAX 1000
+
+/* Flags added to firstbyte or reqbyte; a "non-literal" item is either a
+variable-length repeat, or a anything other than literal characters. */
+
+#define REQ_CASELESS 0x0100    /* indicates caselessness */
+#define REQ_VARY     0x0200    /* reqbyte followed non-literal item */
+
+/* Miscellaneous definitions. The #ifndef is to pacify compiler warnings in
+environments where these macros are defined elsewhere. Unfortunately, there
+is no way to do the same for the typedef. */
+
+typedef gboolean  BOOL;
+
+/* If PCRE is to support UTF-8 on EBCDIC platforms, we cannot use normal
+character constants like '*' because the compiler would emit their EBCDIC code,
+which is different from their ASCII/UTF-8 code. Instead we define macros for
+the characters so that they always use the ASCII/UTF-8 code when UTF-8 support
+is enabled. When UTF-8 support is not enabled, the definitions use character
+literals. Both character and string versions of each character are needed, and
+there are some longer strings as well.
+
+This means that, on EBCDIC platforms, the PCRE library can handle either
+EBCDIC, or UTF-8, but not both. To support both in the same compiled library
+would need different lookups depending on whether PCRE_UTF8 was set or not.
+This would make it impossible to use characters in switch/case statements,
+which would reduce performance. For a theoretical use (which nobody has asked
+for) in a minority area (EBCDIC platforms), this is not sensible. Any
+application that did need both could compile two versions of the library, using
+macros to give the functions distinct names. */
+
+#ifndef SUPPORT_UTF8
+
+/* UTF-8 support is not enabled; use the platform-dependent character literals
+so that PCRE works on both ASCII and EBCDIC platforms, in non-UTF-mode only. */
+
+#define CHAR_HT                     '\t'
+#define CHAR_VT                     '\v'
+#define CHAR_FF                     '\f'
+#define CHAR_CR                     '\r'
+#define CHAR_NL                     '\n'
+#define CHAR_BS                     '\b'
+#define CHAR_BEL                    '\a'
+#ifdef EBCDIC
+#define CHAR_ESC                    '\047'
+#define CHAR_DEL                    '\007'
+#else
+#define CHAR_ESC                    '\033'
+#define CHAR_DEL                    '\177'
+#endif
+
+#define CHAR_SPACE                  ' '
+#define CHAR_EXCLAMATION_MARK       '!'
+#define CHAR_QUOTATION_MARK         '"'
+#define CHAR_NUMBER_SIGN            '#'
+#define CHAR_DOLLAR_SIGN            '$'
+#define CHAR_PERCENT_SIGN           '%'
+#define CHAR_AMPERSAND              '&'
+#define CHAR_APOSTROPHE             '\''
+#define CHAR_LEFT_PARENTHESIS       '('
+#define CHAR_RIGHT_PARENTHESIS      ')'
+#define CHAR_ASTERISK               '*'
+#define CHAR_PLUS                   '+'
+#define CHAR_COMMA                  ','
+#define CHAR_MINUS                  '-'
+#define CHAR_DOT                    '.'
+#define CHAR_SLASH                  '/'
+#define CHAR_0                      '0'
+#define CHAR_1                      '1'
+#define CHAR_2                      '2'
+#define CHAR_3                      '3'
+#define CHAR_4                      '4'
+#define CHAR_5                      '5'
+#define CHAR_6                      '6'
+#define CHAR_7                      '7'
+#define CHAR_8                      '8'
+#define CHAR_9                      '9'
+#define CHAR_COLON                  ':'
+#define CHAR_SEMICOLON              ';'
+#define CHAR_LESS_THAN_SIGN         '<'
+#define CHAR_EQUALS_SIGN            '='
+#define CHAR_GREATER_THAN_SIGN      '>'
+#define CHAR_QUESTION_MARK          '?'
+#define CHAR_COMMERCIAL_AT          '@'
+#define CHAR_A                      'A'
+#define CHAR_B                      'B'
+#define CHAR_C                      'C'
+#define CHAR_D                      'D'
+#define CHAR_E                      'E'
+#define CHAR_F                      'F'
+#define CHAR_G                      'G'
+#define CHAR_H                      'H'
+#define CHAR_I                      'I'
+#define CHAR_J                      'J'
+#define CHAR_K                      'K'
+#define CHAR_L                      'L'
+#define CHAR_M                      'M'
+#define CHAR_N                      'N'
+#define CHAR_O                      'O'
+#define CHAR_P                      'P'
+#define CHAR_Q                      'Q'
+#define CHAR_R                      'R'
+#define CHAR_S                      'S'
+#define CHAR_T                      'T'
+#define CHAR_U                      'U'
+#define CHAR_V                      'V'
+#define CHAR_W                      'W'
+#define CHAR_X                      'X'
+#define CHAR_Y                      'Y'
+#define CHAR_Z                      'Z'
+#define CHAR_LEFT_SQUARE_BRACKET    '['
+#define CHAR_BACKSLASH              '\\'
+#define CHAR_RIGHT_SQUARE_BRACKET   ']'
+#define CHAR_CIRCUMFLEX_ACCENT      '^'
+#define CHAR_UNDERSCORE             '_'
+#define CHAR_GRAVE_ACCENT           '`'
+#define CHAR_a                      'a'
+#define CHAR_b                      'b'
+#define CHAR_c                      'c'
+#define CHAR_d                      'd'
+#define CHAR_e                      'e'
+#define CHAR_f                      'f'
+#define CHAR_g                      'g'
+#define CHAR_h                      'h'
+#define CHAR_i                      'i'
+#define CHAR_j                      'j'
+#define CHAR_k                      'k'
+#define CHAR_l                      'l'
+#define CHAR_m                      'm'
+#define CHAR_n                      'n'
+#define CHAR_o                      'o'
+#define CHAR_p                      'p'
+#define CHAR_q                      'q'
+#define CHAR_r                      'r'
+#define CHAR_s                      's'
+#define CHAR_t                      't'
+#define CHAR_u                      'u'
+#define CHAR_v                      'v'
+#define CHAR_w                      'w'
+#define CHAR_x                      'x'
+#define CHAR_y                      'y'
+#define CHAR_z                      'z'
+#define CHAR_LEFT_CURLY_BRACKET     '{'
+#define CHAR_VERTICAL_LINE          '|'
+#define CHAR_RIGHT_CURLY_BRACKET    '}'
+#define CHAR_TILDE                  '~'
+
+#define STR_HT                      "\t"
+#define STR_VT                      "\v"
+#define STR_FF                      "\f"
+#define STR_CR                      "\r"
+#define STR_NL                      "\n"
+#define STR_BS                      "\b"
+#define STR_BEL                     "\a"
+#ifdef EBCDIC
+#define STR_ESC                     "\047"
+#define STR_DEL                     "\007"
+#else
+#define STR_ESC                     "\033"
+#define STR_DEL                     "\177"
+#endif
+
+#define STR_SPACE                   " "
+#define STR_EXCLAMATION_MARK        "!"
+#define STR_QUOTATION_MARK          "\""
+#define STR_NUMBER_SIGN             "#"
+#define STR_DOLLAR_SIGN             "$"
+#define STR_PERCENT_SIGN            "%"
+#define STR_AMPERSAND               "&"
+#define STR_APOSTROPHE              "'"
+#define STR_LEFT_PARENTHESIS        "("
+#define STR_RIGHT_PARENTHESIS       ")"
+#define STR_ASTERISK                "*"
+#define STR_PLUS                    "+"
+#define STR_COMMA                   ","
+#define STR_MINUS                   "-"
+#define STR_DOT                     "."
+#define STR_SLASH                   "/"
+#define STR_0                       "0"
+#define STR_1                       "1"
+#define STR_2                       "2"
+#define STR_3                       "3"
+#define STR_4                       "4"
+#define STR_5                       "5"
+#define STR_6                       "6"
+#define STR_7                       "7"
+#define STR_8                       "8"
+#define STR_9                       "9"
+#define STR_COLON                   ":"
+#define STR_SEMICOLON               ";"
+#define STR_LESS_THAN_SIGN          "<"
+#define STR_EQUALS_SIGN             "="
+#define STR_GREATER_THAN_SIGN       ">"
+#define STR_QUESTION_MARK           "?"
+#define STR_COMMERCIAL_AT           "@"
+#define STR_A                       "A"
+#define STR_B                       "B"
+#define STR_C                       "C"
+#define STR_D                       "D"
+#define STR_E                       "E"
+#define STR_F                       "F"
+#define STR_G                       "G"
+#define STR_H                       "H"
+#define STR_I                       "I"
+#define STR_J                       "J"
+#define STR_K                       "K"
+#define STR_L                       "L"
+#define STR_M                       "M"
+#define STR_N                       "N"
+#define STR_O                       "O"
+#define STR_P                       "P"
+#define STR_Q                       "Q"
+#define STR_R                       "R"
+#define STR_S                       "S"
+#define STR_T                       "T"
+#define STR_U                       "U"
+#define STR_V                       "V"
+#define STR_W                       "W"
+#define STR_X                       "X"
+#define STR_Y                       "Y"
+#define STR_Z                       "Z"
+#define STR_LEFT_SQUARE_BRACKET     "["
+#define STR_BACKSLASH               "\\"
+#define STR_RIGHT_SQUARE_BRACKET    "]"
+#define STR_CIRCUMFLEX_ACCENT       "^"
+#define STR_UNDERSCORE              "_"
+#define STR_GRAVE_ACCENT            "`"
+#define STR_a                       "a"
+#define STR_b                       "b"
+#define STR_c                       "c"
+#define STR_d                       "d"
+#define STR_e                       "e"
+#define STR_f                       "f"
+#define STR_g                       "g"
+#define STR_h                       "h"
+#define STR_i                       "i"
+#define STR_j                       "j"
+#define STR_k                       "k"
+#define STR_l                       "l"
+#define STR_m                       "m"
+#define STR_n                       "n"
+#define STR_o                       "o"
+#define STR_p                       "p"
+#define STR_q                       "q"
+#define STR_r                       "r"
+#define STR_s                       "s"
+#define STR_t                       "t"
+#define STR_u                       "u"
+#define STR_v                       "v"
+#define STR_w                       "w"
+#define STR_x                       "x"
+#define STR_y                       "y"
+#define STR_z                       "z"
+#define STR_LEFT_CURLY_BRACKET      "{"
+#define STR_VERTICAL_LINE           "|"
+#define STR_RIGHT_CURLY_BRACKET     "}"
+#define STR_TILDE                   "~"
+
+#define STRING_ACCEPT0              "ACCEPT\0"
+#define STRING_COMMIT0              "COMMIT\0"
+#define STRING_F0                   "F\0"
+#define STRING_FAIL0                "FAIL\0"
+#define STRING_PRUNE0               "PRUNE\0"
+#define STRING_SKIP0                "SKIP\0"
+#define STRING_THEN                 "THEN"
+
+#define STRING_alpha0               "alpha\0"
+#define STRING_lower0               "lower\0"
+#define STRING_upper0               "upper\0"
+#define STRING_alnum0               "alnum\0"
+#define STRING_ascii0               "ascii\0"
+#define STRING_blank0               "blank\0"
+#define STRING_cntrl0               "cntrl\0"
+#define STRING_digit0               "digit\0"
+#define STRING_graph0               "graph\0"
+#define STRING_print0               "print\0"
+#define STRING_punct0               "punct\0"
+#define STRING_space0               "space\0"
+#define STRING_word0                "word\0"
+#define STRING_xdigit               "xdigit"
+
+#define STRING_DEFINE               "DEFINE"
+
+#define STRING_CR_RIGHTPAR          "CR)"
+#define STRING_LF_RIGHTPAR          "LF)"
+#define STRING_CRLF_RIGHTPAR        "CRLF)"
+#define STRING_ANY_RIGHTPAR         "ANY)"
+#define STRING_ANYCRLF_RIGHTPAR     "ANYCRLF)"
+#define STRING_BSR_ANYCRLF_RIGHTPAR "BSR_ANYCRLF)"
+#define STRING_BSR_UNICODE_RIGHTPAR "BSR_UNICODE)"
+#define STRING_UTF8_RIGHTPAR        "UTF8)"
+
+#else  /* SUPPORT_UTF8 */
+
+/* UTF-8 support is enabled; always use UTF-8 (=ASCII) character codes. This
+works in both modes non-EBCDIC platforms, and on EBCDIC platforms in UTF-8 mode
+only. */
+
+#define CHAR_HT                     '\011'
+#define CHAR_VT                     '\013'
+#define CHAR_FF                     '\014'
+#define CHAR_CR                     '\015'
+#define CHAR_NL                     '\012'
+#define CHAR_BS                     '\010'
+#define CHAR_BEL                    '\007'
+#define CHAR_ESC                    '\033'
+#define CHAR_DEL                    '\177'
+
+#define CHAR_SPACE                  '\040'
+#define CHAR_EXCLAMATION_MARK       '\041'
+#define CHAR_QUOTATION_MARK         '\042'
+#define CHAR_NUMBER_SIGN            '\043'
+#define CHAR_DOLLAR_SIGN            '\044'
+#define CHAR_PERCENT_SIGN           '\045'
+#define CHAR_AMPERSAND              '\046'
+#define CHAR_APOSTROPHE             '\047'
+#define CHAR_LEFT_PARENTHESIS       '\050'
+#define CHAR_RIGHT_PARENTHESIS      '\051'
+#define CHAR_ASTERISK               '\052'
+#define CHAR_PLUS                   '\053'
+#define CHAR_COMMA                  '\054'
+#define CHAR_MINUS                  '\055'
+#define CHAR_DOT                    '\056'
+#define CHAR_SLASH                  '\057'
+#define CHAR_0                      '\060'
+#define CHAR_1                      '\061'
+#define CHAR_2                      '\062'
+#define CHAR_3                      '\063'
+#define CHAR_4                      '\064'
+#define CHAR_5                      '\065'
+#define CHAR_6                      '\066'
+#define CHAR_7                      '\067'
+#define CHAR_8                      '\070'
+#define CHAR_9                      '\071'
+#define CHAR_COLON                  '\072'
+#define CHAR_SEMICOLON              '\073'
+#define CHAR_LESS_THAN_SIGN         '\074'
+#define CHAR_EQUALS_SIGN            '\075'
+#define CHAR_GREATER_THAN_SIGN      '\076'
+#define CHAR_QUESTION_MARK          '\077'
+#define CHAR_COMMERCIAL_AT          '\100'
+#define CHAR_A                      '\101'
+#define CHAR_B                      '\102'
+#define CHAR_C                      '\103'
+#define CHAR_D                      '\104'
+#define CHAR_E                      '\105'
+#define CHAR_F                      '\106'
+#define CHAR_G                      '\107'
+#define CHAR_H                      '\110'
+#define CHAR_I                      '\111'
+#define CHAR_J                      '\112'
+#define CHAR_K                      '\113'
+#define CHAR_L                      '\114'
+#define CHAR_M                      '\115'
+#define CHAR_N                      '\116'
+#define CHAR_O                      '\117'
+#define CHAR_P                      '\120'
+#define CHAR_Q                      '\121'
+#define CHAR_R                      '\122'
+#define CHAR_S                      '\123'
+#define CHAR_T                      '\124'
+#define CHAR_U                      '\125'
+#define CHAR_V                      '\126'
+#define CHAR_W                      '\127'
+#define CHAR_X                      '\130'
+#define CHAR_Y                      '\131'
+#define CHAR_Z                      '\132'
+#define CHAR_LEFT_SQUARE_BRACKET    '\133'
+#define CHAR_BACKSLASH              '\134'
+#define CHAR_RIGHT_SQUARE_BRACKET   '\135'
+#define CHAR_CIRCUMFLEX_ACCENT      '\136'
+#define CHAR_UNDERSCORE             '\137'
+#define CHAR_GRAVE_ACCENT           '\140'
+#define CHAR_a                      '\141'
+#define CHAR_b                      '\142'
+#define CHAR_c                      '\143'
+#define CHAR_d                      '\144'
+#define CHAR_e                      '\145'
+#define CHAR_f                      '\146'
+#define CHAR_g                      '\147'
+#define CHAR_h                      '\150'
+#define CHAR_i                      '\151'
+#define CHAR_j                      '\152'
+#define CHAR_k                      '\153'
+#define CHAR_l                      '\154'
+#define CHAR_m                      '\155'
+#define CHAR_n                      '\156'
+#define CHAR_o                      '\157'
+#define CHAR_p                      '\160'
+#define CHAR_q                      '\161'
+#define CHAR_r                      '\162'
+#define CHAR_s                      '\163'
+#define CHAR_t                      '\164'
+#define CHAR_u                      '\165'
+#define CHAR_v                      '\166'
+#define CHAR_w                      '\167'
+#define CHAR_x                      '\170'
+#define CHAR_y                      '\171'
+#define CHAR_z                      '\172'
+#define CHAR_LEFT_CURLY_BRACKET     '\173'
+#define CHAR_VERTICAL_LINE          '\174'
+#define CHAR_RIGHT_CURLY_BRACKET    '\175'
+#define CHAR_TILDE                  '\176'
+
+#define STR_HT                      "\011"
+#define STR_VT                      "\013"
+#define STR_FF                      "\014"
+#define STR_CR                      "\015"
+#define STR_NL                      "\012"
+#define STR_BS                      "\010"
+#define STR_BEL                     "\007"
+#define STR_ESC                     "\033"
+#define STR_DEL                     "\177"
+
+#define STR_SPACE                   "\040"
+#define STR_EXCLAMATION_MARK        "\041"
+#define STR_QUOTATION_MARK          "\042"
+#define STR_NUMBER_SIGN             "\043"
+#define STR_DOLLAR_SIGN             "\044"
+#define STR_PERCENT_SIGN            "\045"
+#define STR_AMPERSAND               "\046"
+#define STR_APOSTROPHE              "\047"
+#define STR_LEFT_PARENTHESIS        "\050"
+#define STR_RIGHT_PARENTHESIS       "\051"
+#define STR_ASTERISK                "\052"
+#define STR_PLUS                    "\053"
+#define STR_COMMA                   "\054"
+#define STR_MINUS                   "\055"
+#define STR_DOT                     "\056"
+#define STR_SLASH                   "\057"
+#define STR_0                       "\060"
+#define STR_1                       "\061"
+#define STR_2                       "\062"
+#define STR_3                       "\063"
+#define STR_4                       "\064"
+#define STR_5                       "\065"
+#define STR_6                       "\066"
+#define STR_7                       "\067"
+#define STR_8                       "\070"
+#define STR_9                       "\071"
+#define STR_COLON                   "\072"
+#define STR_SEMICOLON               "\073"
+#define STR_LESS_THAN_SIGN          "\074"
+#define STR_EQUALS_SIGN             "\075"
+#define STR_GREATER_THAN_SIGN       "\076"
+#define STR_QUESTION_MARK           "\077"
+#define STR_COMMERCIAL_AT           "\100"
+#define STR_A                       "\101"
+#define STR_B                       "\102"
+#define STR_C                       "\103"
+#define STR_D                       "\104"
+#define STR_E                       "\105"
+#define STR_F                       "\106"
+#define STR_G                       "\107"
+#define STR_H                       "\110"
+#define STR_I                       "\111"
+#define STR_J                       "\112"
+#define STR_K                       "\113"
+#define STR_L                       "\114"
+#define STR_M                       "\115"
+#define STR_N                       "\116"
+#define STR_O                       "\117"
+#define STR_P                       "\120"
+#define STR_Q                       "\121"
+#define STR_R                       "\122"
+#define STR_S                       "\123"
+#define STR_T                       "\124"
+#define STR_U                       "\125"
+#define STR_V                       "\126"
+#define STR_W                       "\127"
+#define STR_X                       "\130"
+#define STR_Y                       "\131"
+#define STR_Z                       "\132"
+#define STR_LEFT_SQUARE_BRACKET     "\133"
+#define STR_BACKSLASH               "\134"
+#define STR_RIGHT_SQUARE_BRACKET    "\135"
+#define STR_CIRCUMFLEX_ACCENT       "\136"
+#define STR_UNDERSCORE              "\137"
+#define STR_GRAVE_ACCENT            "\140"
+#define STR_a                       "\141"
+#define STR_b                       "\142"
+#define STR_c                       "\143"
+#define STR_d                       "\144"
+#define STR_e                       "\145"
+#define STR_f                       "\146"
+#define STR_g                       "\147"
+#define STR_h                       "\150"
+#define STR_i                       "\151"
+#define STR_j                       "\152"
+#define STR_k                       "\153"
+#define STR_l                       "\154"
+#define STR_m                       "\155"
+#define STR_n                       "\156"
+#define STR_o                       "\157"
+#define STR_p                       "\160"
+#define STR_q                       "\161"
+#define STR_r                       "\162"
+#define STR_s                       "\163"
+#define STR_t                       "\164"
+#define STR_u                       "\165"
+#define STR_v                       "\166"
+#define STR_w                       "\167"
+#define STR_x                       "\170"
+#define STR_y                       "\171"
+#define STR_z                       "\172"
+#define STR_LEFT_CURLY_BRACKET      "\173"
+#define STR_VERTICAL_LINE           "\174"
+#define STR_RIGHT_CURLY_BRACKET     "\175"
+#define STR_TILDE                   "\176"
+
+#define STRING_ACCEPT0              STR_A STR_C STR_C STR_E STR_P STR_T "\0"
+#define STRING_COMMIT0              STR_C STR_O STR_M STR_M STR_I STR_T "\0"
+#define STRING_F0                   STR_F "\0"
+#define STRING_FAIL0                STR_F STR_A STR_I STR_L "\0"
+#define STRING_PRUNE0               STR_P STR_R STR_U STR_N STR_E "\0"
+#define STRING_SKIP0                STR_S STR_K STR_I STR_P "\0"
+#define STRING_THEN                 STR_T STR_H STR_E STR_N
+
+#define STRING_alpha0               STR_a STR_l STR_p STR_h STR_a "\0"
+#define STRING_lower0               STR_l STR_o STR_w STR_e STR_r "\0"
+#define STRING_upper0               STR_u STR_p STR_p STR_e STR_r "\0"
+#define STRING_alnum0               STR_a STR_l STR_n STR_u STR_m "\0"
+#define STRING_ascii0               STR_a STR_s STR_c STR_i STR_i "\0"
+#define STRING_blank0               STR_b STR_l STR_a STR_n STR_k "\0"
+#define STRING_cntrl0               STR_c STR_n STR_t STR_r STR_l "\0"
+#define STRING_digit0               STR_d STR_i STR_g STR_i STR_t "\0"
+#define STRING_graph0               STR_g STR_r STR_a STR_p STR_h "\0"
+#define STRING_print0               STR_p STR_r STR_i STR_n STR_t "\0"
+#define STRING_punct0               STR_p STR_u STR_n STR_c STR_t "\0"
+#define STRING_space0               STR_s STR_p STR_a STR_c STR_e "\0"
+#define STRING_word0                STR_w STR_o STR_r STR_d       "\0"
+#define STRING_xdigit               STR_x STR_d STR_i STR_g STR_i STR_t
+
+#define STRING_DEFINE               STR_D STR_E STR_F STR_I STR_N STR_E
+
+#define STRING_CR_RIGHTPAR          STR_C STR_R STR_RIGHT_PARENTHESIS
+#define STRING_LF_RIGHTPAR          STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_CRLF_RIGHTPAR        STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_ANY_RIGHTPAR         STR_A STR_N STR_Y STR_RIGHT_PARENTHESIS
+#define STRING_ANYCRLF_RIGHTPAR     STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_BSR_ANYCRLF_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_A STR_N STR_Y STR_C STR_R STR_L STR_F STR_RIGHT_PARENTHESIS
+#define STRING_BSR_UNICODE_RIGHTPAR STR_B STR_S STR_R STR_UNDERSCORE STR_U STR_N STR_I STR_C STR_O STR_D STR_E STR_RIGHT_PARENTHESIS
+#define STRING_UTF8_RIGHTPAR        STR_U STR_T STR_F STR_8 STR_RIGHT_PARENTHESIS
+
+#endif  /* SUPPORT_UTF8 */
+
+/* Escape items that are just an encoding of a particular data value. */
+
+#ifndef ESC_e
+#define ESC_e CHAR_ESC
+#endif
+
+#ifndef ESC_f
+#define ESC_f CHAR_FF
+#endif
+
+#ifndef ESC_n
+#define ESC_n CHAR_NL
+#endif
+
+#ifndef ESC_r
+#define ESC_r CHAR_CR
+#endif
+
+/* We can't officially use ESC_t because it is a POSIX reserved identifier
+(presumably because of all the others like size_t). */
+
+#ifndef ESC_tee
+#define ESC_tee CHAR_HT
+#endif
+
+/* Codes for different types of Unicode property */
+
+#define PT_ANY        0    /* Any property - matches all chars */
+#define PT_LAMP       1    /* L& - the union of Lu, Ll, Lt */
+#define PT_GC         2    /* General characteristic (e.g. L) */
+#define PT_PC         3    /* Particular characteristic (e.g. Lu) */
+#define PT_SC         4    /* Script (e.g. Han) */
+
+/* Flag bits and data types for the extended class (OP_XCLASS) for classes that
+contain UTF-8 characters with values greater than 255. */
+
+#define XCL_NOT    0x01    /* Flag: this is a negative class */
+#define XCL_MAP    0x02    /* Flag: a 32-byte map is present */
+
+#define XCL_END       0    /* Marks end of individual items */
+#define XCL_SINGLE    1    /* Single item (one multibyte char) follows */
+#define XCL_RANGE     2    /* A range (two multibyte chars) follows */
+#define XCL_PROP      3    /* Unicode property (2-byte property code follows) */
+#define XCL_NOTPROP   4    /* Unicode inverted property (ditto) */
+
+/* These are escaped items that aren't just an encoding of a particular data
+value such as \n. They must have non-zero values, as check_escape() returns
+their negation. Also, they must appear in the same order as in the opcode
+definitions below, up to ESC_z. There's a dummy for OP_ANY because it
+corresponds to "." rather than an escape sequence, and another for OP_ALLANY
+(which is used for [^] in JavaScript compatibility mode).
+
+The final escape must be ESC_REF as subsequent values are used for
+backreferences (\1, \2, \3, etc). There are two tests in the code for an escape
+greater than ESC_b and less than ESC_Z to detect the types that may be
+repeated. These are the types that consume characters. If any new escapes are
+put in between that don't consume a character, that code will have to change.
+*/
+
+enum { ESC_A = 1, ESC_G, ESC_K, ESC_B, ESC_b, ESC_D, ESC_d, ESC_S, ESC_s,
+       ESC_W, ESC_w, ESC_dum1, ESC_dum2, ESC_C, ESC_P, ESC_p, ESC_R, ESC_H,
+       ESC_h, ESC_V, ESC_v, ESC_X, ESC_Z, ESC_z, ESC_E, ESC_Q, ESC_g, ESC_k,
+       ESC_REF };
+
+
+/* Opcode table: Starting from 1 (i.e. after OP_END), the values up to
+OP_EOD must correspond in order to the list of escapes immediately above.
+
+*** NOTE NOTE NOTE *** Whenever this list is updated, the two macro definitions
+that follow must also be updated to match. There are also tables called
+"coptable" and "poptable" in pcre_dfa_exec.c that must be updated. */
+
+enum {
+  OP_END,            /* 0 End of pattern */
+
+  /* Values corresponding to backslashed metacharacters */
+
+  OP_SOD,            /* 1 Start of data: \A */
+  OP_SOM,            /* 2 Start of match (subject + offset): \G */
+  OP_SET_SOM,        /* 3 Set start of match (\K) */
+  OP_NOT_WORD_BOUNDARY,  /*  4 \B */
+  OP_WORD_BOUNDARY,      /*  5 \b */
+  OP_NOT_DIGIT,          /*  6 \D */
+  OP_DIGIT,              /*  7 \d */
+  OP_NOT_WHITESPACE,     /*  8 \S */
+  OP_WHITESPACE,         /*  9 \s */
+  OP_NOT_WORDCHAR,       /* 10 \W */
+  OP_WORDCHAR,           /* 11 \w */
+  OP_ANY,            /* 12 Match any character (subject to DOTALL) */
+  OP_ALLANY,         /* 13 Match any character (not subject to DOTALL) */
+  OP_ANYBYTE,        /* 14 Match any byte (\C); different to OP_ANY for UTF-8 */
+  OP_NOTPROP,        /* 15 \P (not Unicode property) */
+  OP_PROP,           /* 16 \p (Unicode property) */
+  OP_ANYNL,          /* 17 \R (any newline sequence) */
+  OP_NOT_HSPACE,     /* 18 \H (not horizontal whitespace) */
+  OP_HSPACE,         /* 19 \h (horizontal whitespace) */
+  OP_NOT_VSPACE,     /* 20 \V (not vertical whitespace) */
+  OP_VSPACE,         /* 21 \v (vertical whitespace) */
+  OP_EXTUNI,         /* 22 \X (extended Unicode sequence */
+  OP_EODN,           /* 23 End of data or \n at end of data: \Z. */
+  OP_EOD,            /* 24 End of data: \z */
+
+  OP_OPT,            /* 25 Set runtime options */
+  OP_CIRC,           /* 26 Start of line - varies with multiline switch */
+  OP_DOLL,           /* 27 End of line - varies with multiline switch */
+  OP_CHAR,           /* 28 Match one character, casefully */
+  OP_CHARNC,         /* 29 Match one character, caselessly */
+  OP_NOT,            /* 30 Match one character, not the following one */
+
+  OP_STAR,           /* 31 The maximizing and minimizing versions of */
+  OP_MINSTAR,        /* 32 these six opcodes must come in pairs, with */
+  OP_PLUS,           /* 33 the minimizing one second. */
+  OP_MINPLUS,        /* 34 This first set applies to single characters.*/
+  OP_QUERY,          /* 35 */
+  OP_MINQUERY,       /* 36 */
+
+  OP_UPTO,           /* 37 From 0 to n matches */
+  OP_MINUPTO,        /* 38 */
+  OP_EXACT,          /* 39 Exactly n matches */
+
+  OP_POSSTAR,        /* 40 Possessified star */
+  OP_POSPLUS,        /* 41 Possessified plus */
+  OP_POSQUERY,       /* 42 Posesssified query */
+  OP_POSUPTO,        /* 43 Possessified upto */
+
+  OP_NOTSTAR,        /* 44 The maximizing and minimizing versions of */
+  OP_NOTMINSTAR,     /* 45 these six opcodes must come in pairs, with */
+  OP_NOTPLUS,        /* 46 the minimizing one second. They must be in */
+  OP_NOTMINPLUS,     /* 47 exactly the same order as those above. */
+  OP_NOTQUERY,       /* 48 This set applies to "not" single characters. */
+  OP_NOTMINQUERY,    /* 49 */
+
+  OP_NOTUPTO,        /* 50 From 0 to n matches */
+  OP_NOTMINUPTO,     /* 51 */
+  OP_NOTEXACT,       /* 52 Exactly n matches */
+
+  OP_NOTPOSSTAR,     /* 53 Possessified versions */
+  OP_NOTPOSPLUS,     /* 54 */
+  OP_NOTPOSQUERY,    /* 55 */
+  OP_NOTPOSUPTO,     /* 56 */
+
+  OP_TYPESTAR,       /* 57 The maximizing and minimizing versions of */
+  OP_TYPEMINSTAR,    /* 58 these six opcodes must come in pairs, with */
+  OP_TYPEPLUS,       /* 59 the minimizing one second. These codes must */
+  OP_TYPEMINPLUS,    /* 60 be in exactly the same order as those above. */
+  OP_TYPEQUERY,      /* 61 This set applies to character types such as \d */
+  OP_TYPEMINQUERY,   /* 62 */
+
+  OP_TYPEUPTO,       /* 63 From 0 to n matches */
+  OP_TYPEMINUPTO,    /* 64 */
+  OP_TYPEEXACT,      /* 65 Exactly n matches */
+
+  OP_TYPEPOSSTAR,    /* 66 Possessified versions */
+  OP_TYPEPOSPLUS,    /* 67 */
+  OP_TYPEPOSQUERY,   /* 68 */
+  OP_TYPEPOSUPTO,    /* 69 */
+
+  OP_CRSTAR,         /* 70 The maximizing and minimizing versions of */
+  OP_CRMINSTAR,      /* 71 all these opcodes must come in pairs, with */
+  OP_CRPLUS,         /* 72 the minimizing one second. These codes must */
+  OP_CRMINPLUS,      /* 73 be in exactly the same order as those above. */
+  OP_CRQUERY,        /* 74 These are for character classes and back refs */
+  OP_CRMINQUERY,     /* 75 */
+  OP_CRRANGE,        /* 76 These are different to the three sets above. */
+  OP_CRMINRANGE,     /* 77 */
+
+  OP_CLASS,          /* 78 Match a character class, chars < 256 only */
+  OP_NCLASS,         /* 79 Same, but the bitmap was created from a negative
+                           class - the difference is relevant only when a UTF-8
+                           character > 255 is encountered. */
+
+  OP_XCLASS,         /* 80 Extended class for handling UTF-8 chars within the
+                           class. This does both positive and negative. */
+
+  OP_REF,            /* 81 Match a back reference */
+  OP_RECURSE,        /* 82 Match a numbered subpattern (possibly recursive) */
+  OP_CALLOUT,        /* 83 Call out to external function if provided */
+
+  OP_ALT,            /* 84 Start of alternation */
+  OP_KET,            /* 85 End of group that doesn't have an unbounded repeat */
+  OP_KETRMAX,        /* 86 These two must remain together and in this */
+  OP_KETRMIN,        /* 87 order. They are for groups the repeat for ever. */
+
+  /* The assertions must come before BRA, CBRA, ONCE, and COND.*/
+
+  OP_ASSERT,         /* 88 Positive lookahead */
+  OP_ASSERT_NOT,     /* 89 Negative lookahead */
+  OP_ASSERTBACK,     /* 90 Positive lookbehind */
+  OP_ASSERTBACK_NOT, /* 91 Negative lookbehind */
+  OP_REVERSE,        /* 92 Move pointer back - used in lookbehind assertions */
+
+  /* ONCE, BRA, CBRA, and COND must come after the assertions, with ONCE first,
+  as there's a test for >= ONCE for a subpattern that isn't an assertion. */
+
+  OP_ONCE,           /* 93 Atomic group */
+  OP_BRA,            /* 94 Start of non-capturing bracket */
+  OP_CBRA,           /* 95 Start of capturing bracket */
+  OP_COND,           /* 96 Conditional group */
+
+  /* These three must follow the previous three, in the same order. There's a
+  check for >= SBRA to distinguish the two sets. */
+
+  OP_SBRA,           /* 97 Start of non-capturing bracket, check empty  */
+  OP_SCBRA,          /* 98 Start of capturing bracket, check empty */
+  OP_SCOND,          /* 99 Conditional group, check empty */
+
+  /* The next two pairs must (respectively) be kept together. */
+
+  OP_CREF,           /* 100 Used to hold a capture number as condition */
+  OP_NCREF,          /* 101 Same, but generaged by a name reference*/
+  OP_RREF,           /* 102 Used to hold a recursion number as condition */
+  OP_NRREF,          /* 103 Same, but generaged by a name reference*/
+  OP_DEF,            /* 104 The DEFINE condition */
+
+  OP_BRAZERO,        /* 105 These two must remain together and in this */
+  OP_BRAMINZERO,     /* 106 order. */
+
+  /* These are backtracking control verbs */
+
+  OP_PRUNE,          /* 107 */
+  OP_SKIP,           /* 108 */
+  OP_THEN,           /* 109 */
+  OP_COMMIT,         /* 110 */
+
+  /* These are forced failure and success verbs */
+
+  OP_FAIL,           /* 111 */
+  OP_ACCEPT,         /* 112 */
+  OP_CLOSE,          /* 113 Used before OP_ACCEPT to close open captures */
+
+  /* This is used to skip a subpattern with a {0} quantifier */
+
+  OP_SKIPZERO,       /* 114 */
+
+  /* This is not an opcode, but is used to check that tables indexed by opcode
+  are the correct length, in order to catch updating errors - there have been
+  some in the past. */
+
+  OP_TABLE_LENGTH
+};
+
+/* *** NOTE NOTE NOTE *** Whenever the list above is updated, the two macro
+definitions that follow must also be updated to match. There are also tables
+called "coptable" cna "poptable" in pcre_dfa_exec.c that must be updated. */
+
+
+/* This macro defines textual names for all the opcodes. These are used only
+for debugging. The macro is referenced only in pcre_printint.c. */
+
+#define OP_NAME_LIST \
+  "End", "\\A", "\\G", "\\K", "\\B", "\\b", "\\D", "\\d",         \
+  "\\S", "\\s", "\\W", "\\w", "Any", "AllAny", "Anybyte",         \
+  "notprop", "prop", "\\R", "\\H", "\\h", "\\V", "\\v",           \
+  "extuni",  "\\Z", "\\z",                                        \
+  "Opt", "^", "$", "char", "charnc", "not",                       \
+  "*", "*?", "+", "+?", "?", "??", "{", "{", "{",                 \
+  "*+","++", "?+", "{",                                           \
+  "*", "*?", "+", "+?", "?", "??", "{", "{", "{",                 \
+  "*+","++", "?+", "{",                                           \
+  "*", "*?", "+", "+?", "?", "??", "{", "{", "{",                 \
+  "*+","++", "?+", "{",                                           \
+  "*", "*?", "+", "+?", "?", "??", "{", "{",                      \
+  "class", "nclass", "xclass", "Ref", "Recurse", "Callout",       \
+  "Alt", "Ket", "KetRmax", "KetRmin", "Assert", "Assert not",     \
+  "AssertB", "AssertB not", "Reverse",                            \
+  "Once", "Bra", "CBra", "Cond", "SBra", "SCBra", "SCond",        \
+  "Cond ref", "Cond nref", "Cond rec", "Cond nrec", "Cond def",   \
+  "Brazero", "Braminzero",                                        \
+  "*PRUNE", "*SKIP", "*THEN", "*COMMIT", "*FAIL", "*ACCEPT",      \
+  "Close", "Skip zero"
+
+
+/* This macro defines the length of fixed length operations in the compiled
+regex. The lengths are used when searching for specific things, and also in the
+debugging printing of a compiled regex. We use a macro so that it can be
+defined close to the definitions of the opcodes themselves.
+
+As things have been extended, some of these are no longer fixed lenths, but are
+minima instead. For example, the length of a single-character repeat may vary
+in UTF-8 mode. The code that uses this table must know about such things. */
+
+#define OP_LENGTHS \
+  1,                             /* End                                    */ \
+  1, 1, 1, 1, 1,                 /* \A, \G, \K, \B, \b                     */ \
+  1, 1, 1, 1, 1, 1,              /* \D, \d, \S, \s, \W, \w                 */ \
+  1, 1, 1,                       /* Any, AllAny, Anybyte                   */ \
+  3, 3,                          /* \P, \p                                 */ \
+  1, 1, 1, 1, 1,                 /* \R, \H, \h, \V, \v                     */ \
+  1,                             /* \X                                     */ \
+  1, 1, 2, 1, 1,                 /* \Z, \z, Opt, ^, $                      */ \
+  2,                             /* Char  - the minimum length             */ \
+  2,                             /* Charnc  - the minimum length           */ \
+  2,                             /* not                                    */ \
+  /* Positive single-char repeats                            ** These are  */ \
+  2, 2, 2, 2, 2, 2,              /* *, *?, +, +?, ?, ??      ** minima in  */ \
+  4, 4, 4,                       /* upto, minupto, exact     ** UTF-8 mode */ \
+  2, 2, 2, 4,                    /* *+, ++, ?+, upto+                      */ \
+  /* Negative single-char repeats - only for chars < 256                   */ \
+  2, 2, 2, 2, 2, 2,              /* NOT *, *?, +, +?, ?, ??                */ \
+  4, 4, 4,                       /* NOT upto, minupto, exact               */ \
+  2, 2, 2, 4,                    /* Possessive *, +, ?, upto               */ \
+  /* Positive type repeats                                                 */ \
+  2, 2, 2, 2, 2, 2,              /* Type *, *?, +, +?, ?, ??               */ \
+  4, 4, 4,                       /* Type upto, minupto, exact              */ \
+  2, 2, 2, 4,                    /* Possessive *+, ++, ?+, upto+           */ \
+  /* Character class & ref repeats                                         */ \
+  1, 1, 1, 1, 1, 1,              /* *, *?, +, +?, ?, ??                    */ \
+  5, 5,                          /* CRRANGE, CRMINRANGE                    */ \
+ 33,                             /* CLASS                                  */ \
+ 33,                             /* NCLASS                                 */ \
+  0,                             /* XCLASS - variable length               */ \
+  3,                             /* REF                                    */ \
+  1+LINK_SIZE,                   /* RECURSE                                */ \
+  2+2*LINK_SIZE,                 /* CALLOUT                                */ \
+  1+LINK_SIZE,                   /* Alt                                    */ \
+  1+LINK_SIZE,                   /* Ket                                    */ \
+  1+LINK_SIZE,                   /* KetRmax                                */ \
+  1+LINK_SIZE,                   /* KetRmin                                */ \
+  1+LINK_SIZE,                   /* Assert                                 */ \
+  1+LINK_SIZE,                   /* Assert not                             */ \
+  1+LINK_SIZE,                   /* Assert behind                          */ \
+  1+LINK_SIZE,                   /* Assert behind not                      */ \
+  1+LINK_SIZE,                   /* Reverse                                */ \
+  1+LINK_SIZE,                   /* ONCE                                   */ \
+  1+LINK_SIZE,                   /* BRA                                    */ \
+  3+LINK_SIZE,                   /* CBRA                                   */ \
+  1+LINK_SIZE,                   /* COND                                   */ \
+  1+LINK_SIZE,                   /* SBRA                                   */ \
+  3+LINK_SIZE,                   /* SCBRA                                  */ \
+  1+LINK_SIZE,                   /* SCOND                                  */ \
+  3, 3,                          /* CREF, NCREF                            */ \
+  3, 3,                          /* RREF, NRREF                            */ \
+  1,                             /* DEF                                    */ \
+  1, 1,                          /* BRAZERO, BRAMINZERO                    */ \
+  1, 1, 1, 1,                    /* PRUNE, SKIP, THEN, COMMIT,             */ \
+  1, 1, 3, 1                     /* FAIL, ACCEPT, CLOSE, SKIPZERO          */
+
+
+/* A magic value for OP_RREF and OP_NRREF to indicate the "any recursion"
+condition. */
+
+#define RREF_ANY  0xffff
+
+/* Compile time error code numbers. They are given names so that they can more
+easily be tracked. When a new number is added, the table called eint in
+pcreposix.c must be updated. */
+
+enum { ERR0,  ERR1,  ERR2,  ERR3,  ERR4,  ERR5,  ERR6,  ERR7,  ERR8,  ERR9,
+       ERR10, ERR11, ERR12, ERR13, ERR14, ERR15, ERR16, ERR17, ERR18, ERR19,
+       ERR20, ERR21, ERR22, ERR23, ERR24, ERR25, ERR26, ERR27, ERR28, ERR29,
+       ERR30, ERR31, ERR32, ERR33, ERR34, ERR35, ERR36, ERR37, ERR38, ERR39,
+       ERR40, ERR41, ERR42, ERR43, ERR44, ERR45, ERR46, ERR47, ERR48, ERR49,
+       ERR50, ERR51, ERR52, ERR53, ERR54, ERR55, ERR56, ERR57, ERR58, ERR59,
+       ERR60, ERR61, ERR62, ERR63, ERR64, ERR65, ERRCOUNT };
+
+/* The real format of the start of the pcre block; the index of names and the
+code vector run on as long as necessary after the end. We store an explicit
+offset to the name table so that if a regex is compiled on one host, saved, and
+then run on another where the size of pointers is different, all might still
+be well. For the case of compiled-on-4 and run-on-8, we include an extra
+pointer that is always NULL. For future-proofing, a few dummy fields were
+originally included - even though you can never get this planning right - but
+there is only one left now.
+
+NOTE NOTE NOTE:
+Because people can now save and re-use compiled patterns, any additions to this
+structure should be made at the end, and something earlier (e.g. a new
+flag in the options or one of the dummy fields) should indicate that the new
+fields are present. Currently PCRE always sets the dummy fields to zero.
+NOTE NOTE NOTE
+*/
+
+typedef struct real_pcre {
+  pcre_uint32 magic_number;
+  pcre_uint32 size;               /* Total that was malloced */
+  pcre_uint32 options;            /* Public options */
+  pcre_uint16 flags;              /* Private flags */
+  pcre_uint16 dummy1;             /* For future use */
+  pcre_uint16 top_bracket;
+  pcre_uint16 top_backref;
+  pcre_uint16 first_byte;
+  pcre_uint16 req_byte;
+  pcre_uint16 name_table_offset;  /* Offset to name table that follows */
+  pcre_uint16 name_entry_size;    /* Size of any name items */
+  pcre_uint16 name_count;         /* Number of name items */
+  pcre_uint16 ref_count;          /* Reference count */
+
+  const unsigned char *tables;    /* Pointer to tables or NULL for std */
+  const unsigned char *nullpad;   /* NULL padding */
+} real_pcre;
+
+/* The format of the block used to store data from pcre_study(). The same
+remark (see NOTE above) about extending this structure applies. */
+
+typedef struct pcre_study_data {
+  pcre_uint32 size;               /* Total that was malloced */
+  pcre_uint32 flags;              /* Private flags */
+  uschar start_bits[32];          /* Starting char bits */
+  pcre_uint32 minlength;          /* Minimum subject length */
+} pcre_study_data;
+
+/* Structure for building a chain of open capturing subpatterns during
+compiling, so that instructions to close them can be compiled when (*ACCEPT) is
+encountered. This is also used to identify subpatterns that contain recursive
+back references to themselves, so that they can be made atomic. */
+
+typedef struct open_capitem {
+  struct open_capitem *next;    /* Chain link */
+  pcre_uint16 number;           /* Capture number */
+  pcre_uint16 flag;             /* Set TRUE if recursive back ref */
+} open_capitem;
+
+/* Structure for passing "static" information around between the functions
+doing the compiling, so that they are thread-safe. */
+
+typedef struct compile_data {
+  const uschar *lcc;            /* Points to lower casing table */
+  const uschar *fcc;            /* Points to case-flipping table */
+  const uschar *cbits;          /* Points to character type table */
+  const uschar *ctypes;         /* Points to table of type maps */
+  const uschar *start_workspace;/* The start of working space */
+  const uschar *start_code;     /* The start of the compiled code */
+  const uschar *start_pattern;  /* The start of the pattern */
+  const uschar *end_pattern;    /* The end of the pattern */
+  open_capitem *open_caps;      /* Chain of open capture items */
+  uschar *hwm;                  /* High watermark of workspace */
+  uschar *name_table;           /* The name/number table */
+  int  names_found;             /* Number of entries so far */
+  int  name_entry_size;         /* Size of each entry */
+  int  bracount;                /* Count of capturing parens as we compile */
+  int  final_bracount;          /* Saved value after first pass */
+  int  top_backref;             /* Maximum back reference */
+  unsigned int backref_map;     /* Bitmap of low back refs */
+  int  external_options;        /* External (initial) options */
+  int  external_flags;          /* External flag bits to be set */
+  int  req_varyopt;             /* "After variable item" flag for reqbyte */
+  BOOL had_accept;              /* (*ACCEPT) encountered */
+  BOOL check_lookbehind;        /* Lookbehinds need later checking */
+  int  nltype;                  /* Newline type */
+  int  nllen;                   /* Newline string length */
+  uschar nl[4];                 /* Newline string when fixed length */
+} compile_data;
+
+/* Structure for maintaining a chain of pointers to the currently incomplete
+branches, for testing for left recursion. */
+
+typedef struct branch_chain {
+  struct branch_chain *outer;
+  uschar *current_branch;
+} branch_chain;
+
+/* Structure for items in a linked list that represents an explicit recursive
+call within the pattern. */
+
+typedef struct recursion_info {
+  struct recursion_info *prevrec; /* Previous recursion record (or NULL) */
+  int group_num;                /* Number of group that was called */
+  const uschar *after_call;     /* "Return value": points after the call in the expr */
+  int *offset_save;             /* Pointer to start of saved offsets */
+  int saved_max;                /* Number of saved offsets */
+  int save_offset_top;          /* Current value of offset_top */
+} recursion_info;
+
+/* Structure for building a chain of data for holding the values of the subject
+pointer at the start of each subpattern, so as to detect when an empty string
+has been matched by a subpattern - to break infinite loops. */
+
+typedef struct eptrblock {
+  struct eptrblock *epb_prev;
+  USPTR epb_saved_eptr;
+} eptrblock;
+
+
+/* Structure for passing "static" information around between the functions
+doing traditional NFA matching, so that they are thread-safe. */
+
+typedef struct match_data {
+  unsigned long int match_call_count;      /* As it says */
+  unsigned long int match_limit;           /* As it says */
+  unsigned long int match_limit_recursion; /* As it says */
+  int   *offset_vector;         /* Offset vector */
+  int    offset_end;            /* One past the end */
+  int    offset_max;            /* The maximum usable for return data */
+  int    nltype;                /* Newline type */
+  int    nllen;                 /* Newline string length */
+  int    name_count;            /* Number of names in name table */
+  int    name_entry_size;       /* Size of entry in names table */
+  uschar *name_table;           /* Table of names */
+  uschar nl[4];                 /* Newline string when fixed */
+  const uschar *lcc;            /* Points to lower casing table */
+  const uschar *ctypes;         /* Points to table of type maps */
+  BOOL   offset_overflow;       /* Set if too many extractions */
+  BOOL   notbol;                /* NOTBOL flag */
+  BOOL   noteol;                /* NOTEOL flag */
+  BOOL   utf8;                  /* UTF8 flag */
+  BOOL   jscript_compat;        /* JAVASCRIPT_COMPAT flag */
+  BOOL   endonly;               /* Dollar not before final \n */
+  BOOL   notempty;              /* Empty string match not wanted */
+  BOOL   notempty_atstart;      /* Empty string match at start not wanted */
+  BOOL   hitend;                /* Hit the end of the subject at some point */
+  BOOL   bsr_anycrlf;           /* \R is just any CRLF, not full Unicode */
+  const uschar *start_code;     /* For use when recursing */
+  USPTR  start_subject;         /* Start of the subject string */
+  USPTR  end_subject;           /* End of the subject string */
+  USPTR  start_match_ptr;       /* Start of matched string */
+  USPTR  end_match_ptr;         /* Subject position at end match */
+  USPTR  start_used_ptr;        /* Earliest consulted character */
+  int    partial;               /* PARTIAL options */
+  int    end_offset_top;        /* Highwater mark at end of match */
+  int    capture_last;          /* Most recent capture number */
+  int    start_offset;          /* The start offset value */
+  eptrblock *eptrchain;         /* Chain of eptrblocks for tail recursions */
+  int    eptrn;                 /* Next free eptrblock */
+  recursion_info *recursive;    /* Linked list of recursion data */
+  void  *callout_data;          /* To pass back to callouts */
+} match_data;
+
+/* A similar structure is used for the same purpose by the DFA matching
+functions. */
+
+typedef struct dfa_match_data {
+  const uschar *start_code;     /* Start of the compiled pattern */
+  const uschar *start_subject;  /* Start of the subject string */
+  const uschar *end_subject;    /* End of subject string */
+  const uschar *start_used_ptr; /* Earliest consulted character */
+  const uschar *tables;         /* Character tables */
+  int   start_offset;           /* The start offset value */
+  int   moptions;               /* Match options */
+  int   poptions;               /* Pattern options */
+  int    nltype;                /* Newline type */
+  int    nllen;                 /* Newline string length */
+  uschar nl[4];                 /* Newline string when fixed */
+  void  *callout_data;          /* To pass back to callouts */
+} dfa_match_data;
+
+/* Bit definitions for entries in the pcre_ctypes table. */
+
+#define ctype_space   0x01
+#define ctype_letter  0x02
+#define ctype_digit   0x04
+#define ctype_xdigit  0x08
+#define ctype_word    0x10   /* alphanumeric or '_' */
+#define ctype_meta    0x80   /* regexp meta char or zero (end pattern) */
+
+/* Offsets for the bitmap tables in pcre_cbits. Each table contains a set
+of bits for a class map. Some classes are built by combining these tables. */
+
+#define cbit_space     0      /* [:space:] or \s */
+#define cbit_xdigit   32      /* [:xdigit:] */
+#define cbit_digit    64      /* [:digit:] or \d */
+#define cbit_upper    96      /* [:upper:] */
+#define cbit_lower   128      /* [:lower:] */
+#define cbit_word    160      /* [:word:] or \w */
+#define cbit_graph   192      /* [:graph:] */
+#define cbit_print   224      /* [:print:] */
+#define cbit_punct   256      /* [:punct:] */
+#define cbit_cntrl   288      /* [:cntrl:] */
+#define cbit_length  320      /* Length of the cbits table */
+
+/* Offsets of the various tables from the base tables pointer, and
+total length. */
+
+#define lcc_offset      0
+#define fcc_offset    256
+#define cbits_offset  512
+#define ctypes_offset (cbits_offset + cbit_length)
+#define tables_length (ctypes_offset + 256)
+
+/* Layout of the UCP type table that translates property names into types and
+codes. Each entry used to point directly to a name, but to reduce the number of
+relocations in shared libraries, it now has an offset into a single string
+instead. */
+
+typedef struct {
+  pcre_uint16 name_offset;
+  pcre_uint16 type;
+  pcre_uint16 value;
+} ucp_type_table;
+
+
+/* Internal shared data tables. These are tables that are used by more than one
+of the exported public functions. They have to be "external" in the C sense,
+but are not part of the PCRE public API. The data for these tables is in the
+pcre_tables.c module. */
+
+extern const int    _pcre_utf8_table1[];
+extern const int    _pcre_utf8_table2[];
+extern const int    _pcre_utf8_table3[];
+extern const uschar _pcre_utf8_table4[];
+
+extern const int    _pcre_utf8_table1_size;
+
+extern const char   _pcre_utt_names[];
+extern const ucp_type_table _pcre_utt[];
+extern const int _pcre_utt_size;
+
+extern const uschar _pcre_default_tables[];
+
+extern const uschar _pcre_OP_lengths[];
+
+
+/* Internal shared functions. These are functions that are used by more than
+one of the exported public functions. They have to be "external" in the C
+sense, but are not part of the PCRE public API. */
+
+extern const uschar *_pcre_find_bracket(const uschar *, BOOL, int);
+extern BOOL          _pcre_is_newline(USPTR, int, USPTR, int *, BOOL);
+extern int           _pcre_ord2utf8(int, uschar *);
+extern real_pcre    *_pcre_try_flipped(const real_pcre *, real_pcre *,
+                       const pcre_study_data *, pcre_study_data *);
+#define              _pcre_valid_utf8(u, i) TRUE
+extern BOOL          _pcre_was_newline(USPTR, int, USPTR, int *, BOOL);
+extern BOOL          _pcre_xclass(int, const uschar *);
+
+
+/* Unicode character database (UCD) */
+
+typedef struct {
+  uschar script;
+  uschar chartype;
+  pcre_int32 other_case;
+} ucd_record;
+
+extern const ucd_record  _pcre_ucd_records[];
+extern const uschar      _pcre_ucd_stage1[];
+extern const pcre_uint16 _pcre_ucd_stage2[];
+extern const int         _pcre_ucp_gentype[];
+
+extern unsigned int      _pcre_ucp_othercase (const unsigned int);
+
+/* UCD access macros */
+
+#include "../glib.h"
+
+#define UCD_CHARTYPE(ch)  g_unichar_type(ch)
+#define UCD_SCRIPT(ch)    g_unichar_get_script(ch)
+#define UCD_CATEGORY(ch)  _pcre_ucp_gentype[UCD_CHARTYPE(ch)]
+#define UCD_OTHERCASE(ch) _pcre_ucp_othercase(ch)
+
+#endif
+
+/* End of pcre_internal.h */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_newline.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_newline.c
new file mode 100644 (file)
index 0000000..38cf7f7
--- /dev/null
@@ -0,0 +1,162 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2009 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains internal functions for testing newlines when more than
+one kind of newline is to be recognized. When a newline is found, its length is
+returned. In principle, we could implement several newline "types", each
+referring to a different set of newline characters. At present, PCRE supports
+only NLTYPE_FIXED, which gets handled without these functions, NLTYPE_ANYCRLF,
+and NLTYPE_ANY. The full list of Unicode newline characters is taken from
+http://unicode.org/unicode/reports/tr18/. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+
+/*************************************************
+*      Check for newline at given position       *
+*************************************************/
+
+/* It is guaranteed that the initial value of ptr is less than the end of the
+string that is being processed.
+
+Arguments:
+  ptr          pointer to possible newline
+  type         the newline type
+  endptr       pointer to the end of the string
+  lenptr       where to return the length
+  utf8         TRUE if in utf8 mode
+
+Returns:       TRUE or FALSE
+*/
+
+BOOL
+_pcre_is_newline(USPTR ptr, int type, USPTR endptr, int *lenptr, BOOL utf8)
+{
+int c;
+if (utf8) { GETCHAR(c, ptr); } else c = *ptr;
+
+if (type == NLTYPE_ANYCRLF) switch(c)
+  {
+  case 0x000a: *lenptr = 1; return TRUE;             /* LF */
+  case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
+               return TRUE;                          /* CR */
+  default: return FALSE;
+  }
+
+/* NLTYPE_ANY */
+
+else switch(c)
+  {
+  case 0x000a:                                       /* LF */
+  case 0x000b:                                       /* VT */
+  case 0x000c: *lenptr = 1; return TRUE;             /* FF */
+  case 0x000d: *lenptr = (ptr < endptr - 1 && ptr[1] == 0x0a)? 2 : 1;
+               return TRUE;                          /* CR */
+  case 0x0085: *lenptr = utf8? 2 : 1; return TRUE;   /* NEL */
+  case 0x2028:                                       /* LS */
+  case 0x2029: *lenptr = 3; return TRUE;             /* PS */
+  default: return FALSE;
+  }
+}
+
+
+
+/*************************************************
+*     Check for newline at previous position     *
+*************************************************/
+
+/* It is guaranteed that the initial value of ptr is greater than the start of
+the string that is being processed.
+
+Arguments:
+  ptr          pointer to possible newline
+  type         the newline type
+  startptr     pointer to the start of the string
+  lenptr       where to return the length
+  utf8         TRUE if in utf8 mode
+
+Returns:       TRUE or FALSE
+*/
+
+BOOL
+_pcre_was_newline(USPTR ptr, int type, USPTR startptr, int *lenptr, BOOL utf8)
+{
+int c;
+ptr--;
+#ifdef SUPPORT_UTF8
+if (utf8)
+  {
+  BACKCHAR(ptr);
+  GETCHAR(c, ptr);
+  }
+else c = *ptr;
+#else   /* no UTF-8 support */
+c = *ptr;
+#endif  /* SUPPORT_UTF8 */
+
+if (type == NLTYPE_ANYCRLF) switch(c)
+  {
+  case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
+               return TRUE;                         /* LF */
+  case 0x000d: *lenptr = 1; return TRUE;            /* CR */
+  default: return FALSE;
+  }
+
+else switch(c)
+  {
+  case 0x000a: *lenptr = (ptr > startptr && ptr[-1] == 0x0d)? 2 : 1;
+               return TRUE;                         /* LF */
+  case 0x000b:                                      /* VT */
+  case 0x000c:                                      /* FF */
+  case 0x000d: *lenptr = 1; return TRUE;            /* CR */
+  case 0x0085: *lenptr = utf8? 2 : 1; return TRUE;  /* NEL */
+  case 0x2028:                                      /* LS */
+  case 0x2029: *lenptr = 3; return TRUE;            /* PS */
+  default: return FALSE;
+  }
+}
+
+/* End of pcre_newline.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_ord2utf8.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_ord2utf8.c
new file mode 100644 (file)
index 0000000..6f4eb9e
--- /dev/null
@@ -0,0 +1,87 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2008 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This file contains a private PCRE function that converts an ordinal
+character value into a UTF8 string. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+*       Convert character value to UTF-8         *
+*************************************************/
+
+/* This function takes an integer value in the range 0 - 0x7fffffff
+and encodes it as a UTF-8 character in 0 to 6 bytes.
+
+Arguments:
+  cvalue     the character value
+  buffer     pointer to buffer for result - at least 6 bytes long
+
+Returns:     number of characters placed in the buffer
+*/
+
+int
+_pcre_ord2utf8(int cvalue, uschar *buffer)
+{
+#ifdef SUPPORT_UTF8
+register int i, j;
+for (i = 0; i < _pcre_utf8_table1_size; i++)
+  if (cvalue <= _pcre_utf8_table1[i]) break;
+buffer += i;
+for (j = i; j > 0; j--)
+ {
+ *buffer-- = 0x80 | (cvalue & 0x3f);
+ cvalue >>= 6;
+ }
+*buffer = _pcre_utf8_table2[i] | cvalue;
+return i + 1;
+#else
+(void)(cvalue);  /* Keep compiler happy; this function won't ever be */
+(void)(buffer);  /* called when SUPPORT_UTF8 is not defined. */
+return 0;
+#endif
+}
+
+/* End of pcre_ord2utf8.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_study.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_study.c
new file mode 100644 (file)
index 0000000..bd00a53
--- /dev/null
@@ -0,0 +1,984 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2010 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains the external function pcre_study(), along with local
+supporting functions. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/* Returns from set_start_bits() */
+
+enum { SSB_FAIL, SSB_DONE, SSB_CONTINUE };
+
+
+
+/*************************************************
+*   Find the minimum subject length for a group  *
+*************************************************/
+
+/* Scan a parenthesized group and compute the minimum length of subject that
+is needed to match it. This is a lower bound; it does not mean there is a
+string of that length that matches. In UTF8 mode, the result is in characters
+rather than bytes.
+
+Arguments:
+  code       pointer to start of group (the bracket)
+  startcode  pointer to start of the whole pattern
+  options    the compiling options
+
+Returns:   the minimum length
+           -1 if \C was encountered
+           -2 internal error (missing capturing bracket)
+*/
+
+static int
+find_minlength(const uschar *code, const uschar *startcode, int options)
+{
+int length = -1;
+BOOL utf8 = (options & PCRE_UTF8) != 0;
+BOOL had_recurse = FALSE;
+register int branchlength = 0;
+register uschar *cc = (uschar *)code + 1 + LINK_SIZE;
+
+if (*code == OP_CBRA || *code == OP_SCBRA) cc += 2;
+
+/* Scan along the opcodes for this branch. If we get to the end of the
+branch, check the length against that of the other branches. */
+
+for (;;)
+  {
+  int d, min;
+  uschar *cs, *ce;
+  register int op = *cc;
+
+  switch (op)
+    {
+    case OP_COND:
+    case OP_SCOND:
+
+    /* If there is only one branch in a condition, the implied branch has zero
+    length, so we don't add anything. This covers the DEFINE "condition"
+    automatically. */
+
+    cs = cc + GET(cc, 1);
+    if (*cs != OP_ALT)
+      {
+      cc = cs + 1 + LINK_SIZE;
+      break;
+      }
+
+    /* Otherwise we can fall through and treat it the same as any other
+    subpattern. */
+
+    case OP_CBRA:
+    case OP_SCBRA:
+    case OP_BRA:
+    case OP_SBRA:
+    case OP_ONCE:
+    d = find_minlength(cc, startcode, options);
+    if (d < 0) return d;
+    branchlength += d;
+    do cc += GET(cc, 1); while (*cc == OP_ALT);
+    cc += 1 + LINK_SIZE;
+    break;
+
+    /* Reached end of a branch; if it's a ket it is the end of a nested
+    call. If it's ALT it is an alternation in a nested call. If it is
+    END it's the end of the outer call. All can be handled by the same code. */
+
+    case OP_ALT:
+    case OP_KET:
+    case OP_KETRMAX:
+    case OP_KETRMIN:
+    case OP_END:
+    if (length < 0 || (!had_recurse && branchlength < length))
+      length = branchlength;
+    if (*cc != OP_ALT) return length;
+    cc += 1 + LINK_SIZE;
+    branchlength = 0;
+    had_recurse = FALSE;
+    break;
+
+    /* Skip over assertive subpatterns */
+
+    case OP_ASSERT:
+    case OP_ASSERT_NOT:
+    case OP_ASSERTBACK:
+    case OP_ASSERTBACK_NOT:
+    do cc += GET(cc, 1); while (*cc == OP_ALT);
+    /* Fall through */
+
+    /* Skip over things that don't match chars */
+
+    case OP_REVERSE:
+    case OP_CREF:
+    case OP_NCREF:
+    case OP_RREF:
+    case OP_NRREF:
+    case OP_DEF:
+    case OP_OPT:
+    case OP_CALLOUT:
+    case OP_SOD:
+    case OP_SOM:
+    case OP_EOD:
+    case OP_EODN:
+    case OP_CIRC:
+    case OP_DOLL:
+    case OP_NOT_WORD_BOUNDARY:
+    case OP_WORD_BOUNDARY:
+    cc += _pcre_OP_lengths[*cc];
+    break;
+
+    /* Skip over a subpattern that has a {0} or {0,x} quantifier */
+
+    case OP_BRAZERO:
+    case OP_BRAMINZERO:
+    case OP_SKIPZERO:
+    cc += _pcre_OP_lengths[*cc];
+    do cc += GET(cc, 1); while (*cc == OP_ALT);
+    cc += 1 + LINK_SIZE;
+    break;
+
+    /* Handle literal characters and + repetitions */
+
+    case OP_CHAR:
+    case OP_CHARNC:
+    case OP_NOT:
+    case OP_PLUS:
+    case OP_MINPLUS:
+    case OP_POSPLUS:
+    case OP_NOTPLUS:
+    case OP_NOTMINPLUS:
+    case OP_NOTPOSPLUS:
+    branchlength++;
+    cc += 2;
+#ifdef SUPPORT_UTF8
+    if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];
+#endif
+    break;
+
+    case OP_TYPEPLUS:
+    case OP_TYPEMINPLUS:
+    case OP_TYPEPOSPLUS:
+    branchlength++;
+    cc += (cc[1] == OP_PROP || cc[1] == OP_NOTPROP)? 4 : 2;
+    break;
+
+    /* Handle exact repetitions. The count is already in characters, but we
+    need to skip over a multibyte character in UTF8 mode.  */
+
+    case OP_EXACT:
+    case OP_NOTEXACT:
+    branchlength += GET2(cc,1);
+    cc += 4;
+#ifdef SUPPORT_UTF8
+    if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];
+#endif
+    break;
+
+    case OP_TYPEEXACT:
+    branchlength += GET2(cc,1);
+    cc += (cc[3] == OP_PROP || cc[3] == OP_NOTPROP)? 6 : 4;
+    break;
+
+    /* Handle single-char non-literal matchers */
+
+    case OP_PROP:
+    case OP_NOTPROP:
+    cc += 2;
+    /* Fall through */
+
+    case OP_NOT_DIGIT:
+    case OP_DIGIT:
+    case OP_NOT_WHITESPACE:
+    case OP_WHITESPACE:
+    case OP_NOT_WORDCHAR:
+    case OP_WORDCHAR:
+    case OP_ANY:
+    case OP_ALLANY:
+    case OP_EXTUNI:
+    case OP_HSPACE:
+    case OP_NOT_HSPACE:
+    case OP_VSPACE:
+    case OP_NOT_VSPACE:
+    branchlength++;
+    cc++;
+    break;
+
+    /* "Any newline" might match two characters */
+
+    case OP_ANYNL:
+    branchlength += 2;
+    cc++;
+    break;
+
+    /* The single-byte matcher means we can't proceed in UTF-8 mode */
+
+    case OP_ANYBYTE:
+#ifdef SUPPORT_UTF8
+    if (utf8) return -1;
+#endif
+    branchlength++;
+    cc++;
+    break;
+
+    /* For repeated character types, we have to test for \p and \P, which have
+    an extra two bytes of parameters. */
+
+    case OP_TYPESTAR:
+    case OP_TYPEMINSTAR:
+    case OP_TYPEQUERY:
+    case OP_TYPEMINQUERY:
+    case OP_TYPEPOSSTAR:
+    case OP_TYPEPOSQUERY:
+    if (cc[1] == OP_PROP || cc[1] == OP_NOTPROP) cc += 2;
+    cc += _pcre_OP_lengths[op];
+    break;
+
+    case OP_TYPEUPTO:
+    case OP_TYPEMINUPTO:
+    case OP_TYPEPOSUPTO:
+    if (cc[3] == OP_PROP || cc[3] == OP_NOTPROP) cc += 2;
+    cc += _pcre_OP_lengths[op];
+    break;
+
+    /* Check a class for variable quantification */
+
+#ifdef SUPPORT_UTF8
+    case OP_XCLASS:
+    cc += GET(cc, 1) - 33;
+    /* Fall through */
+#endif
+
+    case OP_CLASS:
+    case OP_NCLASS:
+    cc += 33;
+
+    switch (*cc)
+      {
+      case OP_CRPLUS:
+      case OP_CRMINPLUS:
+      branchlength++;
+      /* Fall through */
+
+      case OP_CRSTAR:
+      case OP_CRMINSTAR:
+      case OP_CRQUERY:
+      case OP_CRMINQUERY:
+      cc++;
+      break;
+
+      case OP_CRRANGE:
+      case OP_CRMINRANGE:
+      branchlength += GET2(cc,1);
+      cc += 5;
+      break;
+
+      default:
+      branchlength++;
+      break;
+      }
+    break;
+
+    /* Backreferences and subroutine calls are treated in the same way: we find
+    the minimum length for the subpattern. A recursion, however, causes an
+    a flag to be set that causes the length of this branch to be ignored. The
+    logic is that a recursion can only make sense if there is another
+    alternation that stops the recursing. That will provide the minimum length
+    (when no recursion happens). A backreference within the group that it is
+    referencing behaves in the same way.
+
+    If PCRE_JAVASCRIPT_COMPAT is set, a backreference to an unset bracket
+    matches an empty string (by default it causes a matching failure), so in
+    that case we must set the minimum length to zero. */
+
+    case OP_REF:
+    if ((options & PCRE_JAVASCRIPT_COMPAT) == 0)
+      {
+      ce = cs = (uschar *)_pcre_find_bracket(startcode, utf8, GET2(cc, 1));
+      if (cs == NULL) return -2;
+      do ce += GET(ce, 1); while (*ce == OP_ALT);
+      if (cc > cs && cc < ce)
+        {
+        d = 0;
+        had_recurse = TRUE;
+        }
+      else d = find_minlength(cs, startcode, options);
+      }
+    else d = 0;
+    cc += 3;
+
+    /* Handle repeated back references */
+
+    switch (*cc)
+      {
+      case OP_CRSTAR:
+      case OP_CRMINSTAR:
+      case OP_CRQUERY:
+      case OP_CRMINQUERY:
+      min = 0;
+      cc++;
+      break;
+
+      case OP_CRRANGE:
+      case OP_CRMINRANGE:
+      min = GET2(cc, 1);
+      cc += 5;
+      break;
+
+      default:
+      min = 1;
+      break;
+      }
+
+    branchlength += min * d;
+    break;
+
+    case OP_RECURSE:
+    cs = ce = (uschar *)startcode + GET(cc, 1);
+    if (cs == NULL) return -2;
+    do ce += GET(ce, 1); while (*ce == OP_ALT);
+    if (cc > cs && cc < ce)
+      had_recurse = TRUE;
+    else
+      branchlength += find_minlength(cs, startcode, options);
+    cc += 1 + LINK_SIZE;
+    break;
+
+    /* Anything else does not or need not match a character. We can get the
+    item's length from the table, but for those that can match zero occurrences
+    of a character, we must take special action for UTF-8 characters. */
+
+    case OP_UPTO:
+    case OP_NOTUPTO:
+    case OP_MINUPTO:
+    case OP_NOTMINUPTO:
+    case OP_POSUPTO:
+    case OP_STAR:
+    case OP_MINSTAR:
+    case OP_NOTMINSTAR:
+    case OP_POSSTAR:
+    case OP_NOTPOSSTAR:
+    case OP_QUERY:
+    case OP_MINQUERY:
+    case OP_NOTMINQUERY:
+    case OP_POSQUERY:
+    case OP_NOTPOSQUERY:
+    cc += _pcre_OP_lengths[op];
+#ifdef SUPPORT_UTF8
+    if (utf8 && cc[-1] >= 0xc0) cc += _pcre_utf8_table4[cc[-1] & 0x3f];
+#endif
+    break;
+
+    /* For the record, these are the opcodes that are matched by "default":
+    OP_ACCEPT, OP_CLOSE, OP_COMMIT, OP_FAIL, OP_PRUNE, OP_SET_SOM, OP_SKIP,
+    OP_THEN. */
+
+    default:
+    cc += _pcre_OP_lengths[op];
+    break;
+    }
+  }
+/* Control never gets here */
+}
+
+
+
+/*************************************************
+*      Set a bit and maybe its alternate case    *
+*************************************************/
+
+/* Given a character, set its bit in the table, and also the bit for the other
+version of a letter if we are caseless.
+
+Arguments:
+  start_bits    points to the bit map
+  c             is the character
+  caseless      the caseless flag
+  cd            the block with char table pointers
+
+Returns:        nothing
+*/
+
+static void
+set_table_bit(uschar *start_bits, unsigned int c, BOOL caseless,
+  compile_data *cd)
+{
+start_bits[c/8] |= (1 << (c&7));
+if (caseless && (cd->ctypes[c] & ctype_letter) != 0)
+  start_bits[cd->fcc[c]/8] |= (1 << (cd->fcc[c]&7));
+}
+
+
+
+/*************************************************
+*          Create bitmap of starting bytes       *
+*************************************************/
+
+/* This function scans a compiled unanchored expression recursively and
+attempts to build a bitmap of the set of possible starting bytes. As time goes
+by, we may be able to get more clever at doing this. The SSB_CONTINUE return is
+useful for parenthesized groups in patterns such as (a*)b where the group
+provides some optional starting bytes but scanning must continue at the outer
+level to find at least one mandatory byte. At the outermost level, this
+function fails unless the result is SSB_DONE.
+
+Arguments:
+  code         points to an expression
+  start_bits   points to a 32-byte table, initialized to 0
+  caseless     the current state of the caseless flag
+  utf8         TRUE if in UTF-8 mode
+  cd           the block with char table pointers
+
+Returns:       SSB_FAIL     => Failed to find any starting bytes
+               SSB_DONE     => Found mandatory starting bytes
+               SSB_CONTINUE => Found optional starting bytes
+*/
+
+static int
+set_start_bits(const uschar *code, uschar *start_bits, BOOL caseless,
+  BOOL utf8, compile_data *cd)
+{
+register int c;
+int yield = SSB_DONE;
+
+#if 0
+/* ========================================================================= */
+/* The following comment and code was inserted in January 1999. In May 2006,
+when it was observed to cause compiler warnings about unused values, I took it
+out again. If anybody is still using OS/2, they will have to put it back
+manually. */
+
+/* This next statement and the later reference to dummy are here in order to
+trick the optimizer of the IBM C compiler for OS/2 into generating correct
+code. Apparently IBM isn't going to fix the problem, and we would rather not
+disable optimization (in this module it actually makes a big difference, and
+the pcre module can use all the optimization it can get). */
+
+volatile int dummy;
+/* ========================================================================= */
+#endif
+
+do
+  {
+  const uschar *tcode = code + (((int)*code == OP_CBRA)? 3:1) + LINK_SIZE;
+  BOOL try_next = TRUE;
+
+  while (try_next)    /* Loop for items in this branch */
+    {
+    int rc;
+    switch(*tcode)
+      {
+      /* Fail if we reach something we don't understand */
+
+      default:
+      return SSB_FAIL;
+
+      /* If we hit a bracket or a positive lookahead assertion, recurse to set
+      bits from within the subpattern. If it can't find anything, we have to
+      give up. If it finds some mandatory character(s), we are done for this
+      branch. Otherwise, carry on scanning after the subpattern. */
+
+      case OP_BRA:
+      case OP_SBRA:
+      case OP_CBRA:
+      case OP_SCBRA:
+      case OP_ONCE:
+      case OP_ASSERT:
+      rc = set_start_bits(tcode, start_bits, caseless, utf8, cd);
+      if (rc == SSB_FAIL) return SSB_FAIL;
+      if (rc == SSB_DONE) try_next = FALSE; else
+        {
+        do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
+        tcode += 1 + LINK_SIZE;
+        }
+      break;
+
+      /* If we hit ALT or KET, it means we haven't found anything mandatory in
+      this branch, though we might have found something optional. For ALT, we
+      continue with the next alternative, but we have to arrange that the final
+      result from subpattern is SSB_CONTINUE rather than SSB_DONE. For KET,
+      return SSB_CONTINUE: if this is the top level, that indicates failure,
+      but after a nested subpattern, it causes scanning to continue. */
+
+      case OP_ALT:
+      yield = SSB_CONTINUE;
+      try_next = FALSE;
+      break;
+
+      case OP_KET:
+      case OP_KETRMAX:
+      case OP_KETRMIN:
+      return SSB_CONTINUE;
+
+      /* Skip over callout */
+
+      case OP_CALLOUT:
+      tcode += 2 + 2*LINK_SIZE;
+      break;
+
+      /* Skip over lookbehind and negative lookahead assertions */
+
+      case OP_ASSERT_NOT:
+      case OP_ASSERTBACK:
+      case OP_ASSERTBACK_NOT:
+      do tcode += GET(tcode, 1); while (*tcode == OP_ALT);
+      tcode += 1 + LINK_SIZE;
+      break;
+
+      /* Skip over an option setting, changing the caseless flag */
+
+      case OP_OPT:
+      caseless = (tcode[1] & PCRE_CASELESS) != 0;
+      tcode += 2;
+      break;
+
+      /* BRAZERO does the bracket, but carries on. */
+
+      case OP_BRAZERO:
+      case OP_BRAMINZERO:
+      if (set_start_bits(++tcode, start_bits, caseless, utf8, cd) == SSB_FAIL)
+        return SSB_FAIL;
+/* =========================================================================
+      See the comment at the head of this function concerning the next line,
+      which was an old fudge for the benefit of OS/2.
+      dummy = 1;
+  ========================================================================= */
+      do tcode += GET(tcode,1); while (*tcode == OP_ALT);
+      tcode += 1 + LINK_SIZE;
+      break;
+
+      /* SKIPZERO skips the bracket. */
+
+      case OP_SKIPZERO:
+      tcode++;
+      do tcode += GET(tcode,1); while (*tcode == OP_ALT);
+      tcode += 1 + LINK_SIZE;
+      break;
+
+      /* Single-char * or ? sets the bit and tries the next item */
+
+      case OP_STAR:
+      case OP_MINSTAR:
+      case OP_POSSTAR:
+      case OP_QUERY:
+      case OP_MINQUERY:
+      case OP_POSQUERY:
+      set_table_bit(start_bits, tcode[1], caseless, cd);
+      tcode += 2;
+#ifdef SUPPORT_UTF8
+      if (utf8 && tcode[-1] >= 0xc0)
+        tcode += _pcre_utf8_table4[tcode[-1] & 0x3f];
+#endif
+      break;
+
+      /* Single-char upto sets the bit and tries the next */
+
+      case OP_UPTO:
+      case OP_MINUPTO:
+      case OP_POSUPTO:
+      set_table_bit(start_bits, tcode[3], caseless, cd);
+      tcode += 4;
+#ifdef SUPPORT_UTF8
+      if (utf8 && tcode[-1] >= 0xc0)
+        tcode += _pcre_utf8_table4[tcode[-1] & 0x3f];
+#endif
+      break;
+
+      /* At least one single char sets the bit and stops */
+
+      case OP_EXACT:       /* Fall through */
+      tcode += 2;
+
+      case OP_CHAR:
+      case OP_CHARNC:
+      case OP_PLUS:
+      case OP_MINPLUS:
+      case OP_POSPLUS:
+      set_table_bit(start_bits, tcode[1], caseless, cd);
+      try_next = FALSE;
+      break;
+
+      /* Single character type sets the bits and stops */
+
+      case OP_NOT_DIGIT:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= ~cd->cbits[c+cbit_digit];
+      try_next = FALSE;
+      break;
+
+      case OP_DIGIT:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= cd->cbits[c+cbit_digit];
+      try_next = FALSE;
+      break;
+
+      /* The cbit_space table has vertical tab as whitespace; we have to
+      discard it. */
+
+      case OP_NOT_WHITESPACE:
+      for (c = 0; c < 32; c++)
+        {
+        int d = cd->cbits[c+cbit_space];
+        if (c == 1) d &= ~0x08;
+        start_bits[c] |= ~d;
+        }
+      try_next = FALSE;
+      break;
+
+      /* The cbit_space table has vertical tab as whitespace; we have to
+      discard it. */
+
+      case OP_WHITESPACE:
+      for (c = 0; c < 32; c++)
+        {
+        int d = cd->cbits[c+cbit_space];
+        if (c == 1) d &= ~0x08;
+        start_bits[c] |= d;
+        }
+      try_next = FALSE;
+      break;
+
+      case OP_NOT_WORDCHAR:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= ~cd->cbits[c+cbit_word];
+      try_next = FALSE;
+      break;
+
+      case OP_WORDCHAR:
+      for (c = 0; c < 32; c++)
+        start_bits[c] |= cd->cbits[c+cbit_word];
+      try_next = FALSE;
+      break;
+
+      /* One or more character type fudges the pointer and restarts, knowing
+      it will hit a single character type and stop there. */
+
+      case OP_TYPEPLUS:
+      case OP_TYPEMINPLUS:
+      tcode++;
+      break;
+
+      case OP_TYPEEXACT:
+      tcode += 3;
+      break;
+
+      /* Zero or more repeats of character types set the bits and then
+      try again. */
+
+      case OP_TYPEUPTO:
+      case OP_TYPEMINUPTO:
+      case OP_TYPEPOSUPTO:
+      tcode += 2;               /* Fall through */
+
+      case OP_TYPESTAR:
+      case OP_TYPEMINSTAR:
+      case OP_TYPEPOSSTAR:
+      case OP_TYPEQUERY:
+      case OP_TYPEMINQUERY:
+      case OP_TYPEPOSQUERY:
+      switch(tcode[1])
+        {
+        case OP_ANY:
+        case OP_ALLANY:
+        return SSB_FAIL;
+
+        case OP_NOT_DIGIT:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= ~cd->cbits[c+cbit_digit];
+        break;
+
+        case OP_DIGIT:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= cd->cbits[c+cbit_digit];
+        break;
+
+        /* The cbit_space table has vertical tab as whitespace; we have to
+        discard it. */
+
+        case OP_NOT_WHITESPACE:
+        for (c = 0; c < 32; c++)
+          {
+          int d = cd->cbits[c+cbit_space];
+          if (c == 1) d &= ~0x08;
+          start_bits[c] |= ~d;
+          }
+        break;
+
+        /* The cbit_space table has vertical tab as whitespace; we have to
+        discard it. */
+
+        case OP_WHITESPACE:
+        for (c = 0; c < 32; c++)
+          {
+          int d = cd->cbits[c+cbit_space];
+          if (c == 1) d &= ~0x08;
+          start_bits[c] |= d;
+          }
+        break;
+
+        case OP_NOT_WORDCHAR:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= ~cd->cbits[c+cbit_word];
+        break;
+
+        case OP_WORDCHAR:
+        for (c = 0; c < 32; c++)
+          start_bits[c] |= cd->cbits[c+cbit_word];
+        break;
+        }
+
+      tcode += 2;
+      break;
+
+      /* Character class where all the information is in a bit map: set the
+      bits and either carry on or not, according to the repeat count. If it was
+      a negative class, and we are operating with UTF-8 characters, any byte
+      with a value >= 0xc4 is a potentially valid starter because it starts a
+      character with a value > 255. */
+
+      case OP_NCLASS:
+#ifdef SUPPORT_UTF8
+      if (utf8)
+        {
+        start_bits[24] |= 0xf0;              /* Bits for 0xc4 - 0xc8 */
+        memset(start_bits+25, 0xff, 7);      /* Bits for 0xc9 - 0xff */
+        }
+#endif
+      /* Fall through */
+
+      case OP_CLASS:
+        {
+        tcode++;
+
+        /* In UTF-8 mode, the bits in a bit map correspond to character
+        values, not to byte values. However, the bit map we are constructing is
+        for byte values. So we have to do a conversion for characters whose
+        value is > 127. In fact, there are only two possible starting bytes for
+        characters in the range 128 - 255. */
+
+#ifdef SUPPORT_UTF8
+        if (utf8)
+          {
+          for (c = 0; c < 16; c++) start_bits[c] |= tcode[c];
+          for (c = 128; c < 256; c++)
+            {
+            if ((tcode[c/8] && (1 << (c&7))) != 0)
+              {
+              int d = (c >> 6) | 0xc0;            /* Set bit for this starter */
+              start_bits[d/8] |= (1 << (d&7));    /* and then skip on to the */
+              c = (c & 0xc0) + 0x40 - 1;          /* next relevant character. */
+              }
+            }
+          }
+
+        /* In non-UTF-8 mode, the two bit maps are completely compatible. */
+
+        else
+#endif
+          {
+          for (c = 0; c < 32; c++) start_bits[c] |= tcode[c];
+          }
+
+        /* Advance past the bit map, and act on what follows */
+
+        tcode += 32;
+        switch (*tcode)
+          {
+          case OP_CRSTAR:
+          case OP_CRMINSTAR:
+          case OP_CRQUERY:
+          case OP_CRMINQUERY:
+          tcode++;
+          break;
+
+          case OP_CRRANGE:
+          case OP_CRMINRANGE:
+          if (((tcode[1] << 8) + tcode[2]) == 0) tcode += 5;
+            else try_next = FALSE;
+          break;
+
+          default:
+          try_next = FALSE;
+          break;
+          }
+        }
+      break; /* End of bitmap class handling */
+
+      }      /* End of switch */
+    }        /* End of try_next loop */
+
+  code += GET(code, 1);   /* Advance to next branch */
+  }
+while (*code == OP_ALT);
+return yield;
+}
+
+
+
+/*************************************************
+*          Study a compiled expression           *
+*************************************************/
+
+/* This function is handed a compiled expression that it must study to produce
+information that will speed up the matching. It returns a pcre_extra block
+which then gets handed back to pcre_exec().
+
+Arguments:
+  re        points to the compiled expression
+  options   contains option bits
+  errorptr  points to where to place error messages;
+            set NULL unless error
+
+Returns:    pointer to a pcre_extra block, with study_data filled in and the
+              appropriate flags set;
+            NULL on error or if no optimization possible
+*/
+
+PCRE_EXP_DEFN pcre_extra * PCRE_CALL_CONVENTION
+pcre_study(const pcre *external_re, int options, const char **errorptr)
+{
+int min;
+BOOL bits_set = FALSE;
+uschar start_bits[32];
+pcre_extra *extra;
+pcre_study_data *study;
+const uschar *tables;
+uschar *code;
+compile_data compile_block;
+const real_pcre *re = (const real_pcre *)external_re;
+
+*errorptr = NULL;
+
+if (re == NULL || re->magic_number != MAGIC_NUMBER)
+  {
+  *errorptr = "argument is not a compiled regular expression";
+  return NULL;
+  }
+
+if ((options & ~PUBLIC_STUDY_OPTIONS) != 0)
+  {
+  *errorptr = "unknown or incorrect option bit(s) set";
+  return NULL;
+  }
+
+code = (uschar *)re + re->name_table_offset +
+  (re->name_count * re->name_entry_size);
+
+/* For an anchored pattern, or an unanchored pattern that has a first char, or
+a multiline pattern that matches only at "line starts", there is no point in
+seeking a list of starting bytes. */
+
+if ((re->options & PCRE_ANCHORED) == 0 &&
+    (re->flags & (PCRE_FIRSTSET|PCRE_STARTLINE)) == 0)
+  {
+  /* Set the character tables in the block that is passed around */
+
+  tables = re->tables;
+  if (tables == NULL)
+    (void)pcre_fullinfo(external_re, NULL, PCRE_INFO_DEFAULT_TABLES,
+    (void *)(&tables));
+
+  compile_block.lcc = tables + lcc_offset;
+  compile_block.fcc = tables + fcc_offset;
+  compile_block.cbits = tables + cbits_offset;
+  compile_block.ctypes = tables + ctypes_offset;
+
+  /* See if we can find a fixed set of initial characters for the pattern. */
+
+  memset(start_bits, 0, 32 * sizeof(uschar));
+  bits_set = set_start_bits(code, start_bits,
+    (re->options & PCRE_CASELESS) != 0, (re->options & PCRE_UTF8) != 0,
+    &compile_block) == SSB_DONE;
+  }
+
+/* Find the minimum length of subject string. */
+
+min = find_minlength(code, code, re->options);
+
+/* Return NULL if no optimization is possible. */
+
+if (!bits_set && min < 0) return NULL;
+
+/* Get a pcre_extra block and a pcre_study_data block. The study data is put in
+the latter, which is pointed to by the former, which may also get additional
+data set later by the calling program. At the moment, the size of
+pcre_study_data is fixed. We nevertheless save it in a field for returning via
+the pcre_fullinfo() function so that if it becomes variable in the future, we
+don't have to change that code. */
+
+extra = (pcre_extra *)(pcre_malloc)
+  (sizeof(pcre_extra) + sizeof(pcre_study_data));
+
+if (extra == NULL)
+  {
+  *errorptr = "failed to get memory";
+  return NULL;
+  }
+
+study = (pcre_study_data *)((char *)extra + sizeof(pcre_extra));
+extra->flags = PCRE_EXTRA_STUDY_DATA;
+extra->study_data = study;
+
+study->size = sizeof(pcre_study_data);
+study->flags = 0;
+
+if (bits_set)
+  {
+  study->flags |= PCRE_STUDY_MAPPED;
+  memcpy(study->start_bits, start_bits, sizeof(start_bits));
+  }
+
+if (min >= 0)
+  {
+  study->flags |= PCRE_STUDY_MINLEN;
+  study->minlength = min;
+  }
+
+return extra;
+}
+
+/* End of pcre_study.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_tables.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_tables.c
new file mode 100644 (file)
index 0000000..b7f7ba5
--- /dev/null
@@ -0,0 +1,523 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2009 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains some fixed tables that are used by more than one of the
+PCRE code modules. The tables are also #included by the pcretest program, which
+uses macros to change their names from _pcre_xxx to xxxx, thereby avoiding name
+clashes with the library. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/* Table of sizes for the fixed-length opcodes. It's defined in a macro so that
+the definition is next to the definition of the opcodes in pcre_internal.h. */
+
+const uschar _pcre_OP_lengths[] = { OP_LENGTHS };
+
+
+
+/*************************************************
+*           Tables for UTF-8 support             *
+*************************************************/
+
+/* These are the breakpoints for different numbers of bytes in a UTF-8
+character. */
+
+#ifdef SUPPORT_UTF8
+
+const int _pcre_utf8_table1[] =
+  { 0x7f, 0x7ff, 0xffff, 0x1fffff, 0x3ffffff, 0x7fffffff};
+
+const int _pcre_utf8_table1_size = sizeof(_pcre_utf8_table1)/sizeof(int);
+
+/* These are the indicator bits and the mask for the data bits to set in the
+first byte of a character, indexed by the number of additional bytes. */
+
+const int _pcre_utf8_table2[] = { 0,    0xc0, 0xe0, 0xf0, 0xf8, 0xfc};
+const int _pcre_utf8_table3[] = { 0xff, 0x1f, 0x0f, 0x07, 0x03, 0x01};
+
+/* Table of the number of extra bytes, indexed by the first byte masked with
+0x3f. The highest number for a valid UTF-8 first byte is in fact 0x3d. */
+
+const uschar _pcre_utf8_table4[] = {
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,
+  2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,2,
+  3,3,3,3,3,3,3,3,4,4,4,4,5,5,5,5 };
+
+/* Table to translate from particular type value to the general value. */
+
+const int _pcre_ucp_gentype[] = {
+  ucp_C, ucp_C, ucp_C, ucp_C, ucp_C,  /* Cc, Cf, Cn, Co, Cs */
+  ucp_L, ucp_L, ucp_L, ucp_L, ucp_L,  /* Ll, Lu, Lm, Lo, Lt */
+  ucp_M, ucp_M, ucp_M,                /* Mc, Me, Mn */
+  ucp_N, ucp_N, ucp_N,                /* Nd, Nl, No */
+  ucp_P, ucp_P, ucp_P, ucp_P, ucp_P,  /* Pc, Pd, Pe, Pf, Pi */
+  ucp_P, ucp_P,                       /* Ps, Po */
+  ucp_S, ucp_S, ucp_S, ucp_S,         /* Sc, Sk, Sm, So */
+  ucp_Z, ucp_Z, ucp_Z                 /* Zl, Zp, Zs */
+};
+
+/* The pcre_utt[] table below translates Unicode property names into type and
+code values. It is searched by binary chop, so must be in collating sequence of
+name. Originally, the table contained pointers to the name strings in the first
+field of each entry. However, that leads to a large number of relocations when
+a shared library is dynamically loaded. A significant reduction is made by
+putting all the names into a single, large string and then using offsets in the
+table itself. Maintenance is more error-prone, but frequent changes to this
+data are unlikely.
+
+July 2008: There is now a script called maint/GenerateUtt.py that can be used
+to generate this data instead of maintaining it entirely by hand.
+
+The script was updated in March 2009 to generate a new EBCDIC-compliant
+version. Like all other character and string literals that are compared against
+the regular expression pattern, we must use STR_ macros instead of literal
+strings to make sure that UTF-8 support works on EBCDIC platforms. */
+
+#define STRING_Any0 STR_A STR_n STR_y "\0"
+#define STRING_Arabic0 STR_A STR_r STR_a STR_b STR_i STR_c "\0"
+#define STRING_Armenian0 STR_A STR_r STR_m STR_e STR_n STR_i STR_a STR_n "\0"
+#define STRING_Avestan0 STR_A STR_v STR_e STR_s STR_t STR_a STR_n "\0"
+#define STRING_Balinese0 STR_B STR_a STR_l STR_i STR_n STR_e STR_s STR_e "\0"
+#define STRING_Bamum0 STR_B STR_a STR_m STR_u STR_m "\0"
+#define STRING_Bengali0 STR_B STR_e STR_n STR_g STR_a STR_l STR_i "\0"
+#define STRING_Bopomofo0 STR_B STR_o STR_p STR_o STR_m STR_o STR_f STR_o "\0"
+#define STRING_Braille0 STR_B STR_r STR_a STR_i STR_l STR_l STR_e "\0"
+#define STRING_Buginese0 STR_B STR_u STR_g STR_i STR_n STR_e STR_s STR_e "\0"
+#define STRING_Buhid0 STR_B STR_u STR_h STR_i STR_d "\0"
+#define STRING_C0 STR_C "\0"
+#define STRING_Canadian_Aboriginal0 STR_C STR_a STR_n STR_a STR_d STR_i STR_a STR_n STR_UNDERSCORE STR_A STR_b STR_o STR_r STR_i STR_g STR_i STR_n STR_a STR_l "\0"
+#define STRING_Carian0 STR_C STR_a STR_r STR_i STR_a STR_n "\0"
+#define STRING_Cc0 STR_C STR_c "\0"
+#define STRING_Cf0 STR_C STR_f "\0"
+#define STRING_Cham0 STR_C STR_h STR_a STR_m "\0"
+#define STRING_Cherokee0 STR_C STR_h STR_e STR_r STR_o STR_k STR_e STR_e "\0"
+#define STRING_Cn0 STR_C STR_n "\0"
+#define STRING_Co0 STR_C STR_o "\0"
+#define STRING_Common0 STR_C STR_o STR_m STR_m STR_o STR_n "\0"
+#define STRING_Coptic0 STR_C STR_o STR_p STR_t STR_i STR_c "\0"
+#define STRING_Cs0 STR_C STR_s "\0"
+#define STRING_Cuneiform0 STR_C STR_u STR_n STR_e STR_i STR_f STR_o STR_r STR_m "\0"
+#define STRING_Cypriot0 STR_C STR_y STR_p STR_r STR_i STR_o STR_t "\0"
+#define STRING_Cyrillic0 STR_C STR_y STR_r STR_i STR_l STR_l STR_i STR_c "\0"
+#define STRING_Deseret0 STR_D STR_e STR_s STR_e STR_r STR_e STR_t "\0"
+#define STRING_Devanagari0 STR_D STR_e STR_v STR_a STR_n STR_a STR_g STR_a STR_r STR_i "\0"
+#define STRING_Egyptian_Hieroglyphs0 STR_E STR_g STR_y STR_p STR_t STR_i STR_a STR_n STR_UNDERSCORE STR_H STR_i STR_e STR_r STR_o STR_g STR_l STR_y STR_p STR_h STR_s "\0"
+#define STRING_Ethiopic0 STR_E STR_t STR_h STR_i STR_o STR_p STR_i STR_c "\0"
+#define STRING_Georgian0 STR_G STR_e STR_o STR_r STR_g STR_i STR_a STR_n "\0"
+#define STRING_Glagolitic0 STR_G STR_l STR_a STR_g STR_o STR_l STR_i STR_t STR_i STR_c "\0"
+#define STRING_Gothic0 STR_G STR_o STR_t STR_h STR_i STR_c "\0"
+#define STRING_Greek0 STR_G STR_r STR_e STR_e STR_k "\0"
+#define STRING_Gujarati0 STR_G STR_u STR_j STR_a STR_r STR_a STR_t STR_i "\0"
+#define STRING_Gurmukhi0 STR_G STR_u STR_r STR_m STR_u STR_k STR_h STR_i "\0"
+#define STRING_Han0 STR_H STR_a STR_n "\0"
+#define STRING_Hangul0 STR_H STR_a STR_n STR_g STR_u STR_l "\0"
+#define STRING_Hanunoo0 STR_H STR_a STR_n STR_u STR_n STR_o STR_o "\0"
+#define STRING_Hebrew0 STR_H STR_e STR_b STR_r STR_e STR_w "\0"
+#define STRING_Hiragana0 STR_H STR_i STR_r STR_a STR_g STR_a STR_n STR_a "\0"
+#define STRING_Imperial_Aramaic0 STR_I STR_m STR_p STR_e STR_r STR_i STR_a STR_l STR_UNDERSCORE STR_A STR_r STR_a STR_m STR_a STR_i STR_c "\0"
+#define STRING_Inherited0 STR_I STR_n STR_h STR_e STR_r STR_i STR_t STR_e STR_d "\0"
+#define STRING_Inscriptional_Pahlavi0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_h STR_l STR_a STR_v STR_i "\0"
+#define STRING_Inscriptional_Parthian0 STR_I STR_n STR_s STR_c STR_r STR_i STR_p STR_t STR_i STR_o STR_n STR_a STR_l STR_UNDERSCORE STR_P STR_a STR_r STR_t STR_h STR_i STR_a STR_n "\0"
+#define STRING_Javanese0 STR_J STR_a STR_v STR_a STR_n STR_e STR_s STR_e "\0"
+#define STRING_Kaithi0 STR_K STR_a STR_i STR_t STR_h STR_i "\0"
+#define STRING_Kannada0 STR_K STR_a STR_n STR_n STR_a STR_d STR_a "\0"
+#define STRING_Katakana0 STR_K STR_a STR_t STR_a STR_k STR_a STR_n STR_a "\0"
+#define STRING_Kayah_Li0 STR_K STR_a STR_y STR_a STR_h STR_UNDERSCORE STR_L STR_i "\0"
+#define STRING_Kharoshthi0 STR_K STR_h STR_a STR_r STR_o STR_s STR_h STR_t STR_h STR_i "\0"
+#define STRING_Khmer0 STR_K STR_h STR_m STR_e STR_r "\0"
+#define STRING_L0 STR_L "\0"
+#define STRING_L_AMPERSAND0 STR_L STR_AMPERSAND "\0"
+#define STRING_Lao0 STR_L STR_a STR_o "\0"
+#define STRING_Latin0 STR_L STR_a STR_t STR_i STR_n "\0"
+#define STRING_Lepcha0 STR_L STR_e STR_p STR_c STR_h STR_a "\0"
+#define STRING_Limbu0 STR_L STR_i STR_m STR_b STR_u "\0"
+#define STRING_Linear_B0 STR_L STR_i STR_n STR_e STR_a STR_r STR_UNDERSCORE STR_B "\0"
+#define STRING_Lisu0 STR_L STR_i STR_s STR_u "\0"
+#define STRING_Ll0 STR_L STR_l "\0"
+#define STRING_Lm0 STR_L STR_m "\0"
+#define STRING_Lo0 STR_L STR_o "\0"
+#define STRING_Lt0 STR_L STR_t "\0"
+#define STRING_Lu0 STR_L STR_u "\0"
+#define STRING_Lycian0 STR_L STR_y STR_c STR_i STR_a STR_n "\0"
+#define STRING_Lydian0 STR_L STR_y STR_d STR_i STR_a STR_n "\0"
+#define STRING_M0 STR_M "\0"
+#define STRING_Malayalam0 STR_M STR_a STR_l STR_a STR_y STR_a STR_l STR_a STR_m "\0"
+#define STRING_Mc0 STR_M STR_c "\0"
+#define STRING_Me0 STR_M STR_e "\0"
+#define STRING_Meetei_Mayek0 STR_M STR_e STR_e STR_t STR_e STR_i STR_UNDERSCORE STR_M STR_a STR_y STR_e STR_k "\0"
+#define STRING_Mn0 STR_M STR_n "\0"
+#define STRING_Mongolian0 STR_M STR_o STR_n STR_g STR_o STR_l STR_i STR_a STR_n "\0"
+#define STRING_Myanmar0 STR_M STR_y STR_a STR_n STR_m STR_a STR_r "\0"
+#define STRING_N0 STR_N "\0"
+#define STRING_Nd0 STR_N STR_d "\0"
+#define STRING_New_Tai_Lue0 STR_N STR_e STR_w STR_UNDERSCORE STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_u STR_e "\0"
+#define STRING_Nko0 STR_N STR_k STR_o "\0"
+#define STRING_Nl0 STR_N STR_l "\0"
+#define STRING_No0 STR_N STR_o "\0"
+#define STRING_Ogham0 STR_O STR_g STR_h STR_a STR_m "\0"
+#define STRING_Ol_Chiki0 STR_O STR_l STR_UNDERSCORE STR_C STR_h STR_i STR_k STR_i "\0"
+#define STRING_Old_Italic0 STR_O STR_l STR_d STR_UNDERSCORE STR_I STR_t STR_a STR_l STR_i STR_c "\0"
+#define STRING_Old_Persian0 STR_O STR_l STR_d STR_UNDERSCORE STR_P STR_e STR_r STR_s STR_i STR_a STR_n "\0"
+#define STRING_Old_South_Arabian0 STR_O STR_l STR_d STR_UNDERSCORE STR_S STR_o STR_u STR_t STR_h STR_UNDERSCORE STR_A STR_r STR_a STR_b STR_i STR_a STR_n "\0"
+#define STRING_Old_Turkic0 STR_O STR_l STR_d STR_UNDERSCORE STR_T STR_u STR_r STR_k STR_i STR_c "\0"
+#define STRING_Oriya0 STR_O STR_r STR_i STR_y STR_a "\0"
+#define STRING_Osmanya0 STR_O STR_s STR_m STR_a STR_n STR_y STR_a "\0"
+#define STRING_P0 STR_P "\0"
+#define STRING_Pc0 STR_P STR_c "\0"
+#define STRING_Pd0 STR_P STR_d "\0"
+#define STRING_Pe0 STR_P STR_e "\0"
+#define STRING_Pf0 STR_P STR_f "\0"
+#define STRING_Phags_Pa0 STR_P STR_h STR_a STR_g STR_s STR_UNDERSCORE STR_P STR_a "\0"
+#define STRING_Phoenician0 STR_P STR_h STR_o STR_e STR_n STR_i STR_c STR_i STR_a STR_n "\0"
+#define STRING_Pi0 STR_P STR_i "\0"
+#define STRING_Po0 STR_P STR_o "\0"
+#define STRING_Ps0 STR_P STR_s "\0"
+#define STRING_Rejang0 STR_R STR_e STR_j STR_a STR_n STR_g "\0"
+#define STRING_Runic0 STR_R STR_u STR_n STR_i STR_c "\0"
+#define STRING_S0 STR_S "\0"
+#define STRING_Samaritan0 STR_S STR_a STR_m STR_a STR_r STR_i STR_t STR_a STR_n "\0"
+#define STRING_Saurashtra0 STR_S STR_a STR_u STR_r STR_a STR_s STR_h STR_t STR_r STR_a "\0"
+#define STRING_Sc0 STR_S STR_c "\0"
+#define STRING_Shavian0 STR_S STR_h STR_a STR_v STR_i STR_a STR_n "\0"
+#define STRING_Sinhala0 STR_S STR_i STR_n STR_h STR_a STR_l STR_a "\0"
+#define STRING_Sk0 STR_S STR_k "\0"
+#define STRING_Sm0 STR_S STR_m "\0"
+#define STRING_So0 STR_S STR_o "\0"
+#define STRING_Sundanese0 STR_S STR_u STR_n STR_d STR_a STR_n STR_e STR_s STR_e "\0"
+#define STRING_Syloti_Nagri0 STR_S STR_y STR_l STR_o STR_t STR_i STR_UNDERSCORE STR_N STR_a STR_g STR_r STR_i "\0"
+#define STRING_Syriac0 STR_S STR_y STR_r STR_i STR_a STR_c "\0"
+#define STRING_Tagalog0 STR_T STR_a STR_g STR_a STR_l STR_o STR_g "\0"
+#define STRING_Tagbanwa0 STR_T STR_a STR_g STR_b STR_a STR_n STR_w STR_a "\0"
+#define STRING_Tai_Le0 STR_T STR_a STR_i STR_UNDERSCORE STR_L STR_e "\0"
+#define STRING_Tai_Tham0 STR_T STR_a STR_i STR_UNDERSCORE STR_T STR_h STR_a STR_m "\0"
+#define STRING_Tai_Viet0 STR_T STR_a STR_i STR_UNDERSCORE STR_V STR_i STR_e STR_t "\0"
+#define STRING_Tamil0 STR_T STR_a STR_m STR_i STR_l "\0"
+#define STRING_Telugu0 STR_T STR_e STR_l STR_u STR_g STR_u "\0"
+#define STRING_Thaana0 STR_T STR_h STR_a STR_a STR_n STR_a "\0"
+#define STRING_Thai0 STR_T STR_h STR_a STR_i "\0"
+#define STRING_Tibetan0 STR_T STR_i STR_b STR_e STR_t STR_a STR_n "\0"
+#define STRING_Tifinagh0 STR_T STR_i STR_f STR_i STR_n STR_a STR_g STR_h "\0"
+#define STRING_Ugaritic0 STR_U STR_g STR_a STR_r STR_i STR_t STR_i STR_c "\0"
+#define STRING_Vai0 STR_V STR_a STR_i "\0"
+#define STRING_Yi0 STR_Y STR_i "\0"
+#define STRING_Z0 STR_Z "\0"
+#define STRING_Zl0 STR_Z STR_l "\0"
+#define STRING_Zp0 STR_Z STR_p "\0"
+#define STRING_Zs0 STR_Z STR_s "\0"
+
+const char _pcre_utt_names[] =
+  STRING_Any0
+  STRING_Arabic0
+  STRING_Armenian0
+  STRING_Avestan0
+  STRING_Balinese0
+  STRING_Bamum0
+  STRING_Bengali0
+  STRING_Bopomofo0
+  STRING_Braille0
+  STRING_Buginese0
+  STRING_Buhid0
+  STRING_C0
+  STRING_Canadian_Aboriginal0
+  STRING_Carian0
+  STRING_Cc0
+  STRING_Cf0
+  STRING_Cham0
+  STRING_Cherokee0
+  STRING_Cn0
+  STRING_Co0
+  STRING_Common0
+  STRING_Coptic0
+  STRING_Cs0
+  STRING_Cuneiform0
+  STRING_Cypriot0
+  STRING_Cyrillic0
+  STRING_Deseret0
+  STRING_Devanagari0
+  STRING_Egyptian_Hieroglyphs0
+  STRING_Ethiopic0
+  STRING_Georgian0
+  STRING_Glagolitic0
+  STRING_Gothic0
+  STRING_Greek0
+  STRING_Gujarati0
+  STRING_Gurmukhi0
+  STRING_Han0
+  STRING_Hangul0
+  STRING_Hanunoo0
+  STRING_Hebrew0
+  STRING_Hiragana0
+  STRING_Imperial_Aramaic0
+  STRING_Inherited0
+  STRING_Inscriptional_Pahlavi0
+  STRING_Inscriptional_Parthian0
+  STRING_Javanese0
+  STRING_Kaithi0
+  STRING_Kannada0
+  STRING_Katakana0
+  STRING_Kayah_Li0
+  STRING_Kharoshthi0
+  STRING_Khmer0
+  STRING_L0
+  STRING_L_AMPERSAND0
+  STRING_Lao0
+  STRING_Latin0
+  STRING_Lepcha0
+  STRING_Limbu0
+  STRING_Linear_B0
+  STRING_Lisu0
+  STRING_Ll0
+  STRING_Lm0
+  STRING_Lo0
+  STRING_Lt0
+  STRING_Lu0
+  STRING_Lycian0
+  STRING_Lydian0
+  STRING_M0
+  STRING_Malayalam0
+  STRING_Mc0
+  STRING_Me0
+  STRING_Meetei_Mayek0
+  STRING_Mn0
+  STRING_Mongolian0
+  STRING_Myanmar0
+  STRING_N0
+  STRING_Nd0
+  STRING_New_Tai_Lue0
+  STRING_Nko0
+  STRING_Nl0
+  STRING_No0
+  STRING_Ogham0
+  STRING_Ol_Chiki0
+  STRING_Old_Italic0
+  STRING_Old_Persian0
+  STRING_Old_South_Arabian0
+  STRING_Old_Turkic0
+  STRING_Oriya0
+  STRING_Osmanya0
+  STRING_P0
+  STRING_Pc0
+  STRING_Pd0
+  STRING_Pe0
+  STRING_Pf0
+  STRING_Phags_Pa0
+  STRING_Phoenician0
+  STRING_Pi0
+  STRING_Po0
+  STRING_Ps0
+  STRING_Rejang0
+  STRING_Runic0
+  STRING_S0
+  STRING_Samaritan0
+  STRING_Saurashtra0
+  STRING_Sc0
+  STRING_Shavian0
+  STRING_Sinhala0
+  STRING_Sk0
+  STRING_Sm0
+  STRING_So0
+  STRING_Sundanese0
+  STRING_Syloti_Nagri0
+  STRING_Syriac0
+  STRING_Tagalog0
+  STRING_Tagbanwa0
+  STRING_Tai_Le0
+  STRING_Tai_Tham0
+  STRING_Tai_Viet0
+  STRING_Tamil0
+  STRING_Telugu0
+  STRING_Thaana0
+  STRING_Thai0
+  STRING_Tibetan0
+  STRING_Tifinagh0
+  STRING_Ugaritic0
+  STRING_Vai0
+  STRING_Yi0
+  STRING_Z0
+  STRING_Zl0
+  STRING_Zp0
+  STRING_Zs0;
+
+const ucp_type_table _pcre_utt[] = {
+  {   0, PT_ANY, 0 },
+  {   4, PT_SC, ucp_Arabic },
+  {  11, PT_SC, ucp_Armenian },
+  {  20, PT_SC, ucp_Avestan },
+  {  28, PT_SC, ucp_Balinese },
+  {  37, PT_SC, ucp_Bamum },
+  {  43, PT_SC, ucp_Bengali },
+  {  51, PT_SC, ucp_Bopomofo },
+  {  60, PT_SC, ucp_Braille },
+  {  68, PT_SC, ucp_Buginese },
+  {  77, PT_SC, ucp_Buhid },
+  {  83, PT_GC, ucp_C },
+  {  85, PT_SC, ucp_Canadian_Aboriginal },
+  { 105, PT_SC, ucp_Carian },
+  { 112, PT_PC, ucp_Cc },
+  { 115, PT_PC, ucp_Cf },
+  { 118, PT_SC, ucp_Cham },
+  { 123, PT_SC, ucp_Cherokee },
+  { 132, PT_PC, ucp_Cn },
+  { 135, PT_PC, ucp_Co },
+  { 138, PT_SC, ucp_Common },
+  { 145, PT_SC, ucp_Coptic },
+  { 152, PT_PC, ucp_Cs },
+  { 155, PT_SC, ucp_Cuneiform },
+  { 165, PT_SC, ucp_Cypriot },
+  { 173, PT_SC, ucp_Cyrillic },
+  { 182, PT_SC, ucp_Deseret },
+  { 190, PT_SC, ucp_Devanagari },
+  { 201, PT_SC, ucp_Egyptian_Hieroglyphs },
+  { 222, PT_SC, ucp_Ethiopic },
+  { 231, PT_SC, ucp_Georgian },
+  { 240, PT_SC, ucp_Glagolitic },
+  { 251, PT_SC, ucp_Gothic },
+  { 258, PT_SC, ucp_Greek },
+  { 264, PT_SC, ucp_Gujarati },
+  { 273, PT_SC, ucp_Gurmukhi },
+  { 282, PT_SC, ucp_Han },
+  { 286, PT_SC, ucp_Hangul },
+  { 293, PT_SC, ucp_Hanunoo },
+  { 301, PT_SC, ucp_Hebrew },
+  { 308, PT_SC, ucp_Hiragana },
+  { 317, PT_SC, ucp_Imperial_Aramaic },
+  { 334, PT_SC, ucp_Inherited },
+  { 344, PT_SC, ucp_Inscriptional_Pahlavi },
+  { 366, PT_SC, ucp_Inscriptional_Parthian },
+  { 389, PT_SC, ucp_Javanese },
+  { 398, PT_SC, ucp_Kaithi },
+  { 405, PT_SC, ucp_Kannada },
+  { 413, PT_SC, ucp_Katakana },
+  { 422, PT_SC, ucp_Kayah_Li },
+  { 431, PT_SC, ucp_Kharoshthi },
+  { 442, PT_SC, ucp_Khmer },
+  { 448, PT_GC, ucp_L },
+  { 450, PT_LAMP, 0 },
+  { 453, PT_SC, ucp_Lao },
+  { 457, PT_SC, ucp_Latin },
+  { 463, PT_SC, ucp_Lepcha },
+  { 470, PT_SC, ucp_Limbu },
+  { 476, PT_SC, ucp_Linear_B },
+  { 485, PT_SC, ucp_Lisu },
+  { 490, PT_PC, ucp_Ll },
+  { 493, PT_PC, ucp_Lm },
+  { 496, PT_PC, ucp_Lo },
+  { 499, PT_PC, ucp_Lt },
+  { 502, PT_PC, ucp_Lu },
+  { 505, PT_SC, ucp_Lycian },
+  { 512, PT_SC, ucp_Lydian },
+  { 519, PT_GC, ucp_M },
+  { 521, PT_SC, ucp_Malayalam },
+  { 531, PT_PC, ucp_Mc },
+  { 534, PT_PC, ucp_Me },
+  { 537, PT_SC, ucp_Meetei_Mayek },
+  { 550, PT_PC, ucp_Mn },
+  { 553, PT_SC, ucp_Mongolian },
+  { 563, PT_SC, ucp_Myanmar },
+  { 571, PT_GC, ucp_N },
+  { 573, PT_PC, ucp_Nd },
+  { 576, PT_SC, ucp_New_Tai_Lue },
+  { 588, PT_SC, ucp_Nko },
+  { 592, PT_PC, ucp_Nl },
+  { 595, PT_PC, ucp_No },
+  { 598, PT_SC, ucp_Ogham },
+  { 604, PT_SC, ucp_Ol_Chiki },
+  { 613, PT_SC, ucp_Old_Italic },
+  { 624, PT_SC, ucp_Old_Persian },
+  { 636, PT_SC, ucp_Old_South_Arabian },
+  { 654, PT_SC, ucp_Old_Turkic },
+  { 665, PT_SC, ucp_Oriya },
+  { 671, PT_SC, ucp_Osmanya },
+  { 679, PT_GC, ucp_P },
+  { 681, PT_PC, ucp_Pc },
+  { 684, PT_PC, ucp_Pd },
+  { 687, PT_PC, ucp_Pe },
+  { 690, PT_PC, ucp_Pf },
+  { 693, PT_SC, ucp_Phags_Pa },
+  { 702, PT_SC, ucp_Phoenician },
+  { 713, PT_PC, ucp_Pi },
+  { 716, PT_PC, ucp_Po },
+  { 719, PT_PC, ucp_Ps },
+  { 722, PT_SC, ucp_Rejang },
+  { 729, PT_SC, ucp_Runic },
+  { 735, PT_GC, ucp_S },
+  { 737, PT_SC, ucp_Samaritan },
+  { 747, PT_SC, ucp_Saurashtra },
+  { 758, PT_PC, ucp_Sc },
+  { 761, PT_SC, ucp_Shavian },
+  { 769, PT_SC, ucp_Sinhala },
+  { 777, PT_PC, ucp_Sk },
+  { 780, PT_PC, ucp_Sm },
+  { 783, PT_PC, ucp_So },
+  { 786, PT_SC, ucp_Sundanese },
+  { 796, PT_SC, ucp_Syloti_Nagri },
+  { 809, PT_SC, ucp_Syriac },
+  { 816, PT_SC, ucp_Tagalog },
+  { 824, PT_SC, ucp_Tagbanwa },
+  { 833, PT_SC, ucp_Tai_Le },
+  { 840, PT_SC, ucp_Tai_Tham },
+  { 849, PT_SC, ucp_Tai_Viet },
+  { 858, PT_SC, ucp_Tamil },
+  { 864, PT_SC, ucp_Telugu },
+  { 871, PT_SC, ucp_Thaana },
+  { 878, PT_SC, ucp_Thai },
+  { 883, PT_SC, ucp_Tibetan },
+  { 891, PT_SC, ucp_Tifinagh },
+  { 900, PT_SC, ucp_Ugaritic },
+  { 909, PT_SC, ucp_Vai },
+  { 913, PT_SC, ucp_Yi },
+  { 916, PT_GC, ucp_Z },
+  { 918, PT_PC, ucp_Zl },
+  { 921, PT_PC, ucp_Zp },
+  { 924, PT_PC, ucp_Zs }
+};
+
+const int _pcre_utt_size = sizeof(_pcre_utt)/sizeof(ucp_type_table);
+
+#endif  /* SUPPORT_UTF8 */
+
+/* End of pcre_tables.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_try_flipped.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_try_flipped.c
new file mode 100644 (file)
index 0000000..606504c
--- /dev/null
@@ -0,0 +1,139 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2009 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function that tests a compiled pattern to
+see if it was compiled with the opposite endianness. If so, it uses an
+auxiliary local function to flip the appropriate bytes. */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+*         Flip bytes in an integer               *
+*************************************************/
+
+/* This function is called when the magic number in a regex doesn't match, in
+order to flip its bytes to see if we are dealing with a pattern that was
+compiled on a host of different endianness. If so, this function is used to
+flip other byte values.
+
+Arguments:
+  value        the number to flip
+  n            the number of bytes to flip (assumed to be 2 or 4)
+
+Returns:       the flipped value
+*/
+
+static unsigned long int
+byteflip(unsigned long int value, int n)
+{
+if (n == 2) return ((value & 0x00ff) << 8) | ((value & 0xff00) >> 8);
+return ((value & 0x000000ff) << 24) |
+       ((value & 0x0000ff00) <<  8) |
+       ((value & 0x00ff0000) >>  8) |
+       ((value & 0xff000000) >> 24);
+}
+
+
+
+/*************************************************
+*       Test for a byte-flipped compiled regex   *
+*************************************************/
+
+/* This function is called from pcre_exec(), pcre_dfa_exec(), and also from
+pcre_fullinfo(). Its job is to test whether the regex is byte-flipped - that
+is, it was compiled on a system of opposite endianness. The function is called
+only when the native MAGIC_NUMBER test fails. If the regex is indeed flipped,
+we flip all the relevant values into a different data block, and return it.
+
+Arguments:
+  re               points to the regex
+  study            points to study data, or NULL
+  internal_re      points to a new regex block
+  internal_study   points to a new study block
+
+Returns:           the new block if is is indeed a byte-flipped regex
+                   NULL if it is not
+*/
+
+real_pcre *
+_pcre_try_flipped(const real_pcre *re, real_pcre *internal_re,
+  const pcre_study_data *study, pcre_study_data *internal_study)
+{
+if (byteflip(re->magic_number, sizeof(re->magic_number)) != MAGIC_NUMBER)
+  return NULL;
+
+*internal_re = *re;           /* To copy other fields */
+internal_re->size = byteflip(re->size, sizeof(re->size));
+internal_re->options = byteflip(re->options, sizeof(re->options));
+internal_re->flags = (pcre_uint16)byteflip(re->flags, sizeof(re->flags));
+internal_re->top_bracket =
+  (pcre_uint16)byteflip(re->top_bracket, sizeof(re->top_bracket));
+internal_re->top_backref =
+  (pcre_uint16)byteflip(re->top_backref, sizeof(re->top_backref));
+internal_re->first_byte =
+  (pcre_uint16)byteflip(re->first_byte, sizeof(re->first_byte));
+internal_re->req_byte =
+  (pcre_uint16)byteflip(re->req_byte, sizeof(re->req_byte));
+internal_re->name_table_offset =
+  (pcre_uint16)byteflip(re->name_table_offset, sizeof(re->name_table_offset));
+internal_re->name_entry_size =
+  (pcre_uint16)byteflip(re->name_entry_size, sizeof(re->name_entry_size));
+internal_re->name_count =
+  (pcre_uint16)byteflip(re->name_count, sizeof(re->name_count));
+
+if (study != NULL)
+  {
+  *internal_study = *study;   /* To copy other fields */
+  internal_study->size = byteflip(study->size, sizeof(study->size));
+  internal_study->flags = byteflip(study->flags, sizeof(study->flags));
+  internal_study->minlength = byteflip(study->minlength,
+    sizeof(study->minlength));
+  }
+
+return internal_re;
+}
+
+/* End of pcre_tryflipped.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_ucp_searchfuncs.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_ucp_searchfuncs.c
new file mode 100644 (file)
index 0000000..36e90b5
--- /dev/null
@@ -0,0 +1,131 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2006 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+/* This file has been modified to use glib instead of the internal table
+ * in ucptable.c -- Marco Barisione */
+
+/* This module contains code for searching the table of Unicode character
+properties. */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+#include "ucp.h"               /* Category definitions */
+
+/* Table to translate from particular type value to the general value. */
+
+#ifdef NOT_USED_IN_GLIB
+
+static int ucp_gentype[] = {
+  ucp_C, ucp_C, ucp_C, ucp_C, ucp_C,  /* Cc, Cf, Cn, Co, Cs */
+  ucp_L, ucp_L, ucp_L, ucp_L, ucp_L,  /* Ll, Lu, Lm, Lo, Lt */
+  ucp_M, ucp_M, ucp_M,                /* Mc, Me, Mn */
+  ucp_N, ucp_N, ucp_N,                /* Nd, Nl, No */
+  ucp_P, ucp_P, ucp_P, ucp_P, ucp_P,  /* Pc, Pd, Pe, Pf, Pi */
+  ucp_P, ucp_P,                       /* Ps, Po */
+  ucp_S, ucp_S, ucp_S, ucp_S,         /* Sc, Sk, Sm, So */
+  ucp_Z, ucp_Z, ucp_Z                 /* Zl, Zp, Zs */
+};
+
+
+
+/*************************************************
+*         Search table and return type           *
+*************************************************/
+
+/* Three values are returned: the category is ucp_C, ucp_L, etc. The detailed
+character type is ucp_Lu, ucp_Nd, etc. The script is ucp_Latin, etc.
+
+Arguments:
+  c           the character value
+  type_ptr    the detailed character type is returned here
+  script_ptr  the script is returned here
+
+Returns:      the character type category
+*/
+
+int
+_pcre_ucp_findprop(const unsigned int c, int *type_ptr, int *script_ptr)
+{
+/* Note that the Unicode types have the same values in glib and in
+ * PCRE, so ucp_Ll == G_UNICODE_LOWERCASE_LETTER,
+ * ucp_Zs == G_UNICODE_SPACE_SEPARATOR, and so on. */
+*type_ptr = g_unichar_type(c);
+*script_ptr = g_unichar_get_script(c);
+return ucp_gentype[*type_ptr];
+}
+
+#endif
+
+
+
+/*************************************************
+*       Search table and return other case       *
+*************************************************/
+
+/* If the given character is a letter, and there is another case for the
+letter, return the other case. Otherwise, return -1.
+
+Arguments:
+  c           the character value
+
+Returns:      the other case or NOTACHAR if none
+*/
+
+unsigned int
+_pcre_ucp_othercase(const unsigned int c)
+{
+int other_case = NOTACHAR;
+
+if (g_unichar_islower(c))
+  other_case = g_unichar_toupper(c);
+else if (g_unichar_isupper(c))
+  other_case = g_unichar_tolower(c);
+
+if (other_case == c)
+  other_case = NOTACHAR;
+
+return other_case;
+}
+
+
+/* End of pcre_ucp_searchfuncs.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_xclass.c b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/pcre_xclass.c
new file mode 100644 (file)
index 0000000..c25ecdc
--- /dev/null
@@ -0,0 +1,145 @@
+/*************************************************
+*      Perl-Compatible Regular Expressions       *
+*************************************************/
+
+/* PCRE is a library of functions to support regular expressions whose syntax
+and semantics are as close as possible to those of the Perl 5 language.
+
+                       Written by Philip Hazel
+           Copyright (c) 1997-2009 University of Cambridge
+
+-----------------------------------------------------------------------------
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+
+    * Redistributions of source code must retain the above copyright notice,
+      this list of conditions and the following disclaimer.
+
+    * 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.
+
+    * Neither the name of the University of Cambridge nor the names of its
+      contributors may be used to endorse or promote products derived from
+      this software without specific prior written permission.
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "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 COPYRIGHT OWNER OR CONTRIBUTORS 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.
+-----------------------------------------------------------------------------
+*/
+
+
+/* This module contains an internal function that is used to match an extended
+class. It is used by both pcre_exec() and pcre_def_exec(). */
+
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "pcre_internal.h"
+
+
+/*************************************************
+*       Match character against an XCLASS        *
+*************************************************/
+
+/* This function is called to match a character against an extended class that
+might contain values > 255 and/or Unicode properties.
+
+Arguments:
+  c           the character
+  data        points to the flag byte of the XCLASS data
+
+Returns:      TRUE if character matches, else FALSE
+*/
+
+BOOL
+_pcre_xclass(int c, const uschar *data)
+{
+int t;
+BOOL negated = (*data & XCL_NOT) != 0;
+
+/* Character values < 256 are matched against a bitmap, if one is present. If
+not, we still carry on, because there may be ranges that start below 256 in the
+additional data. */
+
+if (c < 256)
+  {
+  if ((*data & XCL_MAP) != 0 && (data[1 + c/8] & (1 << (c&7))) != 0)
+    return !negated;   /* char found */
+  }
+
+/* First skip the bit map if present. Then match against the list of Unicode
+properties or large chars or ranges that end with a large char. We won't ever
+encounter XCL_PROP or XCL_NOTPROP when UCP support is not compiled. */
+
+if ((*data++ & XCL_MAP) != 0) data += 32;
+
+while ((t = *data++) != XCL_END)
+  {
+  int x, y;
+  if (t == XCL_SINGLE)
+    {
+    GETCHARINC(x, data);
+    if (c == x) return !negated;
+    }
+  else if (t == XCL_RANGE)
+    {
+    GETCHARINC(x, data);
+    GETCHARINC(y, data);
+    if (c >= x && c <= y) return !negated;
+    }
+
+#ifdef SUPPORT_UCP
+  else  /* XCL_PROP & XCL_NOTPROP */
+    {
+    int chartype = UCD_CHARTYPE(c);
+    switch(*data)
+      {
+      case PT_ANY:
+      if (t == XCL_PROP) return !negated;
+      break;
+
+      case PT_LAMP:
+      if ((chartype == ucp_Lu || chartype == ucp_Ll || chartype == ucp_Lt) ==
+          (t == XCL_PROP)) return !negated;
+      break;
+
+      case PT_GC:
+      if ((data[1] == _pcre_ucp_gentype[chartype]) == (t == XCL_PROP)) return !negated;
+      break;
+
+      case PT_PC:
+      if ((data[1] == chartype) == (t == XCL_PROP)) return !negated;
+      break;
+
+      case PT_SC:
+      if ((data[1] == UCD_SCRIPT(c)) == (t == XCL_PROP)) return !negated;
+      break;
+
+      /* This should never occur, but compilers may mutter if there is no
+      default. */
+
+      default:
+      return FALSE;
+      }
+
+    data += 2;
+    }
+#endif  /* SUPPORT_UCP */
+  }
+
+return negated;   /* char did not match */
+}
+
+/* End of pcre_xclass.c */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/ucp.h b/resource/csdk/connectivity/lib/android/glib-master/glib/pcre/ucp.h
new file mode 100644 (file)
index 0000000..e96c8b4
--- /dev/null
@@ -0,0 +1,159 @@
+/*************************************************
+*          Unicode Property Table handler        *
+*************************************************/
+
+#ifndef _UCP_H
+#define _UCP_H
+
+/* This file contains definitions of the property values that are returned by
+the UCD access macros. New values that are added for new releases of Unicode
+should always be at the end of each enum, for backwards compatibility. */
+
+/* These are the general character categories. */
+
+enum {
+  ucp_C,     /* Other */
+  ucp_L,     /* Letter */
+  ucp_M,     /* Mark */
+  ucp_N,     /* Number */
+  ucp_P,     /* Punctuation */
+  ucp_S,     /* Symbol */
+  ucp_Z      /* Separator */
+};
+
+/* These are the particular character types. */
+
+enum {
+  ucp_Cc,    /* Control */
+  ucp_Cf,    /* Format */
+  ucp_Cn,    /* Unassigned */
+  ucp_Co,    /* Private use */
+  ucp_Cs,    /* Surrogate */
+  ucp_Ll,    /* Lower case letter */
+  ucp_Lm,    /* Modifier letter */
+  ucp_Lo,    /* Other letter */
+  ucp_Lt,    /* Title case letter */
+  ucp_Lu,    /* Upper case letter */
+  ucp_Mc,    /* Spacing mark */
+  ucp_Me,    /* Enclosing mark */
+  ucp_Mn,    /* Non-spacing mark */
+  ucp_Nd,    /* Decimal number */
+  ucp_Nl,    /* Letter number */
+  ucp_No,    /* Other number */
+  ucp_Pc,    /* Connector punctuation */
+  ucp_Pd,    /* Dash punctuation */
+  ucp_Pe,    /* Close punctuation */
+  ucp_Pf,    /* Final punctuation */
+  ucp_Pi,    /* Initial punctuation */
+  ucp_Po,    /* Other punctuation */
+  ucp_Ps,    /* Open punctuation */
+  ucp_Sc,    /* Currency symbol */
+  ucp_Sk,    /* Modifier symbol */
+  ucp_Sm,    /* Mathematical symbol */
+  ucp_So,    /* Other symbol */
+  ucp_Zl,    /* Line separator */
+  ucp_Zp,    /* Paragraph separator */
+  ucp_Zs     /* Space separator */
+};
+
+/* These are the script identifications. */
+
+enum {
+  ucp_Arabic = G_UNICODE_SCRIPT_ARABIC,
+  ucp_Armenian = G_UNICODE_SCRIPT_ARMENIAN,
+  ucp_Bengali = G_UNICODE_SCRIPT_BENGALI,
+  ucp_Bopomofo = G_UNICODE_SCRIPT_BOPOMOFO,
+  ucp_Braille = G_UNICODE_SCRIPT_BRAILLE,
+  ucp_Buginese = G_UNICODE_SCRIPT_BUGINESE,
+  ucp_Buhid = G_UNICODE_SCRIPT_BUHID,
+  ucp_Canadian_Aboriginal = G_UNICODE_SCRIPT_CANADIAN_ABORIGINAL,
+  ucp_Cherokee = G_UNICODE_SCRIPT_CHEROKEE,
+  ucp_Common = G_UNICODE_SCRIPT_COMMON,
+  ucp_Coptic = G_UNICODE_SCRIPT_COPTIC,
+  ucp_Cypriot = G_UNICODE_SCRIPT_CYPRIOT,
+  ucp_Cyrillic = G_UNICODE_SCRIPT_CYRILLIC,
+  ucp_Deseret = G_UNICODE_SCRIPT_DESERET,
+  ucp_Devanagari = G_UNICODE_SCRIPT_DEVANAGARI,
+  ucp_Ethiopic = G_UNICODE_SCRIPT_ETHIOPIC,
+  ucp_Georgian = G_UNICODE_SCRIPT_GEORGIAN,
+  ucp_Glagolitic = G_UNICODE_SCRIPT_GLAGOLITIC,
+  ucp_Gothic = G_UNICODE_SCRIPT_GOTHIC,
+  ucp_Greek = G_UNICODE_SCRIPT_GREEK,
+  ucp_Gujarati = G_UNICODE_SCRIPT_GUJARATI,
+  ucp_Gurmukhi = G_UNICODE_SCRIPT_GURMUKHI,
+  ucp_Han = G_UNICODE_SCRIPT_HAN,
+  ucp_Hangul = G_UNICODE_SCRIPT_HANGUL,
+  ucp_Hanunoo = G_UNICODE_SCRIPT_HANUNOO,
+  ucp_Hebrew = G_UNICODE_SCRIPT_HEBREW,
+  ucp_Hiragana = G_UNICODE_SCRIPT_HIRAGANA,
+  ucp_Inherited = G_UNICODE_SCRIPT_INHERITED,
+  ucp_Kannada = G_UNICODE_SCRIPT_KANNADA,
+  ucp_Katakana = G_UNICODE_SCRIPT_KATAKANA,
+  ucp_Kharoshthi = G_UNICODE_SCRIPT_KHAROSHTHI,
+  ucp_Khmer = G_UNICODE_SCRIPT_KHMER,
+  ucp_Lao = G_UNICODE_SCRIPT_LAO,
+  ucp_Latin = G_UNICODE_SCRIPT_LATIN,
+  ucp_Limbu = G_UNICODE_SCRIPT_LIMBU,
+  ucp_Linear_B = G_UNICODE_SCRIPT_LINEAR_B,
+  ucp_Malayalam = G_UNICODE_SCRIPT_MALAYALAM,
+  ucp_Mongolian = G_UNICODE_SCRIPT_MONGOLIAN,
+  ucp_Myanmar = G_UNICODE_SCRIPT_MYANMAR,
+  ucp_New_Tai_Lue = G_UNICODE_SCRIPT_NEW_TAI_LUE,
+  ucp_Ogham = G_UNICODE_SCRIPT_OGHAM,
+  ucp_Old_Italic = G_UNICODE_SCRIPT_OLD_ITALIC,
+  ucp_Old_Persian = G_UNICODE_SCRIPT_OLD_PERSIAN,
+  ucp_Oriya = G_UNICODE_SCRIPT_ORIYA,
+  ucp_Osmanya = G_UNICODE_SCRIPT_OSMANYA,
+  ucp_Runic = G_UNICODE_SCRIPT_RUNIC,
+  ucp_Shavian = G_UNICODE_SCRIPT_SHAVIAN,
+  ucp_Sinhala = G_UNICODE_SCRIPT_SINHALA,
+  ucp_Syloti_Nagri = G_UNICODE_SCRIPT_SYLOTI_NAGRI,
+  ucp_Syriac = G_UNICODE_SCRIPT_SYRIAC,
+  ucp_Tagalog = G_UNICODE_SCRIPT_TAGALOG,
+  ucp_Tagbanwa = G_UNICODE_SCRIPT_TAGBANWA,
+  ucp_Tai_Le = G_UNICODE_SCRIPT_TAI_LE,
+  ucp_Tamil = G_UNICODE_SCRIPT_TAMIL,
+  ucp_Telugu = G_UNICODE_SCRIPT_TELUGU,
+  ucp_Thaana = G_UNICODE_SCRIPT_THAANA,
+  ucp_Thai = G_UNICODE_SCRIPT_THAI,
+  ucp_Tibetan = G_UNICODE_SCRIPT_TIBETAN,
+  ucp_Tifinagh = G_UNICODE_SCRIPT_TIFINAGH,
+  ucp_Ugaritic = G_UNICODE_SCRIPT_UGARITIC,
+  ucp_Yi = G_UNICODE_SCRIPT_YI,
+  ucp_Balinese = G_UNICODE_SCRIPT_BALINESE,
+  ucp_Cuneiform = G_UNICODE_SCRIPT_CUNEIFORM,
+  ucp_Nko = G_UNICODE_SCRIPT_NKO,
+  ucp_Phags_Pa = G_UNICODE_SCRIPT_PHAGS_PA,
+  ucp_Phoenician = G_UNICODE_SCRIPT_PHOENICIAN,
+  ucp_Carian = G_UNICODE_SCRIPT_CARIAN,
+  ucp_Cham = G_UNICODE_SCRIPT_CHAM,
+  ucp_Kayah_Li = G_UNICODE_SCRIPT_KAYAH_LI,
+  ucp_Lepcha = G_UNICODE_SCRIPT_LEPCHA,
+  ucp_Lycian = G_UNICODE_SCRIPT_LYCIAN,
+  ucp_Lydian = G_UNICODE_SCRIPT_LYDIAN,
+  ucp_Ol_Chiki = G_UNICODE_SCRIPT_OL_CHIKI,
+  ucp_Rejang = G_UNICODE_SCRIPT_REJANG,
+  ucp_Saurashtra = G_UNICODE_SCRIPT_SAURASHTRA,
+  ucp_Sundanese = G_UNICODE_SCRIPT_SUNDANESE,
+  ucp_Vai = G_UNICODE_SCRIPT_VAI,
+  ucp_Avestan = G_UNICODE_SCRIPT_AVESTAN,
+  ucp_Bamum = G_UNICODE_SCRIPT_BAMUM,
+  ucp_Egyptian_Hieroglyphs = G_UNICODE_SCRIPT_EGYPTIAN_HIEROGLYPHS,
+  ucp_Imperial_Aramaic = G_UNICODE_SCRIPT_IMPERIAL_ARAMAIC,
+  ucp_Inscriptional_Pahlavi = G_UNICODE_SCRIPT_INSCRIPTIONAL_PAHLAVI,
+  ucp_Inscriptional_Parthian = G_UNICODE_SCRIPT_INSCRIPTIONAL_PARTHIAN,
+  ucp_Javanese = G_UNICODE_SCRIPT_JAVANESE,
+  ucp_Kaithi = G_UNICODE_SCRIPT_KAITHI,
+  ucp_Lisu = G_UNICODE_SCRIPT_LISU,
+  ucp_Meetei_Mayek = G_UNICODE_SCRIPT_MEETEI_MAYEK,
+  ucp_Old_South_Arabian = G_UNICODE_SCRIPT_OLD_SOUTH_ARABIAN,
+  ucp_Old_Turkic = G_UNICODE_SCRIPT_OLD_TURKISH,
+  ucp_Samaritan = G_UNICODE_SCRIPT_SAMARITAN,
+  ucp_Tai_Tham = G_UNICODE_SCRIPT_TAI_THAM,
+  ucp_Tai_Viet = G_UNICODE_SCRIPT_TAI_VIET
+};
+
+#endif
+
+/* End of ucp.h */
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/glib/win_iconv.c b/resource/csdk/connectivity/lib/android/glib-master/glib/win_iconv.c
new file mode 100644 (file)
index 0000000..4ab1653
--- /dev/null
@@ -0,0 +1,1965 @@
+/*
+ * iconv library implemented with Win32 API.
+ *
+ * This file is placed in the public domain.
+ *
+ * Maintainer: Yukihiro Nakadaira <yukihiro.nakadaira@gmail.com>
+ *
+ * If $WINICONV_LIBICONV_DLL environment variable was defined, win_iconv
+ * loads the specified DLL dynamically and uses it.  If loading the DLL
+ * or iconv_open() failed, falls back to internal conversion.
+ * $WINICONV_LIBICONV_DLL is a comma separated list.  The first loadable
+ * DLL is used.  The specified DLL should have iconv_open(),
+ * iconv_close() and iconv() functions.  Or these functions can be
+ * libiconv_open(), libiconv_close() and libiconv().
+ *
+ * Win32 API does not support strict encoding conversion for some
+ * codepage.  And MLang function drop or replace invalid bytes and does
+ * not return useful error status as iconv.  This implementation cannot
+ * be used for encoding validation purpose.
+ */
+
+/* for WC_NO_BEST_FIT_CHARS */
+#ifndef WINVER
+# define WINVER 0x0500
+#endif
+
+#define STRICT
+#include <windows.h>
+#include <errno.h>
+#include <string.h>
+#include <stdlib.h>
+
+#if 0
+# define MAKE_EXE
+# define MAKE_DLL
+# define USE_LIBICONV_DLL
+#endif
+
+#if !defined(DEFAULT_LIBICONV_DLL)
+# define DEFAULT_LIBICONV_DLL ""
+#endif
+
+#define MB_CHAR_MAX 16
+
+#define UNICODE_MODE_BOM_DONE   1
+#define UNICODE_MODE_SWAPPED    2
+
+#define FLAG_USE_BOM_ENDIAN     1
+#define FLAG_TRANSLIT           2 /* //TRANSLIT */
+#define FLAG_IGNORE             4 /* //IGNORE (not implemented) */
+
+#define return_error(code)  \
+    do {                    \
+        errno = code;       \
+        return -1;          \
+    } while (0)
+
+#define xstrlcpy(dst, src, size)    \
+    do {                            \
+        strncpy(dst, src, size);    \
+        dst[size - 1] = 0;          \
+    } while (0)
+
+#define xstrlcpyn(dst, src, srclen, size) \
+    xstrlcpy(dst, src, xmin((srclen) + 1, size))
+
+#define xmin(a, b) ((a) < (b) ? (a) : (b))
+#define xmax(a, b) ((a) > (b) ? (a) : (b))
+
+#define STATIC_STRLEN(arr) (sizeof(arr) - 1)
+
+typedef unsigned char uchar;
+typedef unsigned short ushort;
+typedef unsigned int uint;
+
+typedef void* iconv_t;
+
+iconv_t iconv_open(const char *tocode, const char *fromcode);
+int iconv_close(iconv_t cd);
+size_t iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
+
+/* libiconv interface for vim */
+#if defined(MAKE_DLL)
+int
+iconvctl (iconv_t cd, int request, void* argument)
+{
+    /* not supported */
+    return 0;
+}
+#endif
+
+typedef struct compat_t compat_t;
+typedef struct csconv_t csconv_t;
+typedef struct rec_iconv_t rec_iconv_t;
+
+typedef iconv_t (*f_iconv_open)(const char *tocode, const char *fromcode);
+typedef int (*f_iconv_close)(iconv_t cd);
+typedef size_t (*f_iconv)(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
+typedef int* (*f_errno)(void);
+typedef int (*f_mbtowc)(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
+typedef int (*f_wctomb)(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
+typedef int (*f_mblen)(csconv_t *cv, const uchar *buf, int bufsize);
+typedef int (*f_flush)(csconv_t *cv, uchar *buf, int bufsize);
+
+#define COMPAT_IN   1
+#define COMPAT_OUT  2
+
+/* unicode mapping for compatibility with other conversion table. */
+struct compat_t {
+    uint in;
+    uint out;
+    uint flag;
+};
+
+struct csconv_t {
+    int codepage;
+    int flags;
+    f_mbtowc mbtowc;
+    f_wctomb wctomb;
+    f_mblen mblen;
+    f_flush flush;
+    DWORD mode;
+    compat_t *compat;
+};
+
+struct rec_iconv_t {
+    iconv_t cd;
+    f_iconv_close iconv_close;
+    f_iconv iconv;
+    f_errno _errno;
+    csconv_t from;
+    csconv_t to;
+#if defined(USE_LIBICONV_DLL)
+    HMODULE hlibiconv;
+#endif
+};
+
+static int win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode);
+static int win_iconv_close(iconv_t cd);
+static size_t win_iconv(iconv_t cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft);
+
+static int load_mlang();
+static csconv_t make_csconv(const char *name);
+static int name_to_codepage(const char *name);
+static uint utf16_to_ucs4(const ushort *wbuf);
+static void ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize);
+static int is_unicode(int codepage);
+static int mbtowc_flags(int codepage);
+static int must_use_null_useddefaultchar(int codepage);
+static void check_utf_bom(rec_iconv_t *cd, ushort *wbuf, int *wbufsize);
+static char *strrstr(const char *str, const char *token);
+
+#if defined(USE_LIBICONV_DLL)
+static int libiconv_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode);
+static PVOID MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size);
+static HMODULE find_imported_module_by_funcname(HMODULE hModule, const char *funcname);
+
+static HMODULE hwiniconv;
+static HMODULE hlastdll; /* keep dll loaded for efficiency (unnecessary?) */
+#endif
+
+static int sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize);
+static int dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize);
+static int mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize);
+static int utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize);
+static int eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize);
+
+static int kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
+static int kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
+static int mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
+static int mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
+static int utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
+static int utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
+static int utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
+static int utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
+static int iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize);
+static int iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize);
+static int iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize);
+
+static struct {
+    int codepage;
+    const char *name;
+} codepage_alias[] = {
+    {65001, "CP65001"},
+    {65001, "UTF8"},
+    {65001, "UTF-8"},
+
+    {1200, "CP1200"},
+    {1200, "UTF16LE"},
+    {1200, "UTF-16LE"},
+    {1200, "UCS2LE"},
+    {1200, "UCS-2LE"},
+
+    {1201, "CP1201"},
+    {1201, "UTF16BE"},
+    {1201, "UTF-16BE"},
+    {1201, "UCS2BE"},
+    {1201, "UCS-2BE"},
+    {1201, "unicodeFFFE"},
+
+    {12000, "CP12000"},
+    {12000, "UTF32LE"},
+    {12000, "UTF-32LE"},
+    {12000, "UCS4LE"},
+    {12000, "UCS-4LE"},
+
+    {12001, "CP12001"},
+    {12001, "UTF32BE"},
+    {12001, "UTF-32BE"},
+    {12001, "UCS4BE"},
+    {12001, "UCS-4BE"},
+
+#ifndef GLIB_COMPILATION
+    /*
+     * Default is big endian.
+     * See rfc2781 4.3 Interpreting text labelled as UTF-16.
+     */
+    {1201, "UTF16"},
+    {1201, "UTF-16"},
+    {12001, "UTF32"},
+    {12001, "UTF-32"},
+    {12001, "UCS-4"},
+    {12001, "UCS4"},
+#else
+    /* Default is little endian, because the platform is */
+    {1200, "UTF16"},
+    {1200, "UTF-16"},
+    {1200, "UCS2"},
+    {1200, "UCS-2"},
+    {12000, "UTF32"},
+    {12000, "UTF-32"},
+    {12000, "UCS4"},
+    {12000, "UCS-4"},
+#endif
+
+    /* copy from libiconv `iconv -l` */
+    /* !IsValidCodePage(367) */
+    {20127, "ANSI_X3.4-1968"},
+    {20127, "ANSI_X3.4-1986"},
+    {20127, "ASCII"},
+    {20127, "CP367"},
+    {20127, "IBM367"},
+    {20127, "ISO-IR-6"},
+    {20127, "ISO646-US"},
+    {20127, "ISO_646.IRV:1991"},
+    {20127, "US"},
+    {20127, "US-ASCII"},
+    {20127, "CSASCII"},
+
+    /* !IsValidCodePage(819) */
+    {1252, "CP819"},
+    {1252, "IBM819"},
+    {28591, "ISO-8859-1"},
+    {28591, "ISO-IR-100"},
+    {28591, "ISO8859-1"},
+    {28591, "ISO_8859-1"},
+    {28591, "ISO_8859-1:1987"},
+    {28591, "L1"},
+    {28591, "LATIN1"},
+    {28591, "CSISOLATIN1"},
+
+    {1250, "CP1250"},
+    {1250, "MS-EE"},
+    {1250, "WINDOWS-1250"},
+
+    {1251, "CP1251"},
+    {1251, "MS-CYRL"},
+    {1251, "WINDOWS-1251"},
+
+    {1252, "CP1252"},
+    {1252, "MS-ANSI"},
+    {1252, "WINDOWS-1252"},
+
+    {1253, "CP1253"},
+    {1253, "MS-GREEK"},
+    {1253, "WINDOWS-1253"},
+
+    {1254, "CP1254"},
+    {1254, "MS-TURK"},
+    {1254, "WINDOWS-1254"},
+
+    {1255, "CP1255"},
+    {1255, "MS-HEBR"},
+    {1255, "WINDOWS-1255"},
+
+    {1256, "CP1256"},
+    {1256, "MS-ARAB"},
+    {1256, "WINDOWS-1256"},
+
+    {1257, "CP1257"},
+    {1257, "WINBALTRIM"},
+    {1257, "WINDOWS-1257"},
+
+    {1258, "CP1258"},
+    {1258, "WINDOWS-1258"},
+
+    {850, "850"},
+    {850, "CP850"},
+    {850, "IBM850"},
+    {850, "CSPC850MULTILINGUAL"},
+
+    /* !IsValidCodePage(862) */
+    {862, "862"},
+    {862, "CP862"},
+    {862, "IBM862"},
+    {862, "CSPC862LATINHEBREW"},
+
+    {866, "866"},
+    {866, "CP866"},
+    {866, "IBM866"},
+    {866, "CSIBM866"},
+
+    /* !IsValidCodePage(154) */
+    {154, "CP154"},
+    {154, "CYRILLIC-ASIAN"},
+    {154, "PT154"},
+    {154, "PTCP154"},
+    {154, "CSPTCP154"},
+
+    /* !IsValidCodePage(1133) */
+    {1133, "CP1133"},
+    {1133, "IBM-CP1133"},
+
+    {874, "CP874"},
+    {874, "WINDOWS-874"},
+
+    /* !IsValidCodePage(51932) */
+    {51932, "CP51932"},
+    {51932, "MS51932"},
+    {51932, "WINDOWS-51932"},
+    {51932, "EUC-JP"},
+
+    {932, "CP932"},
+    {932, "MS932"},
+    {932, "SHIFFT_JIS"},
+    {932, "SHIFFT_JIS-MS"},
+    {932, "SJIS"},
+    {932, "SJIS-MS"},
+    {932, "SJIS-OPEN"},
+    {932, "SJIS-WIN"},
+    {932, "WINDOWS-31J"},
+    {932, "WINDOWS-932"},
+    {932, "CSWINDOWS31J"},
+
+    {50221, "CP50221"},
+    {50221, "ISO-2022-JP"},
+    {50221, "ISO-2022-JP-MS"},
+    {50221, "ISO2022-JP"},
+    {50221, "ISO2022-JP-MS"},
+    {50221, "MS50221"},
+    {50221, "WINDOWS-50221"},
+
+    {936, "CP936"},
+    {936, "GBK"},
+    {936, "MS936"},
+    {936, "WINDOWS-936"},
+
+    {950, "CP950"},
+    {950, "BIG5"},
+
+    {949, "CP949"},
+    {949, "UHC"},
+    {949, "EUC-KR"},
+
+    {1361, "CP1361"},
+    {1361, "JOHAB"},
+
+    {437, "437"},
+    {437, "CP437"},
+    {437, "IBM437"},
+    {437, "CSPC8CODEPAGE437"},
+
+    {737, "CP737"},
+
+    {775, "CP775"},
+    {775, "IBM775"},
+    {775, "CSPC775BALTIC"},
+
+    {852, "852"},
+    {852, "CP852"},
+    {852, "IBM852"},
+    {852, "CSPCP852"},
+
+    /* !IsValidCodePage(853) */
+    {853, "CP853"},
+
+    {855, "855"},
+    {855, "CP855"},
+    {855, "IBM855"},
+    {855, "CSIBM855"},
+
+    {857, "857"},
+    {857, "CP857"},
+    {857, "IBM857"},
+    {857, "CSIBM857"},
+
+    /* !IsValidCodePage(858) */
+    {858, "CP858"},
+
+    {860, "860"},
+    {860, "CP860"},
+    {860, "IBM860"},
+    {860, "CSIBM860"},
+
+    {861, "861"},
+    {861, "CP-IS"},
+    {861, "CP861"},
+    {861, "IBM861"},
+    {861, "CSIBM861"},
+
+    {863, "863"},
+    {863, "CP863"},
+    {863, "IBM863"},
+    {863, "CSIBM863"},
+
+    {864, "CP864"},
+    {864, "IBM864"},
+    {864, "CSIBM864"},
+
+    {865, "865"},
+    {865, "CP865"},
+    {865, "IBM865"},
+    {865, "CSIBM865"},
+
+    {869, "869"},
+    {869, "CP-GR"},
+    {869, "CP869"},
+    {869, "IBM869"},
+    {869, "CSIBM869"},
+
+    /* !IsValidCodePage(1152) */
+    {1125, "CP1125"},
+
+    /*
+     * Code Page Identifiers
+     * http://msdn2.microsoft.com/en-us/library/ms776446.aspx
+     */
+    {37, "IBM037"}, /* IBM EBCDIC US-Canada */
+    {437, "IBM437"}, /* OEM United States */
+    {500, "IBM500"}, /* IBM EBCDIC International */
+    {708, "ASMO-708"}, /* Arabic (ASMO 708) */
+    /* 709             Arabic (ASMO-449+, BCON V4) */
+    /* 710             Arabic - Transparent Arabic */
+    {720, "DOS-720"}, /* Arabic (Transparent ASMO); Arabic (DOS) */
+    {737, "ibm737"}, /* OEM Greek (formerly 437G); Greek (DOS) */
+    {775, "ibm775"}, /* OEM Baltic; Baltic (DOS) */
+    {850, "ibm850"}, /* OEM Multilingual Latin 1; Western European (DOS) */
+    {852, "ibm852"}, /* OEM Latin 2; Central European (DOS) */
+    {855, "IBM855"}, /* OEM Cyrillic (primarily Russian) */
+    {857, "ibm857"}, /* OEM Turkish; Turkish (DOS) */
+    {858, "IBM00858"}, /* OEM Multilingual Latin 1 + Euro symbol */
+    {860, "IBM860"}, /* OEM Portuguese; Portuguese (DOS) */
+    {861, "ibm861"}, /* OEM Icelandic; Icelandic (DOS) */
+    {862, "DOS-862"}, /* OEM Hebrew; Hebrew (DOS) */
+    {863, "IBM863"}, /* OEM French Canadian; French Canadian (DOS) */
+    {864, "IBM864"}, /* OEM Arabic; Arabic (864) */
+    {865, "IBM865"}, /* OEM Nordic; Nordic (DOS) */
+    {866, "cp866"}, /* OEM Russian; Cyrillic (DOS) */
+    {869, "ibm869"}, /* OEM Modern Greek; Greek, Modern (DOS) */
+    {870, "IBM870"}, /* IBM EBCDIC Multilingual/ROECE (Latin 2); IBM EBCDIC Multilingual Latin 2 */
+    {874, "windows-874"}, /* ANSI/OEM Thai (same as 28605, ISO 8859-15); Thai (Windows) */
+    {875, "cp875"}, /* IBM EBCDIC Greek Modern */
+    {932, "shift_jis"}, /* ANSI/OEM Japanese; Japanese (Shift-JIS) */
+    {932, "shift-jis"}, /* alternative name for it */
+    {936, "gb2312"}, /* ANSI/OEM Simplified Chinese (PRC, Singapore); Chinese Simplified (GB2312) */
+    {949, "ks_c_5601-1987"}, /* ANSI/OEM Korean (Unified Hangul Code) */
+    {950, "big5"}, /* ANSI/OEM Traditional Chinese (Taiwan; Hong Kong SAR, PRC); Chinese Traditional (Big5) */
+    {1026, "IBM1026"}, /* IBM EBCDIC Turkish (Latin 5) */
+    {1047, "IBM01047"}, /* IBM EBCDIC Latin 1/Open System */
+    {1140, "IBM01140"}, /* IBM EBCDIC US-Canada (037 + Euro symbol); IBM EBCDIC (US-Canada-Euro) */
+    {1141, "IBM01141"}, /* IBM EBCDIC Germany (20273 + Euro symbol); IBM EBCDIC (Germany-Euro) */
+    {1142, "IBM01142"}, /* IBM EBCDIC Denmark-Norway (20277 + Euro symbol); IBM EBCDIC (Denmark-Norway-Euro) */
+    {1143, "IBM01143"}, /* IBM EBCDIC Finland-Sweden (20278 + Euro symbol); IBM EBCDIC (Finland-Sweden-Euro) */
+    {1144, "IBM01144"}, /* IBM EBCDIC Italy (20280 + Euro symbol); IBM EBCDIC (Italy-Euro) */
+    {1145, "IBM01145"}, /* IBM EBCDIC Latin America-Spain (20284 + Euro symbol); IBM EBCDIC (Spain-Euro) */
+    {1146, "IBM01146"}, /* IBM EBCDIC United Kingdom (20285 + Euro symbol); IBM EBCDIC (UK-Euro) */
+    {1147, "IBM01147"}, /* IBM EBCDIC France (20297 + Euro symbol); IBM EBCDIC (France-Euro) */
+    {1148, "IBM01148"}, /* IBM EBCDIC International (500 + Euro symbol); IBM EBCDIC (International-Euro) */
+    {1149, "IBM01149"}, /* IBM EBCDIC Icelandic (20871 + Euro symbol); IBM EBCDIC (Icelandic-Euro) */
+    {1250, "windows-1250"}, /* ANSI Central European; Central European (Windows) */
+    {1251, "windows-1251"}, /* ANSI Cyrillic; Cyrillic (Windows) */
+    {1252, "windows-1252"}, /* ANSI Latin 1; Western European (Windows) */
+    {1253, "windows-1253"}, /* ANSI Greek; Greek (Windows) */
+    {1254, "windows-1254"}, /* ANSI Turkish; Turkish (Windows) */
+    {1255, "windows-1255"}, /* ANSI Hebrew; Hebrew (Windows) */
+    {1256, "windows-1256"}, /* ANSI Arabic; Arabic (Windows) */
+    {1257, "windows-1257"}, /* ANSI Baltic; Baltic (Windows) */
+    {1258, "windows-1258"}, /* ANSI/OEM Vietnamese; Vietnamese (Windows) */
+    {1361, "Johab"}, /* Korean (Johab) */
+    {10000, "macintosh"}, /* MAC Roman; Western European (Mac) */
+    {10001, "x-mac-japanese"}, /* Japanese (Mac) */
+    {10002, "x-mac-chinesetrad"}, /* MAC Traditional Chinese (Big5); Chinese Traditional (Mac) */
+    {10003, "x-mac-korean"}, /* Korean (Mac) */
+    {10004, "x-mac-arabic"}, /* Arabic (Mac) */
+    {10005, "x-mac-hebrew"}, /* Hebrew (Mac) */
+    {10006, "x-mac-greek"}, /* Greek (Mac) */
+    {10007, "x-mac-cyrillic"}, /* Cyrillic (Mac) */
+    {10008, "x-mac-chinesesimp"}, /* MAC Simplified Chinese (GB 2312); Chinese Simplified (Mac) */
+    {10010, "x-mac-romanian"}, /* Romanian (Mac) */
+    {10017, "x-mac-ukrainian"}, /* Ukrainian (Mac) */
+    {10021, "x-mac-thai"}, /* Thai (Mac) */
+    {10029, "x-mac-ce"}, /* MAC Latin 2; Central European (Mac) */
+    {10079, "x-mac-icelandic"}, /* Icelandic (Mac) */
+    {10081, "x-mac-turkish"}, /* Turkish (Mac) */
+    {10082, "x-mac-croatian"}, /* Croatian (Mac) */
+    {20000, "x-Chinese_CNS"}, /* CNS Taiwan; Chinese Traditional (CNS) */
+    {20001, "x-cp20001"}, /* TCA Taiwan */
+    {20002, "x_Chinese-Eten"}, /* Eten Taiwan; Chinese Traditional (Eten) */
+    {20003, "x-cp20003"}, /* IBM5550 Taiwan */
+    {20004, "x-cp20004"}, /* TeleText Taiwan */
+    {20005, "x-cp20005"}, /* Wang Taiwan */
+    {20105, "x-IA5"}, /* IA5 (IRV International Alphabet No. 5, 7-bit); Western European (IA5) */
+    {20106, "x-IA5-German"}, /* IA5 German (7-bit) */
+    {20107, "x-IA5-Swedish"}, /* IA5 Swedish (7-bit) */
+    {20108, "x-IA5-Norwegian"}, /* IA5 Norwegian (7-bit) */
+    {20127, "us-ascii"}, /* US-ASCII (7-bit) */
+    {20261, "x-cp20261"}, /* T.61 */
+    {20269, "x-cp20269"}, /* ISO 6937 Non-Spacing Accent */
+    {20273, "IBM273"}, /* IBM EBCDIC Germany */
+    {20277, "IBM277"}, /* IBM EBCDIC Denmark-Norway */
+    {20278, "IBM278"}, /* IBM EBCDIC Finland-Sweden */
+    {20280, "IBM280"}, /* IBM EBCDIC Italy */
+    {20284, "IBM284"}, /* IBM EBCDIC Latin America-Spain */
+    {20285, "IBM285"}, /* IBM EBCDIC United Kingdom */
+    {20290, "IBM290"}, /* IBM EBCDIC Japanese Katakana Extended */
+    {20297, "IBM297"}, /* IBM EBCDIC France */
+    {20420, "IBM420"}, /* IBM EBCDIC Arabic */
+    {20423, "IBM423"}, /* IBM EBCDIC Greek */
+    {20424, "IBM424"}, /* IBM EBCDIC Hebrew */
+    {20833, "x-EBCDIC-KoreanExtended"}, /* IBM EBCDIC Korean Extended */
+    {20838, "IBM-Thai"}, /* IBM EBCDIC Thai */
+    {20866, "koi8-r"}, /* Russian (KOI8-R); Cyrillic (KOI8-R) */
+    {20871, "IBM871"}, /* IBM EBCDIC Icelandic */
+    {20880, "IBM880"}, /* IBM EBCDIC Cyrillic Russian */
+    {20905, "IBM905"}, /* IBM EBCDIC Turkish */
+    {20924, "IBM00924"}, /* IBM EBCDIC Latin 1/Open System (1047 + Euro symbol) */
+    {20932, "EUC-JP"}, /* Japanese (JIS 0208-1990 and 0121-1990) */
+    {20936, "x-cp20936"}, /* Simplified Chinese (GB2312); Chinese Simplified (GB2312-80) */
+    {20949, "x-cp20949"}, /* Korean Wansung */
+    {21025, "cp1025"}, /* IBM EBCDIC Cyrillic Serbian-Bulgarian */
+    /* 21027           (deprecated) */
+    {21866, "koi8-u"}, /* Ukrainian (KOI8-U); Cyrillic (KOI8-U) */
+    {28591, "iso-8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */
+    {28591, "iso8859-1"}, /* ISO 8859-1 Latin 1; Western European (ISO) */
+    {28592, "iso-8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */
+    {28592, "iso8859-2"}, /* ISO 8859-2 Central European; Central European (ISO) */
+    {28593, "iso-8859-3"}, /* ISO 8859-3 Latin 3 */
+    {28593, "iso8859-3"}, /* ISO 8859-3 Latin 3 */
+    {28594, "iso-8859-4"}, /* ISO 8859-4 Baltic */
+    {28594, "iso8859-4"}, /* ISO 8859-4 Baltic */
+    {28595, "iso-8859-5"}, /* ISO 8859-5 Cyrillic */
+    {28595, "iso8859-5"}, /* ISO 8859-5 Cyrillic */
+    {28596, "iso-8859-6"}, /* ISO 8859-6 Arabic */
+    {28596, "iso8859-6"}, /* ISO 8859-6 Arabic */
+    {28597, "iso-8859-7"}, /* ISO 8859-7 Greek */
+    {28597, "iso8859-7"}, /* ISO 8859-7 Greek */
+    {28598, "iso-8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */
+    {28598, "iso8859-8"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Visual) */
+    {28599, "iso-8859-9"}, /* ISO 8859-9 Turkish */
+    {28599, "iso8859-9"}, /* ISO 8859-9 Turkish */
+    {28603, "iso-8859-13"}, /* ISO 8859-13 Estonian */
+    {28603, "iso8859-13"}, /* ISO 8859-13 Estonian */
+    {28605, "iso-8859-15"}, /* ISO 8859-15 Latin 9 */
+    {28605, "iso8859-15"}, /* ISO 8859-15 Latin 9 */
+    {29001, "x-Europa"}, /* Europa 3 */
+    {38598, "iso-8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */
+    {38598, "iso8859-8-i"}, /* ISO 8859-8 Hebrew; Hebrew (ISO-Logical) */
+    {50220, "iso-2022-jp"}, /* ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS) */
+    {50221, "csISO2022JP"}, /* ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow 1 byte Kana) */
+    {50222, "iso-2022-jp"}, /* ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte Kana - SO/SI) */
+    {50225, "iso-2022-kr"}, /* ISO 2022 Korean */
+    {50225, "iso2022-kr"}, /* ISO 2022 Korean */
+    {50227, "x-cp50227"}, /* ISO 2022 Simplified Chinese; Chinese Simplified (ISO 2022) */
+    /* 50229           ISO 2022 Traditional Chinese */
+    /* 50930           EBCDIC Japanese (Katakana) Extended */
+    /* 50931           EBCDIC US-Canada and Japanese */
+    /* 50933           EBCDIC Korean Extended and Korean */
+    /* 50935           EBCDIC Simplified Chinese Extended and Simplified Chinese */
+    /* 50936           EBCDIC Simplified Chinese */
+    /* 50937           EBCDIC US-Canada and Traditional Chinese */
+    /* 50939           EBCDIC Japanese (Latin) Extended and Japanese */
+    {51932, "euc-jp"}, /* EUC Japanese */
+    {51936, "EUC-CN"}, /* EUC Simplified Chinese; Chinese Simplified (EUC) */
+    {51949, "euc-kr"}, /* EUC Korean */
+    /* 51950           EUC Traditional Chinese */
+    {52936, "hz-gb-2312"}, /* HZ-GB2312 Simplified Chinese; Chinese Simplified (HZ) */
+    {54936, "GB18030"}, /* Windows XP and later: GB18030 Simplified Chinese (4 byte); Chinese Simplified (GB18030) */
+    {57002, "x-iscii-de"}, /* ISCII Devanagari */
+    {57003, "x-iscii-be"}, /* ISCII Bengali */
+    {57004, "x-iscii-ta"}, /* ISCII Tamil */
+    {57005, "x-iscii-te"}, /* ISCII Telugu */
+    {57006, "x-iscii-as"}, /* ISCII Assamese */
+    {57007, "x-iscii-or"}, /* ISCII Oriya */
+    {57008, "x-iscii-ka"}, /* ISCII Kannada */
+    {57009, "x-iscii-ma"}, /* ISCII Malayalam */
+    {57010, "x-iscii-gu"}, /* ISCII Gujarati */
+    {57011, "x-iscii-pa"}, /* ISCII Punjabi */
+
+    {0, NULL}
+};
+
+/*
+ * SJIS SHIFTJIS table              CP932 table
+ * ---- --------------------------- --------------------------------
+ *   5C U+00A5 YEN SIGN             U+005C REVERSE SOLIDUS
+ *   7E U+203E OVERLINE             U+007E TILDE
+ * 815C U+2014 EM DASH              U+2015 HORIZONTAL BAR
+ * 815F U+005C REVERSE SOLIDUS      U+FF3C FULLWIDTH REVERSE SOLIDUS
+ * 8160 U+301C WAVE DASH            U+FF5E FULLWIDTH TILDE
+ * 8161 U+2016 DOUBLE VERTICAL LINE U+2225 PARALLEL TO
+ * 817C U+2212 MINUS SIGN           U+FF0D FULLWIDTH HYPHEN-MINUS
+ * 8191 U+00A2 CENT SIGN            U+FFE0 FULLWIDTH CENT SIGN
+ * 8192 U+00A3 POUND SIGN           U+FFE1 FULLWIDTH POUND SIGN
+ * 81CA U+00AC NOT SIGN             U+FFE2 FULLWIDTH NOT SIGN
+ *
+ * EUC-JP and ISO-2022-JP should be compatible with CP932.
+ *
+ * Kernel and MLang have different Unicode mapping table.  Make sure
+ * which API is used.
+ */
+static compat_t cp932_compat[] = {
+    {0x00A5, 0x005C, COMPAT_OUT},
+    {0x203E, 0x007E, COMPAT_OUT},
+    {0x2014, 0x2015, COMPAT_OUT},
+    {0x301C, 0xFF5E, COMPAT_OUT},
+    {0x2016, 0x2225, COMPAT_OUT},
+    {0x2212, 0xFF0D, COMPAT_OUT},
+    {0x00A2, 0xFFE0, COMPAT_OUT},
+    {0x00A3, 0xFFE1, COMPAT_OUT},
+    {0x00AC, 0xFFE2, COMPAT_OUT},
+    {0, 0, 0}
+};
+
+static compat_t cp20932_compat[] = {
+    {0x00A5, 0x005C, COMPAT_OUT},
+    {0x203E, 0x007E, COMPAT_OUT},
+    {0x2014, 0x2015, COMPAT_OUT},
+    {0xFF5E, 0x301C, COMPAT_OUT|COMPAT_IN},
+    {0x2225, 0x2016, COMPAT_OUT|COMPAT_IN},
+    {0xFF0D, 0x2212, COMPAT_OUT|COMPAT_IN},
+    {0xFFE0, 0x00A2, COMPAT_OUT|COMPAT_IN},
+    {0xFFE1, 0x00A3, COMPAT_OUT|COMPAT_IN},
+    {0xFFE2, 0x00AC, COMPAT_OUT|COMPAT_IN},
+    {0, 0, 0}
+};
+
+static compat_t *cp51932_compat = cp932_compat;
+
+/* cp20932_compat for kernel.  cp932_compat for mlang. */
+static compat_t *cp5022x_compat = cp932_compat;
+
+typedef HRESULT (WINAPI *CONVERTINETSTRING)(
+    LPDWORD lpdwMode,
+    DWORD dwSrcEncoding,
+    DWORD dwDstEncoding,
+    LPCSTR lpSrcStr,
+    LPINT lpnSrcSize,
+    LPBYTE lpDstStr,
+    LPINT lpnDstSize
+);
+typedef HRESULT (WINAPI *CONVERTINETMULTIBYTETOUNICODE)(
+    LPDWORD lpdwMode,
+    DWORD dwSrcEncoding,
+    LPCSTR lpSrcStr,
+    LPINT lpnMultiCharCount,
+    LPWSTR lpDstStr,
+    LPINT lpnWideCharCount
+);
+typedef HRESULT (WINAPI *CONVERTINETUNICODETOMULTIBYTE)(
+    LPDWORD lpdwMode,
+    DWORD dwEncoding,
+    LPCWSTR lpSrcStr,
+    LPINT lpnWideCharCount,
+    LPSTR lpDstStr,
+    LPINT lpnMultiCharCount
+);
+typedef HRESULT (WINAPI *ISCONVERTINETSTRINGAVAILABLE)(
+    DWORD dwSrcEncoding,
+    DWORD dwDstEncoding
+);
+typedef HRESULT (WINAPI *LCIDTORFC1766A)(
+    LCID Locale,
+    LPSTR pszRfc1766,
+    int nChar
+);
+typedef HRESULT (WINAPI *LCIDTORFC1766W)(
+    LCID Locale,
+    LPWSTR pszRfc1766,
+    int nChar
+);
+typedef HRESULT (WINAPI *RFC1766TOLCIDA)(
+    LCID *pLocale,
+    LPSTR pszRfc1766
+);
+typedef HRESULT (WINAPI *RFC1766TOLCIDW)(
+    LCID *pLocale,
+    LPWSTR pszRfc1766
+);
+static CONVERTINETSTRING ConvertINetString;
+static CONVERTINETMULTIBYTETOUNICODE ConvertINetMultiByteToUnicode;
+static CONVERTINETUNICODETOMULTIBYTE ConvertINetUnicodeToMultiByte;
+static ISCONVERTINETSTRINGAVAILABLE IsConvertINetStringAvailable;
+static LCIDTORFC1766A LcidToRfc1766A;
+static RFC1766TOLCIDA Rfc1766ToLcidA;
+
+static int
+load_mlang()
+{
+    HMODULE h = NULL;
+    char mlang_dll[MAX_PATH + 100];
+    int n;
+    if (ConvertINetString != NULL)
+        return TRUE;
+    n = GetSystemDirectory(mlang_dll, MAX_PATH);
+    if (n > 0 && n < MAX_PATH)
+    {
+        if (mlang_dll[n-1] != '\\' &&
+            mlang_dll[n-1] != '/')
+            strcat(mlang_dll, "\\");
+        strcat(mlang_dll, "mlang.dll");
+        h = LoadLibrary(mlang_dll);
+    }
+    if (!h)
+        return FALSE;
+    ConvertINetString = (CONVERTINETSTRING)GetProcAddress(h, "ConvertINetString");
+    ConvertINetMultiByteToUnicode = (CONVERTINETMULTIBYTETOUNICODE)GetProcAddress(h, "ConvertINetMultiByteToUnicode");
+    ConvertINetUnicodeToMultiByte = (CONVERTINETUNICODETOMULTIBYTE)GetProcAddress(h, "ConvertINetUnicodeToMultiByte");
+    IsConvertINetStringAvailable = (ISCONVERTINETSTRINGAVAILABLE)GetProcAddress(h, "IsConvertINetStringAvailable");
+    LcidToRfc1766A = (LCIDTORFC1766A)GetProcAddress(h, "LcidToRfc1766A");
+    Rfc1766ToLcidA = (RFC1766TOLCIDA)GetProcAddress(h, "Rfc1766ToLcidA");
+    return TRUE;
+}
+
+iconv_t
+iconv_open(const char *tocode, const char *fromcode)
+{
+    rec_iconv_t *cd;
+
+    cd = (rec_iconv_t *)calloc(1, sizeof(rec_iconv_t));
+    if (cd == NULL)
+    {
+        errno = ENOMEM;
+        return (iconv_t)(-1);
+    }
+
+#if defined(USE_LIBICONV_DLL)
+    if (libiconv_iconv_open(cd, tocode, fromcode))
+        return (iconv_t)cd;
+#endif
+
+    if (win_iconv_open(cd, tocode, fromcode))
+        return (iconv_t)cd;
+
+    free(cd);
+    errno = EINVAL;
+    return (iconv_t)(-1);
+}
+
+int
+iconv_close(iconv_t _cd)
+{
+    rec_iconv_t *cd = (rec_iconv_t *)_cd;
+    int r = cd->iconv_close(cd->cd);
+    int e = *(cd->_errno());
+#if defined(USE_LIBICONV_DLL)
+    if (cd->hlibiconv != NULL)
+        FreeLibrary(cd->hlibiconv);
+#endif
+    free(cd);
+    errno = e;
+    return r;
+}
+
+size_t
+iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
+{
+    rec_iconv_t *cd = (rec_iconv_t *)_cd;
+    size_t r = cd->iconv(cd->cd, inbuf, inbytesleft, outbuf, outbytesleft);
+    errno = *(cd->_errno());
+    return r;
+}
+
+static int
+win_iconv_open(rec_iconv_t *cd, const char *tocode, const char *fromcode)
+{
+    cd->from = make_csconv(fromcode);
+    cd->to = make_csconv(tocode);
+    if (cd->from.codepage == -1 || cd->to.codepage == -1)
+        return FALSE;
+    cd->iconv_close = win_iconv_close;
+    cd->iconv = win_iconv;
+    cd->_errno = _errno;
+    cd->cd = (iconv_t)cd;
+    return TRUE;
+}
+
+static int
+win_iconv_close(iconv_t cd)
+{
+    return 0;
+}
+
+static size_t
+win_iconv(iconv_t _cd, const char **inbuf, size_t *inbytesleft, char **outbuf, size_t *outbytesleft)
+{
+    rec_iconv_t *cd = (rec_iconv_t *)_cd;
+    ushort wbuf[MB_CHAR_MAX]; /* enough room for one character */
+    int insize;
+    int outsize;
+    int wsize;
+    DWORD mode;
+    uint wc;
+    compat_t *cp;
+    int i;
+
+    if (inbuf == NULL || *inbuf == NULL)
+    {
+        if (outbuf != NULL && *outbuf != NULL && cd->to.flush != NULL)
+        {
+            outsize = cd->to.flush(&cd->to, (uchar *)*outbuf, *outbytesleft);
+            if (outsize == -1)
+                return (size_t)(-1);
+            *outbuf += outsize;
+            *outbytesleft -= outsize;
+        }
+        if (is_unicode(cd->from.codepage) && (cd->from.mode & UNICODE_MODE_SWAPPED))
+            cd->from.codepage ^= 1;
+        cd->from.mode = 0;
+        cd->to.mode = 0;
+        return 0;
+    }
+
+    while (*inbytesleft != 0)
+    {
+        mode = cd->from.mode;
+        wsize = MB_CHAR_MAX;
+
+        insize = cd->from.mbtowc(&cd->from, (const uchar *)*inbuf, *inbytesleft, wbuf, &wsize);
+        if (insize == -1)
+            return (size_t)(-1);
+
+        if (is_unicode(cd->from.codepage) && !(cd->from.mode & UNICODE_MODE_BOM_DONE))
+        {
+            check_utf_bom(cd, wbuf, &wsize);
+            cd->from.mode |= UNICODE_MODE_BOM_DONE;
+        }
+
+        if (wsize == 0)
+        {
+            *inbuf += insize;
+            *inbytesleft -= insize;
+            continue;
+        }
+
+        if (cd->from.compat != NULL)
+        {
+            wc = utf16_to_ucs4(wbuf);
+            cp = cd->from.compat;
+            for (i = 0; cp[i].in != 0; ++i)
+            {
+                if ((cp[i].flag & COMPAT_IN) && cp[i].out == wc)
+                {
+                    ucs4_to_utf16(cp[i].in, wbuf, &wsize);
+                    break;
+                }
+            }
+        }
+
+        if (cd->to.compat != NULL)
+        {
+            wc = utf16_to_ucs4(wbuf);
+            cp = cd->to.compat;
+            for (i = 0; cp[i].in != 0; ++i)
+            {
+                if ((cp[i].flag & COMPAT_OUT) && cp[i].in == wc)
+                {
+                    ucs4_to_utf16(cp[i].out, wbuf, &wsize);
+                    break;
+                }
+            }
+        }
+
+        outsize = cd->to.wctomb(&cd->to, wbuf, wsize, (uchar *)*outbuf, *outbytesleft);
+        if (outsize == -1)
+        {
+            cd->from.mode = mode;
+            return (size_t)(-1);
+        }
+
+        *inbuf += insize;
+        *outbuf += outsize;
+        *inbytesleft -= insize;
+        *outbytesleft -= outsize;
+    }
+
+    return 0;
+}
+
+static csconv_t
+make_csconv(const char *_name)
+{
+    CPINFOEX cpinfoex;
+    csconv_t cv;
+    int use_compat = TRUE;
+    int flag = 0;
+    char name[128];
+    char *p;
+
+    xstrlcpy(name, _name, sizeof(name));
+
+    /* check for option "enc_name//opt1//opt2" */
+    while ((p = strrstr(name, "//")) != NULL)
+    {
+        if (_stricmp(p + 2, "nocompat") == 0)
+            use_compat = FALSE;
+        else if (_stricmp(p + 2, "translit") == 0)
+            flag |= FLAG_TRANSLIT;
+        else if (_stricmp(p + 2, "ignore") == 0)
+            flag |= FLAG_IGNORE;
+        *p = 0;
+    }
+
+    cv.mode = 0;
+    cv.flags = flag;
+    cv.mblen = NULL;
+    cv.flush = NULL;
+    cv.compat = NULL;
+    cv.codepage = name_to_codepage(name);
+    if (cv.codepage == 1200 || cv.codepage == 1201)
+    {
+        cv.mbtowc = utf16_mbtowc;
+        cv.wctomb = utf16_wctomb;
+        if (_stricmp(name, "UTF-16") == 0 ||
+           _stricmp(name, "UTF16") == 0 ||
+           _stricmp(name, "UCS-2") == 0 ||
+           _stricmp(name, "UCS2") == 0)
+            cv.flags |= FLAG_USE_BOM_ENDIAN;
+    }
+    else if (cv.codepage == 12000 || cv.codepage == 12001)
+    {
+        cv.mbtowc = utf32_mbtowc;
+        cv.wctomb = utf32_wctomb;
+        if (_stricmp(name, "UTF-32") == 0 ||
+           _stricmp(name, "UTF32") == 0 ||
+           _stricmp(name, "UCS-4") == 0 ||
+           _stricmp(name, "UCS4") == 0)
+            cv.flags |= FLAG_USE_BOM_ENDIAN;
+    }
+    else if (cv.codepage == 65001)
+    {
+        cv.mbtowc = kernel_mbtowc;
+        cv.wctomb = kernel_wctomb;
+        cv.mblen = utf8_mblen;
+    }
+    else if ((cv.codepage == 50220 || cv.codepage == 50221 || cv.codepage == 50222) && load_mlang())
+    {
+        cv.mbtowc = iso2022jp_mbtowc;
+        cv.wctomb = iso2022jp_wctomb;
+        cv.flush = iso2022jp_flush;
+    }
+    else if (cv.codepage == 51932 && load_mlang())
+    {
+        cv.mbtowc = mlang_mbtowc;
+        cv.wctomb = mlang_wctomb;
+        cv.mblen = eucjp_mblen;
+    }
+    else if (IsValidCodePage(cv.codepage)
+            && GetCPInfoEx(cv.codepage, 0, &cpinfoex) != 0)
+    {
+        cv.mbtowc = kernel_mbtowc;
+        cv.wctomb = kernel_wctomb;
+        if (cpinfoex.MaxCharSize == 1)
+            cv.mblen = sbcs_mblen;
+        else if (cpinfoex.MaxCharSize == 2)
+            cv.mblen = dbcs_mblen;
+       else
+           cv.mblen = mbcs_mblen;
+    }
+    else
+    {
+        /* not supported */
+        cv.codepage = -1;
+    }
+    if (use_compat)
+    {
+        switch (cv.codepage)
+        {
+        case 932: cv.compat = cp932_compat; break;
+        case 20932: cv.compat = cp20932_compat; break;
+        case 51932: cv.compat = cp51932_compat; break;
+        case 50220: case 50221: case 50222: cv.compat = cp5022x_compat; break;
+        }
+    }
+    return cv;
+}
+
+static int
+name_to_codepage(const char *name)
+{
+    int i;
+
+    if (*name == '\0' ||
+       strcmp(name, "char") == 0)
+        return GetACP();
+    else if (strcmp(name, "wchar_t") == 0)
+        return 1200;
+    else if (_strnicmp(name, "cp", 2) == 0)
+        return atoi(name + 2); /* CP123 */
+    else if ('0' <= name[0] && name[0] <= '9')
+        return atoi(name);     /* 123 */
+    else if (_strnicmp(name, "xx", 2) == 0)
+        return atoi(name + 2); /* XX123 for debug */
+
+    for (i = 0; codepage_alias[i].name != NULL; ++i)
+        if (_stricmp(name, codepage_alias[i].name) == 0)
+            return codepage_alias[i].codepage;
+    return -1;
+}
+
+/*
+ * http://www.faqs.org/rfcs/rfc2781.html
+ */
+static uint
+utf16_to_ucs4(const ushort *wbuf)
+{
+    uint wc = wbuf[0];
+    if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)
+        wc = ((wbuf[0] & 0x3FF) << 10) + (wbuf[1] & 0x3FF) + 0x10000;
+    return wc;
+}
+
+static void
+ucs4_to_utf16(uint wc, ushort *wbuf, int *wbufsize)
+{
+    if (wc < 0x10000)
+    {
+        wbuf[0] = wc;
+        *wbufsize = 1;
+    }
+    else
+    {
+        wc -= 0x10000;
+        wbuf[0] = 0xD800 | ((wc >> 10) & 0x3FF);
+        wbuf[1] = 0xDC00 | (wc & 0x3FF);
+        *wbufsize = 2;
+    }
+}
+
+static int
+is_unicode(int codepage)
+{
+    return (codepage == 1200 || codepage == 1201 ||
+            codepage == 12000 || codepage == 12001 ||
+            codepage == 65000 || codepage == 65001);
+}
+
+/*
+ * Check if codepage is one of those for which the dwFlags parameter
+ * to MultiByteToWideChar() must be zero. Return zero or
+ * MB_ERR_INVALID_CHARS.  The docs in Platform SDK for for Windows
+ * Server 2003 R2 claims that also codepage 65001 is one of these, but
+ * that doesn't seem to be the case. The MSDN docs for MSVS2008 leave
+ * out 65001 (UTF-8), and that indeed seems to be the case on XP, it
+ * works fine to pass MB_ERR_INVALID_CHARS in dwFlags when converting
+ * from UTF-8.
+ */
+static int
+mbtowc_flags(int codepage)
+{
+    return (codepage == 50220 || codepage == 50221 ||
+           codepage == 50222 || codepage == 50225 ||
+           codepage == 50227 || codepage == 50229 ||
+           codepage == 52936 || codepage == 54936 ||
+           (codepage >= 57002 && codepage <= 57011) ||
+           codepage == 65000 || codepage == 42) ? 0 : MB_ERR_INVALID_CHARS;
+}
+
+/*
+ * Check if codepage is one those for which the lpUsedDefaultChar
+ * parameter to WideCharToMultiByte() must be NULL.  The docs in
+ * Platform SDK for for Windows Server 2003 R2 claims that this is the
+ * list below, while the MSDN docs for MSVS2008 claim that it is only
+ * for 65000 (UTF-7) and 65001 (UTF-8). This time the earlier Platform
+ * SDK seems to be correct, at least for XP.
+ */
+static int
+must_use_null_useddefaultchar(int codepage)
+{
+    return (codepage == 65000 || codepage == 65001 ||
+            codepage == 50220 || codepage == 50221 ||
+            codepage == 50222 || codepage == 50225 ||
+            codepage == 50227 || codepage == 50229 ||
+            codepage == 52936 || codepage == 54936 ||
+            (codepage >= 57002 && codepage <= 57011) ||
+            codepage == 42);
+}
+
+static void
+check_utf_bom(rec_iconv_t *cd, ushort *wbuf, int *wbufsize)
+{
+    /* If we have a BOM, trust it, despite what the caller said */
+    if (wbuf[0] == 0xFFFE && (cd->from.flags & FLAG_USE_BOM_ENDIAN))
+    {
+        /* swap endian: 1200 <-> 1201 or 12000 <-> 12001 */
+        cd->from.codepage ^= 1;
+        cd->from.mode |= UNICODE_MODE_SWAPPED;
+        wbuf[0] = 0xFEFF;
+    }
+
+    /*
+     * Remove BOM.
+     * Don't do this if "to" is Unicode,
+     * except if "to" is UTF-8.
+     */
+    if (wbuf[0] == 0xFEFF && (!is_unicode(cd->to.codepage) || cd->to.codepage == 65001))
+        *wbufsize = 0;
+}
+
+static char *
+strrstr(const char *str, const char *token)
+{
+    int len = strlen(token);
+    const char *p = str + strlen(str);
+
+    while (str <= --p)
+        if (p[0] == token[0] && strncmp(p, token, len) == 0)
+            return (char *)p;
+    return NULL;
+}
+
+#if defined(USE_LIBICONV_DLL)
+static int
+libiconv_iconv_open(rec_iconv_t *cd, const char *fromcode, const char *tocode)
+{
+    HMODULE hlibiconv = NULL;
+    HMODULE hmsvcrt = NULL;
+    char dllname[_MAX_PATH];
+    const char *p;
+    const char *e;
+    f_iconv_open _iconv_open;
+
+    /*
+     * always try to load dll, so that we can switch dll in runtime.
+     */
+
+    /* XXX: getenv() can't get variable set by SetEnvironmentVariable() */
+    p = getenv("WINICONV_LIBICONV_DLL");
+    if (p == NULL)
+        p = DEFAULT_LIBICONV_DLL;
+    /* parse comma separated value */
+    for ( ; *p != 0; p = (*e == ',') ? e + 1 : e)
+    {
+        e = strchr(p, ',');
+        if (p == e)
+            continue;
+        else if (e == NULL)
+            e = p + strlen(p);
+        xstrlcpyn(dllname, p, e - p, sizeof(dllname));
+        hlibiconv = LoadLibrary(dllname);
+        if (hlibiconv != NULL)
+        {
+            if (hlibiconv == hwiniconv)
+            {
+                FreeLibrary(hlibiconv);
+                hlibiconv = NULL;
+                continue;
+            }
+            break;
+        }
+    }
+
+    if (hlastdll != NULL)
+    {
+        /* decrement reference count */
+        FreeLibrary(hlastdll);
+        hlastdll = NULL;
+    }
+
+    if (hlibiconv == NULL)
+        goto failed;
+
+    hmsvcrt = find_imported_module_by_funcname(hlibiconv, "_errno");
+    if (hmsvcrt == NULL)
+        goto failed;
+
+    _iconv_open = (f_iconv_open)GetProcAddress(hlibiconv, "libiconv_open");
+    if (_iconv_open == NULL)
+        _iconv_open = (f_iconv_open)GetProcAddress(hlibiconv, "iconv_open");
+    cd->iconv_close = (f_iconv_close)GetProcAddress(hlibiconv, "libiconv_close");
+    if (cd->iconv_close == NULL)
+        cd->iconv_close = (f_iconv_close)GetProcAddress(hlibiconv, "iconv_close");
+    cd->iconv = (f_iconv)GetProcAddress(hlibiconv, "libiconv");
+    if (cd->iconv == NULL)
+        cd->iconv = (f_iconv)GetProcAddress(hlibiconv, "iconv");
+    cd->_errno = (f_errno)GetProcAddress(hmsvcrt, "_errno");
+    if (_iconv_open == NULL || cd->iconv_close == NULL
+            || cd->iconv == NULL || cd->_errno == NULL)
+        goto failed;
+
+    /* increment reference count */
+    hlastdll = LoadLibrary(dllname);
+
+    cd->cd = _iconv_open(tocode, fromcode);
+    if (cd->cd == (iconv_t)(-1))
+        goto failed;
+
+    cd->hlibiconv = hlibiconv;
+    return TRUE;
+
+failed:
+    if (hlibiconv != NULL)
+        FreeLibrary(hlibiconv);
+    /* do not free hmsvcrt which is obtained by GetModuleHandle() */
+    return FALSE;
+}
+
+/*
+ * Reference:
+ * http://forums.belution.com/ja/vc/000/234/78s.shtml
+ * http://nienie.com/~masapico/api_ImageDirectoryEntryToData.html
+ *
+ * The formal way is
+ *   imagehlp.h or dbghelp.h
+ *   imagehlp.lib or dbghelp.lib
+ *   ImageDirectoryEntryToData()
+ */
+#define TO_DOS_HEADER(base) ((PIMAGE_DOS_HEADER)(base))
+#define TO_NT_HEADERS(base) ((PIMAGE_NT_HEADERS)((LPBYTE)(base) + TO_DOS_HEADER(base)->e_lfanew))
+static PVOID
+MyImageDirectoryEntryToData(LPVOID Base, BOOLEAN MappedAsImage, USHORT DirectoryEntry, PULONG Size)
+{
+    /* TODO: MappedAsImage? */
+    PIMAGE_DATA_DIRECTORY p;
+    p = TO_NT_HEADERS(Base)->OptionalHeader.DataDirectory + DirectoryEntry;
+    if (p->VirtualAddress == 0) {
+      *Size = 0;
+      return NULL;
+    }
+    *Size = p->Size;
+    return (PVOID)((LPBYTE)Base + p->VirtualAddress);
+}
+
+static HMODULE
+find_imported_module_by_funcname(HMODULE hModule, const char *funcname)
+{
+    DWORD Base;
+    ULONG Size;
+    PIMAGE_IMPORT_DESCRIPTOR Imp;
+    PIMAGE_THUNK_DATA Name;         /* Import Name Table */
+    PIMAGE_IMPORT_BY_NAME ImpName;
+
+    Base = (DWORD)hModule;
+    Imp = MyImageDirectoryEntryToData(
+            (LPVOID)Base,
+            TRUE,
+            IMAGE_DIRECTORY_ENTRY_IMPORT,
+            &Size);
+    if (Imp == NULL)
+        return NULL;
+    for ( ; Imp->OriginalFirstThunk != 0; ++Imp)
+    {
+        Name = (PIMAGE_THUNK_DATA)(Base + Imp->OriginalFirstThunk);
+        for ( ; Name->u1.Ordinal != 0; ++Name)
+        {
+            if (!IMAGE_SNAP_BY_ORDINAL(Name->u1.Ordinal))
+            {
+                ImpName = (PIMAGE_IMPORT_BY_NAME)
+                    (Base + (DWORD)Name->u1.AddressOfData);
+                if (strcmp((char *)ImpName->Name, funcname) == 0)
+                    return GetModuleHandle((char *)(Base + Imp->Name));
+            }
+        }
+    }
+    return NULL;
+}
+#endif
+
+static int
+sbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)
+{
+    return 1;
+}
+
+static int
+dbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)
+{
+    int len = IsDBCSLeadByteEx(cv->codepage, buf[0]) ? 2 : 1;
+    if (bufsize < len)
+        return_error(EINVAL);
+    return len;
+}
+
+static int
+mbcs_mblen(csconv_t *cv, const uchar *buf, int bufsize)
+{
+    int len = 0;
+
+    if (cv->codepage == 54936) {
+       if (buf[0] <= 0x7F) len = 1;
+       else if (buf[0] >= 0x81 && buf[0] <= 0xFE &&
+                bufsize >= 2 &&
+                ((buf[1] >= 0x40 && buf[1] <= 0x7E) ||
+                 (buf[1] >= 0x80 && buf[1] <= 0xFE))) len = 2;
+       else if (buf[0] >= 0x81 && buf[0] <= 0xFE &&
+                bufsize >= 4 &&
+                buf[1] >= 0x30 && buf[1] <= 0x39) len = 4;
+       else
+           return_error(EINVAL);
+       return len;
+    }
+    else
+       return_error(EINVAL);
+}
+
+static int
+utf8_mblen(csconv_t *cv, const uchar *buf, int bufsize)
+{
+    int len = 0;
+
+    if (buf[0] < 0x80) len = 1;
+    else if ((buf[0] & 0xE0) == 0xC0) len = 2;
+    else if ((buf[0] & 0xF0) == 0xE0) len = 3;
+    else if ((buf[0] & 0xF8) == 0xF0) len = 4;
+    else if ((buf[0] & 0xFC) == 0xF8) len = 5;
+    else if ((buf[0] & 0xFE) == 0xFC) len = 6;
+
+    if (len == 0)
+        return_error(EILSEQ);
+    else if (bufsize < len)
+        return_error(EINVAL);
+    return len;
+}
+
+static int
+eucjp_mblen(csconv_t *cv, const uchar *buf, int bufsize)
+{
+    if (buf[0] < 0x80) /* ASCII */
+        return 1;
+    else if (buf[0] == 0x8E) /* JIS X 0201 */
+    {
+        if (bufsize < 2)
+            return_error(EINVAL);
+        else if (!(0xA1 <= buf[1] && buf[1] <= 0xDF))
+            return_error(EILSEQ);
+        return 2;
+    }
+    else if (buf[0] == 0x8F) /* JIS X 0212 */
+    {
+        if (bufsize < 3)
+            return_error(EINVAL);
+        else if (!(0xA1 <= buf[1] && buf[1] <= 0xFE)
+                || !(0xA1 <= buf[2] && buf[2] <= 0xFE))
+            return_error(EILSEQ);
+        return 3;
+    }
+    else /* JIS X 0208 */
+    {
+        if (bufsize < 2)
+            return_error(EINVAL);
+        else if (!(0xA1 <= buf[0] && buf[0] <= 0xFE)
+                || !(0xA1 <= buf[1] && buf[1] <= 0xFE))
+            return_error(EILSEQ);
+        return 2;
+    }
+}
+
+static int
+kernel_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
+{
+    int len;
+
+    len = cv->mblen(cv, buf, bufsize);
+    if (len == -1)
+        return -1;
+    /* If converting from ASCII, reject 8bit
+     * chars. MultiByteToWideChar() doesn't. Note that for ASCII we
+     * know that the mblen function is sbcs_mblen() so len is 1.
+     */
+    if (cv->codepage == 20127 && buf[0] >= 0x80)
+        return_error(EILSEQ);
+    *wbufsize = MultiByteToWideChar(cv->codepage, mbtowc_flags (cv->codepage),
+            (const char *)buf, len, (wchar_t *)wbuf, *wbufsize);
+    if (*wbufsize == 0)
+        return_error(EILSEQ);
+    return len;
+}
+
+static int
+kernel_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
+{
+    BOOL usedDefaultChar = 0;
+    BOOL *p = NULL;
+    int flags = 0;
+    int len;
+
+    if (bufsize == 0)
+        return_error(E2BIG);
+    if (!must_use_null_useddefaultchar(cv->codepage))
+    {
+        p = &usedDefaultChar;
+#ifdef WC_NO_BEST_FIT_CHARS
+        if (!(cv->flags & FLAG_TRANSLIT))
+            flags |= WC_NO_BEST_FIT_CHARS;
+#endif
+    }
+    len = WideCharToMultiByte(cv->codepage, flags,
+            (const wchar_t *)wbuf, wbufsize, (char *)buf, bufsize, NULL, p);
+    if (len == 0)
+    {
+        if (GetLastError() == ERROR_INSUFFICIENT_BUFFER)
+            return_error(E2BIG);
+        return_error(EILSEQ);
+    }
+    else if (usedDefaultChar)
+        return_error(EILSEQ);
+    else if (cv->mblen(cv, buf, len) != len) /* validate result */
+        return_error(EILSEQ);
+    return len;
+}
+
+/*
+ * It seems that the mode (cv->mode) is fixnum.
+ * For example, when converting iso-2022-jp(cp50221) to unicode:
+ *      in ascii sequence: mode=0xC42C0000
+ *   in jisx0208 sequence: mode=0xC42C0001
+ * "C42C" is same for each convert session.
+ * It should be: ((codepage-1)<<16)|state
+ */
+static int
+mlang_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
+{
+    int len;
+    int insize;
+    HRESULT hr;
+
+    len = cv->mblen(cv, buf, bufsize);
+    if (len == -1)
+        return -1;
+    insize = len;
+    hr = ConvertINetMultiByteToUnicode(&cv->mode, cv->codepage,
+            (const char *)buf, &insize, (wchar_t *)wbuf, wbufsize);
+    if (hr != S_OK || insize != len)
+        return_error(EILSEQ);
+    return len;
+}
+
+static int
+mlang_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
+{
+    char tmpbuf[MB_CHAR_MAX]; /* enough room for one character */
+    int tmpsize = MB_CHAR_MAX;
+    int insize = wbufsize;
+    HRESULT hr;
+
+    hr = ConvertINetUnicodeToMultiByte(&cv->mode, cv->codepage,
+            (const wchar_t *)wbuf, &wbufsize, tmpbuf, &tmpsize);
+    if (hr != S_OK || insize != wbufsize)
+        return_error(EILSEQ);
+    else if (bufsize < tmpsize)
+        return_error(E2BIG);
+    else if (cv->mblen(cv, (uchar *)tmpbuf, tmpsize) != tmpsize)
+        return_error(EILSEQ);
+    memcpy(buf, tmpbuf, tmpsize);
+    return tmpsize;
+}
+
+static int
+utf16_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
+{
+    if (bufsize < 2)
+        return_error(EINVAL);
+    if (cv->codepage == 1200) /* little endian */
+        wbuf[0] = (buf[1] << 8) | buf[0];
+    else if (cv->codepage == 1201) /* big endian */
+        wbuf[0] = (buf[0] << 8) | buf[1];
+    if (0xDC00 <= wbuf[0] && wbuf[0] <= 0xDFFF)
+        return_error(EILSEQ);
+    if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)
+    {
+        if (bufsize < 4)
+            return_error(EINVAL);
+        if (cv->codepage == 1200) /* little endian */
+            wbuf[1] = (buf[3] << 8) | buf[2];
+        else if (cv->codepage == 1201) /* big endian */
+            wbuf[1] = (buf[2] << 8) | buf[3];
+        if (!(0xDC00 <= wbuf[1] && wbuf[1] <= 0xDFFF))
+            return_error(EILSEQ);
+        *wbufsize = 2;
+        return 4;
+    }
+    *wbufsize = 1;
+    return 2;
+}
+
+static int
+utf16_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
+{
+    if (bufsize < 2)
+        return_error(E2BIG);
+    if (cv->codepage == 1200) /* little endian */
+    {
+        buf[0] = (wbuf[0] & 0x00FF);
+        buf[1] = (wbuf[0] & 0xFF00) >> 8;
+    }
+    else if (cv->codepage == 1201) /* big endian */
+    {
+        buf[0] = (wbuf[0] & 0xFF00) >> 8;
+        buf[1] = (wbuf[0] & 0x00FF);
+    }
+    if (0xD800 <= wbuf[0] && wbuf[0] <= 0xDBFF)
+    {
+        if (bufsize < 4)
+            return_error(E2BIG);
+        if (cv->codepage == 1200) /* little endian */
+        {
+            buf[2] = (wbuf[1] & 0x00FF);
+            buf[3] = (wbuf[1] & 0xFF00) >> 8;
+        }
+        else if (cv->codepage == 1201) /* big endian */
+        {
+            buf[2] = (wbuf[1] & 0xFF00) >> 8;
+            buf[3] = (wbuf[1] & 0x00FF);
+        }
+        return 4;
+    }
+    return 2;
+}
+
+static int
+utf32_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
+{
+    uint wc;
+
+    if (bufsize < 4)
+        return_error(EINVAL);
+    if (cv->codepage == 12000) /* little endian */
+        wc = (buf[3] << 24) | (buf[2] << 16) | (buf[1] << 8) | buf[0];
+    else if (cv->codepage == 12001) /* big endian */
+        wc = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3];
+    if ((0xD800 <= wc && wc <= 0xDFFF) || 0x10FFFF < wc)
+        return_error(EILSEQ);
+    ucs4_to_utf16(wc, wbuf, wbufsize);
+    return 4;
+}
+
+static int
+utf32_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
+{
+    uint wc;
+
+    if (bufsize < 4)
+        return_error(E2BIG);
+    wc = utf16_to_ucs4(wbuf);
+    if (cv->codepage == 12000) /* little endian */
+    {
+        buf[0] = wc & 0x000000FF;
+        buf[1] = (wc & 0x0000FF00) >> 8;
+        buf[2] = (wc & 0x00FF0000) >> 16;
+        buf[3] = (wc & 0xFF000000) >> 24;
+    }
+    else if (cv->codepage == 12001) /* big endian */
+    {
+        buf[0] = (wc & 0xFF000000) >> 24;
+        buf[1] = (wc & 0x00FF0000) >> 16;
+        buf[2] = (wc & 0x0000FF00) >> 8;
+        buf[3] = wc & 0x000000FF;
+    }
+    return 4;
+}
+
+/*
+ * 50220: ISO 2022 Japanese with no halfwidth Katakana; Japanese (JIS)
+ * 50221: ISO 2022 Japanese with halfwidth Katakana; Japanese (JIS-Allow
+ *        1 byte Kana)
+ * 50222: ISO 2022 Japanese JIS X 0201-1989; Japanese (JIS-Allow 1 byte
+ *        Kana - SO/SI)
+ *
+ * MultiByteToWideChar() and WideCharToMultiByte() behave differently
+ * depending on Windows version.  On XP, WideCharToMultiByte() doesn't
+ * terminate result sequence with ascii escape.  But Vista does.
+ * Use MLang instead.
+ */
+
+#define ISO2022_MODE(cs, shift) (((cs) << 8) | (shift))
+#define ISO2022_MODE_CS(mode) (((mode) >> 8) & 0xFF)
+#define ISO2022_MODE_SHIFT(mode) ((mode) & 0xFF)
+
+#define ISO2022_SI  0
+#define ISO2022_SO  1
+
+/* shift in */
+static const char iso2022_SI_seq[] = "\x0F";
+/* shift out */
+static const char iso2022_SO_seq[] = "\x0E";
+
+typedef struct iso2022_esc_t iso2022_esc_t;
+struct iso2022_esc_t {
+    const char *esc;
+    int esc_len;
+    int len;
+    int cs;
+};
+
+#define ISO2022JP_CS_ASCII            0
+#define ISO2022JP_CS_JISX0201_ROMAN   1
+#define ISO2022JP_CS_JISX0201_KANA    2
+#define ISO2022JP_CS_JISX0208_1978    3
+#define ISO2022JP_CS_JISX0208_1983    4
+#define ISO2022JP_CS_JISX0212         5
+
+static iso2022_esc_t iso2022jp_esc[] = {
+    {"\x1B\x28\x42", 3, 1, ISO2022JP_CS_ASCII},
+    {"\x1B\x28\x4A", 3, 1, ISO2022JP_CS_JISX0201_ROMAN},
+    {"\x1B\x28\x49", 3, 1, ISO2022JP_CS_JISX0201_KANA},
+    {"\x1B\x24\x40", 3, 2, ISO2022JP_CS_JISX0208_1983}, /* unify 1978 with 1983 */
+    {"\x1B\x24\x42", 3, 2, ISO2022JP_CS_JISX0208_1983},
+    {"\x1B\x24\x28\x44", 4, 2, ISO2022JP_CS_JISX0212},
+    {NULL, 0, 0, 0}
+};
+
+static int
+iso2022jp_mbtowc(csconv_t *cv, const uchar *buf, int bufsize, ushort *wbuf, int *wbufsize)
+{
+    iso2022_esc_t *iesc = iso2022jp_esc;
+    char tmp[MB_CHAR_MAX];
+    int insize;
+    HRESULT hr;
+    DWORD dummy = 0;
+    int len;
+    int esc_len;
+    int cs;
+    int shift;
+    int i;
+
+    if (buf[0] == 0x1B)
+    {
+        for (i = 0; iesc[i].esc != NULL; ++i)
+        {
+            esc_len = iesc[i].esc_len;
+            if (bufsize < esc_len)
+            {
+                if (strncmp((char *)buf, iesc[i].esc, bufsize) == 0)
+                    return_error(EINVAL);
+            }
+            else
+            {
+                if (strncmp((char *)buf, iesc[i].esc, esc_len) == 0)
+                {
+                    cv->mode = ISO2022_MODE(iesc[i].cs, ISO2022_SI);
+                    *wbufsize = 0;
+                    return esc_len;
+                }
+            }
+        }
+        /* not supported escape sequence */
+        return_error(EILSEQ);
+    }
+    else if (buf[0] == iso2022_SO_seq[0])
+    {
+        cv->mode = ISO2022_MODE(ISO2022_MODE_CS(cv->mode), ISO2022_SO);
+        *wbufsize = 0;
+        return 1;
+    }
+    else if (buf[0] == iso2022_SI_seq[0])
+    {
+        cv->mode = ISO2022_MODE(ISO2022_MODE_CS(cv->mode), ISO2022_SI);
+        *wbufsize = 0;
+        return 1;
+    }
+
+    cs = ISO2022_MODE_CS(cv->mode);
+    shift = ISO2022_MODE_SHIFT(cv->mode);
+
+    /* reset the mode for informal sequence */
+    if (buf[0] < 0x20)
+    {
+        cs = ISO2022JP_CS_ASCII;
+        shift = ISO2022_SI;
+    }
+
+    len = iesc[cs].len;
+    if (bufsize < len)
+        return_error(EINVAL);
+    for (i = 0; i < len; ++i)
+        if (!(buf[i] < 0x80))
+            return_error(EILSEQ);
+    esc_len = iesc[cs].esc_len;
+    memcpy(tmp, iesc[cs].esc, esc_len);
+    if (shift == ISO2022_SO)
+    {
+        memcpy(tmp + esc_len, iso2022_SO_seq, 1);
+        esc_len += 1;
+    }
+    memcpy(tmp + esc_len, buf, len);
+
+    if ((cv->codepage == 50220 || cv->codepage == 50221
+                || cv->codepage == 50222) && shift == ISO2022_SO)
+    {
+        /* XXX: shift-out cannot be used for mbtowc (both kernel and
+         * mlang) */
+        esc_len = iesc[ISO2022JP_CS_JISX0201_KANA].esc_len;
+        memcpy(tmp, iesc[ISO2022JP_CS_JISX0201_KANA].esc, esc_len);
+        memcpy(tmp + esc_len, buf, len);
+    }
+
+    insize = len + esc_len;
+    hr = ConvertINetMultiByteToUnicode(&dummy, cv->codepage,
+            (const char *)tmp, &insize, (wchar_t *)wbuf, wbufsize);
+    if (hr != S_OK || insize != len + esc_len)
+        return_error(EILSEQ);
+
+    /* Check for conversion error.  Assuming defaultChar is 0x3F. */
+    /* ascii should be converted from ascii */
+    if (wbuf[0] == buf[0]
+            && cv->mode != ISO2022_MODE(ISO2022JP_CS_ASCII, ISO2022_SI))
+        return_error(EILSEQ);
+
+    /* reset the mode for informal sequence */
+    if (cv->mode != ISO2022_MODE(cs, shift))
+        cv->mode = ISO2022_MODE(cs, shift);
+
+    return len;
+}
+
+static int
+iso2022jp_wctomb(csconv_t *cv, ushort *wbuf, int wbufsize, uchar *buf, int bufsize)
+{
+    iso2022_esc_t *iesc = iso2022jp_esc;
+    char tmp[MB_CHAR_MAX];
+    int tmpsize = MB_CHAR_MAX;
+    int insize = wbufsize;
+    HRESULT hr;
+    DWORD dummy = 0;
+    int len;
+    int esc_len;
+    int cs;
+    int shift;
+    int i;
+
+    /*
+     * MultiByte = [escape sequence] + character + [escape sequence]
+     *
+     * Whether trailing escape sequence is added depends on which API is
+     * used (kernel or MLang, and its version).
+     */
+    hr = ConvertINetUnicodeToMultiByte(&dummy, cv->codepage,
+            (const wchar_t *)wbuf, &wbufsize, tmp, &tmpsize);
+    if (hr != S_OK || insize != wbufsize)
+        return_error(EILSEQ);
+    else if (bufsize < tmpsize)
+        return_error(E2BIG);
+
+    if (tmpsize == 1)
+    {
+        cs = ISO2022JP_CS_ASCII;
+        esc_len = 0;
+    }
+    else
+    {
+        for (i = 1; iesc[i].esc != NULL; ++i)
+        {
+            esc_len = iesc[i].esc_len;
+            if (strncmp(tmp, iesc[i].esc, esc_len) == 0)
+            {
+                cs = iesc[i].cs;
+                break;
+            }
+        }
+        if (iesc[i].esc == NULL)
+            /* not supported escape sequence */
+            return_error(EILSEQ);
+    }
+
+    shift = ISO2022_SI;
+    if (tmp[esc_len] == iso2022_SO_seq[0])
+    {
+        shift = ISO2022_SO;
+        esc_len += 1;
+    }
+
+    len = iesc[cs].len;
+
+    /* Check for converting error.  Assuming defaultChar is 0x3F. */
+    /* ascii should be converted from ascii */
+    if (cs == ISO2022JP_CS_ASCII && !(wbuf[0] < 0x80))
+        return_error(EILSEQ);
+    else if (tmpsize < esc_len + len)
+        return_error(EILSEQ);
+
+    if (cv->mode == ISO2022_MODE(cs, shift))
+    {
+        /* remove escape sequence */
+        if (esc_len != 0)
+            memmove(tmp, tmp + esc_len, len);
+        esc_len = 0;
+    }
+    else
+    {
+        if (cs == ISO2022JP_CS_ASCII)
+        {
+            esc_len = iesc[ISO2022JP_CS_ASCII].esc_len;
+            memmove(tmp + esc_len, tmp, len);
+            memcpy(tmp, iesc[ISO2022JP_CS_ASCII].esc, esc_len);
+        }
+        if (ISO2022_MODE_SHIFT(cv->mode) == ISO2022_SO)
+        {
+            /* shift-in before changing to other mode */
+            memmove(tmp + 1, tmp, len + esc_len);
+            memcpy(tmp, iso2022_SI_seq, 1);
+            esc_len += 1;
+        }
+    }
+
+    if (bufsize < len + esc_len)
+        return_error(E2BIG);
+    memcpy(buf, tmp, len + esc_len);
+    cv->mode = ISO2022_MODE(cs, shift);
+    return len + esc_len;
+}
+
+static int
+iso2022jp_flush(csconv_t *cv, uchar *buf, int bufsize)
+{
+    iso2022_esc_t *iesc = iso2022jp_esc;
+    int esc_len;
+
+    if (cv->mode != ISO2022_MODE(ISO2022JP_CS_ASCII, ISO2022_SI))
+    {
+        esc_len = 0;
+        if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI)
+            esc_len += 1;
+        if (ISO2022_MODE_CS(cv->mode) != ISO2022JP_CS_ASCII)
+            esc_len += iesc[ISO2022JP_CS_ASCII].esc_len;
+        if (bufsize < esc_len)
+            return_error(E2BIG);
+
+        esc_len = 0;
+        if (ISO2022_MODE_SHIFT(cv->mode) != ISO2022_SI)
+        {
+            memcpy(buf, iso2022_SI_seq, 1);
+            esc_len += 1;
+        }
+        if (ISO2022_MODE_CS(cv->mode) != ISO2022JP_CS_ASCII)
+        {
+            memcpy(buf + esc_len, iesc[ISO2022JP_CS_ASCII].esc,
+                    iesc[ISO2022JP_CS_ASCII].esc_len);
+            esc_len += iesc[ISO2022JP_CS_ASCII].esc_len;
+        }
+        return esc_len;
+    }
+    return 0;
+}
+
+#if defined(MAKE_DLL) && defined(USE_LIBICONV_DLL)
+BOOL WINAPI
+DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved)
+{
+    switch( fdwReason )
+    {
+    case DLL_PROCESS_ATTACH:
+        hwiniconv = (HMODULE)hinstDLL;
+        break;
+    case DLL_THREAD_ATTACH:
+    case DLL_THREAD_DETACH:
+    case DLL_PROCESS_DETACH:
+        break;
+    }
+    return TRUE;
+}
+#endif
+
+#if defined(MAKE_EXE)
+#include <stdio.h>
+#include <fcntl.h>
+#include <io.h>
+int
+main(int argc, char **argv)
+{
+    char *fromcode = NULL;
+    char *tocode = NULL;
+    int i;
+    char inbuf[BUFSIZ];
+    char outbuf[BUFSIZ];
+    const char *pin;
+    char *pout;
+    size_t inbytesleft;
+    size_t outbytesleft;
+    size_t rest = 0;
+    iconv_t cd;
+    size_t r;
+    FILE *in = stdin;
+
+    _setmode(_fileno(stdin), _O_BINARY);
+    _setmode(_fileno(stdout), _O_BINARY);
+
+    for (i = 1; i < argc; ++i)
+    {
+        if (strcmp(argv[i], "-l") == 0)
+        {
+            for (i = 0; codepage_alias[i].name != NULL; ++i)
+                printf("%s\n", codepage_alias[i].name);
+            return 0;
+        }
+
+        if (strcmp(argv[i], "-f") == 0)
+            fromcode = argv[++i];
+        else if (strcmp(argv[i], "-t") == 0)
+            tocode = argv[++i];
+        else
+        {
+            in = fopen(argv[i], "rb");
+            if (in == NULL)
+            {
+                fprintf(stderr, "cannot open %s\n", argv[i]);
+                return 1;
+            }
+            break;
+        }
+    }
+
+    if (fromcode == NULL || tocode == NULL)
+    {
+        printf("usage: %s -f from-enc -t to-enc [file]\n", argv[0]);
+        return 0;
+    }
+
+    cd = iconv_open(tocode, fromcode);
+    if (cd == (iconv_t)(-1))
+    {
+        perror("iconv_open error");
+        return 1;
+    }
+
+    while ((inbytesleft = fread(inbuf + rest, 1, sizeof(inbuf) - rest, in)) != 0
+            || rest != 0)
+    {
+        inbytesleft += rest;
+        pin = inbuf;
+        pout = outbuf;
+        outbytesleft = sizeof(outbuf);
+        r = iconv(cd, &pin, &inbytesleft, &pout, &outbytesleft);
+        fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, stdout);
+        if (r == (size_t)(-1) && errno != EINVAL && errno != E2BIG)
+        {
+            perror("conversion error");
+            return 1;
+        }
+        memmove(inbuf, pin, inbytesleft);
+        rest = inbytesleft;
+    }
+    pout = outbuf;
+    outbytesleft = sizeof(outbuf);
+    r = iconv(cd, NULL, NULL, &pout, &outbytesleft);
+    fwrite(outbuf, 1, sizeof(outbuf) - outbytesleft, stdout);
+    if (r == (size_t)(-1))
+    {
+        perror("conversion error");
+        return 1;
+    }
+
+    iconv_close(cd);
+
+    return 0;
+}
+#endif
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/.gitignore b/resource/csdk/connectivity/lib/android/glib-master/gthread/.gitignore
new file mode 100644 (file)
index 0000000..8f2ed21
--- /dev/null
@@ -0,0 +1 @@
+makefile.msc
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/Android.mk b/resource/csdk/connectivity/lib/android/glib-master/gthread/Android.mk
new file mode 100644 (file)
index 0000000..12726dd
--- /dev/null
@@ -0,0 +1,29 @@
+LOCAL_PATH:= $(call my-dir)
+
+include $(CLEAR_VARS)
+
+LOCAL_SRC_FILES :=                     \
+       gthread-impl.c
+
+LOCAL_MODULE := libgthread-2.0
+
+LOCAL_C_INCLUDES :=                    \
+       $(LOCAL_PATH)                   \
+       $(GLIB_TOP)/android-internal    \
+       $(GLIB_C_INCLUDES)
+
+LOCAL_CFLAGS :=                                \
+       -DHAVE_CONFIG_H                 \
+    -DG_LOG_DOMAIN=\"GThread\"         \
+    -D_POSIX4_DRAFT_SOURCE             \
+    -D_POSIX4A_DRAFT10_SOURCE          \
+    -U_OSF_SOURCE                      \
+    -DG_DISABLE_DEPRECATED 
+
+ifeq ($(GLIB_BUILD_STATIC),true)
+include $(BUILD_STATIC_LIBRARY)
+else
+LOCAL_SHARED_LIBRARIES := libglib-2.0
+
+include $(BUILD_SHARED_LIBRARY)
+endif
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/ChangeLog b/resource/csdk/connectivity/lib/android/glib-master/gthread/ChangeLog
new file mode 100644 (file)
index 0000000..b833c1e
--- /dev/null
@@ -0,0 +1,837 @@
+=== ChangeLog discontinued ===
+
+       With the move to git, GLib is switching from a ChangeLog file
+       to relying on commit messages to provide change history. Please
+       see README.commits for guidance on the expected message format.
+
+2009-03-13  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.20.0 ===
+
+2009-03-02  Matthias Clasen <mclasen@redhat.com>
+
+       * === Released 2.19.10 ===
+
+2009-03-02  Matthias Clasen <mclasen@redhat.com>
+
+       * === Released 2.19.9 ===
+
+2009-02-17  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.19.8 ===
+
+2009-02-16  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.19.7 ===
+
+2009-02-02  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.19.6 ===
+
+2009-01-19  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.19.5 ===
+
+2009-01-05  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.19.4 ===
+
+2008-12-15  Matthias Clasen <mclasen@redhat.com>
+
+       * === Released 2.19.3 ===
+
+2008-12-01  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.19.2 ===
+
+2008-12-01  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.19.1 ===
+
+2008-10-16  Matthias Clasen <mclasen@redhat.com>
+
+       * === Released 2.19.0 ===
+
+2008-09-17  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.18.1 ===
+
+2008-09-02  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.18.0 ===
+
+2008-08-18  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.17.7 ===
+
+2008-08-04  Matthias Clasen  <mclasen@redhat.com>
+
+       Bug 460920 – build fix for --disable-threads
+
+       * gthread-impl.c: Implement g_thread_init_with_errorcheck_mutexes
+       in the !G_THREAD_ENABLED case. Pointed out by Jan Nieuwenhuizen
+
+2008-08-04  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.17.6 ===
+
+2008-08-04  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.17.5 ===
+
+2008-07-27  Tor Lillqvist  <tml@novell.com>
+
+       * Makefile.am (gthread-2.0.lib): Pass appropriate -machine flag to lib.exe.
+
+2008-07-21  Matthias Clasen  <mclasen2redhat.com>
+
+       * === Released 2.17.4 ===
+
+2008-07-02  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.17.3 ===
+
+2008-06-12  Matthias Clasen  <mclasen@redhat.com>
+       
+       * === Released 2.17.2 ===
+
+2008-06-12  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.17.1 ===
+
+2008-05-28  Michael Natterer  <mitch@imendio.com>
+
+       * Makefile.am: don't define G_DISABLE_SINGLE_INCLUDES, it's in
+       the global CPPFLAGS now.
+
+2008-05-27  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.17.0 ===
+
+2008-05-05  Michael Natterer  <mitch@imendio.com>
+
+       * Makefile.am. build with G_DISABLE_SINGLE_INCLUDES to prevent
+       code from being checked in that breaks the build of applications
+       which use G_DISABLE_SINGLE_INCLUDES.
+
+2008-03-16  Tor Lillqvist  <tml@novell.com>
+
+       * Makefile.am: Define gthread_def locally here instead of using an
+       Autoconf variable.
+
+2008-03-10  Matthias Clasen  <mclasen@redhat.com>
+       
+       * === Released 2.16.1 ===
+
+2008-03-10  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.16.0 ===
+
+2008-02-25  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.15.6 ===
+
+2008-02-11  Matthias Clasen <mclasen@redhat.com>
+
+       * === Released 2.15.5 ===
+
+2008-01-28  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.15.4 ===
+
+2008-01-27  Matthias Clasen  <mclasen@redhat.com>
+
+       * gthread-posix.c:
+       * gthread-win32.c: Replace uses of G_GNUC_PRETTY_FUNCTION
+       by __FUNCTION__.
+
+2008-01-21  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.15.3 ===
+
+2008-01-14  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.15.2 ===
+
+008-01-07  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.15.1 ===
+
+2007-12-20  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.15.0 ===
+
+2007-11-07  Matthias Clasen <mclasen@redhat.com>
+
+       * === Released 2.14.3 ===
+
+2007-10-16  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.14.2 ===
+
+2007-09-19  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.14.1 ===
+
+2007-08-03  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.14.0 ===
+
+2007-07-12  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.13.7 ===
+
+Fri Jun 29 2007  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.13.6 ===
+
+2007-06-18  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.13.5 ===
+
+2007-06-05  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.13.4 ===
+
+2007-06-04  Matthias Clasen  <mclasen@redhat.com>
+       
+       * === Released 2.13.3 ===
+
+2007-05-22  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.13.2 ===
+
+2007-05-03  Matthias Clasen <mclasen@redhat.com>
+
+       * === Released 2.13.1 ===
+
+2007-03-16  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.13.0 ===
+
+2007-01-19  Tor Lillqvist  <tml@novell.com>
+
+       * Makefile.am (gthread-2.0.lib): Use $(srcdir) for builds outside
+       srcdir.
+
+2007-01-16  Tor Lillqvist  <tml@novell.com>
+
+       * gthread-win32.c (g_gettime_win32_impl):
+       GetSystemTimeAsFileTime() returns 100s of nanoseconds since 1601,
+       so offset to Unix epoch (1970) and multiply by 100 to get
+       nanoseconds which is what we want.
+
+2006-12-28  Tor Lillqvist  <tml@novell.com>
+
+       * gthread-win32.c (g_thread_impl_init): Correct link to discussion
+       about CRITICAL_SECTIONs vs. mutexes. Thanks to Felix Kater for
+       pointing this out.
+
+2006-08-15  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.12.2 ===
+
+2006-07-22  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.12.1 ===
+
+2006-07-02  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.12.0 ===
+
+2006-06-20  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.11.4 ===
+
+2006-06-12  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.11.3 ===
+
+2006-06-05  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.11.2 ===
+
+2006-05-15  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.11.1 ===
+
+2006-05-03  Tor Lillqvist  <tml@novell.com>
+
+       * gthread-win32.c (g_thread_exit_win32_impl): Free with free() and
+       not g_free() what has been allocated with calloc(). (#340530, Jake
+       Goulding)
+
+2006-05-02  Matthias Clasen  <mclasen@redhat.com>
+       
+       * === Released 2.11.0 ===
+
+2006-03-11  Tor Lillqvist  <tml@novell.com>
+
+       * gthread-win32.c: #define _WIN32_WINDOWS as 0x0401 to get
+       declaration for IsDebuggerPresent() when using MSVC6. (#333879,
+       Kazuki Iwamoto)
+
+2006-03-07  Matthias Clasen  <mclasen@redhat.com>
+
+       * ===  Released 2.10.1 ===
+
+2006-03-02  Tor Lillqvist  <tml@novell.com>
+
+       * gthread-win32.c (G_PRIVATE_MAX): Increase to 100. 16 was rather
+       low.
+       (g_private_new_win32_impl): Can't use g_error() here as
+       g_private_new() is called a few times by GLib internally before
+       the messaging system that g_error() requires is ready. Thanks to
+       Tim Janik for noticing. Just display a MessageBox() and abort()
+       instead.
+
+2006-02-24  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.10.0 ===
+
+2006-02-20  Tor Lillqvist  <tml@novell.com>
+
+       * gthread-win32.c (g_thread_exit_win32_impl): Make the
+       implementation of GPrivate behave more closely as in POSIX
+       threads: The value associacted with a GPrivate must be set to NULL
+       before calling the destructor. (The destructor gets the original
+       value as argument.)  A destructor might re-associate a non-NULL
+       value with some GPrivate. To deal with this, if after all
+       destructors have been called, there still are some non-NULL
+       values, the process is repeated. (#331367)
+
+2006-02-10  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.9.6 ===
+
+2006-01-27  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.9.5 ===
+
+2006-01-18  Matthias Clasen  <mclasen@redhat.com>
+       
+       * === Released 2.9.4 ===
+
+2006-01-16  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.9.3 ===
+
+2006-01-05  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.9.2 ===
+
+2005-12-09  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.9.1 ===
+
+2005-12-02  Matthias Clasen  <mclasen@redhat.com>
+
+       * Makefile.am: Remove gthread-solaris.c
+
+2005-11-17  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.9.0 ===
+
+2005-08-23  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.8.1 ===
+
+2005-08-12  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.8.0 ===
+
+2005-08-05  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.7.7 ===
+
+2005-08-03  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.7.6 ===
+
+2005-08-02  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.7.5 ===
+
+2005-07-21  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.7.4 ===
+
+2005-07-15  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.7.3 ===
+       
+2005-07-09  Tor Lillqvist  <tml@novell.com>
+
+       * Makefile.am: Don't use the scripts in build/win32 to compile
+       gthread.rc into a resource object file. (This means we lose the
+       build number increment magic, but I doubt it was that useful
+       anyway.) Instead use windres directly. To pass the normal .o file
+       produced by windres through libtool, which wants .lo files, pass
+       it directly to the linker using a -Wl option.
+
+       * gthread.rc.in: Thus replace BUILDNUMBER with 0.
+
+2005-07-08  Matthias Clasen  <mclasen@redhat.com>
+       
+       * === Released 2.7.2 ===
+
+2005-06-30  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.7.1 ===
+
+2005-06-26  Tor Lillqvist  <tml@novell.com>
+
+       * Makefile.am: libtool installs/uninstalls the import library, no
+       need to do it ourselves. Do still install/uninstall the .def file,
+       though.
+
+2005-06-10  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.7.0 ===
+
+2005-06-09  Matthias Clasen  <mclasen@redhat.com>
+
+       * gthread-posix.c (g_thread_create_posix_impl): Allow
+       setstacksize to fail.  (#304790, Michael Banck)
+
+2005-01-07  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.6.1 ===
+
+2004-12-16  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.6.0 ===
+       
+2004-12-02  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.5.7 ===
+       
+2004-11-12  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.5.6 ===
+       
+2004-11-02  Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.5.5 ===
+
+2004-10-27 Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.5.4 ===
+
+2004-09-18 Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.5.3 ===
+
+2004-08-25 Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.5.2 ===
+
+2004-08-01 Matthias Clasen  <mclasen@redhat.com>
+
+       * === Released 2.5.1 ===
+
+Sun Jul 18 18:03:08 2004  Soeren Sandmann  <sandmann@daimi.au.dk>
+
+       * === Released 2.5.0 ===
+
+2002-11-23  Tor Lillqvist  <tml@iki.fi>
+
+       * gthread-win32.c (g_cond_timed_wait_win32_impl): Fix two bugs: 1)
+       If abs_time is NULL, should use infinite time. 2) Check for
+       current time already being past abs_time. (#99294, Christopher
+       R. Palmer, fix by Sebastian Wilhelmi)
+
+Mon Nov  4 14:45:24 2002  Owen Taylor  <otaylor@redhat.com>
+
+       * gthread-posix.c gthread-solaris.c: Include <config.h>
+
+2002-03-10  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c (g_thread_create_posix_impl): Do a comparison,
+       not an assignment, stupid! Spotted by Daniel Elstner
+       <daniel.elstner@gmx.net>.
+
+2002-02-09  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-impl.c: Only compile most of this file, if
+       G_THREADS_ENABLED is set.
+
+       * Fixed typo in G_THREADS_ENABLED. 
+
+2002-01-16  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-solaris.c: Use g_free instead of free. Pointed out by
+       Sam O'Connor <sam@panviva.com>.
+
+2001-10-23  Tor Lillqvist  <tml@iki.fi>
+
+       * Makefile.am: (Win32): If we have built the MSVC import library,
+       install it. Install the gcc import library. Also support
+       uninstall.
+
+2001-09-28  Tor Lillqvist  <tml@iki.fi>
+
+       * gthread-win32.c: Use an extra level of indirection for GMutex.
+       It is now a pointer either to a pointer to a CRITICAL_SECTION
+       struct, or to a mutex HANDLE. This is needed in case the user
+       defines G_ERRORCHECK_MUTEXES. G_MUTEX_SIZE must correctly reflect
+       the size of *GMutex, but this used to vary depending on whether we
+       at run-time chose to use CRITICAL_SECTIONs or mutexes.
+       (g_mutex_free_win32_cs_impl, g_cond_free_win32_impl): Call
+       DeleteCriticalSection() when done with it.
+
+       * gthread-impl.c (g_thread_init_with_errorcheck_mutexes): Call
+       g_thread_impl_init() before accessing
+       g_thread_functions_for_glib_use_default, as the
+       g_thread_impl_init() function might modify it.
+       
+2001-09-26  Tor Lillqvist  <tml@iki.fi>
+
+       * makefile.mingw.in: Fix couple of typos.
+
+       * gthread.def: Add g_thread_init_with_errorcheck_mutexes.
+
+2001-09-25  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-impl.c: Corrected the array size (cough, cough). Pointed
+       out by gpablo@intersystems.com.ar. Fixes #61065.
+
+2001-09-25  Tor Lillqvist  <tml@iki.fi>
+
+       * Makefile.am: Use new macros for .def file, and check for
+       MS_LIB_AVAILABLE, new rule to build MS import library.
+
+       * makefile.msc.in: Use same DLL and import library names as
+       libtool.
+       
+2001-09-19  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c: Add g_thread_equal_posix_impl and add to the
+       function vector g_thread_functions_for_glib_use_default.
+       
+       * gthread-solaris.c, gthread-win32.c: Add NULL as equal function,
+       as on those two platforms you don't need an equal function.
+
+2001-09-19  Tor Lillqvist  <tml@iki.fi>
+
+       * gthread.rc.in: Correct InternalName and OriginalFilename to
+       match what we actually produce.
+
+2001-07-20  Hans Breuer  <hans@breuer.org>
+
+       * makefile.msc.in : reflect glib move
+
+2001-06-07  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-win32.c: Use g_win32_error_message to beautify error
+       messages.
+
+2001-05-24  Hans Breuer  <hans@breuer.org>
+
+       * makefile.msc.in : pthread isn't required anymore
+
+2001-05-22  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-win32.c (g_cond_wait_internal): Also return TRUE for
+       late arrived signals. Thanks to Steven Brooks
+       <umbrook0@cs.umanitoba.ca> for pointing out.
+
+       * gthread-impl.c (g_thread_init): Move the thread implementation
+       initialization to before assigning GThreadFuncs, which now is just
+       struct assigned and not memcpy'ed. Completed check for zero
+       members of GThreadFuncs. 
+
+       * makefile.mingw: Don't link to pthread anymore.
+
+       * gthread-win32.c: New file for native thread support for
+       win32. Thanks to Hans Breuer <hans@breuer.org> to got me
+       kickstarted.
+
+       * Makefile.am: Also distribute gthread-win32.c.
+
+Fri May  4 04:14:45 2001  Tim Janik  <timj@gtk.org>
+
+       * gthread-posix.c (g_cond_timed_wait_posix_impl): don't g_assert()
+       the user specified time, but g_return_val_if_fail() here.
+
+2001-04-03  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c: Added special case for priorities on
+         FreeBSD. Thanks to David Reid <dreid@jetnet.co.uk> for the info.
+
+       * gthread-impl.c: Made two macros safe with ().
+
+2001-03-10  Tor Lillqvist  <tml@iki.fi>
+
+       * Makefile.am: Use the _LIBADD dependency on libglib only on
+       Win32.
+
+2001-02-21  Tor Lillqvist  <tml@iki.fi>
+
+       * Makefile.am: Use libglib-1.3.la from top_builddir. Invoke
+       libtool with -no-undefined for Win32 and Cygwin.
+
+       * gthread-impl.c (g_thread_init): Win32 code snippet used also on
+       Cygwin.
+
+2001-02-15  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c: Removed the G_THREAD_USE_PID_SURROGATE
+       implementation, which is now in gthread.c.
+
+2001-01-30  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-impl.c (g_thread_init_with_errorcheck_mutexes): Call
+       g_thread_impl_init(), as g_thread_init won't call it.
+
+       * gthread-impl.c (g_mutex_free_errorcheck_impl): Fixed it for
+       real. Sorry for this mess. It looked like a real obvious fix, so I
+       didn't check. Bad boy. Added some casts to quiet the compiler.
+
+2001-01-29  Havoc Pennington  <hp@redhat.com>
+
+       * gthread-impl.c (g_mutex_free_errorcheck_impl): hack this so it
+       compiles, needs fixing for real.
+
+2001-01-29  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-impl.c (g_mutex_free_errorcheck_impl): Add new check to
+       errorcheck mutexes to abort, if a locked mutex is freed.
+
+2001-01-03  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-solaris.c, gthread-posix.c: Made g_thread_min_stack_size
+       static.
+
+2000-11-28  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-impl.c: Revamped errorcheck mutexes and added errorcheck
+       cond_wait() and cond_timed_wait() funtions. This makes he whole
+       thing work. Now we only show the location of the locking/unlocking
+       for -DG_ERRORCHECK_MUTEXES and not the name of the mutex.
+
+2000-11-21  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-impl.c, gthread-posix.c, gthread-solaris.c: Removed
+       g_thread_map_priority function in favour of the
+       g_thread_priority_map array.  Initialize the array with
+       PRIORITY_{...}_VALUE, if available and interpolate beetween the
+       bounds if .._NORMAL_.. and .._HIGH_.. are not available.
+
+       * gthread-posix.c: If we should use the PID niceness as a
+       surrogate for thread priorities (G_THREAD_USE_PID_SURROGATE is
+       defined), then disable normal priority handling and use PIDs and
+       setpriority() instead. Depends on the thread to write its PID into
+       the place after the thread id right after thread creation.
+
+2000-11-15  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c: Include <sched.h> if available.
+
+2000-11-02  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-none.c: Add G_MUTEX_SIZE as needed for gthread-impl.c
+
+2000-10-25  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * Makefile.am : Add @GLIB_DEBUG_FLAGS@ to INCLUDES for accessing
+       -DG_ENABLE_DEBUG as needed in gthread-posix.c.
+
+       * gthread-posix.c: Revamped error handling for native thread
+       function calls. Now EPERM errors are ignored for some commands and
+       only a warning message is output once (at first occurrence).
+
+2000-10-15  Raja R Harinath  <harinath@cs.umn.edu>
+
+       * Makefile.am (BUILT_EXTRA_DIST): New variable.
+       (dist-hook): Handle $(BUILT_EXTRA_DIST).
+
+2000-09-29  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-impl.c: Added errorcheck mutexes. New exported function
+       g_thread_init_with_errorcheck_mutexes, which is called instead of
+       g_thread_init, when compiled with -DG_ERRORCHECK_MUTEXES. New
+       static functions
+       g_mutex_(new|lock|trylock|unlock|free)_errorcheck_impl to
+       implement errorcheck mutexes.
+
+       * gthread-posix.impl.c, gthread-solaris-impl.c: Define the size of
+       a mutex.
+
+2000-09-21  Tor Lillqvist  <tml@iki.fi>
+
+       * makefile.mingw.in: Use pthreads macros from ../build.
+
+2000-09-06  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c, gthread-solaris.c:
+       s/G_MICROSEC/G_USEC_PER_SEC/ and s/G_NANOSEC/G_NSEC_PER_SEC/    
+
+2000-09-01  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c (g_thread_create_posix_impl): Use GError to
+       report errors.
+
+       * gthread-solaris.c (g_thread_create_solaris_impl): Use GError to
+       report errors as well.
+       
+2000-05-13  Tor Lillqvist  <tml@iki.fi>
+
+       * makefile.mingw.in: New file, with gthread stuff moved from
+       ../makefile.mingw.in.
+
+       * Makefile.am: Add to EXTRA_DIST, add rule to build makefile.mingw.
+
+2000-04-25  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-solaris.c (g_mutex_new_solaris_impl): Changed the scope
+       of the initialized mutex to USYNC_THREAD. Thanks to Soeren
+       Sandmann <sandmann@daimi.au.dk> for pointing that out.
+
+2000-03-20  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c (posix_check_for_error): Forgot a '}' in a macro
+       for DCE-threads. Thanks to Karl Nelson <kenelson@ece.ucdavis.edu>
+       for pointing that out.
+
+2000-03-17  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c: Don't use priorities for threads, when the
+       minimal/maximal priorities couldn't be determined at configure
+       time.
+
+       * gthread-posix.c: Don't check for errors, when setting the scope
+       of a tread to system, as some posix implementations can't do that
+       and we don't want the thing to fail because of that.
+
+2000-02-22  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c, gthread-solaris.c: check for sysconf
+       (_SC_THREAD_STACK_MIN), which returns the minimal stack size for
+       new threads. Patch from Soeren Sandmann <sandmann@daimi.au.dk>.
+
+1999-11-16  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c, gthread-solaris.c: Changed the prototype of
+       thread_create and thread_self to return the system thread into
+       provided memory instead of a return value. This is necessary, as
+       HPUX has a pthread_t, that is bigger than the biggest integral
+       type there. Made some more functions static.
+
+       * gthread-posix.c: Small fixes for DCE threads: Detaching has to
+       be done after thread creation for DCE.
+
+1999-06-21  Tor Lillqvist  <tml@iki.fi>
+
+       * gthread-posix.c: Guard pthread_attr_setscope call with test
+       for _POSIX_THREAD_PRIORITY_SCHEDULING, which should be defined
+       in a <pthread.h> that supports that feature.
+       
+1999-06-17  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c, gthread-solaris.c: Added the native
+       implementations for the GLib's extended thread support.
+
+       * gthread-nspr.c: Removed for good. NSPR is nothing we would want
+       to build upon.
+
+       * gthread.c: Renamed to gthread-impl.c to avoid confusion with
+       ../gthread.c (Formerly known as the file called gmutex.c)
+
+       * testgthread.c: Removed. The new and much extended tests are in
+       ../tests/thread-test.c.
+
+       * Makefile.am: Changed to reflect the changes above.
+
+1999-03-31  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c: Use the right default arguments for the
+       construction of mutexes and conds for dce threads, these are
+       &pthread_(cond|mutex)attr_default instead of NULL. Hint from
+       D. Emilio Grimaldo Tunon <emilio_tunon@nl.compuware.com>.
+
+1999-03-18  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * Makefile.am (INCLUDES): Added @GTHREAD_COMPILE_IMPL_DEFINES@.
+
+1999-03-12  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c (g_private_get_posix_impl): Fixed typo for DCE
+       implementation.
+
+1999-03-11  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c: Now handle both dce and posix threads. They are
+       sufficently equal. Please do not commit my change to
+       glib-1-2/gthread/gthread-posix.c from 1999-03-03, as the current
+       change will take care of that too.
+
+1999-03-03  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c: Fixed broken mutex_trylock and slightly broken
+       cond_timed_wait functions.
+
+1999-02-15  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * testgthread.c (test_mutexes): Use new signature of
+       g_static_mutex* functions.
+
+1999-02-08  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * gthread-posix.c (g_private_get_posix_impl): Use the
+       HAVE_PTHREAD_GETSPECIFIC_POSIX macro to determine, which signature
+       to use for pthread_getspecific.
+
+Tue Jan 19 20:56:02 1999  Tor Lillqvist  <tml@iki.fi>
+
+       * Makefile.am (EXTRA_DIST): Added gthread.def.
+
+Sun Jan 17 10:58:19 1999  Tor Lillqvist  <tml@iki.fi>
+
+       * gthread.def: New file.
+
+1999-01-16 1999  Tor Lillqvist  <tml@iki.fi>
+
+       * gthread-posix.c: Conditionalize <sys/time.h> inclusion.
+
+1999-01-07  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * testgthread.c: conditionally compile according to the
+       G_THREADS_IMPL_??? macros.
+       (test_private_func): use rand_r instead of rand to make it
+       thread safe.
+
+1998-12-18  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * testgthread.c (new_thread): As a joinable thread seems to be the
+       default on posix, leave the explicit setting out, as it causes
+       problems on some older platforms.
+
+Wed Dec 16 22:21:33 CST 1998 Shawn T. Amundson <amundson@gtk.org>
+
+       * gthread-posix.c: use g_free in mutex_free (from Tim Janik)
+
+Thu Dec 17 03:38:57 1998  Tim Janik  <timj@gtk.org>
+
+       * Makefile.am: -DG_LOG_DOMAIN="GThread", we don't need an extern
+       variable for that (noticed by Joel Becker <jlbec@ocala.cs.miami.edu>)
+
+Wed Dec 16 03:16:16 1998  Tim Janik  <timj@gtk.org>
+
+       * testgthread.c: s/g_thread_supported/g_thread_supported ()/
+       * gthread.c: s/g_thread_supported/g_threads_got_initialized/
+       (g_thread_init): bail out if G_THREADS_ENABLED is not defined.
+
+1998-12-15  Sebastian Wilhelmi  <wilhelmi@ira.uka.de>
+
+       * Makefile.am (EXTRA_DIST): updated.
+
+       * testgthread.c, gthread-*.c: Changed private to private_key to
+       avoid problems when compiling with under C++.
+
+       * gthread-none.c: 
+       s/g_mutex_functions_for_glib_use/g_thread_functions_for_glib_use/
+
+       * ChangeLog: from now on there is an extra ChangeLog for gthread
+       
+
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/Makefile.am b/resource/csdk/connectivity/lib/android/glib-master/gthread/Makefile.am
new file mode 100644 (file)
index 0000000..617c94a
--- /dev/null
@@ -0,0 +1,103 @@
+## Process this file with automake to produce Makefile.in
+include $(top_srcdir)/Makefile.decl
+
+SUBDIRS = . tests
+DIST_SUBDIRS = tests
+
+AM_CPPFLAGS =                          \
+       $(glib_INCLUDES)                \
+       -DG_LOG_DOMAIN=\"GThread\"      \
+       @GTHREAD_COMPILE_IMPL_DEFINES@  \
+       @GLIB_DEBUG_FLAGS@              \
+       -DG_DISABLE_DEPRECATED
+
+EXTRA_DIST +=                          \
+               makefile.msc.in         \
+               gthread-posix.c         \
+               gthread-win32.c         \
+               gthread-none.c          \
+               gthread.def             \
+               gthread.rc.in
+
+BUILT_EXTRA_DIST =                     \
+               makefile.msc            \
+               gthread.rc
+
+libglib = $(top_builddir)/glib/libglib-2.0.la
+
+top_builddir_full=`cd \$(top_builddir); pwd`
+
+lib_LTLIBRARIES = libgthread-2.0.la
+
+if OS_WIN32_AND_DLL_COMPILATION
+if MS_LIB_AVAILABLE
+noinst_DATA = gthread-2.0.lib
+
+install_ms_lib_cmd = $(INSTALL) gthread-2.0.lib $(DESTDIR)$(libdir)
+uninstall_ms_lib_cmd = -rm $(DESTDIR)$(libdir)/gthread-2.0.lib
+endif
+endif
+
+install-ms-lib:
+       $(install_ms_lib_cmd)
+
+uninstall-ms-lib:
+       $(uninstall_ms_lib_cmd)
+
+if PLATFORM_WIN32
+no_undefined = -no-undefined
+endif
+
+if OS_WIN32_AND_DLL_COMPILATION
+export_symbols = -export-symbols $(srcdir)/gthread.def
+gthread_def = gthread.def
+
+install-def-file:
+       $(INSTALL) $(srcdir)/gthread.def $(DESTDIR)$(libdir)/gthread-2.0.def
+
+uninstall-def-file:
+       -rm $(DESTDIR)$(libdir)/gthread-2.0.def
+else
+install-def-file:
+uninstall-def-file:
+endif
+
+if OS_WIN32_AND_DLL_COMPILATION
+gthread_win32_res = gthread-win32-res.o
+gthread_win32_res_ldflag = -Wl,$(gthread_win32_res)
+endif
+
+libgthread_2_0_la_SOURCES = gthread-impl.c
+libgthread_2_0_la_LDFLAGS = $(GLIB_LINK_FLAGS) \
+       $(gthread_win32_res_ldflag) \
+       -version-info $(LT_CURRENT):$(LT_REVISION):$(LT_AGE) \
+       -export-dynamic $(no_undefined) $(export_symbols)
+
+libgthread_2_0_la_LIBADD = $(G_THREAD_LIBS_EXTRA) $(G_THREAD_LIBS_FOR_GTHREAD) $(libglib)
+
+libgthread_2_0_la_DEPENDENCIES = $(gthread_win32_res) $(gthread_def)
+
+gthread-win32-res.o: gthread.rc
+       $(AM_V_GEN) $(WINDRES) gthread.rc $@
+
+gthread-2.0.lib: libgthread-2.0.la gthread.def
+       lib -machine:@LIB_EXE_MACHINE_FLAG@ -name:libgthread-2.0-$(LT_CURRENT_MINUS_AGE).dll -def:$(srcdir)/gthread.def -out:$@
+
+dist-hook: $(BUILT_EXTRA_DIST)
+       files='$(BUILT_EXTRA_DIST)'; \
+       for f in $$files; do \
+         if test -f $$f; then d=.; else d=$(srcdir); fi; \
+         cp $$d/$$f $(distdir) || exit 1; done
+
+install-data-local: install-ms-lib install-def-file
+
+uninstall-local: uninstall-ms-lib uninstall-def-file
+
+if HAVE_GLIB_RUNTIME_LIBDIR
+install-data-hook:
+       mkdir -p $(DESTDIR)$(libdir)/$(GLIB_RUNTIME_LIBDIR)
+       mv $(DESTDIR)$(libdir)/libgthread-2.0.so.0 $(DESTDIR)$(libdir)/$(GLIB_RUNTIME_LIBDIR)
+       mv $(DESTDIR)$(libdir)/libgthread-2.0.so.0.$(LT_CURRENT).$(LT_REVISION) $(DESTDIR)$(libdir)/$(GLIB_RUNTIME_LIBDIR)
+       rm -f $(DESTDIR)$(libdir)/libgthread-2.0.so
+       ln -s $(GLIB_RUNTIME_LIBDIR)/libgthread-2.0.so.0.$(LT_CURRENT).$(LT_REVISION) $(DESTDIR)$(libdir)/libgthread-2.0.so
+endif
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/gthread-impl.c b/resource/csdk/connectivity/lib/android/glib-master/gthread/gthread-impl.c
new file mode 100644 (file)
index 0000000..b483657
--- /dev/null
@@ -0,0 +1,377 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gthread.c: thread related functions
+ * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "glib.h"
+#include "gthreadprivate.h"
+
+#ifdef G_THREADS_ENABLED
+
+static GSystemThread zero_thread; /* This is initialized to all zero */
+static gboolean thread_system_already_initialized = FALSE;
+static gint g_thread_priority_map [G_THREAD_PRIORITY_URGENT + 1];
+
+#include G_THREAD_SOURCE
+
+#ifndef PRIORITY_LOW_VALUE
+# define PRIORITY_LOW_VALUE 0
+#endif
+
+#ifndef PRIORITY_URGENT_VALUE
+# define PRIORITY_URGENT_VALUE 0
+#endif
+
+#ifndef PRIORITY_NORMAL_VALUE
+# define PRIORITY_NORMAL_VALUE                                         \
+  ((PRIORITY_LOW_VALUE * 6 + PRIORITY_URGENT_VALUE * 4) / 10)
+#endif /* PRIORITY_NORMAL_VALUE */
+
+#ifndef PRIORITY_HIGH_VALUE
+# define PRIORITY_HIGH_VALUE                                           \
+  ((PRIORITY_NORMAL_VALUE + PRIORITY_URGENT_VALUE * 2) / 3)
+#endif /* PRIORITY_HIGH_VALUE */
+
+void g_mutex_init (void);
+void g_mem_init (void);
+void g_messages_init (void);
+void g_convert_init (void);
+void g_rand_init (void);
+void g_main_thread_init (void);
+
+typedef struct _GMutexDebugInfo GMutexDebugInfo;
+struct _GMutexDebugInfo
+{
+  gchar *location;
+  GSystemThread owner;
+};
+
+#define G_MUTEX_DEBUG_INFO(mutex)                                      \
+  (((GMutexDebugInfo*)(((char*)mutex)+G_MUTEX_SIZE)))
+
+static GMutex *
+g_mutex_new_errorcheck_impl (void)
+{
+  GMutex *retval = g_thread_functions_for_glib_use_default.mutex_new ();
+  GMutexDebugInfo *info;
+  retval = g_realloc (retval, G_MUTEX_SIZE + sizeof (GMutexDebugInfo));
+
+  info = G_MUTEX_DEBUG_INFO (retval);
+  g_system_thread_assign (info->owner, zero_thread);
+  info->location = "invalid";
+
+  return retval;
+}
+
+static void
+g_mutex_lock_errorcheck_impl (GMutex *mutex,
+                             const gulong magic,
+                             gchar * const location)
+{
+  GMutexDebugInfo *info = G_MUTEX_DEBUG_INFO (mutex);
+  gchar *loc = (magic == G_MUTEX_DEBUG_MAGIC) ? location : "unknown";
+
+  GSystemThread self;
+  g_thread_functions_for_glib_use.thread_self (&self);
+
+  if (g_system_thread_equal (info->owner, self))
+    g_error ("Trying to recursively lock a mutex at '%s', "
+            "previously locked at '%s'",
+            loc, info->location);
+
+  g_thread_functions_for_glib_use_default.mutex_lock (mutex);
+
+  g_system_thread_assign (info->owner, self);
+  info->location = loc;
+}
+
+static gboolean
+g_mutex_trylock_errorcheck_impl (GMutex *mutex,
+                                const gulong magic,
+                                gchar * const location)
+{
+  GMutexDebugInfo *info = G_MUTEX_DEBUG_INFO (mutex);
+  gchar *loc = (magic == G_MUTEX_DEBUG_MAGIC) ? location : "unknown";
+
+  GSystemThread self;
+  g_thread_functions_for_glib_use.thread_self (&self);
+
+  if (g_system_thread_equal (info->owner, self))
+    g_error ("Trying to recursivly lock a mutex at '%s', "
+            "previously locked at '%s'",
+            loc, info->location);
+
+  if (!g_thread_functions_for_glib_use_default.mutex_trylock (mutex))
+    return FALSE;
+
+  g_system_thread_assign (info->owner, self);
+  info->location = loc;
+
+  return TRUE;
+}
+
+static void
+g_mutex_unlock_errorcheck_impl (GMutex *mutex,
+                               const gulong magic,
+                               gchar * const location)
+{
+  GMutexDebugInfo *info = G_MUTEX_DEBUG_INFO (mutex);
+  gchar *loc = (magic == G_MUTEX_DEBUG_MAGIC) ? location : "unknown";
+
+  GSystemThread self;
+  g_thread_functions_for_glib_use.thread_self (&self);
+
+  if (g_system_thread_equal (info->owner, zero_thread))
+    g_error ("Trying to unlock an unlocked mutex at '%s'", loc);
+
+  if (!g_system_thread_equal (info->owner, self))
+    g_warning ("Trying to unlock a mutex at '%s', "
+              "previously locked by a different thread at '%s'",
+              loc, info->location);
+
+  g_system_thread_assign (info->owner, zero_thread);
+  info->location = NULL;
+
+  g_thread_functions_for_glib_use_default.mutex_unlock (mutex);
+}
+
+static void
+g_mutex_free_errorcheck_impl (GMutex *mutex,
+                             const gulong magic,
+                             gchar * const location)
+{
+  GMutexDebugInfo *info = G_MUTEX_DEBUG_INFO (mutex);
+  gchar *loc = (magic == G_MUTEX_DEBUG_MAGIC) ? location : "unknown";
+
+  if (info && !g_system_thread_equal (info->owner, zero_thread))
+    g_error ("Trying to free a locked mutex at '%s', "
+            "which was previously locked at '%s'",
+            loc, info->location);
+
+  g_thread_functions_for_glib_use_default.mutex_free (mutex);
+}
+
+static void
+g_cond_wait_errorcheck_impl (GCond *cond,
+                            GMutex *mutex,
+                            const gulong magic,
+                            gchar * const location)
+{
+  GMutexDebugInfo *info = G_MUTEX_DEBUG_INFO (mutex);
+  gchar *loc = (magic == G_MUTEX_DEBUG_MAGIC) ? location : "unknown";
+
+  GSystemThread self;
+  g_thread_functions_for_glib_use.thread_self (&self);
+
+  if (g_system_thread_equal (info->owner, zero_thread))
+    g_error ("Trying to use an unlocked mutex in g_cond_wait() at '%s'", loc);
+
+  if (!g_system_thread_equal (info->owner, self))
+    g_error ("Trying to use a mutex locked by another thread in "
+            "g_cond_wait() at '%s'", loc);
+
+  g_system_thread_assign (info->owner, zero_thread);
+  loc = info->location;
+
+  g_thread_functions_for_glib_use_default.cond_wait (cond, mutex);
+
+  g_system_thread_assign (info->owner, self);
+  info->location = loc;
+}
+
+
+static gboolean
+g_cond_timed_wait_errorcheck_impl (GCond *cond,
+                                   GMutex *mutex,
+                                   GTimeVal *end_time,
+                                  const gulong magic,
+                                  gchar * const location)
+{
+  GMutexDebugInfo *info = G_MUTEX_DEBUG_INFO (mutex);
+  gchar *loc = (magic == G_MUTEX_DEBUG_MAGIC) ? location : "unknown";
+  gboolean retval;
+
+  GSystemThread self;
+  g_thread_functions_for_glib_use.thread_self (&self);
+
+  if (g_system_thread_equal (info->owner, zero_thread))
+    g_error ("Trying to use an unlocked mutex in g_cond_timed_wait() at '%s'",
+            loc);
+
+  if (!g_system_thread_equal (info->owner, self))
+    g_error ("Trying to use a mutex locked by another thread in "
+            "g_cond_timed_wait() at '%s'", loc);
+
+  g_system_thread_assign (info->owner, zero_thread);
+  loc = info->location;
+
+  retval = g_thread_functions_for_glib_use_default.cond_timed_wait (cond,
+                                                                   mutex,
+                                                                   end_time);
+
+  g_system_thread_assign (info->owner, self);
+  info->location = loc;
+
+  return retval;
+}
+
+
+/* unshadow function declaration. See gthread.h */
+#undef g_thread_init
+
+void
+g_thread_init_with_errorcheck_mutexes (GThreadFunctions* init)
+{
+  GThreadFunctions errorcheck_functions;
+  if (init)
+    g_error ("Errorcheck mutexes can only be used for native "
+            "thread implementations. Sorry." );
+
+#ifdef HAVE_G_THREAD_IMPL_INIT
+  /* This isn't called in g_thread_init, as it doesn't think to get
+   * the default implementation, so we have to call it on our own.
+   *
+   * We must call this before copying
+   * g_thread_functions_for_glib_use_default as the
+   * implementation-specific init function might modify the contents
+   * of g_thread_functions_for_glib_use_default based on operating
+   * system version, C library version, or whatever. */
+  g_thread_impl_init();
+#endif /* HAVE_G_THREAD_IMPL_INIT */
+
+  errorcheck_functions = g_thread_functions_for_glib_use_default;
+  errorcheck_functions.mutex_new = g_mutex_new_errorcheck_impl;
+  errorcheck_functions.mutex_lock =
+    (void (*)(GMutex *)) g_mutex_lock_errorcheck_impl;
+  errorcheck_functions.mutex_trylock =
+    (gboolean (*)(GMutex *)) g_mutex_trylock_errorcheck_impl;
+  errorcheck_functions.mutex_unlock =
+    (void (*)(GMutex *)) g_mutex_unlock_errorcheck_impl;
+  errorcheck_functions.mutex_free =
+    (void (*)(GMutex *)) g_mutex_free_errorcheck_impl;
+  errorcheck_functions.cond_wait =
+    (void (*)(GCond *, GMutex *)) g_cond_wait_errorcheck_impl;
+  errorcheck_functions.cond_timed_wait =
+    (gboolean (*)(GCond *, GMutex *, GTimeVal *))
+    g_cond_timed_wait_errorcheck_impl;
+
+  g_thread_init (&errorcheck_functions);
+}
+
+void
+g_thread_init (GThreadFunctions* init)
+{
+  gboolean supported;
+
+  if (thread_system_already_initialized)
+    {
+      if (init != NULL)
+       g_warning ("GThread system already initialized, ignoring custom thread implementation.");
+
+      return;
+    }
+
+  thread_system_already_initialized = TRUE;
+
+  if (init == NULL)
+    {
+#ifdef HAVE_G_THREAD_IMPL_INIT
+      /* now do any initialization stuff required by the
+       * implementation, but only if called with a NULL argument, of
+       * course. Otherwise it's up to the user to do so. */
+      g_thread_impl_init();
+#endif /* HAVE_G_THREAD_IMPL_INIT */
+      init = &g_thread_functions_for_glib_use_default;
+    }
+  else
+    g_thread_use_default_impl = FALSE;
+
+  g_thread_functions_for_glib_use = *init;
+  if (g_thread_gettime_impl)
+    g_thread_gettime = g_thread_gettime_impl;
+
+  supported = (init->mutex_new &&
+              init->mutex_lock &&
+              init->mutex_trylock &&
+              init->mutex_unlock &&
+              init->mutex_free &&
+              init->cond_new &&
+              init->cond_signal &&
+              init->cond_broadcast &&
+              init->cond_wait &&
+              init->cond_timed_wait &&
+              init->cond_free &&
+              init->private_new &&
+              init->private_get &&
+              init->private_set &&
+              init->thread_create &&
+              init->thread_yield &&
+              init->thread_join &&
+              init->thread_exit &&
+              init->thread_set_priority &&
+              init->thread_self);
+
+  /* if somebody is calling g_thread_init (), it means that he wants to
+   * have thread support, so check this
+   */
+  if (!supported)
+    {
+      if (g_thread_use_default_impl)
+       g_error ("Threads are not supported on this platform.");
+      else
+       g_error ("The supplied thread function vector is invalid.");
+    }
+
+  g_thread_priority_map [G_THREAD_PRIORITY_LOW] = PRIORITY_LOW_VALUE;
+  g_thread_priority_map [G_THREAD_PRIORITY_NORMAL] = PRIORITY_NORMAL_VALUE;
+  g_thread_priority_map [G_THREAD_PRIORITY_HIGH] = PRIORITY_HIGH_VALUE;
+  g_thread_priority_map [G_THREAD_PRIORITY_URGENT] = PRIORITY_URGENT_VALUE;
+
+  g_thread_init_glib ();
+}
+
+#else /* !G_THREADS_ENABLED */
+
+void
+g_thread_init (GThreadFunctions* init)
+{
+  g_error ("GLib thread support is disabled.");
+}
+
+void
+g_thread_init_with_errorcheck_mutexes (GThreadFunctions* init)
+{
+  g_error ("GLib thread support is disabled.");
+}
+
+#endif /* !G_THREADS_ENABLED */
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/gthread-none.c b/resource/csdk/connectivity/lib/android/glib-master/gthread/gthread-none.c
new file mode 100644 (file)
index 0000000..6fbeff1
--- /dev/null
@@ -0,0 +1,39 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gthread.c: fallback thread system implementation
+ * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/. 
+ */
+
+/* 
+ * MT safe
+ */
+
+static GThreadFunctions
+g_thread_functions_for_glib_use_default; /* is NULLified */
+
+static guint64 (*g_thread_gettime_impl) (void) = NULL;
+#define G_MUTEX_SIZE 0
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/gthread-posix.c b/resource/csdk/connectivity/lib/android/glib-master/gthread/gthread-posix.c
new file mode 100644 (file)
index 0000000..9188f84
--- /dev/null
@@ -0,0 +1,467 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gthread.c: posix thread system implementation
+ * Copyright 1998 Sebastian Wilhelmi; University of Karlsruhe
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include <pthread.h>
+#include <errno.h>
+#include <stdlib.h>
+#ifdef HAVE_SYS_TIME_H
+# include <sys/time.h>
+#endif
+#ifdef HAVE_UNISTD_H
+# include <unistd.h>
+#endif
+
+#ifdef HAVE_SCHED_H
+#include <sched.h>
+#endif
+
+#define posix_check_err(err, name) G_STMT_START{                       \
+  int error = (err);                                                   \
+  if (error)                                                           \
+    g_error ("file %s: line %d (%s): error '%s' during '%s'",          \
+           __FILE__, __LINE__, G_STRFUNC,                              \
+           g_strerror (error), name);                                  \
+  }G_STMT_END
+
+#define posix_check_cmd(cmd) posix_check_err (posix_error (cmd), #cmd)
+
+#ifdef G_ENABLE_DEBUG
+static gboolean posix_check_cmd_prio_warned = FALSE;
+# define posix_check_cmd_prio(cmd) G_STMT_START{                       \
+    int err = posix_error (cmd);                                       \
+    if (err == EPERM)                                                  \
+      {                                                                \
+        if (!posix_check_cmd_prio_warned)                              \
+          {                                                            \
+            posix_check_cmd_prio_warned = TRUE;                                \
+            g_warning ("Priorities can only be changed "               \
+                        "(resp. increased) by root.");                         \
+          }                                                            \
+      }                                                                        \
+    else                                                               \
+      posix_check_err (err, #cmd);                                     \
+     }G_STMT_END
+#else /* G_ENABLE_DEBUG */
+# define posix_check_cmd_prio(cmd) G_STMT_START{                       \
+    int err = posix_error (cmd);                                       \
+    if (err != EPERM)                                                  \
+      posix_check_err (err, #cmd);                                     \
+     }G_STMT_END
+#endif /* G_ENABLE_DEBUG */
+
+#if defined(G_THREADS_IMPL_POSIX)
+# define posix_error(what) (what)
+# define mutexattr_default NULL
+# define condattr_default NULL
+#elif defined(G_THREADS_IMPL_DCE)
+# define posix_error(what) ((what) == -1 ? errno : 0)
+# define pthread_key_create(a, b) pthread_keycreate (a, b)
+# define pthread_attr_init(a) pthread_attr_create (a)
+# define pthread_attr_destroy(a) pthread_attr_delete (a)
+# define pthread_create(a, b, c, d) pthread_create (a, *b, c, d)
+# define mutexattr_default (pthread_mutexattr_default)
+# define condattr_default (pthread_condattr_default)
+#else /* neither G_THREADS_IMPL_POSIX nor G_THREADS_IMPL_DCE are defined */
+# error This should not happen. Contact the GLib team.
+#endif
+
+#if defined (POSIX_MIN_PRIORITY) && defined (POSIX_MAX_PRIORITY)
+# define HAVE_PRIORITIES 1
+static gint priority_normal_value;
+# ifdef __FreeBSD__
+   /* FreeBSD threads use different priority values from the POSIX_
+    * defines so we just set them here. The corresponding macros
+    * PTHREAD_MIN_PRIORITY and PTHREAD_MAX_PRIORITY are implied to be
+    * exported by the docs, but they aren't.
+    */
+#  define PRIORITY_LOW_VALUE      0
+#  define PRIORITY_URGENT_VALUE   31
+# else /* !__FreeBSD__ */
+#  define PRIORITY_LOW_VALUE      POSIX_MIN_PRIORITY
+#  define PRIORITY_URGENT_VALUE   POSIX_MAX_PRIORITY
+# endif /* !__FreeBSD__ */
+# define PRIORITY_NORMAL_VALUE    priority_normal_value
+#endif /* POSIX_MIN_PRIORITY && POSIX_MAX_PRIORITY */
+
+static gulong g_thread_min_stack_size = 0;
+
+#define G_MUTEX_SIZE (sizeof (pthread_mutex_t))
+
+#if defined(HAVE_CLOCK_GETTIME) && defined(HAVE_MONOTONIC_CLOCK) 
+#define USE_CLOCK_GETTIME 1
+static gint posix_clock = 0;
+#endif
+
+#if defined(_SC_THREAD_STACK_MIN) || defined (HAVE_PRIORITIES) || defined (USE_CLOCK_GETTIME)
+#define HAVE_G_THREAD_IMPL_INIT
+static void
+g_thread_impl_init(void)
+{
+#ifdef _SC_THREAD_STACK_MIN
+  g_thread_min_stack_size = MAX (sysconf (_SC_THREAD_STACK_MIN), 0);
+#endif /* _SC_THREAD_STACK_MIN */
+#ifdef HAVE_PRIORITIES
+# ifdef G_THREADS_IMPL_POSIX
+  {
+    struct sched_param sched;
+    int policy;
+    posix_check_cmd (pthread_getschedparam (pthread_self(), &policy, &sched));
+    priority_normal_value = sched.sched_priority;
+  }
+# else /* G_THREADS_IMPL_DCE */
+  posix_check_cmd (priority_normal_value =
+                  pthread_getprio (*(pthread_t*)thread,
+                                   g_thread_priority_map [priority]));
+# endif
+#endif /* HAVE_PRIORITIES */
+
+#ifdef USE_CLOCK_GETTIME
+ if (sysconf (_SC_MONOTONIC_CLOCK) >= 0)
+   posix_clock = CLOCK_MONOTONIC;
+ else
+   posix_clock = CLOCK_REALTIME;
+#endif
+}
+#endif /* _SC_THREAD_STACK_MIN || HAVE_PRIORITIES */
+
+static GMutex *
+g_mutex_new_posix_impl (void)
+{
+  GMutex *result = (GMutex *) g_new (pthread_mutex_t, 1);
+  posix_check_cmd (pthread_mutex_init ((pthread_mutex_t *) result,
+                                      mutexattr_default));
+  return result;
+}
+
+static void
+g_mutex_free_posix_impl (GMutex * mutex)
+{
+  posix_check_cmd (pthread_mutex_destroy ((pthread_mutex_t *) mutex));
+  g_free (mutex);
+}
+
+/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
+   functions from gmem.c and gmessages.c; */
+
+/* pthread_mutex_lock, pthread_mutex_unlock can be taken directly, as
+   signature and semantic are right, but without error check then!!!!,
+   we might want to change this therefore. */
+
+static gboolean
+g_mutex_trylock_posix_impl (GMutex * mutex)
+{
+  int result;
+
+  result = pthread_mutex_trylock ((pthread_mutex_t *) mutex);
+
+#ifdef G_THREADS_IMPL_POSIX
+  if (result == EBUSY)
+    return FALSE;
+#else /* G_THREADS_IMPL_DCE */
+  if (result == 0)
+    return FALSE;
+#endif
+
+  posix_check_err (posix_error (result), "pthread_mutex_trylock");
+  return TRUE;
+}
+
+static GCond *
+g_cond_new_posix_impl (void)
+{
+  GCond *result = (GCond *) g_new (pthread_cond_t, 1);
+  posix_check_cmd (pthread_cond_init ((pthread_cond_t *) result,
+                                     condattr_default));
+  return result;
+}
+
+/* pthread_cond_signal, pthread_cond_broadcast and pthread_cond_wait
+   can be taken directly, as signature and semantic are right, but
+   without error check then!!!!, we might want to change this
+   therefore. */
+
+#define G_NSEC_PER_SEC 1000000000
+
+static gboolean
+g_cond_timed_wait_posix_impl (GCond * cond,
+                             GMutex * entered_mutex,
+                             GTimeVal * abs_time)
+{
+  int result;
+  struct timespec end_time;
+  gboolean timed_out;
+
+  g_return_val_if_fail (cond != NULL, FALSE);
+  g_return_val_if_fail (entered_mutex != NULL, FALSE);
+
+  if (!abs_time)
+    {
+      result = pthread_cond_wait ((pthread_cond_t *)cond,
+                                  (pthread_mutex_t *) entered_mutex);
+      timed_out = FALSE;
+    }
+  else
+    {
+      end_time.tv_sec = abs_time->tv_sec;
+      end_time.tv_nsec = abs_time->tv_usec * (G_NSEC_PER_SEC / G_USEC_PER_SEC);
+
+      g_return_val_if_fail (end_time.tv_nsec < G_NSEC_PER_SEC, TRUE);
+
+      result = pthread_cond_timedwait ((pthread_cond_t *) cond,
+                                       (pthread_mutex_t *) entered_mutex,
+                                       &end_time);
+#ifdef G_THREADS_IMPL_POSIX
+      timed_out = (result == ETIMEDOUT);
+#else /* G_THREADS_IMPL_DCE */
+      timed_out = (result == -1) && (errno == EAGAIN);
+#endif
+    }
+
+  if (!timed_out)
+    posix_check_err (posix_error (result), "pthread_cond_timedwait");
+
+  return !timed_out;
+}
+
+static void
+g_cond_free_posix_impl (GCond * cond)
+{
+  posix_check_cmd (pthread_cond_destroy ((pthread_cond_t *) cond));
+  g_free (cond);
+}
+
+static GPrivate *
+g_private_new_posix_impl (GDestroyNotify destructor)
+{
+  GPrivate *result = (GPrivate *) g_new (pthread_key_t, 1);
+  posix_check_cmd (pthread_key_create ((pthread_key_t *) result, destructor));
+  return result;
+}
+
+/* NOTE: the functions g_private_get and g_private_set may not use
+   functions from gmem.c and gmessages.c */
+
+static void
+g_private_set_posix_impl (GPrivate * private_key, gpointer value)
+{
+  if (!private_key)
+    return;
+  pthread_setspecific (*(pthread_key_t *) private_key, value);
+}
+
+static gpointer
+g_private_get_posix_impl (GPrivate * private_key)
+{
+  if (!private_key)
+    return NULL;
+#ifdef G_THREADS_IMPL_POSIX
+  return pthread_getspecific (*(pthread_key_t *) private_key);
+#else /* G_THREADS_IMPL_DCE */
+  {
+    void* data;
+    posix_check_cmd (pthread_getspecific (*(pthread_key_t *) private_key,
+                                         &data));
+    return data;
+  }
+#endif
+}
+
+static void
+g_thread_create_posix_impl (GThreadFunc thread_func,
+                           gpointer arg,
+                           gulong stack_size,
+                           gboolean joinable,
+                           gboolean bound,
+                           GThreadPriority priority,
+                           gpointer thread,
+                           GError **error)
+{
+  pthread_attr_t attr;
+  gint ret;
+
+  g_return_if_fail (thread_func);
+  g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
+  g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
+
+  posix_check_cmd (pthread_attr_init (&attr));
+
+#ifdef HAVE_PTHREAD_ATTR_SETSTACKSIZE
+  if (stack_size)
+    {
+      stack_size = MAX (g_thread_min_stack_size, stack_size);
+      /* No error check here, because some systems can't do it and
+       * we simply don't want threads to fail because of that. */
+      pthread_attr_setstacksize (&attr, stack_size);
+    }
+#endif /* HAVE_PTHREAD_ATTR_SETSTACKSIZE */
+
+#ifdef PTHREAD_SCOPE_SYSTEM
+  if (bound)
+    /* No error check here, because some systems can't do it and we
+     * simply don't want threads to fail because of that. */
+    pthread_attr_setscope (&attr, PTHREAD_SCOPE_SYSTEM);
+#endif /* PTHREAD_SCOPE_SYSTEM */
+
+#ifdef G_THREADS_IMPL_POSIX
+  posix_check_cmd (pthread_attr_setdetachstate (&attr,
+          joinable ? PTHREAD_CREATE_JOINABLE : PTHREAD_CREATE_DETACHED));
+#endif /* G_THREADS_IMPL_POSIX */
+
+#ifdef HAVE_PRIORITIES
+# ifdef G_THREADS_IMPL_POSIX
+  {
+    struct sched_param sched;
+    posix_check_cmd (pthread_attr_getschedparam (&attr, &sched));
+    sched.sched_priority = g_thread_priority_map [priority];
+    posix_check_cmd_prio (pthread_attr_setschedparam (&attr, &sched));
+  }
+# else /* G_THREADS_IMPL_DCE */
+  posix_check_cmd_prio
+    (pthread_attr_setprio (&attr, g_thread_priority_map [priority]));
+# endif /* G_THREADS_IMPL_DCE */
+#endif /* HAVE_PRIORITIES */
+  ret = posix_error (pthread_create (thread, &attr,
+                                    (void* (*)(void*))thread_func, arg));
+
+  posix_check_cmd (pthread_attr_destroy (&attr));
+
+  if (ret == EAGAIN)
+    {
+      g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN, 
+                  "Error creating thread: %s", g_strerror (ret));
+      return;
+    }
+
+  posix_check_err (ret, "pthread_create");
+
+#ifdef G_THREADS_IMPL_DCE
+  if (!joinable)
+    posix_check_cmd (pthread_detach (thread));
+#endif /* G_THREADS_IMPL_DCE */
+}
+
+static void
+g_thread_yield_posix_impl (void)
+{
+  POSIX_YIELD_FUNC;
+}
+
+static void
+g_thread_join_posix_impl (gpointer thread)
+{
+  gpointer ignore;
+  posix_check_cmd (pthread_join (*(pthread_t*)thread, &ignore));
+}
+
+static void
+g_thread_exit_posix_impl (void)
+{
+  pthread_exit (NULL);
+}
+
+static void
+g_thread_set_priority_posix_impl (gpointer thread, GThreadPriority priority)
+{
+  g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
+  g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
+#ifdef HAVE_PRIORITIES
+# ifdef G_THREADS_IMPL_POSIX
+  {
+    struct sched_param sched;
+    int policy;
+    posix_check_cmd (pthread_getschedparam (*(pthread_t*)thread, &policy,
+                                           &sched));
+    sched.sched_priority = g_thread_priority_map [priority];
+    posix_check_cmd_prio (pthread_setschedparam (*(pthread_t*)thread, policy,
+                                                &sched));
+  }
+# else /* G_THREADS_IMPL_DCE */
+  posix_check_cmd_prio (pthread_setprio (*(pthread_t*)thread,
+                                        g_thread_priority_map [priority]));
+# endif
+#endif /* HAVE_PRIORITIES */
+}
+
+static void
+g_thread_self_posix_impl (gpointer thread)
+{
+  *(pthread_t*)thread = pthread_self();
+}
+
+static gboolean
+g_thread_equal_posix_impl (gpointer thread1, gpointer thread2)
+{
+  return (pthread_equal (*(pthread_t*)thread1, *(pthread_t*)thread2) != 0);
+}
+
+#ifdef USE_CLOCK_GETTIME 
+static guint64
+gettime (void)
+{
+  struct timespec tv;
+
+  clock_gettime (posix_clock, &tv);
+
+  return (guint64) tv.tv_sec * G_NSEC_PER_SEC + tv.tv_nsec;
+}
+static guint64 (*g_thread_gettime_impl)(void) = gettime;
+#else
+static guint64 (*g_thread_gettime_impl)(void) = 0;
+#endif
+
+static GThreadFunctions g_thread_functions_for_glib_use_default =
+{
+  g_mutex_new_posix_impl,
+  (void (*)(GMutex *)) pthread_mutex_lock,
+  g_mutex_trylock_posix_impl,
+  (void (*)(GMutex *)) pthread_mutex_unlock,
+  g_mutex_free_posix_impl,
+  g_cond_new_posix_impl,
+  (void (*)(GCond *)) pthread_cond_signal,
+  (void (*)(GCond *)) pthread_cond_broadcast,
+  (void (*)(GCond *, GMutex *)) pthread_cond_wait,
+  g_cond_timed_wait_posix_impl,
+  g_cond_free_posix_impl,
+  g_private_new_posix_impl,
+  g_private_get_posix_impl,
+  g_private_set_posix_impl,
+  g_thread_create_posix_impl,
+  g_thread_yield_posix_impl,
+  g_thread_join_posix_impl,
+  g_thread_exit_posix_impl,
+  g_thread_set_priority_posix_impl,
+  g_thread_self_posix_impl,
+  g_thread_equal_posix_impl
+};
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/gthread-win32.c b/resource/csdk/connectivity/lib/android/glib-master/gthread/gthread-win32.c
new file mode 100644 (file)
index 0000000..465b205
--- /dev/null
@@ -0,0 +1,639 @@
+/* GLIB - Library of useful routines for C programming
+ * Copyright (C) 1995-1997  Peter Mattis, Spencer Kimball and Josh MacDonald
+ *
+ * gthread.c: solaris thread system implementation
+ * Copyright 1998-2001 Sebastian Wilhelmi; University of Karlsruhe
+ * Copyright 2001 Hans Breuer
+ *
+ * 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 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., 59 Temple Place - Suite 330,
+ * Boston, MA 02111-1307, USA.
+ */
+
+/*
+ * Modified by the GLib Team and others 1997-2000.  See the AUTHORS
+ * file for a list of people on the GLib Team.  See the ChangeLog
+ * files for a list of changes.  These files are distributed with
+ * GLib at ftp://ftp.gtk.org/pub/gtk/.
+ */
+
+/*
+ * MT safe
+ */
+
+#include "config.h"
+
+#include "glib.h"
+
+#define STRICT
+#define _WIN32_WINDOWS 0x0401 /* to get IsDebuggerPresent */
+#include <windows.h>
+#undef STRICT
+
+#include <process.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#define win32_check_for_error(what) G_STMT_START{                      \
+  if (!(what))                                                         \
+    g_error ("file %s: line %d (%s): error %s during %s",              \
+            __FILE__, __LINE__, G_STRFUNC,                             \
+            g_win32_error_message (GetLastError ()), #what);           \
+  }G_STMT_END
+
+#define G_MUTEX_SIZE (sizeof (gpointer))
+
+#define PRIORITY_LOW_VALUE    THREAD_PRIORITY_BELOW_NORMAL
+#define PRIORITY_NORMAL_VALUE THREAD_PRIORITY_NORMAL
+#define PRIORITY_HIGH_VALUE   THREAD_PRIORITY_ABOVE_NORMAL
+#define PRIORITY_URGENT_VALUE THREAD_PRIORITY_HIGHEST
+
+static DWORD g_thread_self_tls;
+static DWORD g_private_tls;
+static DWORD g_cond_event_tls;
+static CRITICAL_SECTION g_thread_global_spinlock;
+
+typedef BOOL (__stdcall *GTryEnterCriticalSectionFunc) (CRITICAL_SECTION *);
+
+static GTryEnterCriticalSectionFunc try_enter_critical_section = NULL;
+
+/* As noted in the docs, GPrivate is a limited resource, here we take
+ * a rather low maximum to save memory, use GStaticPrivate instead. */
+#define G_PRIVATE_MAX 100
+
+static GDestroyNotify g_private_destructors[G_PRIVATE_MAX];
+
+static guint g_private_next = 0;
+
+/* A "forward" declaration of this structure */
+static GThreadFunctions g_thread_functions_for_glib_use_default;
+
+typedef struct _GThreadData GThreadData;
+struct _GThreadData
+{
+  GThreadFunc func;
+  gpointer data;
+  HANDLE thread;
+  gboolean joinable;
+};
+
+struct _GCond
+{
+  GPtrArray *array;
+  CRITICAL_SECTION lock;
+};
+
+static GMutex *
+g_mutex_new_win32_cs_impl (void)
+{
+  CRITICAL_SECTION *cs = g_new (CRITICAL_SECTION, 1);
+  gpointer *retval = g_new (gpointer, 1);
+
+  InitializeCriticalSection (cs);
+  *retval = cs;
+  return (GMutex *) retval;
+}
+
+static void
+g_mutex_free_win32_cs_impl (GMutex *mutex)
+{
+  gpointer *ptr = (gpointer *) mutex;
+  CRITICAL_SECTION *cs = (CRITICAL_SECTION *) *ptr;
+
+  DeleteCriticalSection (cs);
+  g_free (cs);
+  g_free (mutex);
+}
+
+/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
+   functions from gmem.c and gmessages.c; */
+
+static void
+g_mutex_lock_win32_cs_impl (GMutex *mutex)
+{
+  EnterCriticalSection (*(CRITICAL_SECTION **)mutex);
+}
+
+static gboolean
+g_mutex_trylock_win32_cs_impl (GMutex * mutex)
+{
+  return try_enter_critical_section (*(CRITICAL_SECTION **)mutex);
+}
+
+static void
+g_mutex_unlock_win32_cs_impl (GMutex *mutex)
+{
+  LeaveCriticalSection (*(CRITICAL_SECTION **)mutex);
+}
+
+static GMutex *
+g_mutex_new_win32_impl (void)
+{
+  HANDLE handle;
+  HANDLE *retval;
+  win32_check_for_error (handle = CreateMutex (NULL, FALSE, NULL));
+  retval = g_new (HANDLE, 1);
+  *retval = handle;
+  return (GMutex *) retval;
+}
+
+static void
+g_mutex_free_win32_impl (GMutex *mutex)
+{
+  win32_check_for_error (CloseHandle (*(HANDLE *) mutex));
+  g_free (mutex);
+}
+
+/* NOTE: the functions g_mutex_lock and g_mutex_unlock may not use
+   functions from gmem.c and gmessages.c; */
+
+static void
+g_mutex_lock_win32_impl (GMutex *mutex)
+{
+  WaitForSingleObject (*(HANDLE *) mutex, INFINITE);
+}
+
+static gboolean
+g_mutex_trylock_win32_impl (GMutex * mutex)
+{
+  DWORD result;
+  win32_check_for_error (WAIT_FAILED !=
+                        (result = WaitForSingleObject (*(HANDLE *)mutex, 0)));
+  return result != WAIT_TIMEOUT;
+}
+
+static void
+g_mutex_unlock_win32_impl (GMutex *mutex)
+{
+  ReleaseMutex (*(HANDLE *) mutex);
+}
+
+static GCond *
+g_cond_new_win32_impl (void)
+{
+  GCond *retval = g_new (GCond, 1);
+
+  retval->array = g_ptr_array_new ();
+  InitializeCriticalSection (&retval->lock);
+
+  return retval;
+}
+
+static void
+g_cond_signal_win32_impl (GCond * cond)
+{
+  EnterCriticalSection (&cond->lock);
+
+  if (cond->array->len > 0)
+    {
+      SetEvent (g_ptr_array_index (cond->array, 0));
+      g_ptr_array_remove_index (cond->array, 0);
+    }
+
+  LeaveCriticalSection (&cond->lock);
+}
+
+static void
+g_cond_broadcast_win32_impl (GCond * cond)
+{
+  guint i;
+  EnterCriticalSection (&cond->lock);
+
+  for (i = 0; i < cond->array->len; i++)
+    SetEvent (g_ptr_array_index (cond->array, i));
+
+  g_ptr_array_set_size (cond->array, 0);
+  LeaveCriticalSection (&cond->lock);
+}
+
+static gboolean
+g_cond_wait_internal (GCond *cond,
+                     GMutex *entered_mutex,
+                     gulong milliseconds)
+{
+  gulong retval;
+  HANDLE event = TlsGetValue (g_cond_event_tls);
+
+  if (!event)
+    {
+      win32_check_for_error (event = CreateEvent (0, FALSE, FALSE, NULL));
+      TlsSetValue (g_cond_event_tls, event);
+    }
+
+  EnterCriticalSection (&cond->lock);
+
+  /* The event must not be signaled. Check this */
+  g_assert (WaitForSingleObject (event, 0) == WAIT_TIMEOUT);
+
+  g_ptr_array_add (cond->array, event);
+  LeaveCriticalSection (&cond->lock);
+
+  g_thread_functions_for_glib_use_default.mutex_unlock (entered_mutex);
+
+  win32_check_for_error (WAIT_FAILED !=
+                        (retval = WaitForSingleObject (event, milliseconds)));
+
+  g_thread_functions_for_glib_use_default.mutex_lock (entered_mutex);
+
+  if (retval == WAIT_TIMEOUT)
+    {
+      EnterCriticalSection (&cond->lock);
+      g_ptr_array_remove (cond->array, event);
+
+      /* In the meantime we could have been signaled, so we must again
+       * wait for the signal, this time with no timeout, to reset
+       * it. retval is set again to honour the late arrival of the
+       * signal */
+      win32_check_for_error (WAIT_FAILED !=
+                            (retval = WaitForSingleObject (event, 0)));
+
+      LeaveCriticalSection (&cond->lock);
+    }
+
+#ifndef G_DISABLE_ASSERT
+  EnterCriticalSection (&cond->lock);
+
+  /* Now event must not be inside the array, check this */
+  g_assert (g_ptr_array_remove (cond->array, event) == FALSE);
+
+  LeaveCriticalSection (&cond->lock);
+#endif /* !G_DISABLE_ASSERT */
+
+  return retval != WAIT_TIMEOUT;
+}
+
+static void
+g_cond_wait_win32_impl (GCond *cond,
+                       GMutex *entered_mutex)
+{
+  g_return_if_fail (cond != NULL);
+  g_return_if_fail (entered_mutex != NULL);
+
+  g_cond_wait_internal (cond, entered_mutex, INFINITE);
+}
+
+static gboolean
+g_cond_timed_wait_win32_impl (GCond *cond,
+                             GMutex *entered_mutex,
+                             GTimeVal *abs_time)
+{
+  GTimeVal current_time;
+  gulong to_wait;
+
+  g_return_val_if_fail (cond != NULL, FALSE);
+  g_return_val_if_fail (entered_mutex != NULL, FALSE);
+
+  if (!abs_time)
+    to_wait = INFINITE;
+  else
+    {
+      g_get_current_time (&current_time);
+      if (abs_time->tv_sec < current_time.tv_sec ||
+         (abs_time->tv_sec == current_time.tv_sec &&
+          abs_time->tv_usec <= current_time.tv_usec))
+       to_wait = 0;
+      else
+       to_wait = (abs_time->tv_sec - current_time.tv_sec) * 1000 +
+         (abs_time->tv_usec - current_time.tv_usec) / 1000;
+    }
+
+  return g_cond_wait_internal (cond, entered_mutex, to_wait);
+}
+
+static void
+g_cond_free_win32_impl (GCond * cond)
+{
+  DeleteCriticalSection (&cond->lock);
+  g_ptr_array_free (cond->array, TRUE);
+  g_free (cond);
+}
+
+static GPrivate *
+g_private_new_win32_impl (GDestroyNotify destructor)
+{
+  GPrivate *result;
+  EnterCriticalSection (&g_thread_global_spinlock);
+  if (g_private_next >= G_PRIVATE_MAX)
+    {
+      char buf[100];
+      sprintf (buf,
+              "Too many GPrivate allocated. Their number is limited to %d.",
+              G_PRIVATE_MAX);
+      MessageBox (NULL, buf, NULL, MB_ICONERROR|MB_SETFOREGROUND);
+      if (IsDebuggerPresent ())
+       G_BREAKPOINT ();
+      abort ();
+    }
+  g_private_destructors[g_private_next] = destructor;
+  result = GUINT_TO_POINTER (g_private_next);
+  g_private_next++;
+  LeaveCriticalSection (&g_thread_global_spinlock);
+
+  return result;
+}
+
+/* NOTE: the functions g_private_get and g_private_set may not use
+   functions from gmem.c and gmessages.c */
+
+static void
+g_private_set_win32_impl (GPrivate * private_key, gpointer value)
+{
+  gpointer* array = TlsGetValue (g_private_tls);
+  guint index = GPOINTER_TO_UINT (private_key);
+
+  if (index >= G_PRIVATE_MAX)
+      return;
+
+  if (!array)
+    {
+      array = (gpointer*) calloc (G_PRIVATE_MAX, sizeof (gpointer));
+      TlsSetValue (g_private_tls, array);
+    }
+
+  array[index] = value;
+}
+
+static gpointer
+g_private_get_win32_impl (GPrivate * private_key)
+{
+  gpointer* array = TlsGetValue (g_private_tls);
+  guint index = GPOINTER_TO_UINT (private_key);
+
+  if (index >= G_PRIVATE_MAX || !array)
+    return NULL;
+
+  return array[index];
+}
+
+static void
+g_thread_set_priority_win32_impl (gpointer thread, GThreadPriority priority)
+{
+  GThreadData *target = *(GThreadData **)thread;
+
+  g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
+  g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
+
+  win32_check_for_error (SetThreadPriority (target->thread,
+                                           g_thread_priority_map [priority]));
+}
+
+static void
+g_thread_self_win32_impl (gpointer thread)
+{
+  GThreadData *self = TlsGetValue (g_thread_self_tls);
+
+  if (!self)
+    {
+      /* This should only happen for the main thread! */
+      HANDLE handle = GetCurrentThread ();
+      HANDLE process = GetCurrentProcess ();
+      self = g_new (GThreadData, 1);
+      win32_check_for_error (DuplicateHandle (process, handle, process,
+                                             &self->thread, 0, FALSE,
+                                             DUPLICATE_SAME_ACCESS));
+      win32_check_for_error (TlsSetValue (g_thread_self_tls, self));
+      self->func = NULL;
+      self->data = NULL;
+      self->joinable = FALSE;
+    }
+
+  *(GThreadData **)thread = self;
+}
+
+static void
+g_thread_exit_win32_impl (void)
+{
+  GThreadData *self = TlsGetValue (g_thread_self_tls);
+  guint i, private_max;
+  gpointer *array = TlsGetValue (g_private_tls);
+  HANDLE event = TlsGetValue (g_cond_event_tls);
+
+  EnterCriticalSection (&g_thread_global_spinlock);
+  private_max = g_private_next;
+  LeaveCriticalSection (&g_thread_global_spinlock);
+
+  if (array)
+    {
+      gboolean some_data_non_null;
+
+      do {
+       some_data_non_null = FALSE;
+       for (i = 0; i < private_max; i++)
+         {
+           GDestroyNotify destructor = g_private_destructors[i];
+           GDestroyNotify data = array[i];
+
+           if (data)
+             some_data_non_null = TRUE;
+
+           array[i] = NULL;
+
+           if (destructor && data)
+             destructor (data);
+         }
+      } while (some_data_non_null);
+
+      free (array);
+
+      win32_check_for_error (TlsSetValue (g_private_tls, NULL));
+    }
+
+  if (self)
+    {
+      if (!self->joinable)
+       {
+         win32_check_for_error (CloseHandle (self->thread));
+         g_free (self);
+       }
+      win32_check_for_error (TlsSetValue (g_thread_self_tls, NULL));
+    }
+
+  if (event)
+    {
+      CloseHandle (event);
+      win32_check_for_error (TlsSetValue (g_cond_event_tls, NULL));
+    }
+
+  _endthreadex (0);
+}
+
+static guint __stdcall
+g_thread_proxy (gpointer data)
+{
+  GThreadData *self = (GThreadData*) data;
+
+  win32_check_for_error (TlsSetValue (g_thread_self_tls, self));
+
+  self->func (self->data);
+
+  g_thread_exit_win32_impl ();
+
+  g_assert_not_reached ();
+
+  return 0;
+}
+
+static void
+g_thread_create_win32_impl (GThreadFunc func,
+                           gpointer data,
+                           gulong stack_size,
+                           gboolean joinable,
+                           gboolean bound,
+                           GThreadPriority priority,
+                           gpointer thread,
+                           GError **error)
+{
+  guint ignore;
+  GThreadData *retval;
+
+  g_return_if_fail (func);
+  g_return_if_fail (priority >= G_THREAD_PRIORITY_LOW);
+  g_return_if_fail (priority <= G_THREAD_PRIORITY_URGENT);
+
+  retval = g_new(GThreadData, 1);
+  retval->func = func;
+  retval->data = data;
+
+  retval->joinable = joinable;
+
+  retval->thread = (HANDLE) _beginthreadex (NULL, stack_size, g_thread_proxy,
+                                           retval, 0, &ignore);
+
+  if (retval->thread == NULL)
+    {
+      gchar *win_error = g_win32_error_message (GetLastError ());
+      g_set_error (error, G_THREAD_ERROR, G_THREAD_ERROR_AGAIN,
+                   "Error creating thread: %s", win_error);
+      g_free (retval);
+      g_free (win_error);
+      return;
+    }
+
+  *(GThreadData **)thread = retval;
+
+  g_thread_set_priority_win32_impl (thread, priority);
+}
+
+static void
+g_thread_yield_win32_impl (void)
+{
+  Sleep(0);
+}
+
+static void
+g_thread_join_win32_impl (gpointer thread)
+{
+  GThreadData *target = *(GThreadData **)thread;
+
+  g_return_if_fail (target->joinable);
+
+  win32_check_for_error (WAIT_FAILED !=
+                        WaitForSingleObject (target->thread, INFINITE));
+
+  win32_check_for_error (CloseHandle (target->thread));
+  g_free (target);
+}
+
+static guint64
+g_thread_gettime_impl (void)
+{
+  guint64 v;
+
+  /* Returns 100s of nanoseconds since start of 1601 */
+  GetSystemTimeAsFileTime ((FILETIME *)&v);
+
+  /* Offset to Unix epoch */
+  v -= G_GINT64_CONSTANT (116444736000000000);
+  /* Convert to nanoseconds */
+  v *= 100;
+
+  return v;
+}
+
+static GThreadFunctions g_thread_functions_for_glib_use_default =
+{
+  g_mutex_new_win32_impl,           /* mutex */
+  g_mutex_lock_win32_impl,
+  g_mutex_trylock_win32_impl,
+  g_mutex_unlock_win32_impl,
+  g_mutex_free_win32_impl,
+  g_cond_new_win32_impl,            /* condition */
+  g_cond_signal_win32_impl,
+  g_cond_broadcast_win32_impl,
+  g_cond_wait_win32_impl,
+  g_cond_timed_wait_win32_impl,
+  g_cond_free_win32_impl,
+  g_private_new_win32_impl,         /* private thread data */
+  g_private_get_win32_impl,
+  g_private_set_win32_impl,
+  g_thread_create_win32_impl,       /* thread */
+  g_thread_yield_win32_impl,
+  g_thread_join_win32_impl,
+  g_thread_exit_win32_impl,
+  g_thread_set_priority_win32_impl,
+  g_thread_self_win32_impl,
+  NULL                             /* no equal function necessary */
+};
+
+#define HAVE_G_THREAD_IMPL_INIT
+static void
+g_thread_impl_init ()
+{
+  static gboolean beenhere = FALSE;
+  HMODULE kernel32;
+
+  if (beenhere)
+    return;
+
+  beenhere = TRUE;
+
+  win32_check_for_error (TLS_OUT_OF_INDEXES !=
+                        (g_thread_self_tls = TlsAlloc ()));
+  win32_check_for_error (TLS_OUT_OF_INDEXES !=
+                        (g_private_tls = TlsAlloc ()));
+  win32_check_for_error (TLS_OUT_OF_INDEXES !=
+                        (g_cond_event_tls = TlsAlloc ()));
+  InitializeCriticalSection (&g_thread_global_spinlock);
+
+  /* Here we are looking for TryEnterCriticalSection in KERNEL32.DLL,
+   * if it is found, we can use the in general faster critical
+   * sections instead of mutexes. See
+   * http://world.std.com/~jmhart/csmutx.htm for some discussion.
+   */
+  kernel32 = GetModuleHandle ("KERNEL32.DLL");
+  if (kernel32)
+    {
+      try_enter_critical_section = (GTryEnterCriticalSectionFunc)
+       GetProcAddress(kernel32, "TryEnterCriticalSection");
+
+      /* Even if TryEnterCriticalSection is found, it is not
+       * necessarily working..., we have to check it */
+      if (try_enter_critical_section &&
+         try_enter_critical_section (&g_thread_global_spinlock))
+       {
+         LeaveCriticalSection (&g_thread_global_spinlock);
+
+         g_thread_functions_for_glib_use_default.mutex_new =
+           g_mutex_new_win32_cs_impl;
+         g_thread_functions_for_glib_use_default.mutex_lock =
+           g_mutex_lock_win32_cs_impl;
+         g_thread_functions_for_glib_use_default.mutex_trylock =
+           g_mutex_trylock_win32_cs_impl;
+         g_thread_functions_for_glib_use_default.mutex_unlock =
+           g_mutex_unlock_win32_cs_impl;
+         g_thread_functions_for_glib_use_default.mutex_free =
+           g_mutex_free_win32_cs_impl;
+       }
+    }
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/gthread.def b/resource/csdk/connectivity/lib/android/glib-master/gthread/gthread.def
new file mode 100644 (file)
index 0000000..200b043
--- /dev/null
@@ -0,0 +1,3 @@
+EXPORTS
+       g_thread_init
+       g_thread_init_with_errorcheck_mutexes
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/gthread.rc.in b/resource/csdk/connectivity/lib/android/glib-master/gthread/gthread.rc.in
new file mode 100644 (file)
index 0000000..67a2a46
--- /dev/null
@@ -0,0 +1,30 @@
+#include <winver.h>
+
+VS_VERSION_INFO VERSIONINFO
+  FILEVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
+  PRODUCTVERSION @GLIB_MAJOR_VERSION@,@GLIB_MINOR_VERSION@,@GLIB_MICRO_VERSION@,0
+  FILEFLAGSMASK 0
+  FILEFLAGS 0
+  FILEOS VOS__WINDOWS32
+  FILETYPE VFT_DLL
+  FILESUBTYPE VFT2_UNKNOWN
+  BEGIN
+    BLOCK "StringFileInfo"
+    BEGIN
+      BLOCK "040904B0"
+      BEGIN
+       VALUE "CompanyName", "The GLib developer community"
+       VALUE "FileDescription", "GThread"
+       VALUE "FileVersion", "@GLIB_VERSION@.0"
+       VALUE "InternalName", "libgthread-2.0-@LT_CURRENT_MINUS_AGE@"
+       VALUE "LegalCopyright", "Copyright © 1995-2010 Peter Mattis, Spencer Kimball, Josh MacDonald, Sebastian Wilhelmi and others."
+       VALUE "OriginalFilename", "libgthread-2.0-@LT_CURRENT_MINUS_AGE@.dll"
+       VALUE "ProductName", "GLib"
+       VALUE "ProductVersion", "@GLIB_VERSION@"
+      END
+    END
+    BLOCK "VarFileInfo"
+    BEGIN
+      VALUE "Translation", 0x409, 1200
+    END
+  END
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/makefile.msc.in b/resource/csdk/connectivity/lib/android/glib-master/gthread/makefile.msc.in
new file mode 100644 (file)
index 0000000..226bf9c
--- /dev/null
@@ -0,0 +1,26 @@
+## Makefile for building the gthread dll with Microsoft C
+## Use: nmake -f makefile.msc install
+
+TOP = ..\..
+
+!INCLUDE ..\build\win32\make.msc
+
+################################################################
+
+INCLUDES = -FImsvc_recommended_pragmas.h -I .. -I . -I ..\glib
+DEFINES = -DHAVE_CONFIG_H -DG_LOG_DOMAIN=\"GThread\"
+all : \
+       libgthread-2.0-@LT_CURRENT_MINUS_AGE@.dll
+
+gthread_OBJECTS = \
+       gthread-impl.obj
+
+gthread-impl.obj : gthread-impl.c gthread-win32.c
+       $(CC) -c $(CFLAGS) gthread-impl.c
+
+gthread.res : gthread.rc
+       rc -DBUILDNUMBER=0 -r -fo gthread.res gthread.rc
+
+libgthread-2.0-@LT_CURRENT_MINUS_AGE@.dll : $(gthread_OBJECTS) gthread.def gthread.res
+       $(CC) $(CFLAGS) -LD -Fe$@ $(gthread_OBJECTS) gthread.res \
+       ..\glib\glib-2.0.lib $(DEPCLIBS) user32.lib $(LDFLAGS) /implib:gthread-2.0.lib /def:gthread.def
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/tests/.gitignore b/resource/csdk/connectivity/lib/android/glib-master/gthread/tests/.gitignore
new file mode 100644 (file)
index 0000000..ad7fa10
--- /dev/null
@@ -0,0 +1,2 @@
+1bit-mutex
+1bit-emufutex
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/tests/1bit-mutex.c b/resource/csdk/connectivity/lib/android/glib-master/gthread/tests/1bit-mutex.c
new file mode 100644 (file)
index 0000000..6c5d0cd
--- /dev/null
@@ -0,0 +1,135 @@
+/*
+ * Copyright © 2008 Ryan Lortie
+ * Copyright © 2010 Codethink Limited
+ *
+ * This program 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 of the
+ * License, or (at your option) any later version.
+ *
+ * See the included COPYING file for more information.
+ */
+
+/* LOCKS should be more than the number of contention
+ * counters in gthread.c in order to ensure we exercise
+ * the case where they overlap.
+ */
+#define LOCKS      48
+#define ITERATIONS 10000
+#define THREADS    100
+
+
+#if TEST_EMULATED_FUTEX
+  /* this is defined for the 1bit-mutex-emufutex test.
+   *
+   * we want to test the emulated futex even if futex(2) is available.
+   */
+
+  /* side-step some glib build stuff */
+  #ifndef DISABLE_VISIBILITY
+  #define DISABLE_VISIBILITY
+  #endif
+  #define GLIB_COMPILATION
+
+  /* rebuild gbitlock.c without futex support,
+     defining our own version of the g_bit_*lock symbols
+   */
+  #define g_bit_lock            _emufutex_g_bit_lock
+  #define g_bit_trylock         _emufutex_g_bit_trylock
+  #define g_bit_unlock          _emufutex_g_bit_unlock
+  #define _g_futex_thread_init  _emufutex_g_futex_thread_init
+
+  #define G_BIT_LOCK_FORCE_FUTEX_EMULATION
+
+  #include <glib/gbitlock.c>
+#endif
+
+#include <glib.h>
+
+volatile GThread *owners[LOCKS];
+volatile gint     locks[LOCKS];
+volatile gint     bits[LOCKS];
+
+static void
+acquire (int nr)
+{
+  GThread *self;
+
+  self = g_thread_self ();
+
+  if (!g_bit_trylock (&locks[nr], bits[nr]))
+    {
+      if (g_test_verbose ())
+        g_print ("thread %p going to block on lock %d\n", self, nr);
+      g_bit_lock (&locks[nr], bits[nr]);
+    }
+
+  g_assert (owners[nr] == NULL);   /* hopefully nobody else is here */
+  owners[nr] = self;
+
+  /* let some other threads try to ruin our day */
+  g_thread_yield ();
+  g_thread_yield ();
+  g_thread_yield ();
+
+  g_assert (owners[nr] == self);   /* hopefully this is still us... */
+  owners[nr] = NULL;               /* make way for the next guy */
+  g_bit_unlock (&locks[nr], bits[nr]);
+}
+
+static gpointer
+thread_func (gpointer data)
+{
+  gint i;
+
+  for (i = 0; i < ITERATIONS; i++)
+    acquire (g_random_int () % LOCKS);
+
+  return NULL;
+}
+
+static void
+testcase (void)
+{
+  GThread *threads[THREADS];
+  int i;
+
+  g_thread_init (NULL);
+
+#ifdef TEST_EMULATED_FUTEX
+  _g_futex_thread_init ();
+  #define SUFFIX "-emufutex"
+
+  /* ensure that we are using the emulated futex by checking
+   * (at compile-time) for the existance of 'g_futex_mutex'
+   */
+  g_assert (g_futex_mutex != NULL);
+#else
+  #define SUFFIX ""
+#endif
+
+  for (i = 0; i < LOCKS; i++)
+    bits[i] = g_random_int () % 32;
+
+  for (i = 0; i < THREADS; i++)
+    threads[i] = g_thread_create (thread_func, NULL, TRUE, NULL);
+
+  for (i = 0; i < THREADS; i++)
+    g_thread_join (threads[i]);
+
+  for (i = 0; i < LOCKS; i++)
+    {
+      g_assert (owners[i] == NULL);
+      g_assert (locks[i] == 0);
+    }
+}
+
+int
+main (int argc, char **argv)
+{
+  g_test_init (&argc, &argv, NULL);
+
+  g_test_add_func ("/glib/1bit-mutex" SUFFIX, testcase);
+
+  return g_test_run ();
+}
diff --git a/resource/csdk/connectivity/lib/android/glib-master/gthread/tests/Makefile.am b/resource/csdk/connectivity/lib/android/glib-master/gthread/tests/Makefile.am
new file mode 100644 (file)
index 0000000..387098a
--- /dev/null
@@ -0,0 +1,15 @@
+include $(top_srcdir)/Makefile.decl
+
+INCLUDES = -g $(gthread_INCLUDES) $(GLIB_DEBUG_FLAGS)
+
+noinst_PROGRAMS = $(TEST_PROGS)
+progs_ldadd     = $(top_builddir)/glib/libglib-2.0.la \
+                 $(top_builddir)/gthread/libgthread-2.0.la
+
+TEST_PROGS      += 1bit-mutex
+1bit_mutex_LDADD  = $(progs_ldadd) $(top_builddir)/gthread/libgthread-2.0.la
+
+TEST_PROGS           += 1bit-emufutex
+1bit_emufutex_SOURCES  = 1bit-mutex.c
+1bit_emufutex_CFLAGS   = -DTEST_EMULATED_FUTEX
+1bit_emufutex_LDADD    = $(progs_ldadd) $(top_builddir)/gthread/libgthread-2.0.la
diff --git a/resource/csdk/connectivity/samples/android/sample_app/Makefile b/resource/csdk/connectivity/samples/android/sample_app/Makefile
new file mode 100644 (file)
index 0000000..ae9fca9
--- /dev/null
@@ -0,0 +1,18 @@
+#Assumes ndk directory is at ~/
+#set ndk directory PATH in .bashrc and use the ndk-build directly
+NDK_PATH = ~/ndk
+NDK_BUILD = $(NDK_PATH)/ndk-build
+
+BUILD_DIR = $(CURDIR)
+APPLICATION_BUILD = $(BUILD_DIR)
+ROOT_DIR = $(BUILD_DIR)
+
+#Clean files
+LIBS_DIR = $(ROOT_DIR)/libs
+OBJ_DIR = $(ROOT_DIR)/obj
+
+all:
+       $(NDK_BUILD) NDK_PROJECT_PATH=$(APPLICATION_BUILD)
+
+clean :        
+       @$(RM) -rf $(LIBS_DIR) $(OBJ_DIR)
\ No newline at end of file
diff --git a/resource/csdk/connectivity/samples/android/sample_app/jni/Android.mk b/resource/csdk/connectivity/samples/android/sample_app/jni/Android.mk
new file mode 100644 (file)
index 0000000..91c18d9
--- /dev/null
@@ -0,0 +1,24 @@
+APP_PATH := $(call my-dir)
+
+#specify project root path here wrt make file directory
+PROJECT_ROOT_PATH      = ../../..
+PROJECT_API_PATH       = $(PROJECT_ROOT_PATH)/api
+
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#Build sample_main
+include $(CLEAR_VARS)
+LOCAL_PATH = $(APP_PATH)
+LOCAL_MODULE = sample
+LOCAL_C_INCLUDES = $(PROJECT_API_PATH)
+LOCAL_STATIC_LIBRARIES = CA
+LOCAL_SRC_FILES = sample_main.c
+include $(BUILD_EXECUTABLE)
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#Build glib CACommon CACoap CA
+include $(CLEAR_VARS)
+PROJECT_LIB_PATH = $(PROJECT_ROOT_PATH)/build/android
+include $(PROJECT_LIB_PATH)/jni/Android.mk
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+
diff --git a/resource/csdk/connectivity/samples/android/sample_app/jni/Application.mk b/resource/csdk/connectivity/samples/android/sample_app/jni/Application.mk
new file mode 100644 (file)
index 0000000..40d9615
--- /dev/null
@@ -0,0 +1,6 @@
+APP_STL := gnustl_static
+
+APP_PLATFORM = android-19
+APP_CPPFLAGS += -fexceptions
+#APP_CPPFLAGS += -frtti += -Wno-error=format-security
+APP_CFLAGS = -Wno-error=format-security
\ No newline at end of file
diff --git a/resource/csdk/connectivity/samples/android/sample_app/sample_main.c b/resource/csdk/connectivity/samples/android/sample_app/sample_main.c
new file mode 100644 (file)
index 0000000..c0a40cc
--- /dev/null
@@ -0,0 +1,577 @@
+/******************************************************************
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "cacommon.h"
+#include "cainterface.h"
+
+#define MAX_BUF_LEN 1024
+#define MAX_OPT_LEN 16
+#define TRUE 1
+#define FALSE 0
+
+char get_menu();
+void process();
+
+void start_listening_server();
+void start_discovery_server();
+void find_resource();
+void send_request();
+void send_response();
+void advertise_resource();
+void send_notification();
+void select_network();
+void unselect_network();
+void handle_request_response();
+void find_fixed_resource();
+
+void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo);
+void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo);
+void send_request_tmp(CARemoteEndpoint_t* endpoint, CAToken_t token);
+int received = FALSE;
+
+int main()
+{
+    system("clear");
+
+    printf("=============================================\n");
+    printf("\t\tsample main\n");
+    printf("=============================================\n");
+
+    CAInitialize();
+
+    // network enable
+    // default
+    printf("select default network(WIFI)\n");
+    CASelectNetwork(CA_WIFI);
+
+    // set handler.
+    CARegisterHandler(request_handler, response_handler);
+
+    process();
+
+    CATerminate();
+
+    return 0;
+}
+
+void process()
+{
+    while (1)
+    {
+        char menu = get_menu();
+
+        switch (menu)
+        {
+            case 'm': // menu
+            case 'M':
+                continue;
+
+            case 'q': // quit
+            case 'Q':
+                printf("quit..!!\n");
+                return;
+
+            case 's': // start server
+            case 'S':
+                start_listening_server();
+                break;
+
+            case 'c': // start client
+            case 'D':
+                start_discovery_server();
+                break;
+
+            case 'f': // find resource
+            case 'F':
+                find_resource();
+                break;
+
+            case 'r': // send request
+            case 'R':
+                send_request();
+                break;
+
+            case 'a': // advertise resource
+            case 'A':
+                advertise_resource();
+                break;
+
+            case 'b': // send notification
+            case 'B':
+                send_notification();
+                break;
+
+            case 'n': // select network
+            case 'N':
+                select_network();
+                break;
+
+            case 'x': // unselect network
+            case 'X':
+                unselect_network();
+                break;
+
+            case 'h': // handle request response
+            case 'H':
+                handle_request_response();
+                break;
+            case 'y':
+            case 'Y':
+                while (1)
+                {
+                    received = FALSE;
+                    find_fixed_resource();
+                    while (received == FALSE)
+                    {
+                        sleep(1);
+                        handle_request_response();
+
+                    }
+                }
+                break;
+            case 'z':
+            case 'Z':
+                start_listening_server();
+                while (1)
+                {
+                    sleep(1);
+                    handle_request_response();
+                }
+                break;
+
+            default:
+                printf("not supported menu!!\n");
+                break;
+        }
+    }
+
+}
+
+void start_listening_server()
+{
+    printf("start listening server!!\n");
+
+    CAStartListeningServer();
+}
+
+void start_discovery_server()
+{
+    printf("start discovery client!!\n");
+
+    CAStartDiscoveryServer();
+}
+
+void find_fixed_resource()
+{
+    char buf[MAX_BUF_LEN] =
+    { 0, };
+    strcpy(buf, "a/light");
+
+    CAResult_t res = CAFindResource(buf, "temptoken");
+
+    if (res != CA_STATUS_OK)
+    {
+        printf("find resource error!!\n");
+    }
+    else
+    {
+        printf("find resource to %s URI\n", buf);
+    }
+
+    printf("=============================================\n");
+}
+
+void find_resource()
+{
+    char buf[MAX_BUF_LEN];
+
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+
+    printf("\n=============================================\n");
+    printf("ex) a/light\n");
+    printf("reference uri : ");
+
+    gets(buf);
+
+    CAResult_t res = CAFindResource(buf, "temptoken");
+
+    if (res != CA_STATUS_OK)
+    {
+        printf("find resource error!!\n");
+    }
+    else
+    {
+        printf("find resource to %s URI\n", buf);
+    }
+
+    printf("=============================================\n");
+}
+
+void send_request()
+{
+    char buf[MAX_BUF_LEN];
+
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+
+    printf("\n=============================================\n");
+    printf("10.11.12.13:4545/resource_uri ( for IP )\n");
+    printf("10:11:12:13:45:45/resource_uri ( for BT )\n");
+    printf("uri : ");
+
+    gets(buf);
+
+    // create remote endpoint
+    CARemoteEndpoint_t* endpoint = NULL;
+    CAResult_t res = CACreateRemoteEndpoint(buf, &endpoint);
+
+    if (res != CA_STATUS_OK)
+    {
+        printf("create remote endpoint error!!");
+        CADestroyRemoteEndpoint(endpoint);
+        return;
+    }
+
+    // create token
+    CAToken_t token = NULL;
+    res = CAGenerateToken(&token);
+
+    if (res != CA_STATUS_OK)
+    {
+        printf("token generate error!!");
+        token = NULL;
+    }
+
+    printf("generated token %s\n", (token != NULL) ? token : "");
+
+    CAInfo_t requestData;
+    memset(&requestData, 0, sizeof(CAInfo_t));
+    requestData.token = token;
+    requestData.payload = "Temp Json Payload";
+
+    CARequestInfo_t requestInfo;
+    memset(&requestInfo, 0, sizeof(CARequestInfo_t));
+    requestInfo.method = CA_GET;
+    requestInfo.info = requestData;
+
+    // send request
+    CASendRequest(endpoint, &requestInfo);
+
+    if (token != NULL)
+    {
+        CADestroyToken(token);
+    }
+
+    // destroy remote endpoint
+    if (endpoint != NULL)
+    {
+        CADestroyRemoteEndpoint(endpoint);
+    }
+
+    printf("=============================================\n");
+}
+
+void advertise_resource()
+{
+    char buf[MAX_BUF_LEN];
+
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+
+    printf("\n=============================================\n");
+    printf("uri : ");
+
+    scanf("%s", buf);
+
+    int optionNum = 0;
+    char optionData[MAX_OPT_LEN];
+
+    printf("Option Num : ");
+    scanf("%d", &optionNum);
+    CAHeaderOption_t *headerOpt;
+    headerOpt = (CAHeaderOption_t*) malloc(sizeof(CAHeaderOption_t) * optionNum);
+    if (NULL == headerOpt)
+    {
+        printf("Memory allocation failed!\n");
+        return;
+    }
+    memset(headerOpt, 0, sizeof(CAHeaderOption_t) * optionNum);
+
+    int i;
+    for (i = 0; i < optionNum; i++)
+    {
+        int optionID = 0;
+        printf("[%d] Option ID : ", i + 1);
+        scanf("%d", &optionID);
+        headerOpt[i].optionID = optionID;
+
+        memset(optionData, 0, sizeof(char) * MAX_OPT_LEN);
+        printf("[%d] Option Data : ", i + 1);
+        scanf("%s", optionData);
+        memcpy(headerOpt[i].optionData, optionData, strlen(optionData));
+        printf("[%d] inputed option : ID : %d, data : %s\n", i + 1, optionID, optionData);
+
+        headerOpt[i].optionLength = (uint16_t) strlen(optionData);
+    }
+    printf("\n=============================================\n");
+
+    CAAdvertiseResource(buf, "temptoken", headerOpt, (uint8_t) optionNum);
+
+    free(headerOpt);
+
+}
+
+void send_notification()
+{
+    char buf[MAX_BUF_LEN];
+
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+
+    printf("\n=============================================\n");
+    printf("10.11.12.13:4545/resource_uri ( for IP )\n");
+    printf("10:11:12:13:45:45/resource_uri ( for BT )\n");
+    printf("uri : ");
+
+    gets(buf);
+
+    // create remote endpoint
+    CARemoteEndpoint_t* endpoint = NULL;
+    CAResult_t res = CACreateRemoteEndpoint(buf, &endpoint);
+
+    if (res != CA_STATUS_OK)
+    {
+        printf("create remote endpoint error!!");
+        CADestroyRemoteEndpoint(endpoint);
+        return;
+    }
+
+    CAInfo_t respondeData;
+    memset(&respondeData, 0, sizeof(CAInfo_t));
+    respondeData.token = "client token";
+    respondeData.payload = "Temp Notification Data";
+
+    CAResponseInfo_t responseInfo;
+    memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
+    responseInfo.result = CA_SUCCESS;
+    responseInfo.info = respondeData;
+
+    // send request
+    CASendNotification(endpoint, &responseInfo);
+
+    // destroy remote endpoint
+    if (endpoint != NULL)
+    {
+        CADestroyRemoteEndpoint(endpoint);
+    }
+    printf("\n=============================================\n");
+}
+
+void select_network()
+{
+    char buf[MAX_BUF_LEN];
+
+    printf("\n=============================================\n");
+    printf("\tselect network\n");
+    printf("ETHERNET : 0\n");
+    printf("WIFI : 1\n");
+    printf("EDR : 2\n");
+    printf("LE : 3\n");
+    printf("select : ");
+
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+    gets(buf);
+
+    int number = buf[0] - '0';
+
+    number = (number < 0 || number > 3) ? 1 : number;
+
+    CASelectNetwork(1 << number);
+
+    printf("=============================================\n");
+}
+
+void unselect_network()
+{
+    char buf[MAX_BUF_LEN];
+
+    printf("\n=============================================\n");
+    printf("\tunselect enabled network\n");
+    printf("ETHERNET : 0\n");
+    printf("WIFI : 1\n");
+    printf("EDR : 2\n");
+    printf("LE : 3\n");
+    printf("select : ");
+
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+    gets(buf);
+
+    int number = buf[0] - '0';
+
+    number = (number < 0 || number > 3) ? 1 : number;
+
+    CAUnSelectNetwork(1 << number);
+
+    printf("=============================================\n");
+}
+
+char get_menu()
+{
+    char buf[MAX_BUF_LEN];
+
+    printf("\n=============================================\n");
+    printf("\t\tMenu\n");
+    printf("\ts : start server\n");
+    printf("\tc : start client\n");
+    printf("\tf : find resource\n");
+    printf("\tr : send request\n");
+    printf("\ta : advertise resource\n");
+    printf("\tb : send notification\n");
+    printf("\tn : select network\n");
+    printf("\tx : unselect network\n");
+    printf("\th : handle request response\n");
+    printf("\ty : run static client\n");
+    printf("\tz : run static server\n");
+    printf("\tq : quit\n");
+    printf("=============================================\n");
+    printf("select : ");
+
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+
+    gets(buf);
+
+    return buf[0];
+}
+
+void handle_request_response()
+{
+    printf("handle_request_response\n");
+    CAHandleRequestResponse();
+}
+
+void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo)
+{
+
+    printf("[CALLBACK] request_handler, uri : %s, data : %s\n",
+            (object != NULL) ? object->resourceUri : "",
+            (requestInfo != NULL) ? requestInfo->info.payload : "");
+
+    printf("[CALLBACK] request_handler, address : %s\n",
+            (object != NULL) ? object->addressInfo.IP.ipAddress : "");
+
+    if (requestInfo->info.options)
+    {
+        uint32_t len = requestInfo->info.numOptions;
+        uint32_t i;
+        for (i = 0; i < len; i++)
+        {
+            printf("[CALLBACK] request_handler, option ID : %d\n",
+                    requestInfo->info.options[i].optionID);
+            printf("[CALLBACK] request_handler, options data length : %d\n",
+                    requestInfo->info.options[i].optionLength);
+            printf("[CALLBACK] request_handler, options data : %s\n",
+                    requestInfo->info.options[i].optionData);
+        }
+    }
+
+    printf("send response with URI\n");
+    send_response(object, (requestInfo != NULL) ? requestInfo->info.token : "");
+
+    received = TRUE;
+
+}
+
+void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo)
+{
+
+    printf("[CALLBACK] response_handler, uri : %s, data : %s\n",
+            (object != NULL) ? object->resourceUri : "",
+            (responseInfo != NULL) ? responseInfo->info.payload : "");
+
+    printf("[CALLBACK] response_handler, address : %s\n",
+            (object != NULL) ? object->addressInfo.IP.ipAddress : "");
+
+    if (responseInfo->info.options)
+    {
+        uint32_t len = responseInfo->info.numOptions;
+        uint32_t i;
+        for (i = 0; i < len; i++)
+        {
+            printf("[CALLBACK] response_handler, option ID : %d\n",
+                    responseInfo->info.options[i].optionID);
+            printf("[CALLBACK] response_handler, options data length : %d\n",
+                    responseInfo->info.options[i].optionLength);
+            printf("[CALLBACK] response_handler, options data : %s\n",
+                    responseInfo->info.options[i].optionData);
+        }
+    }
+    received = TRUE;
+
+    //printf("send request with URI\n");
+    //send_request_tmp(object, (responseInfo != NULL) ? responseInfo->info.token : "");
+}
+
+void send_response(CARemoteEndpoint_t* endpoint, CAToken_t request_token)
+{
+
+    printf("\n=============================================\n");
+
+    CAInfo_t responseData;
+    //responseData = (CAInfo*) malloc(sizeof(CAInfo));
+    memset(&responseData, 0, sizeof(CAInfo_t));
+    responseData.token = request_token;
+    responseData.payload = "response payload";
+
+    CAResponseInfo_t responseInfo;
+    //responseInfo = (CAResponseInfo*) malloc(sizeof(CAResponseInfo));
+    memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
+    responseInfo.result = 203;
+    responseInfo.info = responseData;
+
+    // send request (connectivityType from remoteEndpoint of request Info)
+    CASendResponse(endpoint, &responseInfo);
+
+    printf("=============================================\n");
+
+}
+
+void send_request_tmp(CARemoteEndpoint_t* endpoint, CAToken_t token)
+{
+
+    printf("\n=============================================\n");
+
+    CAInfo_t requestData;
+    memset(&requestData, 0, sizeof(CAInfo_t));
+    requestData.token = token;
+    requestData.payload = "Temp Json Payload";
+
+    CARequestInfo_t requestInfo;
+    memset(&requestInfo, 0, sizeof(CARequestInfo_t));
+    requestInfo.method = CA_GET;
+    requestInfo.info = requestData;
+
+    // send request
+    endpoint->connectivityType = CA_WIFI;
+    CASendRequest(endpoint, &requestInfo);
+
+    printf("=============================================\n");
+
+}
+
diff --git a/resource/csdk/connectivity/samples/android/sample_service/AndroidManifest.xml b/resource/csdk/connectivity/samples/android/sample_service/AndroidManifest.xml
new file mode 100644 (file)
index 0000000..9c56849
--- /dev/null
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="utf-8"?>
+<manifest xmlns:android="http://schemas.android.com/apk/res/android"
+    package="com.iotivity.sample_service"
+    android:versionCode="1"
+    android:versionName="1.0" >
+
+    <uses-sdk
+        android:minSdkVersion="19"
+        android:targetSdkVersion="21" />
+
+    <application
+        android:allowBackup="true"
+        android:icon="@drawable/ic_launcher"
+        android:label="@string/app_name"
+        android:theme="@style/AppTheme" >
+        <activity
+            android:name="com.iotivity.service.MainActivity"
+            android:label="@string/app_name" 
+            android:windowSoftInputMode="stateHidden" >
+            <intent-filter>
+                <action android:name="android.intent.action.MAIN" />
+
+                <category android:name="android.intent.category.LAUNCHER" />
+            </intent-filter>
+        </activity>
+    </application>
+    
+    <uses-permission android:name="android.permission.BLUETOOTH" />
+    <uses-permission android:name="android.permission.BLUETOOTH_ADMIN" />
+    <uses-permission android:name="android.permission.INTERNET" />
+    <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_MULTICAST_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_NETWORK_STATE" />
+    <uses-permission android:name="android.permission.CHANGE_WIFI_STATE" />
+
+</manifest>
diff --git a/resource/csdk/connectivity/samples/android/sample_service/Makefile b/resource/csdk/connectivity/samples/android/sample_service/Makefile
new file mode 100644 (file)
index 0000000..9710ed2
--- /dev/null
@@ -0,0 +1,18 @@
+#Assumes ndk directory is at ~/
+#set ndk directory PATH in .bashrc and use the ndk-build directly
+NDK_PATH = ~/ndk
+NDK_BUILD = $(NDK_PATH)/ndk-build
+
+BUILD_DIR = $(CURDIR)
+APPLICATION_BUILD = $(BUILD_DIR)
+ROOT_DIR = $(BUILD_DIR)
+
+#Clean files
+LIBS_DIR = $(ROOT_DIR)/libs
+OBJ_DIR = $(ROOT_DIR)/obj
+
+all:
+       $(NDK_BUILD) NDK_PROJECT_PATH=$(APPLICATION_BUILD)
+
+clean :
+       @$(RM) -rf $(LIBS_DIR) $(OBJ_DIR)
\ No newline at end of file
diff --git a/resource/csdk/connectivity/samples/android/sample_service/jni/Android.mk b/resource/csdk/connectivity/samples/android/sample_service/jni/Android.mk
new file mode 100644 (file)
index 0000000..8bf3c5d
--- /dev/null
@@ -0,0 +1,25 @@
+APP_PATH := $(call my-dir)
+#specify project root path here wrt make file directory
+PROJECT_ROOT_PATH      = ../../..
+
+include $(CLEAR_VARS)
+LOCAL_PATH := $(APP_PATH)
+LOCAL_MODULE := CAInterface
+LOCAL_STATIC_LIBRARIES = CA
+include $(BUILD_SHARED_LIBRARY)
+
+include $(CLEAR_VARS)
+LOCAL_PATH := $(APP_PATH)
+LOCAL_MODULE := RMInterface
+LOCAL_SRC_FILES := ResourceModel.c
+LOCAL_STATIC_LIBRARIES := CA
+LOCAL_LDLIBS := -llog
+include $(BUILD_SHARED_LIBRARY)
+
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
+#Build glib CACommon CACoap CA
+include $(CLEAR_VARS)
+PROJECT_ROOT_PATH                      = ../../..
+CA_LIB_PATH                            = $(PROJECT_ROOT_PATH)/build/android
+include $(CA_LIB_PATH)/jni/Android.mk
+#+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
diff --git a/resource/csdk/connectivity/samples/android/sample_service/jni/Application.mk b/resource/csdk/connectivity/samples/android/sample_service/jni/Application.mk
new file mode 100644 (file)
index 0000000..26f13d9
--- /dev/null
@@ -0,0 +1,6 @@
+APP_STL := gnustl_static
+
+APP_PLATFORM = android-19
+APP_CPPFLAGS += -fexceptions
+APP_CPPFLAGS += -frtti
+APP_CFLAGS = -Wno-error=format-security
\ No newline at end of file
diff --git a/resource/csdk/connectivity/samples/android/sample_service/jni/ResourceModel.c b/resource/csdk/connectivity/samples/android/sample_service/jni/ResourceModel.c
new file mode 100644 (file)
index 0000000..5fc134b
--- /dev/null
@@ -0,0 +1,352 @@
+#include <jni.h>
+#include <android/log.h>
+#include <stdio.h>
+#include <dlfcn.h>
+#include <stdlib.h>
+
+#include <../../../../api/cainterface.h>
+#include <../../../../api/cacommon.h>
+#include "com_iotivity_service_RMInterface.h"
+
+#define  LOG_TAG   "JNI_INTERFACE_SAMPLE"
+#define  LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
+#define  LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+
+void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo);
+void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo);
+
+static CAToken_t gLastRequestToken = NULL;
+
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMInitialize
+  (JNIEnv *env, jobject obj, jobject context)
+{
+    LOGI("RMInitialize");
+    //Currently set context for WiFiCore
+    CAJniSetContext(context);
+
+    if(CA_STATUS_OK != CAInitialize())
+    {
+        LOGI("Could not Initialize");
+    }
+}
+
+JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMTerminate(JNIEnv *env, jobject obj)
+{
+    LOGI("RMTerminate");
+
+    CATerminate();
+}
+
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMStartListeningServer(JNIEnv *env,
+    jobject obj)
+{
+    LOGI("RMStartListeningServer");
+
+    if(CA_STATUS_OK != CAStartListeningServer())
+    {
+        LOGI("Could not start Listening server");
+    }
+}
+
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMStartDiscoveryServer(JNIEnv *env,
+    jobject obj)
+{
+    LOGI("RMStartDiscoveryServer");
+
+    if(CA_STATUS_OK != CAStartDiscoveryServer())
+    {
+        LOGI("Could not start discovery server");
+    }
+}
+
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMRegisterHandler(JNIEnv *env,
+    jobject obj)
+{
+    LOGI("RMRegisterHandler");
+
+    if (CA_STATUS_OK != CARegisterHandler(request_handler, response_handler))
+    {
+        LOGI("Could not register handler");
+    }
+}
+
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMFindResource(JNIEnv *env, jobject obj,
+    jstring uri)
+{
+    const char* strUri = (*env)->GetStringUTFChars(env, uri, NULL);
+    LOGI("RMFindResource - %s", strUri);
+
+    // create token
+    CAToken_t token = NULL;
+    CAResult_t res = CAGenerateToken(&token);
+    if (res != CA_STATUS_OK)
+    {
+        printf("token generate error!!\n");
+        token = NULL;
+    }
+
+    if(CA_STATUS_OK != CAFindResource(strUri, token))
+    {
+        LOGI("Could not find resource");
+    }
+    else
+    {
+        LOGI("find resource to %s URI", strUri);
+        gLastRequestToken = "";
+    }
+}
+
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMSendRequest(JNIEnv *env, jobject obj,
+    jstring data)
+{
+    const char* strData = (*env)->GetStringUTFChars(env, data, NULL);
+    LOGI("RMSendRequest - %s", strData);
+
+    // create token
+    CAToken_t token = NULL;
+    CAResult_t res = CAGenerateToken(&token);
+    if (res != CA_STATUS_OK)
+    {
+        printf("token generate error!!\n");
+        token = NULL;
+    }
+
+    CAInfo_t requestData;
+    memset(&requestData, 0, sizeof(CAInfo_t));
+    requestData.token = token;
+    requestData.payload = "Temp Json Payload";
+
+    CARequestInfo_t requestInfo;
+    memset(&requestInfo, 0, sizeof(CARequestInfo_t));
+    requestInfo.method = CA_GET;
+    requestInfo.info = requestData;
+
+    //create remote endpoint
+    CARemoteEndpoint_t* endpoint = NULL;
+
+    if(CA_STATUS_OK != CACreateRemoteEndpoint(strData, &endpoint))
+    {
+        LOGI("Could not create remote end point");
+    }
+
+    // send request
+    if(CA_STATUS_OK != CASendRequest(endpoint, &requestInfo))
+    {
+        LOGI("Could not send request");
+    }
+
+    // destroy token
+    if (token != NULL)
+    {
+        CADestroyToken(token);
+    }
+
+    // destroy remote endpoint
+    if (endpoint != NULL)
+    {
+        CADestroyRemoteEndpoint(endpoint);
+    }
+}
+
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMSendResponse(JNIEnv *env, jobject obj,
+    jstring data)
+{
+    const char* strData = (*env)->GetStringUTFChars(env, data, NULL);
+    LOGI("RMSendResponse - %s", strData);
+
+    const CAURI_t endpoint_uri = "/a/temp_uri";
+
+    // create token
+    CAToken_t token = NULL;
+    CAResult_t res = CAGenerateToken(&token);
+    if (res != CA_STATUS_OK)
+    {
+        printf("token generate error!!\n");
+        token = NULL;
+    }
+
+    CAInfo_t responseData;
+    memset(&responseData, 0, sizeof(CAInfo_t));
+    responseData.token = token;
+    responseData.payload = (char*) strData;
+
+    CAResponseInfo_t responseInfo;
+    memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
+    responseInfo.result = 203;
+    responseInfo.info = responseData;
+
+    CARemoteEndpoint_t* endpoint = NULL;
+
+    if(CA_STATUS_OK != CACreateRemoteEndpoint(endpoint_uri, &endpoint))
+    {
+        LOGI("Could not create remote end point");
+    }
+
+    if(CA_STATUS_OK != CASendResponse(endpoint, &responseInfo))
+    {
+        LOGI("Could not send response");
+    }
+}
+
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMSendNotification(JNIEnv *env,
+    jobject obj, jstring data)
+{
+    const char* strData = (*env)->GetStringUTFChars(env, data, NULL);
+    LOGI("RMSendNotification - %s", strData);
+
+    const CAURI_t endpoint_uri = "/a/temp_uri";
+
+    // create token
+    CAToken_t token = NULL;
+    CAResult_t res = CAGenerateToken(&token);
+    if (res != CA_STATUS_OK)
+    {
+        printf("token generate error!!\n");
+        token = NULL;
+    }
+
+    CAInfo_t respondeData;
+    memset(&respondeData, 0, sizeof(CAInfo_t));
+    respondeData.token = token;
+    respondeData.payload = (char*)strData;
+
+    CAResponseInfo_t responseInfo;
+    memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
+    responseInfo.result = CA_SUCCESS;
+    responseInfo.info = respondeData;
+
+    CARemoteEndpoint_t* endpoint = NULL;
+
+    if(CA_STATUS_OK != CACreateRemoteEndpoint(endpoint_uri, &endpoint))
+    {
+        LOGI("Could not create remote end point");
+    }
+
+    if(CA_STATUS_OK != CASendNotification(endpoint, &responseInfo))
+    {
+        LOGI("Could not send notification");
+    }
+}
+
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMSelectNetwork(JNIEnv *env, jobject obj,
+    jint networkType)
+{
+    LOGI("RMSelectNetwork Type : %d", networkType);
+
+    if(CA_STATUS_OK != CASelectNetwork(networkType))
+    {
+        LOGI("Could not select network");
+    }
+}
+
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMHandleRequestResponse(JNIEnv *env,
+    jobject obj)
+{
+    LOGI("RMHandleRequestResponse");
+
+    if(CA_STATUS_OK != CAHandleRequestResponse())
+    {
+        LOGI("Could not handle request and response");
+    }
+}
+
+void request_handler(const CARemoteEndpoint_t* object, const CARequestInfo_t* requestInfo)
+{
+    /*
+    printf("[CALLBACK] request_handler, uri : %s, data : %s\n",
+            (object != NULL) ? object->resourceUri : "",
+            (requestInfo != NULL) ? requestInfo->info.payload : "");
+    */
+    LOGI("[CALLBACK] request_handler, uri: %s, data: %s, token: %s \n",
+            (object != NULL) ? object->resourceUri : "",
+            (requestInfo != NULL) ? requestInfo->info.payload : "",
+            (requestInfo->info.token != NULL) ? requestInfo->info.token : "");
+
+    if (gLastRequestToken != NULL && requestInfo->info.token != NULL
+        && (strcmp((char*)gLastRequestToken, requestInfo->info.token) == 0))
+    {
+        printf("token is same. received request of it's own. skip.. \n");
+
+        return;
+    }
+
+    LOGI("[CALLBACK] request_handler, address : %s\n",
+            (object != NULL) ? object->addressInfo.IP.ipAddress : "");
+
+    if (requestInfo->info.options)
+    {
+        uint32_t len = requestInfo->info.numOptions;
+        uint32_t i;
+        for (i = 0; i < len; i++)
+        {
+            LOGI("[CALLBACK] request_handler, option ID : %d\n",
+                    requestInfo->info.options[i].optionID);
+            LOGI("[CALLBACK] request_handler, options data length : %d\n",
+                    requestInfo->info.options[i].optionLength);
+            LOGI("[CALLBACK] request_handler, options data : %s\n",
+                    requestInfo->info.options[i].optionData);
+        }
+    }
+
+    printf("send response with URI\n");
+
+    CAInfo_t responseData;
+    //responseData = (CAInfo*) malloc(sizeof(CAInfo));
+    memset(&responseData, 0, sizeof(CAInfo_t));
+    if (requestInfo != NULL)
+    {
+        responseData.token = requestInfo->info.token;
+    }
+    else
+    {
+        responseData.token = "";
+    }
+    responseData.payload = "response payload";
+
+    CAResponseInfo_t responseInfo;
+    //responseInfo = (CAResponseInfo*) malloc(sizeof(CAResponseInfo));
+    memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
+    responseInfo.result = 203;
+    responseInfo.info = responseData;
+
+    // send request (connectivityType from remoteEndpoint of request Info)
+    CAResult_t res = CASendResponse(object, &responseInfo);
+    if (res != CA_STATUS_OK)
+    {
+        LOGI("send response error\n");
+    }
+    else
+    {
+        LOGI("send response success\n");
+    }
+
+}
+
+void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo)
+{
+
+    LOGI("[CALLBACK] response_handler, uri : %s, data : %s\n",
+            (object != NULL) ? object->resourceUri : "",
+            (responseInfo != NULL) ? responseInfo->info.payload : "");
+
+    LOGI("[CALLBACK] response_handler, address : %s\n",
+            (object != NULL) ? object->addressInfo.IP.ipAddress : "");
+
+    if (responseInfo->info.options)
+    {
+        uint32_t len = responseInfo->info.numOptions;
+        uint32_t i;
+        for (i = 0; i < len; i++)
+        {
+            LOGI("[CALLBACK] response_handler, option ID : %d\n",
+                    responseInfo->info.options[i].optionID);
+            LOGI("[CALLBACK] response_handler, options data length : %d\n",
+                    responseInfo->info.options[i].optionLength);
+            LOGI("[CALLBACK] response_handler, options data : %s\n",
+                    responseInfo->info.options[i].optionData);
+        }
+    }
+
+    //printf("send request with URI\n");
+    //send_request_tmp(object, (responseInfo != NULL) ? responseInfo->info.token : "");
+}
diff --git a/resource/csdk/connectivity/samples/android/sample_service/jni/com_iotivity_service_RMInterface.h b/resource/csdk/connectivity/samples/android/sample_service/jni/com_iotivity_service_RMInterface.h
new file mode 100644 (file)
index 0000000..898714c
--- /dev/null
@@ -0,0 +1,101 @@
+/* DO NOT EDIT THIS FILE - it is machine generated */
+#include <jni.h>
+/* Header for class com_iotivity_service_RMInterface */
+
+#ifndef _Included_com_iotivity_service_RMInterface
+#define _Included_com_iotivity_service_RMInterface
+#ifdef __cplusplus
+extern "C" {
+#endif
+/*
+ * Class:     com_iotivity_service_RMInterface
+ * Method:    RMInitialize
+ * Signature: (Landroid/content/Context;)I
+ */
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMInitialize
+  (JNIEnv *, jobject, jobject);
+
+/*
+ * Class:     com_iotivity_service_RMInterface
+ * Method:    RMTerminate
+ * Signature: ()V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_service_RMInterface_RMTerminate
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_iotivity_service_RMInterface
+ * Method:    RMStartListeningServer
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMStartListeningServer
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_iotivity_service_RMInterface
+ * Method:    RMStartDiscoveryServer
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMStartDiscoveryServer
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_iotivity_service_RMInterface
+ * Method:    RMRegisterHandler
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMRegisterHandler
+  (JNIEnv *, jobject);
+
+/*
+ * Class:     com_iotivity_service_RMInterface
+ * Method:    RMFindResource
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMFindResource
+  (JNIEnv *, jobject, jstring);
+
+/*
+ * Class:     com_iotivity_service_RMInterface
+ * Method:    RMSendRequest
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMSendRequest
+  (JNIEnv *, jobject, jstring);
+
+/*
+ * Class:     com_iotivity_service_RMInterface
+ * Method:    RMSendResponse
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMSendResponse
+  (JNIEnv *, jobject, jstring);
+
+/*
+ * Class:     com_iotivity_service_RMInterface
+ * Method:    RMSendNotification
+ * Signature: (Ljava/lang/String;)I
+ */
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMSendNotification
+  (JNIEnv *, jobject, jstring);
+
+/*
+ * Class:     com_iotivity_service_RMInterface
+ * Method:    RMSelectNetwork
+ * Signature: (I)I
+ */
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMSelectNetwork
+  (JNIEnv *, jobject, jint);
+
+/*
+ * Class:     com_iotivity_service_RMInterface
+ * Method:    RMHandleRequestResponse
+ * Signature: ()I
+ */
+JNIEXPORT jint JNICALL Java_com_iotivity_service_RMInterface_RMHandleRequestResponse
+  (JNIEnv *, jobject);
+
+#ifdef __cplusplus
+}
+#endif
+#endif
diff --git a/resource/csdk/connectivity/samples/android/sample_service/proguard-project.txt b/resource/csdk/connectivity/samples/android/sample_service/proguard-project.txt
new file mode 100644 (file)
index 0000000..f2fe155
--- /dev/null
@@ -0,0 +1,20 @@
+# To enable ProGuard in your project, edit project.properties
+# to define the proguard.config property as described in that file.
+#
+# Add project specific ProGuard rules here.
+# By default, the flags in this file are appended to flags specified
+# in ${sdk.dir}/tools/proguard/proguard-android.txt
+# You can edit the include path and order by changing the ProGuard
+# include property in project.properties.
+#
+# For more details, see
+#   http://developer.android.com/guide/developing/tools/proguard.html
+
+# Add any project specific keep options here:
+
+# If your project uses WebView with JS, uncomment the following
+# and specify the fully qualified class name to the JavaScript interface
+# class:
+#-keepclassmembers class fqcn.of.javascript.interface.for.webview {
+#   public *;
+#}
diff --git a/resource/csdk/connectivity/samples/android/sample_service/res/layout/activity_main.xml b/resource/csdk/connectivity/samples/android/sample_service/res/layout/activity_main.xml
new file mode 100644 (file)
index 0000000..48d9332
--- /dev/null
@@ -0,0 +1,190 @@
+<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    android:layout_width="match_parent"
+    android:layout_height="match_parent"
+    android:paddingBottom="@dimen/activity_vertical_margin"
+    android:paddingLeft="@dimen/activity_horizontal_margin"
+    android:paddingRight="@dimen/activity_horizontal_margin"
+    android:paddingTop="@dimen/activity_vertical_margin"
+    tools:context="com.iotivity.service.MainActivity" >
+    
+    <RelativeLayout
+        android:id="@+id/sample_service_layout"
+        android:layout_width="fill_parent"
+        android:layout_height="wrap_content"
+        android:layout_alignParentTop="true"
+        android:background="#cccccc" >
+
+        <LinearLayout
+            android:id="@+id/layout_mode"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_alignParentTop="true"
+            android:orientation="horizontal" >
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content" />
+
+            <TextView
+                android:id="@+id/tv_mode"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content" />
+        </LinearLayout>
+        
+        <RelativeLayout
+            android:id="@+id/layout_network"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/layout_mode"
+            android:orientation="horizontal" >
+
+            <TextView
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content" />
+
+            <TextView
+                android:id="@+id/tv_network"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content" />
+        </RelativeLayout>
+
+        <RelativeLayout
+            android:id="@+id/layout_find"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/layout_mode" >
+
+            <Button
+                android:id="@+id/btn_find_resource"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:text="@string/find" />
+
+            <EditText
+                android:id="@+id/et_uri"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:layout_centerVertical="true"
+                android:layout_toLeftOf="@id/btn_find_resource"
+                android:text="@string/uri" />
+        </RelativeLayout>
+        
+        <RelativeLayout
+            android:id="@+id/layout_notify"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/layout_mode" >
+
+            <Button
+                android:id="@+id/btn_notify"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:text="@string/notify" />
+
+            <EditText
+                android:id="@+id/et_notification"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:layout_centerVertical="true"
+                android:layout_toLeftOf="@id/btn_notify"
+                android:text="@string/notification" />
+        </RelativeLayout>
+        
+        <RelativeLayout
+            android:id="@+id/layout_request"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/layout_find" >
+
+            <Button
+                android:id="@+id/btn_Request"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:text="@string/request" />
+
+            <EditText
+                android:id="@+id/et_req_data"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:layout_centerVertical="true"
+                android:layout_toLeftOf="@id/btn_Request"
+                android:text="@string/req_data" />
+        </RelativeLayout>
+        
+        <RelativeLayout
+            android:id="@+id/layout_response"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/layout_notify" >
+
+            <Button
+                android:id="@+id/btn_Response"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:text="@string/response" />
+
+            <EditText
+                android:id="@+id/et_resp_data"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:layout_centerVertical="true"
+                android:layout_toLeftOf="@id/btn_Response"
+                android:text="@string/resp_data" />
+        </RelativeLayout>
+
+        <RelativeLayout
+            android:id="@+id/layout_receive"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/layout_request" >
+
+            <Button
+                android:id="@+id/btn_receive"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:layout_alignParentRight="true"
+                android:text="@string/receive" />
+        </RelativeLayout>
+        
+        <RelativeLayout
+            android:id="@+id/layout_received"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content"
+            android:layout_below="@id/layout_receive" >
+
+            <TextView
+                android:id="@+id/tv_rev_text"
+                android:layout_width="wrap_content"
+                android:layout_height="wrap_content"
+                android:visibility="invisible"
+                android:text="@string/received" />
+
+            <TextView
+                android:id="@+id/tv_ble_received"
+                android:layout_width="fill_parent"
+                android:layout_height="wrap_content"
+                android:layout_toRightOf="@id/tv_rev_text"
+                android:visibility="invisible"
+                android:text="@string/received" />
+        </RelativeLayout>
+    </RelativeLayout>
+    
+    <ScrollView
+        android:id="@+id/sv_result_scoll"
+        android:layout_width="fill_parent"
+        android:layout_height="fill_parent"
+        android:layout_below="@id/sample_service_layout"
+        android:layout_marginTop="10pt" >
+
+        <TextView
+            android:id="@+id/tv_result"
+            android:layout_width="fill_parent"
+            android:layout_height="wrap_content" />
+    </ScrollView>
+
+</RelativeLayout>
diff --git a/resource/csdk/connectivity/samples/android/sample_service/res/menu/main.xml b/resource/csdk/connectivity/samples/android/sample_service/res/menu/main.xml
new file mode 100644 (file)
index 0000000..95f70c9
--- /dev/null
@@ -0,0 +1,11 @@
+<menu xmlns:android="http://schemas.android.com/apk/res/android"
+    xmlns:tools="http://schemas.android.com/tools"
+    tools:context="com.iotivity.sample_service.MainActivity" >
+
+    <item
+        android:id="@+id/action_settings"
+        android:orderInCategory="100"
+        android:showAsAction="never"
+        android:title="@string/action_settings"/>
+
+</menu>
diff --git a/resource/csdk/connectivity/samples/android/sample_service/res/values-v11/styles.xml b/resource/csdk/connectivity/samples/android/sample_service/res/values-v11/styles.xml
new file mode 100644 (file)
index 0000000..3c02242
--- /dev/null
@@ -0,0 +1,11 @@
+<resources>
+
+    <!--
+        Base application theme for API 11+. This theme completely replaces
+        AppBaseTheme from res/values/styles.xml on API 11+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light">
+        <!-- API 11 theme customizations can go here. -->
+    </style>
+
+</resources>
diff --git a/resource/csdk/connectivity/samples/android/sample_service/res/values-v14/styles.xml b/resource/csdk/connectivity/samples/android/sample_service/res/values-v14/styles.xml
new file mode 100644 (file)
index 0000000..a91fd03
--- /dev/null
@@ -0,0 +1,12 @@
+<resources>
+
+    <!--
+        Base application theme for API 14+. This theme completely replaces
+        AppBaseTheme from BOTH res/values/styles.xml and
+        res/values-v11/styles.xml on API 14+ devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Holo.Light.DarkActionBar">
+        <!-- API 14 theme customizations can go here. -->
+    </style>
+
+</resources>
diff --git a/resource/csdk/connectivity/samples/android/sample_service/res/values-w820dp/dimens.xml b/resource/csdk/connectivity/samples/android/sample_service/res/values-w820dp/dimens.xml
new file mode 100644 (file)
index 0000000..f3e7020
--- /dev/null
@@ -0,0 +1,10 @@
+<resources>
+
+    <!--
+         Example customization of dimensions originally defined in res/values/dimens.xml
+         (such as screen margins) for screens with more than 820dp of available width. This
+         would include 7" and 10" devices in landscape (~960dp and ~1280dp respectively).
+    -->
+    <dimen name="activity_horizontal_margin">64dp</dimen>
+
+</resources>
diff --git a/resource/csdk/connectivity/samples/android/sample_service/res/values/dimens.xml b/resource/csdk/connectivity/samples/android/sample_service/res/values/dimens.xml
new file mode 100644 (file)
index 0000000..55c1e59
--- /dev/null
@@ -0,0 +1,7 @@
+<resources>
+
+    <!-- Default screen margins, per the Android Design guidelines. -->
+    <dimen name="activity_horizontal_margin">16dp</dimen>
+    <dimen name="activity_vertical_margin">16dp</dimen>
+
+</resources>
diff --git a/resource/csdk/connectivity/samples/android/sample_service/res/values/strings.xml b/resource/csdk/connectivity/samples/android/sample_service/res/values/strings.xml
new file mode 100644 (file)
index 0000000..4c2f126
--- /dev/null
@@ -0,0 +1,15 @@
+<?xml version="1.0" encoding="utf-8"?>
+<resources>
+    <string name="app_name">sample_service</string>
+    <string name="find">Find</string>
+    <string name="notify">Notify</string>
+    <string name="request">Request</string>
+    <string name="response">Response</string>
+    <string name="uri">127.0.0.0:5000/a/light</string>
+    <string name="notification">notification</string>
+    <string name="req_data">request data</string>
+    <string name="resp_data">response data</string>
+    <string name="receive">Receive</string>
+    <string name="received">Received Message</string>
+    <string name="action_settings">Settings</string>
+</resources>
diff --git a/resource/csdk/connectivity/samples/android/sample_service/res/values/styles.xml b/resource/csdk/connectivity/samples/android/sample_service/res/values/styles.xml
new file mode 100644 (file)
index 0000000..6ce89c7
--- /dev/null
@@ -0,0 +1,20 @@
+<resources>
+
+    <!--
+        Base application theme, dependent on API level. This theme is replaced
+        by AppBaseTheme from res/values-vXX/styles.xml on newer devices.
+    -->
+    <style name="AppBaseTheme" parent="android:Theme.Light">
+        <!--
+            Theme customizations available in newer API levels can go in
+            res/values-vXX/styles.xml, while customizations related to
+            backward-compatibility can go here.
+        -->
+    </style>
+
+    <!-- Application theme. -->
+    <style name="AppTheme" parent="AppBaseTheme">
+        <!-- All customizations that are NOT specific to a particular API-level can go here. -->
+    </style>
+
+</resources>
diff --git a/resource/csdk/connectivity/samples/android/sample_service/src/com/iotivity/jar/CALeInterface.java b/resource/csdk/connectivity/samples/android/sample_service/src/com/iotivity/jar/CALeInterface.java
new file mode 100644 (file)
index 0000000..6c29709
--- /dev/null
@@ -0,0 +1,308 @@
+
+package com.iotivity.jar;
+
+import android.bluetooth.BluetoothAdapter;
+import android.bluetooth.BluetoothDevice;
+import android.bluetooth.BluetoothGatt;
+import android.bluetooth.BluetoothGattCallback;
+import android.bluetooth.BluetoothGattCharacteristic;
+import android.bluetooth.BluetoothGattDescriptor;
+import android.bluetooth.BluetoothGattServerCallback;
+import android.bluetooth.BluetoothGattService;
+
+public class CALeInterface {
+    
+    public CALeInterface() {
+        CARegisterLeScanCallback(mLeScanCallback);
+        CARegisterLeGattCallback(mGattCallback);
+//        CARegisterLeGattServerCallback(mGattServerCallback);
+//        CARegisterBluetoothLeAdvertiseCallback(mAdvertiseCallback);
+//        CARegisterBluetoothLeScanCallback(mScanCallback);
+    }
+    
+    public static void getLeScanCallback() {
+        CARegisterLeScanCallback(mLeScanCallback);
+    }
+    
+    public static void getLeGattCallback() {
+        CARegisterLeGattCallback(mGattCallback);
+    }
+    
+//    public static void getLeGattServerCallback() {
+//        CARegisterLeGattServerCallback(mGattServerCallback);
+//    }
+    
+//    public static void getBluetoothLeAdvertiseCallback() {
+//        CARegisterBluetoothLeAdvertiseCallback(mAdvertiseCallback);
+//    }
+//    
+//    public static void getBluetoothLeScanCallback() {
+//        CARegisterBluetoothLeScanCallback(mScanCallback);
+//    }
+
+    public native static void CARegisterLeScanCallback(BluetoothAdapter.LeScanCallback callback);
+    public native static void CARegisterLeGattCallback(BluetoothGattCallback callback);
+    public native static void CARegisterLeGattServerCallback(BluetoothGattServerCallback callback);
+//    public native static void CARegisterBluetoothLeAdvertiseCallback(AdvertiseCallback callback);
+//    public native static void CARegisterBluetoothLeScanCallback(ScanCallback callback);
+    
+    // BluetoothAdapter.LeScanCallback
+    public native static void CALeScanCallback(BluetoothDevice device, int rssi, byte[] scanRecord);
+    
+    // BluetoothGattCallback
+    public native static void CALeGattConnectionStateChangeCallback(BluetoothGatt gatt, int status, int newState);
+    
+    public native static void CALeGattServicesDiscoveredCallback(BluetoothGatt gatt, int status);
+    
+    public native static void CALeGattCharacteristicReadCallback(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, String data, int status);
+    
+    public native static void CALeGattCharacteristicWriteCallback(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic, String data, int status);
+    
+    public native static void CALeGattCharacteristicChangedCallback(BluetoothGatt gatt, BluetoothGattCharacteristic characteristic);
+    
+    public native static void CALeGattDescriptorReadCallback(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status);
+    
+    public native static void CALeGattDescriptorWriteCallback(BluetoothGatt gatt, BluetoothGattDescriptor descriptor, int status);
+    
+    public native static void CALeGattReliableWriteCompletedCallback(BluetoothGatt gatt, int status);
+    
+    public native static void CALeGattReadRemoteRssiCallback(BluetoothGatt gatt, int rssi, int status);
+    
+    // BluetoothGattServerCallback
+    public native static void CALeGattServerConnectionStateChangeCallback(BluetoothDevice device, int status, int newState);
+    
+    public native static void CALeGattServerServiceAddedCallback(int status, BluetoothGattService service);
+    
+    public native static void CALeGattServerCharacteristicReadRequestCallback(BluetoothDevice device,
+            int requestId, int offset, BluetoothGattCharacteristic characteristic);
+    
+    public native static void CALeGattServerCharacteristicWriteRequestCallback(BluetoothDevice device, int requestId,
+            BluetoothGattCharacteristic characteristic, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value);
+    
+    public native static void CALeGattServerDescriptorReadRequestCallback(BluetoothDevice device,
+            int requestId, int offset, BluetoothGattDescriptor descriptor);
+    
+    public native static void CALeGattServerDescriptorWriteRequestCallback(BluetoothDevice device, int requestId,
+            BluetoothGattDescriptor descriptor, boolean preparedWrite, boolean responseNeeded, int offset, byte[] value);
+    
+    public native static void CALeGattServerExecuteWriteCallback(BluetoothDevice device, int requestId, boolean execute);
+    
+    public native static void CALeGattServerNotificationSentCallback(BluetoothDevice device, int status);
+
+    // AdvertiseCallback
+//    public native static void CALeAdvertiseStartSuccessCallback(AdvertiseSettings settingsInEffect);
+//    
+//    public native static void CALeAdvertiseStartFailureCallback(int errorCode);
+    
+    // ScanCallback
+//    public native static void CABluetoothLeScanResultCallback(int callbackType, ScanResult result);
+//    
+//    public native static void CABluetoothLeBatchScanResultsCallback(List<ScanResult> results);
+//    
+//    public native static void CABluetoothLeScanFailedCallback(int errorCode);
+    
+     
+    private static BluetoothAdapter.LeScanCallback mLeScanCallback = new BluetoothAdapter.LeScanCallback() {
+        
+        @Override
+        public void onLeScan(BluetoothDevice device, int rssi, byte[] scanRecord) {
+               
+            try {
+                CALeScanCallback(device, rssi, scanRecord);    
+            } catch(UnsatisfiedLinkError e) {
+            
+            }
+        }
+    };
+
+    private static final BluetoothGattCallback mGattCallback = new BluetoothGattCallback() {
+
+        @Override
+        public void onConnectionStateChange(BluetoothGatt gatt, int status, int newState) {
+            super.onConnectionStateChange(gatt, status, newState);
+            
+            CALeGattConnectionStateChangeCallback(gatt, status, newState);
+        }
+
+        @Override
+        public void onServicesDiscovered(BluetoothGatt gatt, int status) {
+            super.onServicesDiscovered(gatt, status);
+            
+            CALeGattServicesDiscoveredCallback(gatt, status);
+        }
+
+        @Override
+        public void onCharacteristicRead(BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic, int status) {
+            super.onCharacteristicRead(gatt, characteristic, status);
+            
+            String data = new String(characteristic.getValue());
+            CALeGattCharacteristicReadCallback(gatt, characteristic, data, status);
+        }
+
+        @Override
+        public void onCharacteristicWrite(BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic, int status) {
+            super.onCharacteristicWrite(gatt, characteristic, status);
+            
+            String data = new String(characteristic.getValue());
+            CALeGattCharacteristicWriteCallback(gatt, characteristic, data, status);
+        }
+
+        @Override
+        public void onCharacteristicChanged(BluetoothGatt gatt,
+                BluetoothGattCharacteristic characteristic) {
+            super.onCharacteristicChanged(gatt, characteristic);
+            
+            String data = new String(characteristic.getValue());
+            CALeGattCharacteristicChangedCallback(gatt, characteristic, data);
+        }
+
+        @Override
+        public void onDescriptorRead(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+                int status) {
+            super.onDescriptorRead(gatt, descriptor, status);
+            
+            CALeGattDescriptorReadCallback(gatt, descriptor, status);
+        }
+
+        @Override
+        public void onDescriptorWrite(BluetoothGatt gatt, BluetoothGattDescriptor descriptor,
+                int status) {
+            super.onDescriptorWrite(gatt, descriptor, status);
+            
+            CALeGattDescriptorWriteCallback(gatt, descriptor, status);
+        }
+
+        @Override
+        public void onReliableWriteCompleted(BluetoothGatt gatt, int status) {
+            super.onReliableWriteCompleted(gatt, status);
+            
+            CALeGattReliableWriteCompletedCallback(gatt, status);
+        }
+
+        @Override
+        public void onReadRemoteRssi(BluetoothGatt gatt, int rssi, int status) {
+            super.onReadRemoteRssi(gatt, rssi, status);
+            
+            CALeGattReadRemoteRssiCallback(gatt, rssi, status);
+        }
+    };
+    
+    /*
+    private static final BluetoothGattServerCallback mGattServerCallback = new BluetoothGattServerCallback() {
+
+        @Override
+        public void onConnectionStateChange(BluetoothDevice device, int status,
+                int newState) {
+            super.onConnectionStateChange(device, status, newState);
+            
+            CALeGattServerConnectionStateChangeCallback(device, status, newState);
+        }
+
+        @Override
+        public void onServiceAdded(int status, BluetoothGattService service) {
+            super.onServiceAdded(status, service);
+            
+            CALeGattServerServiceAddedCallback(status, service);
+        }
+
+        @Override
+        public void onCharacteristicReadRequest(BluetoothDevice device,
+                int requestId, int offset,
+                BluetoothGattCharacteristic characteristic) {
+            super.onCharacteristicReadRequest(device, requestId, offset, characteristic);
+            
+            CALeGattServerCharacteristicReadRequestCallback(device, requestId, offset, characteristic);
+        }
+
+        @Override
+        public void onCharacteristicWriteRequest(BluetoothDevice device,
+                int requestId, BluetoothGattCharacteristic characteristic,
+                boolean preparedWrite, boolean responseNeeded, int offset,
+                byte[] value) {
+            super.onCharacteristicWriteRequest(device, requestId, characteristic,
+                    preparedWrite, responseNeeded, offset, value);
+            
+            CALeGattServerCharacteristicWriteRequestCallback(device, requestId, characteristic,
+                    preparedWrite, responseNeeded, offset, value);
+        }
+
+        @Override
+        public void onDescriptorReadRequest(BluetoothDevice device,
+                int requestId, int offset, BluetoothGattDescriptor descriptor) {
+            super.onDescriptorReadRequest(device, requestId, offset, descriptor);
+            
+            CALeGattServerDescriptorReadRequestCallback(device, requestId, offset, descriptor);
+        }
+
+        @Override
+        public void onDescriptorWriteRequest(BluetoothDevice device,
+                int requestId, BluetoothGattDescriptor descriptor,
+                boolean preparedWrite, boolean responseNeeded, int offset,
+                byte[] value) {
+            super.onDescriptorWriteRequest(device, requestId, descriptor, preparedWrite,
+                    responseNeeded, offset, value);
+            
+            CALeGattServerDescriptorWriteRequestCallback(device, requestId, descriptor, preparedWrite,
+                    responseNeeded, offset, value);
+        }
+
+        @Override
+        public void onExecuteWrite(BluetoothDevice device, int requestId,
+                boolean execute) {
+            super.onExecuteWrite(device, requestId, execute);
+            
+            CALeGattServerExecuteWriteCallback(device, requestId, execute);
+        }
+
+        @Override
+        public void onNotificationSent(BluetoothDevice device, int status) {
+            super.onNotificationSent(device, status);
+            
+            CALeGattServerNotificationSentCallback(device, status);
+        }
+    };
+    
+    private static final AdvertiseCallback mAdvertiseCallback = new AdvertiseCallback() {
+
+        @Override
+        public void onStartSuccess(AdvertiseSettings settingsInEffect) {
+            super.onStartSuccess(settingsInEffect);
+            
+            CALeAdvertiseStartSuccessCallback(settingsInEffect);
+        }
+
+        @Override
+        public void onStartFailure(int errorCode) {
+            super.onStartFailure(errorCode);
+            
+            CALeAdvertiseStartFailureCallback(errorCode);
+        }
+    };
+    
+    private static final ScanCallback mScanCallback = new ScanCallback() {
+
+        @Override
+        public void onScanResult(int callbackType, ScanResult result) {
+            super.onScanResult(callbackType, result);
+            
+            CABluetoothLeScanResultCallback(callbackType, result);
+        }
+
+        @Override
+        public void onBatchScanResults(List<ScanResult> results) {
+            super.onBatchScanResults(results);
+            
+            CABluetoothLeBatchScanResultsCallback(results);
+        }
+
+        @Override
+        public void onScanFailed(int errorCode) {
+            super.onScanFailed(errorCode);
+            
+            CABluetoothLeScanFailedCallback(errorCode);
+        }
+    };
+    */
+}
diff --git a/resource/csdk/connectivity/samples/android/sample_service/src/com/iotivity/jar/CAWiFiInterface.java b/resource/csdk/connectivity/samples/android/sample_service/src/com/iotivity/jar/CAWiFiInterface.java
new file mode 100644 (file)
index 0000000..842f319
--- /dev/null
@@ -0,0 +1,47 @@
+package com.iotivity.jar;
+
+import android.content.BroadcastReceiver;
+import android.content.Context;
+import android.content.Intent;
+import android.content.IntentFilter;
+import android.net.wifi.WifiManager;
+import android.util.Log;
+
+public class CAWiFiInterface {
+
+    private static String TAG = "CAWiFiInterface";
+    private static Context mContext = null;
+
+    public CAWiFiInterface(Context context) {
+        Log.d(TAG, "CAWiFiInterface");
+        mContext = context;
+        registerWiFiStateReceiver();
+    }
+
+    private void registerWiFiStateReceiver() {
+
+        IntentFilter intentFilter = new IntentFilter();
+        intentFilter.addAction(WifiManager.WIFI_STATE_CHANGED_ACTION);
+
+        mContext.registerReceiver(mReceiver, intentFilter);
+    }
+
+    private static BroadcastReceiver mReceiver = new BroadcastReceiver() {
+
+        @Override
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+                   WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_ENABLED) {
+                 CAWiFiStateEnabled();
+
+            } else if (intent.getIntExtra(WifiManager.EXTRA_WIFI_STATE,
+                WifiManager.WIFI_STATE_UNKNOWN) == WifiManager.WIFI_STATE_DISABLED) {
+                CAWiFiStateDisabled();
+            }
+        }
+    };
+
+    public native static void CAWiFiStateEnabled();
+
+    public native static void CAWiFiStateDisabled();
+}
diff --git a/resource/csdk/connectivity/samples/android/sample_service/src/com/iotivity/service/MainActivity.java b/resource/csdk/connectivity/samples/android/sample_service/src/com/iotivity/service/MainActivity.java
new file mode 100644 (file)
index 0000000..d3e586b
--- /dev/null
@@ -0,0 +1,330 @@
+
+package com.iotivity.service;
+
+import java.util.ArrayList;
+
+import android.app.Activity;
+import android.app.AlertDialog;
+import android.content.DialogInterface;
+import android.os.Bundle;
+import android.view.Menu;
+import android.view.MenuItem;
+import android.view.View;
+import android.view.View.OnClickListener;
+import android.widget.Button;
+import android.widget.EditText;
+import android.widget.RelativeLayout;
+import android.widget.TextView;
+
+import com.iotivity.sample_service.R;
+
+public class MainActivity extends Activity {
+
+    static RMInterface RM = new RMInterface();
+
+    private final CharSequence[] mCheckBoxItems = {
+            Network.WIFI.name(), Network.LE.name()
+    };
+
+    private enum Mode {
+        SERVER, CLIENT, BOTH, UNKNOWN
+    };
+
+    private enum Network {
+        WIFI, LE
+    };
+
+    private Mode mCurrentMode = Mode.UNKNOWN;
+
+    private ArrayList<Integer> mSelectedItems = new ArrayList<Integer>();
+
+    private boolean mCheckedItems[] = {
+            false, false
+    };
+
+    private RelativeLayout mFindResourceLayout = null;
+
+    private RelativeLayout mSendNotificationLayout = null;
+
+    private RelativeLayout mSendRequestLayout = null;
+
+    private RelativeLayout mSendResponseLayout = null;
+
+    private RelativeLayout mReceiveLayout = null;
+
+    private TextView mMode_tv = null;
+
+    private TextView mNetwork_tv = null;
+
+    private EditText mUri_ed = null;
+
+    private EditText mNotification_ed = null;
+
+    private EditText mReqData_ed = null;
+
+    private EditText mRespData_ed = null;
+
+    private Button mFind_btn = null;
+
+    private Button mNotify_btn = null;
+
+    private Button mReqeust_btn = null;
+
+    private Button mResponse_btn = null;
+
+    private Button mRecv_btn = null;
+
+    /**
+     * Defined ConnectivityType in cacommon.c
+     *
+     * CA_ETHERNET = (1 << 0)
+     * CA_WIFI = (1 << 1)
+     * CA_EDR = (1 << 2)
+     * CA_LE = (1 << 3)
+     */
+    private int CA_WIFI = (1 << 1);
+    private int CA_LE = (1 << 3);
+
+    @Override
+    protected void onCreate(Bundle savedInstanceState) {
+        super.onCreate(savedInstanceState);
+        setContentView(R.layout.activity_main);
+
+        // Initialize UI
+        mFindResourceLayout = (RelativeLayout)findViewById(R.id.layout_find);
+        mSendNotificationLayout = (RelativeLayout)findViewById(R.id.layout_notify);
+        mSendRequestLayout = (RelativeLayout)findViewById(R.id.layout_request);
+        mSendResponseLayout = (RelativeLayout)findViewById(R.id.layout_response);
+        mReceiveLayout = (RelativeLayout)findViewById(R.id.layout_receive);
+
+        mMode_tv = (TextView)findViewById(R.id.tv_mode);
+        mNetwork_tv = (TextView)findViewById(R.id.tv_network);
+
+        mUri_ed = (EditText)findViewById(R.id.et_uri);
+        mNotification_ed = (EditText)findViewById(R.id.et_notification);
+        mReqData_ed = (EditText)findViewById(R.id.et_req_data);
+        mRespData_ed = (EditText)findViewById(R.id.et_resp_data);
+
+        mFind_btn = (Button)findViewById(R.id.btn_find_resource);
+        mNotify_btn = (Button)findViewById(R.id.btn_notify);
+        mReqeust_btn = (Button)findViewById(R.id.btn_Request);
+        mResponse_btn = (Button)findViewById(R.id.btn_Response);
+        mRecv_btn = (Button)findViewById(R.id.btn_receive);
+
+        mFind_btn.setOnClickListener(mFindResourceHandler);
+        mNotify_btn.setOnClickListener(mNotifyHandler);
+        mReqeust_btn.setOnClickListener(mSendRequestHandler);
+        mResponse_btn.setOnClickListener(mSendResponseHandler);
+        mRecv_btn.setOnClickListener(mResponseHandler);
+
+        showSelectModeView();
+
+        // Initialize Connectivity Abstraction
+        RM.RMInitialize(getApplicationContext());
+        // Select default network(WIFI)
+        RM.RMSelectNetwork(CA_WIFI);
+        // set handler
+        RM.RMRegisterHandler();
+    }
+
+    private void showSelectModeView() {
+
+        mFindResourceLayout.setVisibility(View.INVISIBLE);
+        mSendNotificationLayout.setVisibility(View.INVISIBLE);
+        mSendRequestLayout.setVisibility(View.INVISIBLE);
+        mSendResponseLayout.setVisibility(View.INVISIBLE);
+        mReceiveLayout.setVisibility(View.INVISIBLE);
+
+        mMode_tv.setText("Select Mode (Server or Client)");
+    }
+
+    private void showNetworkView() {
+
+        mNetwork_tv.setText("Select Network Type");
+    }
+
+    private void showModeView() {
+
+        if (mCurrentMode == Mode.SERVER) {
+
+            mFindResourceLayout.setVisibility(View.INVISIBLE);
+            mSendNotificationLayout.setVisibility(View.VISIBLE);
+            mSendRequestLayout.setVisibility(View.INVISIBLE);
+            mSendResponseLayout.setVisibility(View.VISIBLE);
+            mReceiveLayout.setVisibility(View.VISIBLE);
+
+            mNetwork_tv.setText("");
+
+        } else if (mCurrentMode == Mode.CLIENT) {
+
+            mFindResourceLayout.setVisibility(View.VISIBLE);
+            mSendNotificationLayout.setVisibility(View.INVISIBLE);
+            mSendRequestLayout.setVisibility(View.VISIBLE);
+            mSendResponseLayout.setVisibility(View.INVISIBLE);
+            mReceiveLayout.setVisibility(View.VISIBLE);
+
+            mNetwork_tv.setText("");
+        }
+    }
+
+    @Override
+    protected void onDestroy() {
+        super.onDestroy();
+
+        // Terminate Connectivity Abstraction
+        RM.RMTerminate();
+    }
+
+    @Override
+    public boolean onCreateOptionsMenu(Menu menu) {
+
+        menu.add(0, 1, Menu.NONE, "Start Server");
+        menu.add(0, 2, Menu.NONE, "Start Client");
+        menu.add(0, 3, Menu.NONE, "Select Network");
+
+        return true;
+    }
+
+    @Override
+    public boolean onOptionsItemSelected(MenuItem item) {
+
+        switch (item.getItemId()) {
+
+            case 1:
+
+                RM.RMStartListeningServer();
+
+                if (mCurrentMode == Mode.UNKNOWN || mSelectedItems.size() == 0) {
+                    mCurrentMode = Mode.SERVER;
+                    mMode_tv.setText("MODE: " + mCurrentMode.toString());
+                    showNetworkView();
+
+                } else {
+                    mCurrentMode = Mode.SERVER;
+                    mMode_tv.setText("MODE: " + mCurrentMode.toString());
+                    showModeView();
+                }
+
+                break;
+
+            case 2:
+
+                RM.RMStartDiscoveryServer();
+
+                if (mCurrentMode == Mode.UNKNOWN || mSelectedItems.size() == 0) {
+                    mCurrentMode = Mode.CLIENT;
+                    mMode_tv.setText("MODE: " + mCurrentMode.toString());
+                    showNetworkView();
+
+                } else {
+                    mCurrentMode = Mode.CLIENT;
+                    mMode_tv.setText("MODE: " + mCurrentMode.toString());
+                    showModeView();
+                }
+
+                break;
+
+            case 3:
+
+                showAlertDialog("Select Network");
+
+                break;
+        }
+
+        return super.onOptionsItemSelected(item);
+    }
+
+    private OnClickListener mFindResourceHandler = new OnClickListener() {
+
+        @Override
+        public void onClick(View v) {
+
+            RM.RMFindResource(mUri_ed.getText().toString());
+
+        }
+    };
+
+    private OnClickListener mNotifyHandler = new OnClickListener() {
+
+        @Override
+        public void onClick(View v) {
+
+            RM.RMSendNotification(mNotification_ed.getText().toString());
+
+        }
+    };
+
+    private OnClickListener mSendRequestHandler = new OnClickListener() {
+
+        @Override
+        public void onClick(View v) {
+
+            RM.RMSendRequest(mReqData_ed.getText().toString());
+
+        }
+    };
+
+    private OnClickListener mSendResponseHandler = new OnClickListener() {
+
+        @Override
+        public void onClick(View v) {
+
+            RM.RMSendResponse(mRespData_ed.getText().toString());
+
+        }
+    };
+
+    private OnClickListener mResponseHandler = new OnClickListener() {
+
+        @Override
+        public void onClick(View v) {
+
+            RM.RMHandleRequestResponse();
+        }
+    };
+
+    private void showAlertDialog(String title) {
+
+        AlertDialog.Builder builder = new AlertDialog.Builder(MainActivity.this);
+        builder.setTitle(title)
+        .setMultiChoiceItems(mCheckBoxItems, mCheckedItems,
+                new DialogInterface.OnMultiChoiceClickListener() {
+
+            @Override
+            public void onClick(DialogInterface dialog, int which, boolean isChecked) {
+
+                if (isChecked) {
+
+                    mSelectedItems.add(which);
+
+                } else if (mSelectedItems.contains(which)) {
+
+                    mSelectedItems.remove(Integer.valueOf(which));
+                }
+            }
+        }).setPositiveButton("OK", new DialogInterface.OnClickListener() {
+
+            @Override
+            public void onClick(DialogInterface dialog, int which) {
+
+                int interestedNetwork = 0;
+
+                for (int i = 0; i < mSelectedItems.size(); i++) {
+
+                    if (mSelectedItems.get(i) == Network.WIFI.ordinal()) {
+                        interestedNetwork |= CA_WIFI;
+
+                    } else if (mSelectedItems.get(i) == Network.LE.ordinal()) {
+                        interestedNetwork |= CA_LE;
+                    }
+                }
+
+                RM.RMSelectNetwork(interestedNetwork);
+
+                if (interestedNetwork != 0 && mCurrentMode != Mode.UNKNOWN) {
+                    showModeView();
+                }
+            }
+        }).show();
+    }
+}
diff --git a/resource/csdk/connectivity/samples/android/sample_service/src/com/iotivity/service/RMInterface.java b/resource/csdk/connectivity/samples/android/sample_service/src/com/iotivity/service/RMInterface.java
new file mode 100644 (file)
index 0000000..46d9a1b
--- /dev/null
@@ -0,0 +1,38 @@
+
+package com.iotivity.service;
+
+import android.content.Context;
+
+public class RMInterface {
+
+    static {
+        // Load RI JNI interface
+        System.loadLibrary("RMInterface");
+        
+        // Load CA JNI interface
+        System.loadLibrary("CAInterface");
+    }
+
+    public native int RMInitialize(Context context);
+
+    public native void RMTerminate();
+
+    public native int RMStartListeningServer();
+
+    public native int RMStartDiscoveryServer();
+
+    public native int RMRegisterHandler();
+
+    public native int RMFindResource(String uri);
+
+    public native int RMSendRequest(String requestData);
+
+    public native int RMSendResponse(String responseData);
+
+    public native int RMSendNotification(String notification);
+
+    public native int RMSelectNetwork(int interestedNetwork);
+
+    public native int RMHandleRequestResponse();
+
+}
index 8550c53..14802e5 100644 (file)
@@ -416,7 +416,7 @@ void send_notification()
 
     CAResponseInfo_t responseInfo;
     memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
-    responseInfo.result = CA_CONTENT;
+    responseInfo.result = CA_SUCCESS;
     responseInfo.info = respondeData;
 
     // send request
index 6089f49..81f9200 100644 (file)
@@ -168,17 +168,17 @@ void loop()
         switch (Serial.read())
         {
             case 's':
-        {
+           {
                 Serial.println("sending data");
-        if ( ble_connected() )
-        {
-            Serial.println("Sending Data");
-                gConnectivityHandlers->sendData(&remoteEndpoint[1], coapData, strlen(coapData));
-                Serial.println("Sent Data");
-        }
-       }
-           break;
-    }
+               if ( ble_connected() )
+               {
+                       Serial.println("Sending Data");
+                       gConnectivityHandlers->sendData(&remoteEndpoint[1], coapData, strlen(coapData));
+                       Serial.println("Sent Data");
+               }
+          }
+          break;
+       }
     }
     gConnectivityHandlers->readData();
 }
index b2da299..37852ca 100644 (file)
@@ -37,6 +37,7 @@ void start_listening_server();
 void start_discovery_server();
 void find_resource();
 void send_request();
+void send_request_all();
 void send_response();
 void advertise_resource();
 void send_notification();
@@ -115,6 +116,11 @@ void process()
                 start_listening_server();
                 break;
 
+            case 't': // send request
+            case 'T':
+                send_request_all();
+                break;
+
             case 'c': // start client
             case 'D':
                 start_discovery_server();
@@ -347,6 +353,7 @@ void send_request()
     memset(&requestData, 0, sizeof(CAInfo_t));
     requestData.token = token;
     requestData.payload = "Temp Json Payload";
+    requestData.type = CA_MSG_NONCONFIRM;
 
     CARequestInfo_t requestInfo;
     memset(&requestInfo, 0, sizeof(CARequestInfo_t));
@@ -370,6 +377,79 @@ void send_request()
     printf("=============================================\n");
 }
 
+void send_request_all()
+{
+    char buf[MAX_BUF_LEN];
+
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+
+    printf("\n=============================================\n");
+    printf("10.11.12.13:4545/resource_uri ( for IP )\n");
+    printf("10:11:12:13:45:45/resource_uri ( for BT )\n");
+    printf("uri : ");
+
+    gets(buf);
+
+    // create remote endpoint
+    CARemoteEndpoint_t* endpoint = NULL;
+    CAResult_t res = CACreateRemoteEndpoint(buf, &endpoint);
+
+    if (res != CA_STATUS_OK)
+    {
+        printf("create remote endpoint error!!\n");
+        CADestroyRemoteEndpoint(endpoint);
+        return;
+    }
+
+
+    CAGroupEndpoint_t* group = NULL;
+    group = (CAGroupEndpoint_t*)malloc(sizeof(CAGroupEndpoint_t));
+    group->connectivityType = endpoint->connectivityType;
+    group->resourceUri = endpoint->resourceUri;
+    
+
+    // create token
+    CAToken_t token = NULL;
+    res = CAGenerateToken(&token);
+
+    if (res != CA_STATUS_OK)
+    {
+        printf("token generate error!!\n");
+        token = NULL;
+    }
+
+    printf("generated token %s\n", (token != NULL) ? token : "");
+
+    CAInfo_t requestData;
+    memset(&requestData, 0, sizeof(CAInfo_t));
+    requestData.token = token;
+    requestData.payload = "Temp Json Payload";
+
+    CARequestInfo_t requestInfo;
+    memset(&requestInfo, 0, sizeof(CARequestInfo_t));
+    requestInfo.method = CA_GET;
+    requestInfo.info = requestData;
+
+    // send request
+    // CASendRequest(endpoint, &requestInfo);
+    CASendRequestToAll(group, &requestInfo);
+
+    if (token != NULL)
+    {
+        CADestroyToken(token);
+    }
+
+    // destroy remote endpoint
+    if (endpoint != NULL)
+    {
+        CADestroyRemoteEndpoint(endpoint);
+    }
+
+    free(group);
+
+    printf("=============================================\n");
+}
+
 void advertise_resource()
 {
     char buf[MAX_BUF_LEN];
@@ -469,7 +549,7 @@ void send_notification()
 
     CAResponseInfo_t responseInfo;
     memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
-    responseInfo.result = CA_CONTENT;
+    responseInfo.result = CA_SUCCESS;
     responseInfo.info = respondeData;
 
     // send request
@@ -566,6 +646,7 @@ char get_menu()
     printf("\tc : start client\n");
     printf("\tf : find resource\n");
     printf("\tr : send request\n");
+    printf("\tt : send request to all\n");
     printf("\ta : advertise resource\n");
     printf("\tb : send notification\n");
     printf("\tn : select network\n");
@@ -610,9 +691,9 @@ void get_network_info()
     tempInfo = (CALocalConnectivity_t*) malloc(sizeof(CALocalConnectivity_t));
 
     CAResult_t res = CAGetNetworkInformation(&tempInfo, &tempSize);
-    if (res != CA_STATUS_OK)
+    if (!tempSize)
     {
-        printf("get network information error\n");
+        printf("network not connected\n");
         return;
     }
 
index 9ea21a3..b493ad0 100644 (file)
 /******************************************************************
-*
-* Copyright 2014 Samsung Electronics All Rights Reserved.
-*
-*
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-******************************************************************/
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
 
-#include <stdlib.h>
-#include <stdio.h>
-#include <string.h>
 #include <ctype.h>
 #include <fcntl.h>
 #include <errno.h>
-#include <wifi.h>
 #include <glib.h>
-
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <pthread.h>
 #include "cacommon.h"
-#include "caadapterinterface.h"
-#include "uthreadpool.h"
-
-#define MOD_NAME "TizenSample"
-
-/**
- * Enable/disable one or more of the following macros to enable/disable 
- * functionality of that particular adapter type in the interfacesample.
- */
-//#define WIFI_ADAPTER_TEST
-#define BT_ADAPTER_TEST
-//#define BLE_ADAPTER_TEST
-
-#if defined(WIFI_ADAPTER_TEST)
-#include "cawifiadapter.h"
-#include "caethernetadapter.h"
-static u_thread_pool_t gWiFiThreadPool = NULL;
-#elif defined(BT_ADAPTER_TEST)
-#include "caedradapter.h"
-static  u_thread_pool_t gBTThreadPool = NULL;
-#elif defined(BLE_ADAPTER_TEST)
-#include "caleadapter.h"
-static u_thread_pool_t gLEThreadPool = NULL;
-#endif
+#include "cainterface.h"
 
 static GMainLoop *mainloop;
 static GIOChannel *channel;
 static guint g_test_io_watch_id;
 static GError *g_err_Sample;
 
-static CALocalConnectivity_t *localWifiEndpoint = NULL;
-//Hardcoded coap data for Test
-static char coapData[500] =
-    "{\"oc:\[{href\":\"/a/light\",\"ref\":{\"power\":\"20\",\"state\":\"true\"}}]}";
+pthread_t thread;
 
-void testInitializeBTInterface(void);
-void testTerminateBTInterface(void);
-void testInitializeWIFIInterface(void);
-void testTerminateWIFIInterface(void);
-void testInitializeBLEInterface(void);
-void testTerminateBLEInterface(void);
+#define MAX_BUF_LEN 1024
+#define MAX_OPT_LEN 16
 
-typedef struct ConnectivityHandlerList
-{
-    CAConnectivityType_t type;
-    CAConnectivityHandler_t handler;
-    struct ConnectivityHandlerList *nextHandler;
-} ConnectivityHandlerList;
+char get_menu();
+void process();
+
+void initialize();
+void start_listening_server();
+void start_discovery_server();
+void find_resource();
+void send_request();
+void send_response();
+void advertise_resource();
+void send_notification();
+void select_network();
+void unselect_network();
+void handle_request_response();
 
-static ConnectivityHandlerList *gConnectivityHandlers = NULL;
+void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo);
+void response_handler(const CARemoteEndpoint_t *object, const CAResponseInfo_t *responseInfo);
+void send_request_tmp(CARemoteEndpoint_t *endpoint, CAToken_t token);
+void terminate();
 
-void initializeThreadPool(CAConnectivityType_t type)
+void pthread_func()
 {
-#ifdef BT_ADAPTER_TEST
-    if (CA_EDR == type && NULL == gBTThreadPool)
-    {
-        if (CA_STATUS_OK != u_thread_pool_init(3, &gBTThreadPool))
-        {
-            printf("Failed to create thread pool for BT adapter!\n");
-            return;
-        }
-    }
-#endif
-#ifdef WIFI_ADAPTER_TEST
-    if (CA_WIFI == type && NULL == gWiFiThreadPool)
-    {
-        if (CA_STATUS_OK != u_thread_pool_init(3, &gWiFiThreadPool))
-        {
-            printf("Failed to create thread pool for BT adapter!\n");
-            return;
-        }
-    }
-#endif
-#ifdef BLE_ADAPTER_TEST
-    if (CA_LE == type && NULL == gLEThreadPool)
-    {
-        if (CA_STATUS_OK != u_thread_pool_init(3, &gLEThreadPool))
-        {
-            printf("Failed to create thread pool for BT adapter!\n");
-            return;
-        }
-    }
-#endif
+    g_main_loop_run(mainloop);
 }
 
-
-void storeInterfaceCallbacks(ConnectivityHandlerList *newHandler)
+int main()
 {
-    printf("storeInterfaceCallbacks Entry in Sample\n");
-    newHandler->nextHandler = NULL;
-    ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers;
 
-    if (!tempConnectivityHandlers)
-    {
-        gConnectivityHandlers = newHandler;
-        printf("storeInterfaceCallbacks Exit in Sample\n");
-        return;
-    }
+    printf("=============================================\n");
+    printf("\t\tsample main\n");
+    printf("=============================================\n");
 
-    while (tempConnectivityHandlers->nextHandler)
-    {
-        tempConnectivityHandlers = tempConnectivityHandlers->nextHandler;
-    }
+    process();
 
-    tempConnectivityHandlers->nextHandler = newHandler;
-    printf("storeInterfaceCallbacks Exit in Sample\n");
+    return 0;
 }
 
-void interfaceRegisterCallback(CAConnectivityHandler_t handler,
-                               CAConnectivityType_t connType)
+void process()
 {
-    printf("interfaceRegisterCallback Entry in Sample\n");
-    ConnectivityHandlerList *newConnectivityHandler = (ConnectivityHandlerList *) malloc(sizeof(
-                ConnectivityHandlerList));
-    if (NULL == newConnectivityHandler)
+    while (1)
     {
-        printf("Memory allocation failed\n");
-        return;
-    }
+        char menu = toupper(get_menu());
 
-    newConnectivityHandler->type = connType;
-    newConnectivityHandler->handler = handler;
-    storeInterfaceCallbacks(newConnectivityHandler);
-    printf("interfaceRegisterCallback Exit in Sample\n");
-}
+        switch (menu)
+        {
+            case 'Q': // quits the sample program
+                printf("quit..!!\n");
+                g_main_loop_quit(mainloop);
+                return;
 
-void networkPacketHandler(CARemoteEndpoint_t *object, void *data, uint32_t dataLength)
-{
-    printf("networkPacketHandler Entry in Sample\n");
-    if (object == NULL || data == NULL)
-    {
-        printf("NULL Object\n");
-        return;
-    }
+            case 'I': // Initialize interface
+                initialize();
+                break;
 
-    printf("Data Received from: ");
-    if (CA_EDR == object->connectivityType)
-    {
-        printf(object->addressInfo.BT.btMacAddress);
-    }
-    else if (CA_LE == object->connectivityType)
-    {
-        printf(object->addressInfo.LE.leMacAddress);
-    }
-    else if (CA_WIFI == object->connectivityType || CA_ETHERNET == object->connectivityType)
-    {
-        printf(object->addressInfo.IP.ipAddress);
-    }
+            case 'S': // start server
+                start_listening_server();
+                break;
 
-    printf("\nReceived Data [Length: %d]: %s\n", dataLength, (char *)data);
-    printf("networkPacketHandler Exit in Sample\n");
-}
+            case 'C': // start client
+                start_discovery_server();
+                break;
 
-void networkInterfaceCallback(CALocalConnectivity_t *localEndPoint,
-                              CANetworkStatus_t networkConnectivityState)
-{
-    printf("networkInterfaceCallback Entry in Sample\n");
-    if (localEndPoint == NULL)
-    {
-        printf("NULL Object\n");
-        return;
-    }
+            case 'F': // find resource
+                find_resource();
+                break;
 
-    if (networkConnectivityState == CA_INTERFACE_UP)
-    {
-        printf("Network Status is UP\n");
-    }
-    else
-    {
-        printf("Network Status is DOWN\n");
-    }
+            case 'R': // send request
+                send_request();
+                break;
 
-    printf("Address: ");
-    if (CA_EDR == localEndPoint->type)
-    {
-        printf("%s\n", localEndPoint->addressInfo.BT.btMacAddress);
-    }
-    else if (CA_LE == localEndPoint->type)
-    {
-        printf("%s\n", localEndPoint->addressInfo.LE.leMacAddress);
-    }
-    else if (CA_WIFI == localEndPoint->type || CA_ETHERNET == localEndPoint->type)
-    {
-        printf("%s\n", localEndPoint->addressInfo.IP.ipAddress);
-    }
+            case 'A': // advertise resource
+                advertise_resource();
+                break;
 
-    printf("networkInterfaceCallback Exit in Sample\n");
-}
+            case 'N': // select network
+                select_network();
+                break;
 
+            case 'X': // unselect network
+                unselect_network();
+                break;
 
-void freeData(void *data)
-{
-    printf("freeData Entry in Sample\n");
-    if (data)
-    {
-        free(data);
-    }
-    printf("freeData Exit in Sample\n");
-}
+            case 'H': // handle request response
+                handle_request_response();
+                break;
 
-int16_t selectConnectivityType()
-{
-    int32_t cType;
-    printf("*******Select the Connectivity Type*******\n");
-    printf("  [1] WIFI \n");
-    printf("  [2] BT \n");
-    printf("  [3] BLE \n");
-
-    fflush(stdin);
-    scanf("%d", &cType);
-    if (cType < 1 && cType > 3)
-    {
-        printf("Invalid Selection!!!!\n");
-        return 0;
+            case 'T': // Terminate interface
+                terminate();
+                break;
+
+            default:
+                printf("not supported menu!!\n");
+                break;
+        }
     }
-    return (int16_t)cType;
+
 }
 
-int16_t interfaceStartAdapter(CAConnectivityType_t connType)
+void initialize()
 {
-    ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers;
-    if (NULL == tempConnectivityHandlers)
-    {
-        printf("None of the interface is initialized\n");
-        return 0;
-    }
-
-    while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType)
-    {
-        tempConnectivityHandlers = tempConnectivityHandlers->nextHandler;
-    }
+    mainloop = g_main_loop_new(NULL, FALSE);
+    pthread_create (&thread, NULL, (void *) &pthread_func, NULL);
 
-    if (NULL == tempConnectivityHandlers)
-    {
-        printf( "No interface handler for type %d", connType);
-        return 0;
-    }
+    CAInitialize();
 
-    if (CA_STATUS_OK != tempConnectivityHandlers->handler.startAdapter())
-    {
-        printf("Failed to Start adapter\n");
-        return 0;
-    }
+    // network enable
+    // default
+    printf("select default network(WIFI)\n");
+    CASelectNetwork(CA_WIFI);
 
-    return 1;
+    // set handler.
+    CARegisterHandler(request_handler, response_handler);
 }
 
-int16_t interfaceMulticastStartServer(CAConnectivityType_t connType, int serverType)
+void start_listening_server()
 {
-    printf("interfaceMulticastStartServer Starting...\n");
-    ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers;
-    if (NULL == tempConnectivityHandlers)
-    {
-        printf("None of the interface is initialized\n");
-        return 0;
-    }
+    printf("start listening server!!\n");
 
-    while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType)
-    {
-        tempConnectivityHandlers = tempConnectivityHandlers->nextHandler;
-    }
-
-    if (NULL == tempConnectivityHandlers)
-    {
-        printf( "No interface handler for type %d", connType);
-        return 0;
-    }
+    CAStartListeningServer();
+}
 
-    CAAdapterStartDiscoveryServer startServer = NULL;
-    switch (serverType)
-    {
-        case 1: //Discovery server
-            startServer = tempConnectivityHandlers->handler.startDiscoverServer;
-            break;
-        case 2: //Listening server
-            startServer = tempConnectivityHandlers->handler.startListenServer;
-            break;
-    }
+void start_discovery_server()
+{
+    printf("start discovery server at client!!\n");
 
-    if (startServer)
-    {
-        printf("Invoking start server method\n");
-        startServer();
-    }
+    CAStartDiscoveryServer();
 }
 
-int16_t interfaceSendUnicastData(CAConnectivityType_t connType)
+void find_resource()
 {
-    ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers;
-    if (NULL == tempConnectivityHandlers)
-    {
-        printf(" None of the interface is initialized \n");
-        return 0;
-    }
+    char buf[MAX_BUF_LEN];
 
-    while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType)
-    {
-        tempConnectivityHandlers = tempConnectivityHandlers->nextHandler;
-    }
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
 
-    if (NULL == tempConnectivityHandlers)
-    {
-        printf( "No interface handler for type %d", connType);
-        return 0;
-    }
+    printf("\n=============================================\n");
+    printf("ex) a/light\n");
+    printf("reference uri : ");
 
-    if (CA_WIFI == connType)
-    {
-        CARemoteEndpoint_t endpoint;
-        char remoteIPAddress[CA_IPADDR_SIZE] = {0};
-        printf("\nEnter the Remote Endpoint IP: ");
-        scanf("%s", remoteIPAddress);
-        if (strlen(remoteIPAddress) == 0)
-        {
-            printf("Invalid device address\n");
-            return;
-        }
-        endpoint.connectivityType = CA_WIFI;
-        strncpy(endpoint.addressInfo.IP.ipAddress, remoteIPAddress, CA_IPADDR_SIZE);
-        endpoint.addressInfo.IP.port = 5283; /* Send the corresponding port here */
+    gets(buf);
 
-        int sdatalen = tempConnectivityHandlers->handler.sendData(&endpoint, coapData,
-                       strlen(coapData));
-        if (sdatalen == strlen(coapData))
-        {
-            printf("Send Unicast data success\n");
-        }
-        else
-        {
-            printf("Send Unicast data failed\n");
-        }
-    }
-    else if (CA_EDR == connType)
+       // create token
+    CAToken_t token = NULL;
+    CAResult_t res = CAGenerateToken(&token);
+    if (res != CA_STATUS_OK)
     {
-        //create endpoint
-        CARemoteEndpoint_t endpoint;
-
-        //Get the device address from user
-        char deviceaddress[100] = {0};
-        printf("Enter the device address: \n");
-        scanf("%s", deviceaddress);
+        printf("token generate error!!\n");
+        token = NULL;
+    }
 
-        if (strlen(deviceaddress) == 0)
-        {
-            printf("Invlaid device address\n");
-            return;
-        }
+    printf("generated token %s\n", (token != NULL) ? token : "");
 
-        endpoint.connectivityType = CA_EDR;
-        strncpy(endpoint.addressInfo.BT.btMacAddress, deviceaddress, CA_MACADDR_SIZE - 1);
-        endpoint.addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
-        endpoint.resourceUri = NULL;
+    res = CAFindResource(buf, token);
 
-        printf("Sent Unicast data to device: %s\n", endpoint.addressInfo.BT.btMacAddress);
-        tempConnectivityHandlers->handler.sendData(&endpoint, coapData, strlen(coapData) + 1);
+    if (res != CA_STATUS_OK)
+    {
+        printf("find resource error:%d !!\n", res);
     }
-    else if (CA_LE == connType)
+    else
     {
-        //create endpoint
-        CARemoteEndpoint_t endpoint;
-
-        //Get the device address from user
-        char deviceaddress[100] = {0};
-        printf("Enter the device address: \n");
-        scanf("%s", deviceaddress);
+        printf("find resource for %s URI\n", buf);
+    }
 
-        if (strlen(deviceaddress) == 0)
-        {
-            printf("Invlaid device address\n");
-            return;
-        }
+    printf("=============================================\n");
+}
 
-        //Get the service uuid from user
-        char uuid[100] = {0};
-        printf("Enter the service uuid: \n");
-        scanf("%s", uuid);
+void send_request()
+{
+    char buf[MAX_BUF_LEN];
 
-        if (strlen(uuid) == 0)
-        {
-            printf("Invlaid service uuid\n");
-            return;
-        }
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
 
-        endpoint.connectivityType = CA_LE;
-        strncpy(endpoint.addressInfo.BT.btMacAddress, deviceaddress, CA_MACADDR_SIZE - 1);
-        endpoint.addressInfo.BT.btMacAddress[CA_MACADDR_SIZE - 1] = '\0';
-        endpoint.resourceUri = strdup(uuid);
+    printf("\n=============================================\n");
+    printf("10.11.12.13:4545/resource_uri ( for IP )\n");
+    printf("10:11:12:13:45:45/resource_uri ( for BT )\n");
+    printf("uri : ");
 
-        tempConnectivityHandlers->handler.sendData(&endpoint, coapData, strlen(coapData));
-        printf("Sent Unicast data \n");
-        free(endpoint.resourceUri);
-    }
+    gets(buf);
 
-    return 1;
-}
+    // create remote endpoint
+    CARemoteEndpoint_t *endpoint = NULL;
+    CAResult_t res = CACreateRemoteEndpoint(buf, &endpoint);
 
-int16_t interfaceSendMulticastData(CAConnectivityType_t connType)
-{
-    ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers;
-    if (NULL == tempConnectivityHandlers)
+    if (res != CA_STATUS_OK)
     {
-        printf("None of the interface is initialized\n");
-        return 0;
+        printf("create remote endpoint error!!");
+        CADestroyRemoteEndpoint(endpoint);
+        return;
     }
 
-    while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType)
-    {
-        tempConnectivityHandlers = tempConnectivityHandlers->nextHandler;
-    }
+    // create token
+    CAToken_t token = NULL;
+    res = CAGenerateToken(&token);
 
-    if (NULL == tempConnectivityHandlers)
+    if (res != CA_STATUS_OK)
     {
-        printf( "No interface handler for type %d", connType);
-        return 0;
+        printf("token generate error!!");
+        token = NULL;
     }
 
-    if (connType == CA_WIFI)
-    {
-        tempConnectivityHandlers->handler.sendDataToAll(coapData,
-                strlen(coapData) + 1);
-    }
-    else if (connType == CA_EDR || connType == CA_LE)
-    {
-        tempConnectivityHandlers->handler.sendDataToAll(coapData, strlen(coapData));
-    }
-}
+    printf("generated token %s\n", (token != NULL) ? token : "");
 
-void interfaceReadData(CAConnectivityType_t connType)
-{
-    ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers;
-    if (NULL == tempConnectivityHandlers)
-    {
-        printf("None of the interface is initialized\n");
-        return;
-    }
+    CAInfo_t requestData;
+    memset(&requestData, 0, sizeof(CAInfo_t));
+    requestData.token = token;
+    requestData.payload = "Temp Json Payload";
 
-    while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType)
-    {
-        tempConnectivityHandlers = tempConnectivityHandlers->nextHandler;
-    }
+    CARequestInfo_t requestInfo;
+    memset(&requestInfo, 0, sizeof(CARequestInfo_t));
+    requestInfo.method = CA_GET;
+    requestInfo.info = requestData;
 
-    if (NULL == tempConnectivityHandlers)
+    // send request
+    CASendRequest(endpoint, &requestInfo);
+
+    if (token != NULL)
     {
-        printf( "No interface handler for type %d", connType);
-        return;
+        CADestroyToken(token);
     }
 
-    if (CA_STATUS_OK != tempConnectivityHandlers->handler.readData())
+    // destroy remote endpoint
+    if (endpoint != NULL)
     {
-        printf("Failed to Read Data\n");
-        return;
+        CADestroyRemoteEndpoint(endpoint);
     }
 
-    printf("Read Data is successfull\n");
-    return;
+    printf("=============================================\n");
 }
 
-void interfaceGetNetworkInfo(CAConnectivityType_t connType)
+void advertise_resource()
 {
-    int i = 0;
+    char buf[MAX_BUF_LEN];
 
-    ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers;
-    if (NULL == tempConnectivityHandlers)
-    {
-        printf("None of the interface is initialized\n");
-        return;
-    }
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
 
-    while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType)
-    {
-        tempConnectivityHandlers = tempConnectivityHandlers->nextHandler;
-    }
+    printf("\n=============================================\n");
+    printf("uri : ");
 
-    if (NULL == tempConnectivityHandlers)
-    {
-        printf( "No interface handler for type %d", connType);
-        return;
-    }
+    scanf("%s", buf);
 
-    //Get the network interface info
-    CALocalConnectivity_t *info = NULL;
-    uint32_t size = 0;
-    if (CA_STATUS_OK != tempConnectivityHandlers->handler.GetnetInfo(&info, &size))
-    {
-        printf("Failed to get network info\n");
-        return;
-    }
+    int optionNum = 0;
+    char optionData[MAX_OPT_LEN];
 
-    if (0 >= size || info == NULL)
-    {
-        printf("No network found !!!\n");
-        return;
-    }
+    printf("Option Num : ");
+    scanf("%d", &optionNum);
+    CAHeaderOption_t *headerOpt;
 
-    printf("Network Information: \n");
-    for (; i < size; i++)
+    if(optionNum > 0)
     {
-        if (connType == CA_WIFI)
+        headerOpt = (CAHeaderOption_t *) malloc(sizeof(CAHeaderOption_t) * optionNum);
+        if (NULL == headerOpt)
         {
-            printf("Type : %s\n", (connType == CA_ETHERNET) ? "CA_ETHERNET" : "CA_WIFI");
-            printf("Address : %s\n", info[i].addressInfo.IP.ipAddress);
-        }
-        else
-        {
-            printf("Type : %s\n", (connType == CA_EDR) ? "CA_EDR" : "CA_LE");
-            printf("Address : %s\n\n", info[i].addressInfo.BT.btMacAddress);
+            printf("memory allocation failed!\n");
+            return;
         }
+        memset(headerOpt, 0, sizeof(CAHeaderOption_t) * optionNum);
     }
-}
 
-int16_t interfaceStopAdapter(CAConnectivityType_t connType)
-{
-    ConnectivityHandlerList *tempConnectivityHandlers = gConnectivityHandlers;
-    if (NULL == tempConnectivityHandlers)
+    int i;
+    for (i = 0 ; i < optionNum ; i++)
     {
-        printf("None of the interface is initialized\n");
-        return 0;
-    }
+        int optionID = 0;
+        printf("[%d] Option ID : ", i + 1);
+        scanf("%d", &optionID);
+        headerOpt[i].optionID = optionID;
 
-    while (tempConnectivityHandlers && tempConnectivityHandlers->type != connType)
-    {
-        tempConnectivityHandlers = tempConnectivityHandlers->nextHandler;
-    }
+        memset(optionData, 0, sizeof(char) * MAX_OPT_LEN);
+        printf("[%d] Option Data : ", i + 1);
+        scanf("%s", optionData);
+        memcpy(headerOpt[i].optionData, optionData, MAX_OPT_LEN);
+        printf("[%d] inputed option : ID : %d, data : %s\n", i + 1, optionID, optionData );
 
-    if (NULL == tempConnectivityHandlers)
-    {
-        printf( "No interface handler for type %d", connType);
-        return 0;
+        headerOpt[i].optionLength = (uint16_t)strlen(optionData);
     }
+    printf("\n=============================================\n");
 
-    if (CA_STATUS_OK != tempConnectivityHandlers->handler.stopAdapter())
+    // create token
+    CAToken_t token = NULL;
+    CAResult_t res = CAGenerateToken(&token);
+    if (res != CA_STATUS_OK)
     {
-        printf("Failed to Stop adapter\n");
-        return 0;
+        printf("token generate error!!\n");
+        token = NULL;
     }
 
-    printf("Stopped the adapter\n");
-    return 1;
-}
+    printf("generated token %s\n", (token != NULL) ? token : "");
 
-void testInitializeInterface()
-{
-    printf("testInitializeInterface Entry\n");
+    CAAdvertiseResource(buf, token, headerOpt, (uint8_t)optionNum);
 
-    int16_t type = selectConnectivityType();
-    if (0 >= type || 3 < type)
-    {
-        printf("Invalid selection...\n");
-        return;
-    }
+    free(headerOpt);
 
-    switch (type)
-    {
-#ifdef WIFI_ADAPTER_TEST
-        case 1: //WIFI
-            {
-                testInitializeWIFIInterface();
-            }
-            break;
-#endif
-#ifdef BT_ADAPTER_TEST
-        case 2:   //BT
-            {
-                testInitializeBTInterface();
-            }
-            break;
-#endif
-#ifdef BLE_ADAPTER_TEST
-        case 3: //BLE
-            {
-                testInitializeBLEInterface();
-            }
-            break;
-#endif
-        default:
-            printf("Feature is not enabled or not implemented\n");
-    }
 }
 
-void testTerminateInterface()
+void select_network()
 {
-    int16_t type = selectConnectivityType();
-    if (0 >= type || 3 < type)
-    {
-        printf("Invalid selection...\n");
-        return;
-    }
+    char buf[MAX_BUF_LEN];
 
-#ifdef WIFI_ADAPTER_TEST
-    if (1 == type)   /* WIFI */
-    {
-        testTerminateWIFIInterface();
-    }
-#endif
-#ifdef BT_ADAPTER_TEST
-    if (2 == type)   /*BT*/
-    {
-        testTerminateBTInterface();
-    }
-#endif
-#ifdef BLE_ADAPTER_TEST
-    if (3 == type)   /*BLE*/
-    {
-        testTerminateBLEInterface();
-    }
-#endif
+    printf("\n=============================================\n");
+    printf("\tselect network\n");
+    printf("ETHERNET : 0\n");
+    printf("WIFI : 1\n");
+    printf("EDR : 2\n");
+    printf("LE : 3\n");
+    printf("select : ");
 
-    ConnectivityHandlerList *currentConnectivityHandler = gConnectivityHandlers;
-    ConnectivityHandlerList *prevConnectivityHandler = NULL;
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+    gets(buf);
 
-    printf("Linked list delete start\n");
-    while (currentConnectivityHandler != NULL)
-    {
-        printf("Iterating through the list to find the matching interface\n");
-        if (currentConnectivityHandler->type == type)
-        {
-            printf("Matching interface found\n");
-            if (prevConnectivityHandler == NULL)
-            {
-                currentConnectivityHandler = currentConnectivityHandler->nextHandler;
-                freeData(gConnectivityHandlers);
-                gConnectivityHandlers = NULL;
-                printf( "Node deleted with interface type %d", type);
-            }
-            else
-            {
-                prevConnectivityHandler->nextHandler = currentConnectivityHandler->nextHandler;
-                freeData(currentConnectivityHandler);
-                currentConnectivityHandler = prevConnectivityHandler->nextHandler;
-                printf( "Node deleted with interface type %d from linked list", type);
-            }
-        }
-        else
-        {
-            prevConnectivityHandler = currentConnectivityHandler;
-            currentConnectivityHandler = currentConnectivityHandler->nextHandler;
-        }
-    }
-    gConnectivityHandlers = NULL;
-    return;
-}
+    int number = buf[0] - '0';
 
-void testStartAdapter()
-{
-    int type = selectConnectivityType();
-    if (0 >= type || 3 < type)
-    {
-        printf("Invalid selection...\n");
-        return;
-    }
+    number = (number < 0 || number > 3) ? 1 : number;
 
-    switch (type)
-    {
-#ifdef WIFI_ADAPTER_TEST
-        case 1: //WIFI
-            {
-                interfaceStartAdapter(CA_WIFI);
-            }
-            break;
-#endif
-#ifdef BT_ADAPTER_TEST
-        case 2:   //BT
-            {
-                interfaceStartAdapter(CA_EDR);
-            }
-            break;
-#endif
-#ifdef BLE_ADAPTER_TEST
-        case 3: //BLE
-            {
-                interfaceStartAdapter(CA_LE);
-            }
-            break;
-#endif
-        default:
-            printf("Feature is not enabled or not implemented\n");
-    }
+    CASelectNetwork(1 << number);
+
+    printf("=============================================\n");
 }
 
-void testStartServer(int serverType)
+void unselect_network()
 {
-    int type = selectConnectivityType();
-    if (0 >= type || 3 < type)
-    {
-        printf("Invalid selection...\n");
-        return;
-    }
+    char buf[MAX_BUF_LEN];
 
-    switch (type)
-    {
-#ifdef WIFI_ADAPTER_TEST
-        case 1: //WIFI
-            {
-                interfaceMulticastStartServer(CA_WIFI, serverType);
-            }
-            break;
-#endif
-#ifdef BT_ADAPTER_TEST
-        case 2:   //BT
-            {
-                interfaceMulticastStartServer(CA_EDR, serverType);
-            }
-            break;
-#endif
-#ifdef BLE_ADAPTER_TEST
-        case 3: //BLE
-            {
-                interfaceMulticastStartServer(CA_LE, serverType);
-            }
-            break;
-#endif
-        default:
-            printf("Feature is not enabled or not implemented\n");
-    }
-}
+    printf("\n=============================================\n");
+    printf("\tunselect enabled network\n");
+    printf("ETHERNET : 0\n");
+    printf("WIFI : 1\n");
+    printf("EDR : 2\n");
+    printf("LE : 3\n");
+    printf("select : ");
 
-void testSendUnicastData()
-{
-    int16_t type = selectConnectivityType();
-    if (0 >= type || 3 < type)
-    {
-        printf("Invalid selection...\n");
-        return;
-    }
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
+    gets(buf);
 
-    switch (type)
-    {
-#ifdef WIFI_ADAPTER_TEST
-        case 1: //WIFI
-            {
-                interfaceSendUnicastData(CA_WIFI);
-            }
-            break;
-#endif
-#ifdef BT_ADAPTER_TEST
-        case 2:   //BT
-            {
-                interfaceSendUnicastData(CA_EDR);
-            }
-            break;
-#endif
-#ifdef BLE_ADAPTER_TEST
-        case 3: //BLE
-            {
-                interfaceSendUnicastData(CA_LE);
-            }
-            break;
-#endif
-        default:
-            printf("Feature is not enabled or not implemented\n");
-    }
-}
+    int number = buf[0] - '0';
 
-void testSendMulticastData()
-{
-    int16_t type = selectConnectivityType();
-    if (0 >= type || 3 < type)
-    {
-        printf("Invalid selection...\n");
-        return;
-    }
+    number = (number < 0 || number > 3) ? 1 : number;
 
-    switch (type)
-    {
-#ifdef WIFI_ADAPTER_TEST
-        case 1: //WIFI
-            {
-                interfaceSendMulticastData(CA_WIFI);
-            }
-            break;
-#endif
-#ifdef BT_ADAPTER_TEST
-        case 2:   //BT
-            {
-                interfaceSendMulticastData(CA_EDR);
-            }
-            break;
-#endif
-#ifdef BLE_ADAPTER_TEST
-        case 3: //BLE
-            {
-                interfaceSendMulticastData(CA_LE);
-            }
-            break;
-#endif
-        default:
-            printf("Feature is not enabled or not implemented\n");
-    }
+    CAUnSelectNetwork(1 << number);
+    printf("Terminating...\n");
+    CATerminate();
+    //pthread_join(thread, NULL);
+    printf("=============================================\n");
 }
 
-void testReadData(void)
+char get_menu()
 {
-    int16_t type = selectConnectivityType();
-    if (0 >= type || 3 < type)
-    {
-        printf("Invalid selection...\n");
-        return;
-    }
+    char buf[MAX_BUF_LEN];
 
-    switch (type)
-    {
-#ifdef WIFI_ADAPTER_TEST
-        case 1: //WIFI
-            {
-                interfaceReadData(CA_WIFI);
-            }
-            break;
-#endif
-#ifdef BT_ADAPTER_TEST
-        case 2:   //BT
-            {
-                interfaceReadData(CA_EDR);
-            }
-            break;
-#endif
-#ifdef BLE_ADAPTER_TEST
-        case 3: //BLE
-            {
-                interfaceReadData(CA_LE);
-            }
-            break;
-#endif
-        default:
-            printf("Feature is not enabled or not implemented\n");
-    }
-}
+    printf("\n=============================================\n");
+    printf("\t\tMenu\n");
+    printf("\ti : Initialize\n");
+    printf("\ts : start server\n");
+    printf("\tc : start client\n");
+    printf("\tf : find resource\n");
+    printf("\tr : send request\n");
+    printf("\ta : advertise resource\n");
+    printf("\tn : select network\n");
+    printf("\tx : unselect network\n");
+    printf("\th : handle request response\n");
+    printf("\tt : terminate\n");
+    printf("\tq : quit\n");
+    printf("=============================================\n");
+    printf("select : ");
 
-void testGetNetworkInfo(void)
-{
-    int16_t type = selectConnectivityType();
-    if (0 >= type || 3 < type)
-    {
-        printf("Invalid selection...\n");
-        return;
-    }
+    memset(buf, 0, sizeof(char) * MAX_BUF_LEN);
 
-    switch (type)
-    {
-#ifdef WIFI_ADAPTER_TEST
-        case 1: //WIFI
-            {
-                interfaceGetNetworkInfo(CA_WIFI);
-            }
-            break;
-#endif
-#ifdef BT_ADAPTER_TEST
-        case 2:   //BT
-            {
-                interfaceGetNetworkInfo(CA_EDR);
-            }
-            break;
-#endif
-#ifdef BLE_ADAPTER_TEST
-        case 3: //BLE
-            {
-                interfaceGetNetworkInfo(CA_LE);
-            }
-            break;
-#endif
-        default:
-            printf("Feature is not enabled or not implemented\n");
-    }
+    gets(buf);
+
+    return buf[0];
 }
 
-void testStopAdapter()
+void handle_request_response()
 {
-    int16_t type = selectConnectivityType();
-    if (0 >= type || 3 < type)
-    {
-        printf("Invalid selection...\n");
-        return;
-    }
-
-    switch (type)
-    {
-#ifdef WIFI_ADAPTER_TEST
-        case 1: //WIFI
-            {
-                interfaceStopAdapter(CA_WIFI);
-            }
-            break;
-#endif
-#ifdef BT_ADAPTER_TEST
-        case 2:   //BT
-            {
-                interfaceStopAdapter(CA_EDR);
-            }
-            break;
-#endif
-#ifdef BLE_ADAPTER_TEST
-        case 3: //BLE
-            {
-                interfaceStopAdapter(CA_LE);
-            }
-            break;
-#endif
-        default:
-            printf("Feature is not enabled or not implemented\n");
-    }
+    printf("handle_request_response\n");
+    CAHandleRequestResponse();
 }
 
-#ifdef BT_ADAPTER_TEST
-void testInitializeBTInterface(void)
+void request_handler(const CARemoteEndpoint_t *object, const CARequestInfo_t *requestInfo)
 {
-    printf("Initiazing EDR\n");
 
-    printf("Initializing BT Adapter threadpool\n");
-    initializeThreadPool(CA_EDR);
+    printf("[CALLBACK] request_handler, uri : %s, data : %s\n", (object != NULL) ? object->resourceUri : "",
+            (requestInfo != NULL) ? requestInfo->info.payload : "");
+
+    printf("[CALLBACK] request_handler, address : %s\n", (object != NULL) ? object->addressInfo.IP.ipAddress : "");
 
-    //Start bluetooth communication adapter
-    CAResult_t err = CAInitializeEDR(interfaceRegisterCallback, networkPacketHandler,
-                                     networkInterfaceCallback, gBTThreadPool);
-    if (CA_STATUS_OK != err && CA_ADAPTER_NOT_ENABLED != err)
+    if(requestInfo->info.options)
     {
-        printf("Failed to initialize bluetooth communication adapter!\n");
+        uint32_t len =  requestInfo->info.numOptions;
+        uint32_t i;
+        for(i = 0 ; i < len ; i++)
+        {
+            printf("[CALLBACK] request_handler, option ID : %d\n", requestInfo->info.options[i].optionID);
+            printf("[CALLBACK] request_handler, options data length : %d\n", requestInfo->info.options[i].optionLength);
+            printf("[CALLBACK] request_handler, options data : %s\n", requestInfo->info.options[i].optionData );
+        }
     }
-}
 
-void testTerminateBTInterface(void)
-{
-    printf("Terminating EDR\n");
-
-    //Terminate the Bluetooth communication adapter
-    CATerminateEDR();
+    printf("send response with URI\n");
+    send_response(object, (requestInfo != NULL) ? requestInfo->info.token : "");
 
-    printf( "Terminating BT Adapter thread pool");
-    u_thread_pool_free(gBTThreadPool);
 }
-#endif //BT_ADAPTER_TEST
 
-#ifdef WIFI_ADAPTER_TEST
-void testInitializeWIFIInterface(void)
+void response_handler(const CARemoteEndpoint_t* object, const CAResponseInfo_t* responseInfo)
 {
-    printf("testInitializeWIFIInterface IN\n");
 
-    printf("Initializing WIFI adapter threadpool\n");
-    initializeThreadPool(CA_WIFI);
+    printf("[CALLBACK] response_handler, uri : %s, data : %s\n", (object != NULL) ? object->resourceUri : "",
+            (responseInfo != NULL) ? responseInfo->info.payload : "");
 
-    //Start Wifi communication adapter
-    if (0 != CAInitializeWifi(interfaceRegisterCallback, networkPacketHandler,
-                              networkInterfaceCallback, gWiFiThreadPool))
+    printf("[CALLBACK] response_handler, address : %s\n", (object != NULL) ? object->addressInfo.IP.ipAddress : "");
+
+    if(responseInfo->info.options)
     {
-        printf("testInitializeWIFIInterface Failed to initialize bluetooth communication adapter\n");
-        return;
+        uint32_t len =  responseInfo->info.numOptions;
+        uint32_t i;
+        for(i = 0 ; i < len ; i++)
+        {
+            printf("[CALLBACK] response_handler, option ID : %d\n", responseInfo->info.options[i].optionID);
+            printf("[CALLBACK] response_handler, options data length : %d\n", responseInfo->info.options[i].optionLength);
+            printf("[CALLBACK] response_handler, options data : %s\n", responseInfo->info.options[i].optionData );
+        }
     }
 
-    printf("testInitializeWIFIInterface OUT\n");
+    //printf("send request with URI\n");
+    //send_request_tmp(object, (responseInfo != NULL) ? responseInfo->info.token : "");
 }
 
-void testTerminateWIFIInterface(void)
+void send_response(CARemoteEndpoint_t *endpoint, CAToken_t request_token)
 {
-    printf("testTerminateWIFIInterface IN\n");
-
-    // Stop if Wifi communication adapter is running
-    interfaceStopAdapter(CA_WIFI);
-
-    // Freeing threadpool for wifi communication adapter
-    printf( "Terminating WIFI Adapter thread pool");
-    u_thread_pool_free(gWiFiThreadPool);
 
-    //Terminate the Wifi communication adapter
-    CATerminateWIfI();
+    printf("\n=============================================\n");
 
+    CAInfo_t responseData;
+    //responseData = (CAInfo*) malloc(sizeof(CAInfo));
+    memset(&responseData, 0, sizeof(CAInfo_t));
+    responseData.token = request_token;
+    responseData.payload = "response payload";
 
-    printf("testTerminateWIFIInterface OUT\n");
-}
-#endif //WIFI_ADAPTER_TEST
+    CAResponseInfo_t responseInfo;
+    //responseInfo = (CAResponseInfo*) malloc(sizeof(CAResponseInfo));
+    memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
+    responseInfo.result = 203;
+    responseInfo.info = responseData;
 
-#ifdef BLE_ADAPTER_TEST
-void testInitializeBLEInterface(void)
-{
-    printf("testInitializeBLEInterface IN\n");
+    // send request (connectivityType from remoteEndpoint of request Info)
+    CASendResponse(endpoint, &responseInfo);
 
-    printf("Initializing BLE adapter threadpool\n");
-    initializeThreadPool(CA_LE);
+    printf("=============================================\n");
 
-    //Start bluetooth communication adapter
-    if (0 != CAInitializeLE(interfaceRegisterCallback, networkPacketHandler,
-                            networkInterfaceCallback, gLEThreadPool))
-    {
-        printf("testInitializeBLEInterface Failed due to CAInitializeLE\n");
-        return;
-    }
-
-    printf("testInitializeBLEInterface OUT\n");
 }
 
-void testTerminateBLEInterface(void)
+void send_request_tmp(CARemoteEndpoint_t *endpoint, CAToken_t token)
 {
-    printf("testTerminateBLEInterface IN\n");
 
-    //Terminate the BLE server & Client
-    CATerminateLE();
+    printf("\n=============================================\n");
 
-    printf( "Terminating BLE Adapter thread pool");
-    u_thread_pool_free(gLEThreadPool);
-
-    printf("testTerminateBLEInterface OUT\n");
-}
-#endif //BLE_ADAPTER_TEST
+    CAInfo_t requestData;
+    memset(&requestData, 0, sizeof(CAInfo_t));
+    requestData.token = token;
+    requestData.payload = "Temp Json Payload";
 
-static void testPrintHelp(void)
-{
-    printf(" =====================================================================\n");
-    printf("|                 Welcome to Connectivity Abstraction                 |\n");
-    printf("|                   - CA Unit Test v1.0 -                             |\n");
-    printf("|---------------------------------------------------------------------|\n");
-    printf("|                           ** Options **                             |\n");
-    printf("|  i - Initialize the Interface                                       |\n");
-    printf("|  d - Terminate the Interface                                        |\n");
-    printf("|  a - Start adapter                                                  |\n");
-    printf("|  b - Stop adapter                                                   |\n");
-    printf("|  sd- Start Discovery Server                                         |\n");
-    printf("|  sl- Start Listening Server                                         |\n");
-    printf("|  u - Send Unicast Data                                              |\n");
-    printf("|  m - Send Multicast Data                                            |\n");
-    printf("|  g - Get Network Info                                               |\n");
-    printf("|  r - Read data synchronously                                        |\n");
-    printf("|  x - quit the test.                                                 |\n");
-    printf("|  h - Help menu.                                                     |\n");
-    printf(" =====================================================================\n");
-}
+    CARequestInfo_t requestInfo;
+    memset(&requestInfo, 0, sizeof(CARequestInfo_t));
+    requestInfo.method = CA_GET;
+    requestInfo.info = requestData;
 
-static gboolean testThread(GIOChannel *source, GIOCondition condition , gpointer data)
-{
-    gchar buf[10] = {'\0'};
-    gsize read = 0;
+    // send request
+    endpoint->connectivityType = CA_WIFI;
+    CASendRequest(endpoint, &requestInfo);
 
+    printf("=============================================\n");
 
-    if (g_io_channel_read(channel, buf, 10, &read) != G_IO_ERROR_NONE)
-    {
-        printf("g_io_channel_read error!!!\n");
-        return 1;
-    }
-    buf[read] = '\0';
-    g_strstrip(buf);
-
-    /*if ((!has_register) && (((buf[0]!= 'i') && (buf[0]!= 'h') && (buf[0]!= 'q')) || (read != 2))) {
-        testPrintHelp();
-        printf("***Warning***: You should Register firstly!\n");
-        return 1;
-    }*/
-    switch (buf[0])
-    {
-        case 'i':
-            testInitializeInterface();
-            break;
-        case 'x':
-            testTerminateInterface();
-            if (g_source_remove(g_test_io_watch_id))
-            {
-                printf("g_source_remove() OK!!!\n");
-                g_io_channel_shutdown(channel, TRUE, &g_err_Sample);
-                g_io_channel_unref(channel);
-                g_main_loop_quit(mainloop);
-            }
-            break;
-        case 'd':
-            testTerminateInterface();
-            break;
-        case 'a':
-            testStartAdapter();
-            break;
-        case 'b':
-            testStopAdapter();
-            break;
-        case 's':
-            if (read == 3)
-            {
-                if (buf[1] == 'd')
-                {
-                    testStartServer(1);
-                }
-                if (buf[1] == 'l')
-                {
-                    testStartServer(2);
-                }
-            }
-            break;
-        case 'u':
-            testSendUnicastData();
-            break;
-        case 'm':
-            testSendMulticastData();
-            break;
-        case 'r':
-            testReadData();
-            break;
-        case 'g':
-            testGetNetworkInfo();
-            break;
-        case 'h':
-            testPrintHelp();
-    }
-    return 1;
 }
 
-int main(int argc, char *argv[])
+void terminate()
 {
-    printf("Starting sample\n");
-    mainloop = g_main_loop_new(NULL, FALSE);
-    channel = g_io_channel_unix_new(0);/* read from stdin */
-    g_test_io_watch_id = g_io_add_watch(channel,
-                                        (GIOCondition)(G_IO_IN | G_IO_ERR | G_IO_HUP | G_IO_NVAL), testThread,
-                                        NULL);
-    printf("CM Test Thread created...\n");
-    testPrintHelp();
-    g_main_loop_run(mainloop);
-    return 0;
+    unselect_network();
 }
-
index 258f555..f60c07f 100644 (file)
@@ -103,7 +103,7 @@ uint32_t CAParseHeader(const char *header)
     for (i = 0; i < 8; i++)
     {
         int pos = 8 - i;
-        int bit = !!((*header << pos) & 0x80);
+        int bit = !!((*header << i) & 0x80);
         if ( i >= 4)
         {
             if ( 1 == bit)
@@ -178,10 +178,11 @@ uint32_t CAFragmentData(const char *data, char **dataSegment, uint32_t TotalLen,
     }
     else
     {
-        OIC_LOG_V(DEBUG, CA_MSG_PARSER_TAG, "Appending actual data of length [%d]", length);
+        OIC_LOG_V(DEBUG, CA_MSG_PARSER_TAG, "Appending actual data of length [%d] and offset [%d]", length,
+                  offset);
 
         *dataSegment = (char *) OICMalloc(sizeof(char) * length);
-        memcpy(*dataSegment, data, length);
+        memcpy(*dataSegment, data + offset, length);
     }
 
     return length;
index 7e872cc..57ba895 100644 (file)
@@ -65,7 +65,7 @@ CAResult_t CABTClientConnect(const char *remoteAddress, const char *serviceUUID)
 
 CAResult_t CABTClientDisconnect(const int32_t clientID)
 {
-       OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
+    OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
 
     //Input validation
     if (0 > clientID)
@@ -79,7 +79,7 @@ CAResult_t CABTClientDisconnect(const int32_t clientID)
     {
         OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed close rfcomm client socket!, error num [%x]",
                   err);
-        return CA_STATUS_FAILED;    
+        return CA_STATUS_FAILED;
     }
 
     OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
index 875d353..af2393d 100644 (file)
@@ -31,6 +31,7 @@
 #include "cabtutils.h"
 #include "caadapterutils.h"
 #include "camessagequeue.h"
+#include "camsgparser.h"
 
 /**
  * @struct CABTNetworkEvent
@@ -97,24 +98,53 @@ static u_thread_pool_t gBTThreadPool = NULL;
 static CAAdapterMessageQueue_t *gSendDataQueue = NULL;
 
 /**
+ * @var gReceiverDataQueue
+ * @brief Queue to maintain data received from remote Bluetooth devices.
+ */
+static CAAdapterMessageQueue_t *gReceiverDataQueue = NULL;
+
+/**
  * @var gSendDataMutex
  * @brief Mutex to synchronize access to data send queue.
  */
 static u_mutex gSendDataMutex = NULL;
 
 /**
+ * @var gReceiverDataMutex
+ * @brief Mutex to synchronize access to data recv queue.
+ */
+static u_mutex gReceiverDataMutex = NULL;
+
+/**
  * @var gSendDataCond
  * @brief Condition used for notifying handler the presence of data in send queue.
  */
 static u_cond gSendDataCond = NULL;
 
 /**
+ * @var gReceiverDataCond
+ * @brief Condition used for notifying handler the presence of data in recv queue.
+ */
+static u_cond gReceiverDataCond = NULL;
+
+/**
  * @var gDataSendHandlerState
  * @brief Stop condition of sendhandler.
  */
 static bool gDataSendHandlerState = false;
 
 /**
+ * @var gDataReceiverHandlerState
+ * @brief Stop condition of redvhandler.
+ */
+static bool gDataReceiverHandlerState = false;
+
+/**
+ * @var isHeaderAvailable
+ * @brief to differentiate btw header and data packet.
+ */
+static CABool_t isHeaderAvailable = false;
+/**
  * @fn CABTAdapterStateChangeCallback
  * @brief This callback is registered to receive bluetooth adapter state changes.
  */
@@ -184,6 +214,12 @@ static void CABTManagerTerminateMutex(void);
 static void CABTManagerDataSendHandler(void *context);
 
 /**
+ * @fn CABTManagerDataReceiverHandler
+ * @brief This function handles data from recv message queue.
+ */
+static void CABTManagerDataReceiverHandler(void *context);
+
+/**
  * @fn CABTManagerSendUnicastData
  * @brief This function sends data to specified remote bluetooth device.
  */
@@ -394,6 +430,13 @@ CAResult_t CABTManagerStart(void)
         }
     }
 
+    gDataReceiverHandlerState = true;
+    if (CA_STATUS_OK != u_thread_pool_add_task(gBTThreadPool, CABTManagerDataReceiverHandler, NULL))
+    {
+        OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to start data send handler!");
+        return CA_STATUS_FAILED;
+    }
+
     OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -411,6 +454,15 @@ void CABTManagerStop(void)
         u_mutex_unlock(gSendDataMutex);
     }
 
+    //Stop data send and receive handlers
+    if (gReceiverDataMutex && gReceiverDataCond && gDataReceiverHandlerState)
+    {
+        u_mutex_lock(gReceiverDataMutex);
+        gDataReceiverHandlerState = CA_FALSE;
+        u_cond_signal(gReceiverDataCond);
+        u_mutex_unlock(gReceiverDataMutex);
+    }
+
     //Stop service search
     CABTStopServiceSearch();
     
@@ -440,6 +492,44 @@ void CABTManagerSetNetworkChangeCallback(CANetworkChangeCallback networkChangeCa
     gNetworkChangeCallback = networkChangeCallback;
 }
 
+CAResult_t CABTManagerPushDataToReceiverQueue(const char *remoteAddress, const char *serviceUUID,
+        void *data, uint32_t dataLength, uint32_t *sentLength)
+{
+    OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
+
+    //Input validation
+    VERIFY_NON_NULL(serviceUUID, BLUETOOTH_ADAPTER_TAG, "service UUID is null");
+    VERIFY_NON_NULL(data, BLUETOOTH_ADAPTER_TAG, "Data is null");
+    VERIFY_NON_NULL(sentLength, BLUETOOTH_ADAPTER_TAG, "Sent data length holder is null");
+
+    //Add message to data queue
+    CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
+                                         serviceUUID);
+    if (NULL == remoteEndpoint)
+    {
+        OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to create remote endpoint !");
+        return CA_STATUS_FAILED;
+    }
+
+    if (CA_STATUS_OK != CAAdapterEnqueueMessage(gReceiverDataQueue, remoteEndpoint, data, dataLength))
+    {
+        OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to add message to queue !");
+
+        CAAdapterFreeRemoteEndpoint(remoteEndpoint);
+        return CA_STATUS_FAILED;
+    }
+
+    *sentLength = dataLength;
+
+    //Signal message handler for processing data for sending
+    OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Signalling message send handler");
+    u_mutex_lock(gReceiverDataMutex);
+    u_cond_signal(gReceiverDataCond);
+    u_mutex_unlock(gReceiverDataMutex);
+
+    OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
 CAResult_t CABTManagerSendData(const char *remoteAddress, const char *serviceUUID,
                                void *data, uint32_t dataLength, uint32_t *sentLength)
 {
@@ -554,6 +644,14 @@ CAResult_t CABTManagerInitializeQueues(void)
         }
     }
 
+    if (NULL == gReceiverDataQueue)
+    {
+        if (CA_STATUS_OK != CAAdapterInitializeMessageQueue(&gReceiverDataQueue))
+        {
+            return CA_STATUS_FAILED;
+        }
+    }
+
     OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
     return CA_STATUS_OK;
 }
@@ -568,7 +666,14 @@ void CABTManagerTerminateQueues(void)
         gSendDataQueue = NULL;
     }
 
-    OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");    
+    if (gReceiverDataQueue)
+    {
+        CAAdapterTerminateMessageQueue(gReceiverDataQueue);
+        gReceiverDataQueue = NULL;
+    }
+
+
+    OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
 }
 
 void CABTManagerInitializeMutex(void)
@@ -587,11 +692,21 @@ void CABTManagerInitializeMutex(void)
         gSendDataMutex = u_mutex_new();
     }
 
+    if (!gReceiverDataMutex)
+    {
+        gReceiverDataMutex = u_mutex_new();
+    }
+
     if (!gSendDataCond)
     {
         gSendDataCond = u_cond_new();
     }
 
+    if (!gReceiverDataCond)
+    {
+        gReceiverDataCond = u_cond_new();
+    }
+
     OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");    
 }
 
@@ -611,15 +726,109 @@ void CABTManagerTerminateMutex(void)
         gSendDataMutex = NULL;
     }
 
+    if (gReceiverDataMutex)
+    {
+        u_mutex_free(gReceiverDataMutex);
+        gReceiverDataMutex = NULL;
+    }
+
     if (gSendDataCond)
     {
         u_cond_free(gSendDataCond);
         gSendDataCond = NULL;
     }
 
+    if (gReceiverDataCond)
+    {
+        u_cond_free(gReceiverDataCond);
+        gReceiverDataCond = NULL;
+    }
+
+
     OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
 }
 
+
+void CABTManagerDataReceiverHandler(void *context)
+{
+    OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
+
+    u_mutex_lock(gReceiverDataMutex);
+
+    CAAdapterMessage_t *message = NULL;
+    const char *remoteAddress = NULL;
+    const char *serviceUUID = NULL;
+    uint32_t recvDataLen = 0;
+    uint32_t totalDataLen = 0;
+    char *dataSegment = NULL;
+    char *defragData = NULL;
+    CARemoteEndpoint_t *remoteEndpoint = NULL;
+
+    while (gDataReceiverHandlerState)
+    {
+
+        OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, " waiting for the data");
+
+        u_cond_wait(gReceiverDataCond, gReceiverDataMutex);
+
+        OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "wait unlocked");
+
+        //Extract the message from queue and send to remote bluetooth device
+        while (CA_STATUS_OK == CAAdapterDequeueMessage(gReceiverDataQueue, &message))
+        {
+            OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "checking for DE Fragmentation");
+
+            if (!isHeaderAvailable)
+            {
+                char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
+                memcpy(header, message->data, CA_HEADER_LENGTH);
+                totalDataLen = CAParseHeader(header);
+                OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Total data to be accumulated [%d] bytes", totalDataLen);
+                defragData = (char *) OICMalloc(sizeof(char) * totalDataLen);
+                OICFree(header);
+
+                remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
+                serviceUUID = message->remoteEndpoint->resourceUri;
+
+                remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
+                                 serviceUUID);
+
+                memcpy(defragData + recvDataLen, message->data + CA_HEADER_LENGTH,
+                       message->dataLen - CA_HEADER_LENGTH);
+                recvDataLen += message->dataLen - CA_HEADER_LENGTH;
+                isHeaderAvailable = true;
+            }
+            else
+            {
+                memcpy(defragData + recvDataLen, message->data, message->dataLen);
+                recvDataLen += message->dataLen ;
+            }
+            CAAdapterFreeMessage(message);
+            if (totalDataLen == recvDataLen)
+            {
+                OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "Sending data up !");
+                gNetworkPacketReceivedCallback(remoteEndpoint, defragData, recvDataLen);
+                OICFree(remoteEndpoint);
+                OICFree(defragData);
+                recvDataLen = 0;
+                totalDataLen = 0;
+                isHeaderAvailable = false;
+            }
+
+        }
+
+        if (false == gDataReceiverHandlerState)
+        {
+            break;
+        }
+
+
+    }
+    u_mutex_unlock(gReceiverDataMutex);
+    OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
+}
+
+
 void CABTManagerDataSendHandler(void *context)
 {
     OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "IN");
@@ -631,29 +840,72 @@ void CABTManagerDataSendHandler(void *context)
         const char *remoteAddress = NULL;
         const char *serviceUUID = NULL;
         uint32_t sentLength = 0;
+        int headerAdded = 0;
 
         //Extract the message from queue and send to remote bluetooth device
         while (CA_STATUS_OK == CAAdapterDequeueMessage(gSendDataQueue, &message))
         {
             remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
             serviceUUID = message->remoteEndpoint->resourceUri;
-            if (strlen(remoteAddress)) //Unicast data
+
+            char *dataSegment = NULL;
+            uint32_t offset = 0, ret = 1;
+            int datalen = message->dataLen;
+            OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "checking for fragmentation and the dataLen is %d",
+                      datalen);
+            while ( 1)
             {
-                if (CA_STATUS_OK != CABTManagerSendUnicastData(remoteAddress, serviceUUID,
-                        message->data, message->dataLen, &sentLength))
+                OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "fragmenting the data DataLen [%d] Offset [%d]", datalen,
+                          offset);
+                ret = CAFragmentData(message->data, &dataSegment, datalen, offset);
+                sleep(1);
+                if (0 == ret)
                 {
-                    OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send unicast data !");
+                    break;
                 }
-            }
-            else //Multicast data
-            {
-                if (CA_STATUS_OK != CABTManagerSendMulticastData(serviceUUID, message->data,
-                        message->dataLen, &sentLength))
+                if (strlen(remoteAddress)) //Unicast data
                 {
-                    OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send multicast data !");
+                    if (CA_STATUS_OK != CABTManagerSendUnicastData(remoteAddress, serviceUUID,
+                            dataSegment, ret, &sentLength))
+                    {
+                        OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send unicast data !");
+                    }
                 }
-            }
+                else
+                {
+                    OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "sending multicast data");
+                    if (CA_STATUS_OK != CABTManagerSendMulticastData(serviceUUID, dataSegment,
+                            ret, &sentLength))
+                    {
+                        OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to send multicast data !");
+                    }
+                }
+                OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "freeing dataSegment");
 
+                OICFree(dataSegment);
+                dataSegment = NULL;
+                offset += ret;
+                if (headerAdded == 0)
+                {
+                    datalen -= offset - CA_HEADER_LENGTH;
+                    offset = offset - CA_HEADER_LENGTH;
+                    headerAdded = 1;
+                }
+                else
+                {
+                    datalen -= ret;
+                }
+
+                if (datalen < 0)
+                {
+                    datalen += ret ;
+                }
+                if (datalen == message->dataLen)
+                {
+                    OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "All data has been fragmented and sent");
+                    break;
+                }
+            }
             //Free message
             CAAdapterFreeMessage(message);
         }
@@ -840,7 +1092,7 @@ CAResult_t CABTGetAdapterEnableState(bool *state)
     VERIFY_NON_NULL(state, BLUETOOTH_ADAPTER_TAG, "state holder is NULL!");
 
     int err = BT_ERROR_NONE;
-    bt_adapter_state_e adapterState;    
+    bt_adapter_state_e adapterState;
 
     //Get Bluetooth adapter state
     if (BT_ERROR_NONE != (err = bt_adapter_get_state(&adapterState)))
@@ -918,7 +1170,7 @@ CAResult_t CABTStopDeviceDiscovery(void)
     }
 
     OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;    
+    return CA_STATUS_OK;
 }
 
 CAResult_t CABTStartServiceSearch(const char *remoteAddress)
@@ -1083,26 +1335,30 @@ void CABTDataRecvCallback(bt_socket_received_data_s *data, void *userData)
     }
     u_mutex_unlock(gBTDeviceListMutex);
 
-    //Create RemoteEndPoint
-    CARemoteEndpoint_t *remoteEndpoint = NULL;
-    remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, device->remoteAddress,
-                     OIC_BT_SERVICE_ID);
-    if (NULL == remoteEndpoint)
-    {
-        OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to crate remote endpoint!");
-        return;
-    }
+    /*    //Create RemoteEndPoint
+        CARemoteEndpoint_t *remoteEndpoint = NULL;
+        remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, device->remoteAddress,
+                         OIC_BT_SERVICE_ID);
+        if (NULL == remoteEndpoint)
+        {
+            OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed to crate remote endpoint!");
+            return;
+        }
 
-    void *copyData = OICMalloc(data->data_size);
-    if (NULL == copyData)
-    {
-        OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed allocate memory!");
-        CAAdapterFreeRemoteEndpoint(remoteEndpoint);
-        return;
-    }
-    memcpy(copyData, data->data, data->data_size);
+        void *copyData = OICMalloc(data->data_size);
+        if (NULL == copyData)
+        {
+            OIC_LOG_V(ERROR, BLUETOOTH_ADAPTER_TAG, "Failed allocate memory!");
+            CAAdapterFreeRemoteEndpoint(remoteEndpoint);
+            return;
+        }
+        memcpy(copyData, data->data, data->data_size);
+    */
+    uint32_t sentLength = 0;
 
-    gNetworkPacketReceivedCallback(remoteEndpoint, copyData, (uint32_t)data->data_size);
+    CAResult_t res = CABTManagerPushDataToReceiverQueue(device->remoteAddress, OIC_BT_SERVICE_ID,
+                     data->data, (uint32_t)data->data_size, &sentLength);
+//    gNetworkPacketReceivedCallback(remoteEndpoint, copyData, (uint32_t)data->data_size);
 
     OIC_LOG_V(DEBUG, BLUETOOTH_ADAPTER_TAG, "OUT");
 }
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/caleadapter.c b/resource/csdk/connectivity/src/bt_le_adapter/android/caleadapter.c
new file mode 100644 (file)
index 0000000..4992e7f
--- /dev/null
@@ -0,0 +1,181 @@
+/******************************************************************
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "jni.h"
+#include "caleadapter.h"
+#include "calecore.h"
+#include "logger.h"
+
+#define TAG PCF("CA")
+
+// received packet callback
+static CANetworkPacketReceivedCallback gLEReceivedCallback = NULL;
+
+static void CALEPacketReceiveCallback(const char* address, const char* data)
+{
+    OIC_LOG_V(DEBUG, TAG,
+            "CALEPacketReceiveCallback, from: %s, data: %s", address, data);
+
+    // call the callback
+    if (gLEReceivedCallback != NULL)
+    {
+        CARemoteEndpoint_t* endpoint = NULL;
+        endpoint = (CARemoteEndpoint_t*) OICMalloc(sizeof(CARemoteEndpoint_t));
+
+        if (endpoint == NULL)
+        {
+            OIC_LOG(DEBUG, TAG, "CALEPacketReceiveCallback, Memory allocation failed !");
+            OICFree(address);
+            return;
+        }
+
+        // set address
+        memset((void*) endpoint->addressInfo.BT.btMacAddress, 0, CA_MACADDR_SIZE);
+        if (CA_MACADDR_SIZE > strlen(address))
+        {
+            strcpy((char*) endpoint->addressInfo.BT.btMacAddress, address);
+        }
+        OICFree(address);
+
+        // set connectivity type
+        endpoint->connectivityType = CA_LE;
+
+        gLEReceivedCallback(endpoint, (void *) data, strlen(data));
+    }
+}
+
+CAResult_t CAInitializeLE(CARegisterConnectivityCallback registerCallback,
+        CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback,
+        u_thread_pool_t handle)
+{
+    OIC_LOG(DEBUG, TAG, "IntializeBLE");
+
+    gLEReceivedCallback = reqRespCallback;
+
+    // register handlers
+    CAConnectivityHandler_t handler;
+    memset(&handler, 0, sizeof(CAConnectivityHandler_t));
+
+    handler.startAdapter = CAStartLE;
+    handler.startListenServer = CAStartLEListeningServer;
+    handler.startDiscoverServer = CAStartLEDiscoveryServer;
+    handler.sendData = CASendLEUnicastData;
+    handler.sendDataToAll = CASendLEMulticastData;
+    handler.GetnetInfo = CAGetLEInterfaceInformation;
+    handler.readData = CAReadLEData;
+    handler.stopAdapter = CAStopLE;
+    handler.terminate = CATerminateLE;
+    registerCallback(handler, CA_LE);
+
+    CALEInitialize(handle);
+    CALESetCallback(CALEPacketReceiveCallback);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStartLE()
+{
+    OIC_LOG_V(DEBUG, TAG, "CAStartLE");
+    CANativeLEStartScan();
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStartLEListeningServer()
+{
+    OIC_LOG_V(DEBUG, TAG, "CAStartLEListeningServer");
+    CALEStartMulticastServer();
+//    CALESendMulticastMessage("1111", 4);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStartLEDiscoveryServer()
+{
+    OIC_LOG_V(DEBUG, TAG, "CAStartLEDiscoveryServer");
+    CALEStartMulticastServer();
+
+    return CA_STATUS_OK;
+}
+
+uint32_t CASendLEUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CASendLEUnicastData");
+//    "E1:70:56:CF:E3:67"
+    CALESendUnicastMessage(endpoint->addressInfo.BT.btMacAddress, data, dataLen);
+
+    return 0;
+}
+
+uint32_t CASendLEMulticastData(void* data, uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CASendLEMulticastData");
+    CALESendMulticastMessage(data, dataLen);
+
+    return 0;
+}
+
+CAResult_t CAStartLENotifyServer()
+{
+    OIC_LOG_V(DEBUG, TAG, "CAStartLENotifyServer");
+
+    return CA_STATUS_OK;
+}
+
+uint32_t CASendLENotification(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CASendLENotification");
+    CALESendUnicastMessage(endpoint->addressInfo.BT.btMacAddress, data, dataLen);
+
+    return 0;
+}
+
+CAResult_t CAGetLEInterfaceInformation(CALocalConnectivity_t** info, uint32_t* size)
+{
+    OIC_LOG_V(DEBUG, TAG, "CAGetLEInterfaceInformation");
+    CALEGetInterfaceInfo(info, size);
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAReadLEData()
+{
+    OIC_LOG_V(DEBUG, TAG, "Read LE Data");
+
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStopLE()
+{
+    OIC_LOG_V(DEBUG, TAG, "CAStopLE");
+    CANativeLEStopScan();
+
+    return CA_STATUS_OK;
+}
+
+void CATerminateLE()
+{
+    OIC_LOG_V(DEBUG, TAG, "TerminatLE");
+    CALETerminate();
+}
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c b/resource/csdk/connectivity/src/bt_le_adapter/android/caleclient.c
new file mode 100644 (file)
index 0000000..ab398cd
--- /dev/null
@@ -0,0 +1,1804 @@
+#include <stdio.h>
+#include <string.h>
+#include <jni.h>
+#include "calecore.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "uthreadpool.h" /* for thread pool */
+#include "uarraylist.h"
+#include "com_iotivity_jar_CALeInterface.h"
+
+#define TAG PCF("CA")
+
+#define METHODID_OBJECTNONPARAM   "()Landroid/bluetooth/BluetoothAdapter;"
+#define METHODID_INTNONPARAM   "()I"
+#define METHODID_STRINGNONPARAM   "()Ljava/lang/String;"
+#define METHODID_OBJECT_STRINGUUIDPARAM   "(Ljava/lang/String;Ljava/util/UUID;)Ljava/lang/Object;"
+#define METHODID_ONRESPONSE_PARAM  "(Ljava/lang/String;)V"
+#define CLASSPATH_BT_ADPATER "android/bluetooth/BluetoothAdapter"
+#define CLASSPATH_BT_UUID "java/util/UUID"
+
+static const uint32_t STATE_CONNECTED = 2;
+static const uint32_t STATE_DISCONNECTED = 0;
+static const uint32_t GATT_SUCCESS = 0;
+
+static JavaVM *g_jvm;
+static u_arraylist_t *gdeviceList = NULL;
+static u_arraylist_t *gGattObjectList = NULL;
+static CAPacketReceiveCallback gPacketReceiveCallback = NULL;
+static u_thread_pool_t gThreadPoolHandle = NULL;
+static jobject gLeScanCallback;
+static jobject gLeGattCallback;
+static jobject gContext;
+static jboolean gIsStartServer;
+
+////////////////////////////////////////////////////////////////////////////////////////////////////
+void CALeCreateJniInterfaceObject()
+{
+    OIC_LOG_V(DEBUG, TAG, "CALeCreateJniInterfaceObject");
+
+    jboolean isAttached = FALSE;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+    if(res != JNI_OK)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+        if(res != JNI_OK)
+        {
+            OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+            return;
+        }
+        isAttached = TRUE;
+    }
+
+    jclass LeJniInterface = (*env)->FindClass(env, "com/iotivity/jar/CALeInterface");
+    if (!LeJniInterface)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Could not get CALeInterface class");
+        return;
+    }
+
+    jmethodID LeInterfaceConstructorMethod =
+            (*env)->GetMethodID(env, LeJniInterface, "<init>", "()V");
+    if (!LeInterfaceConstructorMethod)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Could not get CALeInterface constructor method");
+        return;
+    }
+
+    jobject jni_instance = (*env)->NewObject(env, LeJniInterface, LeInterfaceConstructorMethod);
+    gContext = (*env)->NewGlobalRef(env, jni_instance);
+    OIC_LOG_V(DEBUG, TAG, "Create CALeInterface instance");
+
+    if(isAttached)
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+}
+
+JNIEXPORT jint JNI_OnLoad(JavaVM *jvm, void *reserved)
+{
+    OIC_LOG_V(DEBUG, TAG, "JNI_OnLoad in calecore");
+
+    JNIEnv* env;
+    if((*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_6) != JNI_OK)
+    {
+        return -1;
+    }
+    g_jvm = jvm;  /* cache the JavaVM pointer */
+
+    //JVM required for WifiCore to work with JNI interface
+    CAWiFiJniInit(jvm);
+
+    return JNI_VERSION_1_6;
+}
+
+void JNI_OnUnload(JavaVM *jvm, void *reserved)
+{
+    OIC_LOG_V(DEBUG, TAG, "JNI_OnUnload in calecore");
+
+    JNIEnv* env;
+    if((*jvm)->GetEnv(jvm, (void**)&env, JNI_VERSION_1_6) != JNI_OK)
+    {
+        return;
+    }
+    g_jvm = 0;
+    return;
+}
+
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterLeScanCallback(JNIEnv *env,
+        jobject obj, jobject callback)
+{
+    OIC_LOG_V(DEBUG, TAG, "CARegisterLeScanCallback");
+
+    gLeScanCallback = (*env)->NewGlobalRef(env, callback);
+}
+
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CARegisterLeGattCallback(JNIEnv *env,
+        jobject obj, jobject callback)
+{
+    OIC_LOG_V(DEBUG, TAG, "CARegisterLeGattCallback");
+
+    gLeGattCallback = (*env)->NewGlobalRef(env, callback);
+}
+
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeScanCallback (JNIEnv *env,
+        jobject obj, jobject device, jint rssi, jbyteArray scanRecord)
+{
+    CANativeAddScanDeviceToList(env, device);
+}
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattConnectionStateChangeCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattConnectionStateChangeCallback
+  (JNIEnv *env, jobject obj, jobject gatt, jint status, jint newstate)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALeGattConnectionStateChangeCallback - status %d, newstate %d", status, newstate);
+
+    if(GATT_SUCCESS == status && STATE_CONNECTED == newstate)
+    {
+        if(gatt) {
+            CANativeAddGattobjToList(env, gatt);
+            CANativeLEDiscoverServices(env, gatt);
+        }
+    }
+    else if (GATT_SUCCESS == status && STATE_DISCONNECTED == newstate)
+    {
+        if(gatt) {
+            CANativeRemoveGattObj(env, gatt);
+        }
+    }
+}
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattServicesDiscoveredCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattServicesDiscoveredCallback
+  (JNIEnv *env, jobject obj, jobject gatt, jint status)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALeGattServicesDiscoveredCallback - status %d: ", status);
+
+    if(0 == status)
+    {
+        jboolean ret = CANativeSetCharacteristicNoti(env, gatt);
+        if(1 == ret)
+        {
+            jstring data = (*env)->NewStringUTF(env, "HelloWorld");
+            jobject jni_obj_character = CANativeCreateGattCharacteristic(env, gatt, data);
+            if(jni_obj_character)
+            {
+                CANativeLESendData(env, gatt, jni_obj_character);
+            }
+        }
+    }
+}
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattCharacteristicReadCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristicReadCallback
+  (JNIEnv *env, jobject obj, jobject gatt, jobject characteristic, jstring data, jint status)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicReadCallback - status : %d", status);
+
+    const char* readData = (*env)->GetStringUTFChars(env, data, NULL);
+    OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicReadCallback - read data : %s", readData);
+}
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattCharacteristicWritjclasseCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;I)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristicWriteCallback
+  (JNIEnv *env, jobject obj, jobject gatt, jobject characteristic, jstring data, jint status)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - status : %d", status);
+
+    const char* writeData = (*env)->GetStringUTFChars(env, data, NULL);
+    OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicWriteCallback - write data : %s", writeData);
+
+//    jobjectArray jni_obj_data_array = CANativeGetValueFromCharacteristic(env, characteristic);
+//    if(!jni_obj_data_array)
+//    {
+//        OIC_LOG_V(DEBUG, TAG, "jni_obj_data_array is null");
+//        return;
+//    }
+}
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattCharacteristicChangedCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattCharacteristic;)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattCharacteristicChangedCallback
+  (JNIEnv *env, jobject obj, jobject gatt, jobject characteristic, jstring data)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback");
+
+    const char* changedData = (*env)->GetStringUTFChars(env, data, NULL);
+    OIC_LOG_V(DEBUG, TAG, "CALeGattCharacteristicChangedCallback - data : %s", changedData);
+
+    CANativeLEDisconnect(env, gatt);
+}
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattDescriptorReadCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattDescriptorReadCallback
+  (JNIEnv *env, jobject obj, jobject gatt, jobject descriptor, jint status)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorReadCallback - status %d: ", status);
+}
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattDescriptorWriteCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;Landroid/bluetooth/BluetoothGattDescriptor;I)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattDescriptorWriteCallback
+  (JNIEnv *env, jobject obj, jobject gatt, jobject descriptor, jint status)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALeGattDescriptorWriteCallback - status %d: ", status);
+}
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattReliableWriteCompletedCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;I)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattReliableWriteCompletedCallback
+  (JNIEnv *env, jobject obj, jobject gatt, jint status)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALeGattReliableWriteCompletedCallback - status %d: ", status);
+}
+
+/*
+ * Class:     com_iotivity_jar_CALeInterface
+ * Method:    CALeGattReadRemoteRssiCallback
+ * Signature: (Landroid/bluetooth/BluetoothGatt;II)V
+ */
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CALeInterface_CALeGattReadRemoteRssiCallback
+  (JNIEnv *env, jobject obj, jobject gatt, jint rssi, jint status)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALeGattReadRemoteRssiCallback - rssi %d,  status %d: ", rssi, status);
+}
+
+
+void CALEInitialize(u_thread_pool_t handle)
+{
+    OIC_LOG(DEBUG, TAG, "CALEInitialize");
+
+    gThreadPoolHandle = handle;
+
+    CALeCreateJniInterfaceObject(); /* create java CALeInterface instance*/
+}
+
+void CALETerminate()
+{
+    OIC_LOG(DEBUG, TAG, "CALETerminate");
+
+    jboolean isAttached = FALSE;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+    if(res != JNI_OK)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+        if(res != JNI_OK)
+        {
+            OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+            return;
+        }
+        isAttached = TRUE;
+    }
+
+    CANativeLEDisconnectAll(env);
+
+    if(gLeScanCallback)
+    {
+        CANativeLEStopScanImpl(env, gLeScanCallback);
+    }
+
+    if(gLeScanCallback)
+    {
+        (*env)->DeleteGlobalRef(env, gLeScanCallback);
+    }
+
+    if(gLeGattCallback)
+    {
+        (*env)->DeleteGlobalRef(env, gLeGattCallback);
+    }
+
+    if(gContext)
+    {
+        (*env)->DeleteGlobalRef(env, gContext);
+    }
+
+    CANativeRemoveAllDevices(env);
+    CANativeRemoveAllGattObjsList(env);
+    gIsStartServer = FALSE;
+
+    if(isAttached)
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+
+}
+
+int32_t CALESendUnicastMessage(const char* address, const char* data, uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALESendUnicastMessage(%s, %s)", address, data);
+
+    CALESendUnicastMessageImpl(address, data, dataLen);
+    return 0;
+}
+
+int32_t CALESendMulticastMessage(const char* data, uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALESendMulticastMessage(%s)", data);
+
+    jboolean isAttached = FALSE;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+    if(res != JNI_OK)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+        if(res != JNI_OK)
+        {
+            OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+            return;
+        }
+        isAttached = TRUE;
+    }
+
+    CALESendMulticastMessageImpl(env, data, dataLen);
+
+    if(isAttached)
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+
+    return 0;
+}
+
+int32_t CALEStartUnicastServer(const char* address)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALEStartUnicastServer(%s)", address);
+
+    return 0;
+}
+
+int32_t CALEStartMulticastServer()
+{
+    OIC_LOG_V(DEBUG, TAG, "CALEStartMulticastServer");
+
+    if(gIsStartServer)
+    {
+        OIC_LOG_V(DEBUG, TAG, "server is already started..it will be skipped");
+        return 0;
+    }
+
+    jboolean isAttached = FALSE;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+    if(res != JNI_OK)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+
+        if(res != JNI_OK)
+        {
+            OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+            return;
+        }
+        isAttached = TRUE;
+    }
+
+    gIsStartServer = TRUE;
+    CANativeLEStartScan();
+
+    if(isAttached)
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+
+    return 0;
+}
+
+int32_t CALEStopUnicastServer(int32_t serverID)
+{
+    OIC_LOG(DEBUG, TAG, "CALEStopUnicastServer");
+
+    return 0;
+}
+
+int32_t CALEStopMulticastServer(int32_t serverID)
+{
+    OIC_LOG(DEBUG, TAG, "CALEStopMulticastServer");
+    gIsStartServer = FALSE;
+    CANativeLEStopScan();
+    return 0;
+}
+
+void CALESetCallback(CAPacketReceiveCallback callback)
+{
+    gPacketReceiveCallback = callback;
+}
+
+void CALEGetInterfaceInfo(CALocalConnectivity_t **info, uint32_t* size)
+{
+    return;
+}
+
+void CALEGetLocalAddress(char* address)
+{
+    jboolean isAttached = FALSE;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+    if(res != JNI_OK)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+        if(res != JNI_OK)
+        {
+            OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+            return;
+        }
+        isAttached = TRUE;
+    }
+
+    jstring jni_address = CANativeGetLocalDeviceAddress(env);
+    const char* localAddress = (*env)->GetStringUTFChars(env, jni_address, NULL);
+    memcpy(address, localAddress, strlen(localAddress));
+
+    OIC_LOG_V(DEBUG, TAG, "Local Address : %s", address);
+    if(isAttached)
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+}
+
+int32_t CALESendUnicastMessageImpl(const char* address, const char* data, uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CALESendUnicastMessageImpl, address: %s, data: %s", address, data);
+
+    jboolean isAttached = FALSE;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+    if(res != JNI_OK)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+        if(res != JNI_OK)
+        {
+            OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+            return;
+        }
+        isAttached = TRUE;
+    }
+
+    // connect to gatt server
+    CANativeLEStopScanImpl(env, gLeScanCallback);
+
+    jobject jni_obj_bluetoothDevice = NULL;
+    if(gContext && gdeviceList)
+    {
+        jint index;
+        for (index = 0; index < u_arraylist_length(gdeviceList); index++)
+        {
+            jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
+            if(!jarrayObj)
+            {
+                OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
+                return;
+            }
+
+            jstring jni_setAddress = CANativeGetAddressFromBTDevice(env, jarrayObj);
+            if(!jni_setAddress)
+            {
+                OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
+                return;
+            }
+            const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+
+            if(!strcmp(setAddress, address))
+            {
+                jni_obj_bluetoothDevice = jarrayObj;
+                break;
+            }
+        }
+
+        if(jni_obj_bluetoothDevice)
+        {
+            jboolean autoConnect = FALSE;
+            CANativeLEConnect(env, jni_obj_bluetoothDevice, gContext, autoConnect, gLeGattCallback);
+        }
+    }
+
+    if(isAttached)
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+
+    return 0;
+}
+
+int32_t CALESendMulticastMessageImpl(JNIEnv *env, const char* data, uint32_t dataLen)
+{
+    OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, send to, data: %s", data);
+
+    if(!gdeviceList)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceList is null");
+        return 0;
+    }
+
+    // connect to gatt server
+    CANativeLEStopScanImpl(env, gLeScanCallback);
+
+    // reset gatt list
+    CANativeRemoveAllGattObjsList(env);
+    CANativeCreateGattObjList(env);
+
+    jint index;
+    for (index = 0; index < u_arraylist_length(gdeviceList); index++)
+    {
+        jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
+        if(!jarrayObj)
+        {
+            OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
+            return;
+        }
+
+        CANativeLEConnect(env, jarrayObj, gContext, FALSE, gLeGattCallback);
+        sleep(1);
+    }
+//    CANativeLEStartScan();
+
+    return 0;
+}
+
+/**
+ * BT common
+ */
+jstring CANativeGetLocalDeviceAddress(JNIEnv* env)
+{
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
+    if(!jni_cid_BTAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_cid_BTAdapter is null");
+        return NULL;
+    }
+
+    jmethodID jni_mid_getDefaultAdapter =
+            (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
+    if(!jni_mid_getDefaultAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_mid_getDefaultAdapter is null");
+        return NULL;
+    }
+
+    jmethodID jni_mid_getAddress = (*env)->GetMethodID(env, jni_cid_BTAdapter, "getAddress", METHODID_STRINGNONPARAM);
+    if(!jni_mid_getAddress)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_mid_getAddress is null");
+        return NULL;
+    }
+
+    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
+    if(!jni_obj_BTAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_obj_BTAdapter is null");
+        return NULL;
+    }
+
+    jstring jni_str_address = (jstring)(*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_getAddress);
+    if(!jni_str_address)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getAddress: jni_str_address is null");
+        return NULL;
+    }
+
+    return jni_str_address;
+}
+
+jobjectArray CANativeBondedDevices(JNIEnv *env)
+{
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
+    if(!jni_cid_BTAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_cid_BTAdapter is null");
+        return NULL;
+    }
+
+    jmethodID jni_mid_getDefaultAdapter =
+            (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
+
+    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
+    if(!jni_obj_BTAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: bluetooth adapter is null");
+        return NULL;
+    }
+
+    // Get a list of currently paired devices
+    jmethodID jni_mid_getBondedDevices = (*env)->GetMethodID(env, jni_cid_BTAdapter,
+            "getBondedDevices", "()Ljava/util/Set;");
+    if(!jni_mid_getBondedDevices)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_mid_getBondedDevicesr is null");
+        return NULL;
+    }
+
+    jobject jni_obj_setPairedDevices = (*env)->CallObjectMethod(env, jni_obj_BTAdapter, jni_mid_getBondedDevices);
+    if(!jni_obj_setPairedDevices)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_obj_setPairedDevices is null");
+        return NULL;
+    }
+
+    // Convert the set to an object array
+    // object[] array = Set<BluetoothDevice>.toArray();
+    jclass jni_cid_Set = (*env)->FindClass(env,  "java/util/Set");
+    jmethodID jni_mid_toArray = (*env)->GetMethodID(env, jni_cid_Set, "toArray", "()[Ljava/lang/Object;");
+
+    if(!jni_mid_toArray)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_mid_toArray is null");
+        return NULL;
+    }
+
+    jobjectArray jni_arrayPairedDevices = (jobjectArray)((*env)->CallObjectMethod(env,
+            jni_obj_setPairedDevices, jni_mid_toArray));
+    if(!jni_arrayPairedDevices)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBondedDevices: jni_arrayPairedDevices is null");
+        return NULL;
+    }
+
+    return jni_arrayPairedDevices;
+}
+
+jint CANativeGetBTStateOnInfo(JNIEnv *env)
+{
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
+    if(!jni_cid_BTAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getBTStateOnInfo: jni_cid_BTAdapter is null");
+        return -1;
+    }
+
+    jfieldID jni_fid_stateon = (*env)->GetStaticFieldID(env, jni_cid_BTAdapter, "STATE_ON", "I");
+    if (jni_fid_stateon == 0)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] get_field_state is 0");
+        return;
+    }
+    jint jni_int_val = (*env)->GetStaticIntField(env, jni_cid_BTAdapter, jni_fid_stateon);
+
+    OIC_LOG_V(DEBUG, TAG, "[BLE][Native] bluetooth STATE_ON state integer value : %d", jni_int_val);
+
+    return jni_int_val;
+}
+
+jboolean CANativeIsEnableBTAdapter(JNIEnv *env)
+{
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
+    if(!jni_cid_BTAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BTAdapter: jni_cid_BTAdapter is null");
+        return FALSE;
+    }
+
+    jmethodID jni_mid_getDefaultAdapter =
+            (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
+    if(!jni_mid_getDefaultAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getDefaultAdapter is null");
+        return FALSE;
+    }
+
+    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
+    if(!jni_obj_BTAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_BTAdapter is null");
+        return FALSE;
+    }
+
+    // isEnable()
+    jmethodID jni_mid_isEnable = (*env)->GetMethodID(env, jni_cid_BTAdapter, "isEnabled",
+            "()Z");
+    if(!jni_mid_isEnable)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_isEnable is null");
+        return FALSE;
+    }
+
+    jboolean jni_isEnable = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_isEnable);
+    OIC_LOG_V(DEBUG, TAG, "[BLE][Native] adapter state is %d", jni_isEnable);
+
+    return jni_isEnable;
+}
+
+jstring CANativeGetAddressFromBTDevice(JNIEnv *env, jobject bluetoothDevice)
+{
+    jclass jni_cid_device_list = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
+    if(!jni_cid_device_list)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_device_list is null");
+        return 0;
+    }
+
+    jmethodID jni_mid_getAddress = (*env)->GetMethodID(env, jni_cid_device_list, "getAddress",
+            "()Ljava/lang/String;");
+    if(!jni_mid_getAddress)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getAddress is null");
+        return 0;
+    }
+
+    jstring jni_address = (jstring)(*env)->CallObjectMethod(env, bluetoothDevice, jni_mid_getAddress);
+    if(!jni_address)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_address is null");
+        return 0;
+    }
+    return jni_address;
+}
+
+jstring CANativeGetAddressFromGattObj(JNIEnv *env, jobject gatt)
+{
+    if(!gatt)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] gatt is null");
+        return 0;
+    }
+
+    jclass jni_cid_gattdevice_list = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
+    if(!jni_cid_gattdevice_list)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_gattdevice_list is null");
+        return 0;
+    }
+
+    jmethodID jni_mid_getDevice = (*env)->GetMethodID(env, jni_cid_gattdevice_list, "getDevice",
+            "()Landroid/bluetooth/BluetoothDevice;");
+    if(!jni_mid_getDevice)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getDevice is null");
+        return 0;
+    }
+
+    jobject jni_obj_device = (*env)->CallObjectMethod(env, gatt, jni_mid_getDevice);
+    if(!jni_obj_device)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_device is null");
+        return 0;
+    }
+
+    jstring jni_address = CANativeGetAddressFromBTDevice(env, jni_obj_device);
+    if(!jni_address)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_address is null");
+        return 0;
+    }
+
+    return jni_address;
+}
+
+/**
+ * BLE layer
+ */
+void CANativeGattClose(JNIEnv *env, jobject bluetoothGatt)
+{
+    // GATT CLOSE
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT CLOSE");
+
+    // get BluetoothGatt class
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt class");
+    jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
+    if(!jni_cid_BluetoothGatt)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
+        return;
+    }
+
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get gatt disconnect method");
+    jmethodID jni_mid_closeGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "close","()V");
+    if(!jni_mid_closeGatt)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_closeGatt is null");
+        return;
+    }
+
+    // call disconnect gatt method
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] request close Gatt");
+    (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_closeGatt);
+}
+
+void CANativeLEStartScan()
+{
+    if(!gIsStartServer)
+    {
+        OIC_LOG_V(DEBUG, TAG, "server is not started yet..scan will be passed");
+        return;
+    }
+
+    jboolean isAttached = FALSE;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+    if(res != JNI_OK)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+        if(res != JNI_OK)
+        {
+            OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+            return;
+        }
+        isAttached = TRUE;
+    }
+
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeLEStartScan");
+    // create new object array
+    jclass jni_cid_uuid_list = (*env)->FindClass(env, CLASSPATH_BT_UUID);
+    if(!jni_cid_uuid_list)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_uuid_list is null");
+        return;
+    }
+
+    jobjectArray jni_obj_uuid_list = (jobjectArray)(*env)->NewObjectArray(env, 1, jni_cid_uuid_list, NULL);
+    if(!jni_obj_uuid_list)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_uuid_list is null");
+        return;
+    }
+
+    // remove previous list and create list again
+    CANativeRemoveAllDevices(env);
+    CANativeCreateScanDeviceList(env);
+
+    // make uuid list
+    jobject jni_obj_uuid = CANativeGetUUIDObject(env, "713d0000-503e-4c75-ba94-3148f18d941e");
+    (*env)->SetObjectArrayElement(env, jni_obj_uuid_list, 0, jni_obj_uuid);
+
+    // scan gatt server with UUID
+    if(gLeScanCallback && jni_obj_uuid_list)
+    {
+//        CANativeLEStartScanWithUUIDImpl(env, jni_obj_uuid_list, gLeScanCallback);
+        CANativeLEStartScanImpl(env, gLeScanCallback);
+    }
+
+    if(isAttached)
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+
+}
+
+void CANativeLEStartScanImpl(JNIEnv *env, jobject callback)
+{
+    if(!CANativeIsEnableBTAdapter(env))
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+        return;
+    }
+
+    // get default bt adapter class
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
+    if(!jni_cid_BTAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
+        return;
+    }
+
+    // get remote bt adapter method
+    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
+    if(!jni_mid_getDefaultAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_mid_getDefaultAdapter is null");
+        return;
+    }
+
+    // get start le scan method
+    jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
+            "(Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)Z");
+    if(!jni_mid_startLeScan)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan: jni_mid_startLeScan is null");
+        return;
+    }
+
+    // gat bt adapter object
+    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
+    if(!jni_obj_BTAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_obj_BTAdapter is null");
+        return;
+    }
+
+    // call start le scan method
+    jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_startLeScan, callback);
+    if(!jni_obj_startLeScan)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] bleConnect: jni_obj_startLeScan is null");
+        return;
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan..");
+    }
+}
+
+jobject CANativeGetUUIDObject(JNIEnv *env, const char* uuid)
+{
+    // setting UUID
+    jclass jni_cid_uuid = (*env)->FindClass(env, CLASSPATH_BT_UUID);
+    if(!jni_cid_uuid)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_uuid is null");
+        return NULL;
+    }
+
+    jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_uuid, "fromString", "(Ljava/lang/String;)Ljava/util/UUID;");
+    if(!jni_mid_fromString)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_fromString is null");
+        return NULL;
+    }
+
+    jstring jni_uuid = (*env)->NewStringUTF(env, uuid);
+    jobject jni_obj_uuid = (*env)->CallStaticObjectMethod(env, jni_cid_uuid, jni_mid_fromString, jni_uuid);
+    if(!jni_obj_uuid)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_uuid is null");
+        return NULL;
+    }
+
+    return jni_obj_uuid;
+}
+
+void CANativeLEStartScanWithUUIDImpl(JNIEnv *env, jobjectArray uuids, jobject callback)
+{
+    // get default bt adapter class
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get default bt adapter class");
+
+    if(!CANativeIsEnableBTAdapter(env))
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+        return;
+    }
+
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
+    if(!jni_cid_BTAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
+        return;
+    }
+
+    // get remote bt adapter method
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get remote bt adapter method");
+    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
+    if(!jni_mid_getDefaultAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_mid_getDefaultAdapter is null");
+        return;
+    }
+
+    // get start le scan method
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get start le scan method");
+    jmethodID jni_mid_startLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "startLeScan",
+            "([Ljava/util/UUID;Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)Z");
+    if(!jni_mid_startLeScan)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan: jni_mid_startLeScan is null");
+        return;
+    }
+
+    // get bt adapter object
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get bt adapter object");
+    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
+    if(!jni_obj_BTAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_obj_BTAdapter is null");
+        return;
+    }
+
+    // call start le scan method
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] call start le scan service method");
+    jboolean jni_obj_startLeScan = (*env)->CallBooleanMethod(env, jni_obj_BTAdapter, jni_mid_startLeScan, uuids, callback);
+    if(!jni_obj_startLeScan)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] bleConnect: jni_obj_startLeScan is null");
+        return;
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] startLeScan..");
+    }
+}
+
+void CANativeLEStopScan()
+{
+    jboolean isAttached = FALSE;
+    JNIEnv* env;
+    jint res = (*g_jvm)->GetEnv(g_jvm, (void**)&env, JNI_VERSION_1_6);
+    if(res != JNI_OK)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Could not get JNIEnv pointer");
+        res = (*g_jvm)->AttachCurrentThread(g_jvm, &env, NULL);
+        if(res != JNI_OK)
+        {
+            OIC_LOG_V(DEBUG, TAG, "AttachCurrentThread failed");
+            return;
+        }
+        isAttached = TRUE;
+    }
+
+    CANativeLEStopScanImpl(env, gLeScanCallback);
+
+    if(isAttached)
+        (*g_jvm)->DetachCurrentThread(g_jvm);
+
+}
+
+void CANativeLEStopScanImpl(JNIEnv *env, jobject callback)
+{
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeLEStopScan");
+
+    if(!CANativeIsEnableBTAdapter(env))
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+        return;
+    }
+
+    // get default bt adapter class
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env,  CLASSPATH_BT_ADPATER);
+    if(!jni_cid_BTAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_cid_BTAdapter is null");
+        return;
+    }
+
+    // get remote bt adapter method
+    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter, "getDefaultAdapter", METHODID_OBJECTNONPARAM);
+    if(!jni_mid_getDefaultAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_mid_getDefaultAdapter is null");
+        return;
+    }
+
+    // get start le scan method
+    jmethodID jni_mid_stopLeScan = (*env)->GetMethodID(env, jni_cid_BTAdapter, "stopLeScan",
+            "(Landroid/bluetooth/BluetoothAdapter$LeScanCallback;)V");
+    if(!jni_mid_stopLeScan)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] stopLeScan: jni_mid_stopLeScan is null");
+        return;
+    }
+
+    // gat bt adapter object
+    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter, jni_mid_getDefaultAdapter);
+    if(!jni_obj_BTAdapter)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] getState From BTAdapter: jni_obj_BTAdapter is null");
+        return;
+    }
+
+    // call start le scan method
+    (*env)->CallVoidMethod(env, jni_obj_BTAdapter, jni_mid_stopLeScan, callback);
+}
+
+void CANativeLEConnect(JNIEnv *env, jobject bluetoothDevice, jobject context, jboolean autoconnect, jobject callback)
+{
+    if(!CANativeIsEnableBTAdapter(env))
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+        return;
+    }
+
+    jstring jni_address = CANativeGetAddressFromBTDevice(env, bluetoothDevice);
+    const char * addr = (*env)->GetStringUTFChars(env, jni_address, NULL);
+    OIC_LOG_V(DEBUG, TAG, "[BLE][Native] request connectGatt to %s", addr);
+
+    // GATT CONNECT
+
+    // get BluetoothDevice class
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothDevice class");
+    jclass jni_cid_BluetoothDevice = (*env)->FindClass(env, "android/bluetooth/BluetoothDevice");
+    if(!jni_cid_BluetoothDevice)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] bleConnect: jni_cid_BluetoothDevice is null");
+        return;
+    }
+
+    // get connectGatt method
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get connectGatt method");
+    jmethodID jni_mid_connectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothDevice, "connectGatt",
+            "(Landroid/content/Context;ZLandroid/bluetooth/BluetoothGattCallback;)Landroid/bluetooth/BluetoothGatt;");
+    if(!jni_mid_connectGatt)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] bleConnect: jni_mid_connectGatt is null");
+        return;
+    }
+
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] Call object method - connectGatt");
+    jobject jni_obj_connectGatt = (*env)->CallObjectMethod(env, bluetoothDevice, jni_mid_connectGatt, context, autoconnect, callback);
+    if(!jni_obj_connectGatt)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] bleConnect: connectGatt was failed..obj will be removed");
+        CANativeRemoveDevice(env, jni_address);
+        return;
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] bleConnect: connecting..");
+    }
+}
+
+void CANativeLEDisconnect(JNIEnv *env, jobject bluetoothGatt)
+{
+    if(!CANativeIsEnableBTAdapter(env))
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+        return;
+    }
+
+    // GATT DISCONNECT
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT DISCONNECT");
+
+    // get BluetoothGatt class
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt classjobject bluetoothGatt");
+    jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
+    if(!jni_cid_BluetoothGatt)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
+        return;
+    }
+
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get gatt disconnect method");
+    jmethodID jni_mid_disconnectGatt = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "disconnect","()V");
+    if(!jni_mid_disconnectGatt)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_disconnectGatt is null");
+        return;
+    }
+
+    // call disconnect gatt method
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] request disconnectGatt");
+    (*env)->CallVoidMethod(env, bluetoothGatt, jni_mid_disconnectGatt);
+
+}
+
+void CANativeLEDiscoverServices(JNIEnv *env, jobject bluetoothGatt)
+{
+    if(!CANativeIsEnableBTAdapter(env))
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+        return;
+    }
+
+    // GATT SERVICE DISCOVERY
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] GATT SERVICE DISCOVERY");
+
+    // get BluetoothGatt class
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt class");
+    jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
+    if(!jni_cid_BluetoothGatt)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
+        return;
+    }
+
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] discovery gatt services method");
+    jmethodID jni_mid_discoverServices = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "discoverServices","()Z");
+    if(!jni_mid_discoverServices)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_discoverServices is null");
+        return;
+    }
+    // call disconnect gatt method
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] request discovery gatt services");
+    (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_discoverServices);
+}
+
+void CANativeLESendData(JNIEnv *env, jobject bluetoothGatt, jobject gattCharacteristic)
+{
+    if(!CANativeIsEnableBTAdapter(env))
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+        return;
+    }
+
+    // WRITE GATT CHARACTERISTIC
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] WRITE GATT CHARACTERISTIC");
+
+    // get BluetoothGatt class
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get BluetoothGatt class");
+    jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
+    if(!jni_cid_BluetoothGatt)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
+        return;
+    }
+
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] write characteristic method");
+    jmethodID jni_mid_writeCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "writeCharacteristic", "(Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
+    if(!jni_mid_writeCharacteristic)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_writeCharacteristic is null");
+        return;
+    }
+
+    // call disconnect gatt method
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] request write gatt characteristic");
+    (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_writeCharacteristic, gattCharacteristic);
+
+}
+
+jboolean CANativeSetCharacteristicNoti(JNIEnv *env, jobject bluetoothGatt)
+{
+    if(!CANativeIsEnableBTAdapter(env))
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+        return;
+    }
+
+    // get BluetoothGatt class
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeSetCharacteristicNoti");
+    jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
+    if(!jni_cid_BluetoothGatt)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
+        return FALSE;
+    }
+
+    jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, "713d0002-503e-4c75-ba94-3148f18d941e");
+    if(!jni_obj_GattCharacteristic)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
+        return FALSE;
+    }
+
+    // set Characteristic Notification
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get gatt disconnect method");
+    jmethodID jni_mid_setNotification = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "setCharacteristicNotification",
+            "(Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
+    if(!jni_mid_setNotification)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getService is null");
+        return FALSE;
+    }
+
+    jboolean enable = TRUE;
+    jboolean ret = (*env)->CallBooleanMethod(env, bluetoothGatt, jni_mid_setNotification, jni_obj_GattCharacteristic, enable);
+    if(1 == ret)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] setCharacteristicNotification is success");
+        return TRUE;
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] setCharacteristicNotification is failed");
+        return FALSE;
+    }
+}
+
+jobject CANativeGetGattService(JNIEnv *env, jobject bluetoothGatt, jstring characterUUID)
+{
+    if(!CANativeIsEnableBTAdapter(env))
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+        return;
+    }
+
+    // get BluetoothGatt class
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeGetGattService");
+    jclass jni_cid_BluetoothGatt = (*env)->FindClass(env, "android/bluetooth/BluetoothGatt");
+    if(!jni_cid_BluetoothGatt)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGatt is null");
+        return NULL;
+    }
+
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get gatt disconnect method");
+    jmethodID jni_mid_getService = (*env)->GetMethodID(env, jni_cid_BluetoothGatt, "getService",
+            "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
+    if(!jni_mid_getService)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getService is null");
+        return NULL;
+    }
+
+    jobject jni_obj_service_uuid = CANativeGetUUIDObject(env, "713d0000-503e-4c75-ba94-3148f18d941e");
+    if(!jni_obj_service_uuid)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_service_uuid is null");
+        return NULL;
+    }
+
+    // get bluetooth gatt service
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] request to get service");
+    jobject jni_obj_gattService = (*env)->CallObjectMethod(env, bluetoothGatt, jni_mid_getService, jni_obj_service_uuid);
+
+    // get bluetooth gatt service class
+    jclass jni_cid_BluetoothGattService = (*env)->FindClass(env, "android/bluetooth/BluetoothGattService");
+    if(!jni_cid_BluetoothGattService)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BluetoothGattService is null");
+        return NULL;
+    }
+
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get gatt getCharacteristic method");
+    jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_BluetoothGattService, "getCharacteristic",
+            "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattCharacteristic;");
+    if(!jni_mid_getCharacteristic)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getCharacteristic is null");
+        return NULL;
+    }
+
+    const char* uuid = (*env)->GetStringUTFChars(env, characterUUID, NULL);
+    jobject jni_obj_tx_uuid = CANativeGetUUIDObject(env, uuid);
+    if(!jni_obj_tx_uuid)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_tx_uuid is null");
+        return NULL;
+    }
+
+    // get
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] request to get Characteristic");
+    jobject jni_obj_GattCharacteristic = (*env)->CallObjectMethod(env, jni_obj_gattService, jni_mid_getCharacteristic, jni_obj_tx_uuid);
+
+    return jni_obj_GattCharacteristic;
+}
+
+jobject CANativeCreateGattCharacteristic(JNIEnv *env, jobject bluetoothGatt, jstring data)
+{
+    if(!CANativeIsEnableBTAdapter(env))
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+        return;
+    }
+
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateGattCharacteristic");
+    jobject jni_obj_GattCharacteristic = CANativeGetGattService(env, bluetoothGatt, "713d0003-503e-4c75-ba94-3148f18d941e");
+    if(!jni_obj_GattCharacteristic)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_obj_GattCharacteristic is null");
+        return NULL;
+    }
+
+    jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/BluetoothGattCharacteristic");
+    if(!jni_cid_BTGattCharacteristic)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BTGattCharacteristic is null");
+        return NULL;
+    }
+
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] set value in Characteristic");
+    jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "setValue",
+            "(Ljava/lang/String;)Z");
+    if(!jni_mid_setValue)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_setValue is null");
+        return NULL;
+    }
+
+    jboolean ret = (*env)->CallBooleanMethod(env, jni_obj_GattCharacteristic, jni_mid_setValue, data);
+    if(1 == ret)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] the locally stored value has been set");
+        return jni_obj_GattCharacteristic;
+    }
+    else
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] the locally stored value hasn't been set");
+        return NULL;
+    }
+}
+
+jbyteArray CANativeGetValueFromCharacteristic(JNIEnv *env, jobject characteristic)
+{
+    if(!CANativeIsEnableBTAdapter(env))
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] BT adpater is not enable");
+        return;
+    }
+
+    jclass jni_cid_BTGattCharacteristic = (*env)->FindClass(env, "android/bluetooth/BluetoothGattCharacteristic");
+    if(!jni_cid_BTGattCharacteristic)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_cid_BTGattCharacteristic is null");
+        return NULL;
+    }
+
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] get value in Characteristic");
+    jmethodID jni_mid_getValue = (*env)->GetMethodID(env, jni_cid_BTGattCharacteristic, "getValue",
+            "()[B");
+    if(!jni_mid_getValue)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_mid_getValue is null");
+        return NULL;
+    }
+
+    jbyteArray jni_obj_data_array =  (*env)->CallObjectMethod(env, characteristic, jni_mid_getValue);
+    return jni_obj_data_array;
+}
+
+void CANativeCreateScanDeviceList(JNIEnv *env)
+{
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateScanDeviceList");
+
+    // create new object array
+    if (gdeviceList == NULL)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Create device list");
+
+        gdeviceList = u_arraylist_create();
+    }
+}
+
+void CANativeAddScanDeviceToList(JNIEnv *env, jobject device)
+{
+    if(!device)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] device is null");
+        return;
+    }
+
+    if(!gdeviceList)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] gdevice_list is null");
+        return;
+    }
+
+    jstring jni_remoteAddress = CANativeGetAddressFromBTDevice(env, device);
+    if(!jni_remoteAddress)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
+        return;
+    }
+
+    const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
+
+    if(!CANativeIsDeviceInList(env, remoteAddress)) {
+        jobject gdevice = (*env)->NewGlobalRef(env, device);
+        u_arraylist_add(gdeviceList, gdevice);
+        OIC_LOG_V(DEBUG, TAG, "Set Object to Array as Element");
+    }
+}
+
+jboolean CANativeIsDeviceInList(JNIEnv *env, const char* remoteAddress){
+    // get address value from device list
+
+    jint index;
+    for (index = 0; index < u_arraylist_length(gdeviceList); index++)
+    {
+        jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
+        if(!jarrayObj)
+        {
+            OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
+            return TRUE;
+        }
+
+        jstring jni_setAddress = CANativeGetAddressFromBTDevice(env, jarrayObj);
+        if(!jni_setAddress)
+        {
+            OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
+            return TRUE;
+        }
+
+        const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+
+        if(!strcmp(remoteAddress, setAddress))
+        {
+            OIC_LOG_V(DEBUG, TAG, "the device is already set");
+            return TRUE;
+        }
+        else
+        {
+            continue;
+        }
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "there are no the device in list. we can add");
+    return FALSE;
+}
+
+void CANativeRemoveAllDevices(JNIEnv *env)
+{
+    OIC_LOG_V(DEBUG, TAG, "CANativeRemoveAllDevices");
+
+    if(!gdeviceList)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceList is null");
+        return;
+    }
+
+    jint index;
+    for (index = 0; index < u_arraylist_length(gdeviceList); index++)
+    {
+        jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
+        if(!jarrayObj)
+        {
+            OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
+            return;
+        }
+        (*env)->DeleteGlobalRef(env, jarrayObj);
+    }
+
+    OICFree(gdeviceList);
+    gdeviceList = NULL;
+    return;
+}
+
+void CANativeRemoveDevice(JNIEnv *env, jstring address)
+{
+    OIC_LOG_V(DEBUG, TAG, "CANativeRemoveDevice");
+
+    if(!gdeviceList)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] gdeviceList is null");
+        return;
+    }
+
+    jint index;
+    for (index = 0; index < u_arraylist_length(gdeviceList); index++)
+    {
+        jobject jarrayObj = (jobject) u_arraylist_get(gdeviceList, index);
+        if(!jarrayObj)
+        {
+            OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
+            return;
+        }
+
+        jstring jni_setAddress = CANativeGetAddressFromBTDevice(env, jarrayObj);
+        if(!jni_setAddress)
+        {
+            OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
+            return;
+        }
+        const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+        const char* remoteAddress = (*env)->GetStringUTFChars(env, address, NULL);
+
+        if(!strcmp(setAddress, remoteAddress))
+        {
+            OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress);
+            (*env)->DeleteGlobalRef(env, jarrayObj);
+
+            CAReorderingDeviceList(index);
+            return;
+        }
+    }
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object");
+    return;
+}
+
+void CAReorderingDeviceList(uint32_t index)
+{
+    if (index >= gdeviceList->length)
+    {
+        return;
+    }
+
+    if (index < gdeviceList->length - 1)
+    {
+        memmove(&gdeviceList->data[index], &gdeviceList->data[index + 1],
+                (gdeviceList->length - index - 1) * sizeof(void *));
+    }
+
+    gdeviceList->size--;
+    gdeviceList->length--;
+}
+
+/**
+ * Gatt Object List
+ */
+void CANativeCreateGattObjList(JNIEnv *env)
+{
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeCreateGattObjList");
+
+    // create new object array
+    if (gGattObjectList == NULL)
+    {
+        OIC_LOG_V(DEBUG, TAG, "Create Gatt object list");
+
+        gGattObjectList = u_arraylist_create();
+    }
+}
+
+void CANativeAddGattobjToList(JNIEnv *env, jobject gatt)
+{
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeAddGattobjToList");
+
+    if(!gatt)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] gatt is null");
+        return;
+    }
+
+    if(!gGattObjectList)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
+        return;
+    }
+
+    jstring jni_remoteAddress = CANativeGetAddressFromGattObj(env, gatt);
+    if(!jni_remoteAddress)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
+        return;
+    }
+
+    const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
+
+    if(!CANativeIsGattObjInList(env, remoteAddress))
+    {
+        jobject gGatt = (*env)->NewGlobalRef(env, gatt);
+        u_arraylist_add(gGattObjectList, gGatt);
+        OIC_LOG_V(DEBUG, TAG, "Set Object to Array as Element");
+    }
+}
+
+jboolean CANativeIsGattObjInList(JNIEnv *env, const char* remoteAddress)
+{
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] CANativeIsGattObjInList");
+
+    jint index;
+    for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
+    {
+
+        jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
+        if(!jarrayObj)
+        {
+            OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
+            return TRUE;
+        }
+
+        jstring jni_setAddress = CANativeGetAddressFromGattObj(env, jarrayObj);
+        if(!jni_setAddress)
+        {
+            OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
+            return TRUE;
+        }
+
+        const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+
+        if(!strcmp(remoteAddress, setAddress))
+        {
+            OIC_LOG_V(DEBUG, TAG, "the device is already set");
+            return TRUE;
+        }
+        else
+        {
+            continue;
+        }
+    }
+
+    OIC_LOG_V(DEBUG, TAG, "there are no the gatt obejct in list. we can add");
+    return FALSE;
+}
+
+void CANativeRemoveAllGattObjsList(JNIEnv *env)
+{
+    OIC_LOG_V(DEBUG, TAG, "CANativeRemoveAllGattObjsList");
+
+    if(!gGattObjectList)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
+        return;
+    }
+
+    jint index;
+    for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
+    {
+        jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
+        if(!jarrayObj)
+        {
+            OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
+            return;
+        }
+        (*env)->DeleteGlobalRef(env, jarrayObj);
+    }
+
+    OICFree(gGattObjectList);
+    gGattObjectList = NULL;
+    return;
+}
+
+void CANativeLEDisconnectAll(JNIEnv *env)
+{
+    OIC_LOG_V(DEBUG, TAG, "CANativeLEDisconnectAll");
+
+    if(!gGattObjectList)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
+        return;
+    }
+
+    jint index;
+    for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
+    {
+        jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
+        if(!jarrayObj)
+        {
+            OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
+            return;
+        }
+        CANativeLEDisconnect(env, jarrayObj);
+    }
+
+    OICFree(gGattObjectList);
+    gGattObjectList = NULL;
+    return;
+}
+
+void CANativeRemoveGattObj(JNIEnv *env, jobject gatt)
+{
+    OIC_LOG_V(DEBUG, TAG, "CANativeRemoveGattObj");
+
+    if(!gGattObjectList)
+    {
+        OIC_LOG(DEBUG, TAG, "[BLE][Native] gGattObjectList is null");
+        return;
+    }
+
+    jint index;
+    for (index = 0; index < u_arraylist_length(gGattObjectList); index++)
+    {
+        jobject jarrayObj = (jobject) u_arraylist_get(gGattObjectList, index);
+        if(!jarrayObj)
+        {
+            OIC_LOG(DEBUG, TAG, "[BLE][Native] jarrayObj is null");
+            return;
+        }
+
+        jstring jni_setAddress = CANativeGetAddressFromGattObj(env, jarrayObj);
+        if(!jni_setAddress)
+        {
+            OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_setAddress is null");
+            return;
+        }
+        const char* setAddress = (*env)->GetStringUTFChars(env, jni_setAddress, NULL);
+
+        jstring jni_remoteAddress = CANativeGetAddressFromGattObj(env, gatt);
+        if(!jni_remoteAddress)
+        {
+            OIC_LOG(DEBUG, TAG, "[BLE][Native] jni_remoteAddress is null");
+            return;
+        }
+        const char* remoteAddress = (*env)->GetStringUTFChars(env, jni_remoteAddress, NULL);
+
+        if(!strcmp(setAddress, remoteAddress))
+        {
+            OIC_LOG_V(DEBUG, TAG, "[BLE][Native] remove object : %s", remoteAddress);
+            (*env)->DeleteGlobalRef(env, jarrayObj);
+
+            CAReorderingGattList(index);
+            return;
+        }
+    }
+    OIC_LOG(DEBUG, TAG, "[BLE][Native] there are no target object");
+    return;
+}
+
+void CAReorderingGattList(uint32_t index)
+{
+    if (index >= gGattObjectList->length)
+    {
+        return;
+    }
+
+    if (index < gGattObjectList->length - 1)
+    {
+        memmove(&gGattObjectList->data[index], &gGattObjectList->data[index + 1],
+                (gGattObjectList->length - index - 1) * sizeof(void *));
+    }
+
+    gGattObjectList->size--;
+    gGattObjectList->length--;
+}
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.c b/resource/csdk/connectivity/src/bt_le_adapter/android/caleserver.c
new file mode 100644 (file)
index 0000000..a74f237
--- /dev/null
@@ -0,0 +1,466 @@
+#include <jni.h>
+#include <stdio.h>
+#include <android/log.h>
+#include "com_iotivity_jar_CALeInterface.h"
+
+#define  LOG_TAG   "jni_BLE_Server"
+#define  LOGI(...) __android_log_print(ANDROID_LOG_INFO, LOG_TAG, __VA_ARGS__)
+#define  LOGE(...) __android_log_print(ANDROID_LOG_ERROR, LOG_TAG, __VA_ARGS__)
+
+static const char *OIC_GATT_SERVICE_UUID = "713d0000-503e-4c75-ba94-3148f18d941e";
+static const char *OIC_GATT_CHARACTERISTIC_RESPONSE_UUID = "713d0002-503e-4c75-ba94-3148f18d941e";
+static const char *OIC_GATT_CHARACTERISTIC_REQUEST_UUID = "713d0003-503e-4c75-ba94-3148f18d941e";
+
+static jobject gContext;
+static jobject gBluetoothGattServer;
+static jobject gBluetoothGattServerCallback;
+static jobject gAdvertiseCallback;
+
+jobject getUuidFromString(JNIEnv *env, const char* uuid)
+{
+
+    LOGI("[BLE Server] getUuidFromString");
+
+    jclass jni_cid_UUID = (*env)->FindClass(env, "java/util/UUID");
+    if (!jni_cid_UUID)
+    {
+        LOGI("[BLE Server] jni_cid_UUID is null");
+        return NULL;
+    }
+
+    jmethodID jni_mid_fromString = (*env)->GetStaticMethodID(env, jni_cid_UUID, "fromString",
+            "(Ljava/lang/String;)Ljava/util/UUID;");
+    if (!jni_mid_fromString)
+    {
+        LOGI("[BLE Server] jni_mid_fromString is null");
+        return NULL;
+    }
+
+    jstring str_serviceUUID = (*env)->NewStringUTF(env, uuid);
+    LOGI("[BLE Server] uuid: %s", uuid);
+    jobject jni_obj_serviceUUID = (*env)->CallStaticObjectMethod(env, jni_cid_UUID,
+            jni_mid_fromString, str_serviceUUID);
+    if (!jni_obj_serviceUUID)
+    {
+        LOGI("[BLE][Server] jni_obj_serviceUUID is null");
+        return NULL;
+    }
+
+    return jni_obj_serviceUUID;
+}
+
+jobject getParcelUuid(JNIEnv *env, jobject uuid)
+{
+
+    jclass jni_cid_ParcelUuid = (*env)->FindClass(env, "android/os/ParcelUuid");
+    if (!jni_cid_ParcelUuid)
+    {
+        LOGI("[BLE Server] jni_cid_ParcelUuid is null");
+        return;
+    }
+
+    jmethodID jni_mid_ParcelUuid = (*env)->GetMethodID(env, jni_cid_ParcelUuid, "<init>",
+            "(Ljava/util/UUID;)V");
+    if (!jni_mid_ParcelUuid)
+    {
+        LOGI("[BLE Server] jni_mid_ParcelUuid is null");
+        return;
+    }
+
+    jobject jni_ParcelUuid = (*env)->NewObject(env, jni_cid_ParcelUuid, jni_mid_ParcelUuid, uuid);
+    if (!jni_ParcelUuid)
+    {
+        LOGI("[BLE Server] jni_ParcelUuid is null");
+        return;
+    }
+
+    return jni_ParcelUuid;
+}
+
+jobject setData(JNIEnv *env, char* responseData)
+{
+
+    LOGI("[BLE Server] set response");
+
+    jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
+            "android/bluetooth/BluetoothGattServer");
+    jclass jni_cid_bluetoothGattService = (*env)->FindClass(env,
+            "android/bluetooth/BluetoothGattService");
+    jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env,
+            "android/bluetooth/BluetoothGattCharacteristic");
+    LOGI("[BLE Server] get classes");
+
+    jmethodID jni_mid_getService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
+            "getService", "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattService;");
+    LOGI("[BLE Server] get methodID");
+
+    jobject jni_obj_serviceUUID = getUuidFromString(env, OIC_GATT_SERVICE_UUID);
+    LOGI("[BLE Server] get serviceUUID");
+
+    if (!gBluetoothGattServer)
+    {
+        LOGI("[BLE Server] gBluetoothGattServer is null");
+        return NULL;
+    }
+
+    jobject jni_obj_bluetoothGattService = (*env)->CallObjectMethod(env, gBluetoothGattServer,
+            jni_mid_getService, jni_obj_serviceUUID);
+    LOGI("[BLE Server] jni_obj_bluetoothGattService");
+
+    jmethodID jni_mid_getCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
+            "getCharacteristic",
+            "(Ljava/util/UUID;)Landroid/bluetooth/BluetoothGattCharacteristic;");
+
+    jobject jni_obj_responseUUID = getUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
+    jobject jni_obj_bluetoothGattCharacteristic = (*env)->CallObjectMethod(env,
+            jni_obj_bluetoothGattService, jni_mid_getCharacteristic, jni_obj_responseUUID);
+    LOGI("[BLE Server] jni_obj_bluetoothGattCharacteristic");
+
+    jmethodID jni_mid_setValue = (*env)->GetMethodID(env, jni_cid_bluetoothGattCharacteristic,
+            "setValue", "(Ljava/land/String;)Z");
+    jstring str_responseData = (*env)->NewStringUTF(env, responseData);
+    jboolean jni_boolean_setValue = (*env)->CallBooleanMethod(env,
+            jni_obj_bluetoothGattCharacteristic, jni_mid_setValue, str_responseData);
+
+    return jni_obj_bluetoothGattCharacteristic;
+}
+
+jboolean sendData(JNIEnv *env, jobject device, jobject responseData)
+{
+
+    if (!device)
+    {
+        LOGI("[BLE Server] device is null");
+        return JNI_FALSE;
+    }
+
+    if (!responseData)
+    {
+        LOGI("[BLE Server] responseData is null");
+        return JNI_FALSE;
+    }
+
+    jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
+            "android/bluetooth/BluetoothGattServer");
+
+    jmethodID jni_mid_notifyCharacteristicChanged =
+            (*env)->GetMethodID(env, jni_cid_bluetoothGattServer, "notifyCharacteristicChanged",
+                    "(Landroid/bluetooth/BluetoothDevice;Landroid/bluetooth/BluetoothGattCharacteristic;Z)Z");
+    jboolean jni_boolean_notifyCharacteristicChanged = (*env)->CallBooleanMethod(env,
+            gBluetoothGattServer, jni_mid_notifyCharacteristicChanged, device, responseData,
+            JNI_TRUE);
+
+    if (!jni_boolean_notifyCharacteristicChanged)
+        return JNI_FALSE;
+
+    return JNI_TRUE;
+}
+
+jboolean sendResponse(JNIEnv *env, jobject device, jint requestId, jint status, jint offset)
+{
+
+    jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
+            "android/bluetooth/BluetoothGattServer");
+    jmethodID jni_mid_sendResponse = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
+            "sendResponse", "(Landroid/bluetooth/BluetoothDevice;III)Z");
+    (*env)->CallVoidMethod(env, gBluetoothGattServer, jni_mid_sendResponse, device, requestId,
+            status, offset);
+    LOGI("[BLE Server] sendResponse");
+
+}
+
+void startAdvertize(JNIEnv *env, jobject advertiseCallback)
+{
+
+    jclass jni_cid_AdvertiseSettings = (*env)->FindClass(env,
+            "android/bluetooth/le/AdvertiseSettings$Builder");
+
+    jmethodID jni_mid_AdvertiseSettings = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
+            "<init>", "()V");
+
+    jobject jni_AdvertiseSettings = (*env)->NewObject(env, jni_cid_AdvertiseSettings,
+            jni_mid_AdvertiseSettings);
+    if (!jni_AdvertiseSettings)
+    {
+        LOGI("[BLE Server] jni_AdvertiseSettings is null");
+        return;
+    }
+
+    jmethodID jni_mid_setConnectable = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings,
+            "setConnectable", "(Z)Landroid/bluetooth/le/AdvertiseSettings$Builder;");
+
+    jobject jni_obj_setConnectable = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
+            jni_mid_setConnectable, JNI_TRUE);
+    if (!jni_obj_setConnectable)
+    {
+        LOGI("[BLE][Server] jni_obj_setConnectable is null");
+        return;
+    }
+
+    jmethodID jni_mid_setTimeout = (*env)->GetMethodID(env, jni_cid_AdvertiseSettings, "setTimeout",
+            "(I)Landroid/bluetooth/le/AdvertiseSettings$Builder;");
+
+    jobject jni_obj_setTimeout = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
+            jni_mid_setTimeout, 10000);
+    if (!jni_obj_setTimeout)
+    {
+        LOGI("[BLE][Server] jni_obj_setTimeout is null");
+        return;
+    }
+
+    jclass jni_cid_AdvertiseDataBuilder = (*env)->FindClass(env,
+            "android/bluetooth/le/AdvertiseData$Builder");
+
+    jmethodID jni_mid_AdvertiseDataBuilder = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
+            "<init>", "()V");
+
+    jobject jni_AdvertiseDataBuilder = (*env)->NewObject(env, jni_cid_AdvertiseDataBuilder,
+            jni_mid_AdvertiseDataBuilder);
+    if (!jni_AdvertiseDataBuilder)
+    {
+        LOGI("[BLE Server] jni_AdvertiseDataBuilder is null");
+        return;
+    }
+
+    jobject jni_obj_serviceUUID = getUuidFromString(env, OIC_GATT_SERVICE_UUID);
+    jobject jni_ParcelUuid = getParcelUuid(env, jni_obj_serviceUUID);
+    jmethodID jni_mid_addServiceUuid = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
+            "addServiceUuid",
+            "(Landroid/os/ParcelUuid;)Landroid/bluetooth/le/AdvertiseData$Builder;");
+
+    jobject jni_obj_addServiceUuid = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
+            jni_mid_addServiceUuid, jni_ParcelUuid);
+    if (!jni_obj_addServiceUuid)
+    {
+        LOGI("[BLE Server] jni_obj_addServiceUuid is null");
+        return;
+    }
+
+    jclass jni_cid_BTAdapter = (*env)->FindClass(env, "android/bluetooth/BluetoothAdapter");
+    jmethodID jni_mid_getDefaultAdapter = (*env)->GetStaticMethodID(env, jni_cid_BTAdapter,
+            "getDefaultAdapter", "()Landroid/bluetooth/BluetoothAdapter;");
+
+    jobject jni_obj_BTAdapter = (*env)->CallStaticObjectMethod(env, jni_cid_BTAdapter,
+            jni_mid_getDefaultAdapter);
+    if (!jni_obj_BTAdapter)
+    {
+        LOGI("[BLE Server] jni_obj_BTAdapter is null");
+        return;
+    }
+
+    jmethodID jni_mid_getBluetoothLeAdvertiser = (*env)->GetMethodID(env, jni_cid_BTAdapter,
+            "getBluetoothLeAdvertiser", "()Landroid/bluetooth/le/BluetoothLeAdvertiser;");
+
+    jobject jni_obj_getBluetoothLeAdvertiser = (*env)->CallObjectMethod(env, jni_obj_BTAdapter,
+            jni_mid_getBluetoothLeAdvertiser);
+    if (!jni_obj_getBluetoothLeAdvertiser)
+    {
+        LOGI("[BLE Server] jni_obj_getBluetoothLeAdvertiser is null");
+        return;
+    }
+
+    jmethodID jni_mid_build_LeAdvertiseSettings = (*env)->GetMethodID(env,
+            jni_cid_AdvertiseSettings, "build", "()Landroid/bluetooth/le/AdvertiseSettings;");
+
+    jobject jni_obj_build_LeAdvertiseSettings = (*env)->CallObjectMethod(env, jni_AdvertiseSettings,
+            jni_mid_build_LeAdvertiseSettings);
+    if (!jni_obj_build_LeAdvertiseSettings)
+    {
+        LOGI("[BLE Server] jni_obj_build_LeAdvertiseSettings is null");
+        return;
+    }
+
+    jmethodID jni_mid_build_LeAdvertiseData = (*env)->GetMethodID(env, jni_cid_AdvertiseDataBuilder,
+            "build", "()Landroid/bluetooth/le/AdvertiseData;");
+
+    jobject jni_obj_build_LeAdvertiseData = (*env)->CallObjectMethod(env, jni_AdvertiseDataBuilder,
+            jni_mid_build_LeAdvertiseData);
+    if (!jni_obj_build_LeAdvertiseData)
+    {
+        LOGI("[BLE Server] jni_obj_build_LeAdvertiseData is null");
+        return;
+    }
+
+    jclass jni_cid_leAdvertiser = (*env)->FindClass(env,
+            "android/bluetooth/le/BluetoothLeAdvertiser");
+
+    jmethodID jni_mid_startAdvertising =
+            (*env)->GetMethodID(env, jni_cid_leAdvertiser, "startAdvertising",
+                    "(Landroid/bluetooth/le/AdvertiseSettings;Landroid/bluetooth/le/AdvertiseData;Landroid/bluetooth/le/AdvertiseCallback;)V");
+
+    (*env)->CallVoidMethod(env, jni_obj_getBluetoothLeAdvertiser, jni_mid_startAdvertising,
+            jni_obj_build_LeAdvertiseSettings, jni_obj_build_LeAdvertiseData, advertiseCallback);
+
+    LOGI("[BLE Server] jni start Advertising");
+}
+
+jobject openGattServer(JNIEnv *env)
+{
+
+    jclass jni_cid_context = (*env)->FindClass(env, "android/content/Context");
+    jfieldID jni_fid_bluetoothService = (*env)->GetStaticFieldID(env, jni_cid_context,
+            "BLUETOOTH_SERVICE", "Ljava/lang/String;");
+    jobject jni_obj_bluetoothService = (*env)->GetStaticObjectField(env, jni_cid_context,
+            jni_fid_bluetoothService);
+
+    jmethodID jni_mid_getSystemService = (*env)->GetMethodID(env, jni_cid_context,
+            "getSystemService", "(Ljava/lang/String;)Ljava/lang/Object;");
+    jobject jni_obj_bluetoothManager = (*env)->CallObjectMethod(env, gContext,
+            jni_mid_getSystemService, jni_obj_bluetoothService);
+
+    jclass jni_cid_bluetoothManager = (*env)->FindClass(env, "android/bluetooth/BluetoothManager");
+    jmethodID jni_mid_openGattServer =
+            (*env)->GetMethodID(env, jni_cid_bluetoothManager, "openGattServer",
+                    "(Landroid/content/Context;Landroid/bluetooth/BluetoothGattServerCallback;)Landroid/bluetooth/BluetoothGattServer;");
+    jobject jni_obj_bluetoothGattServer = (*env)->CallObjectMethod(env, jni_obj_bluetoothManager,
+            jni_mid_openGattServer, gContext, gBluetoothGattServerCallback);
+
+    return jni_obj_bluetoothGattServer;
+}
+
+jobject createGattService(JNIEnv *env)
+{
+
+    jclass jni_cid_bluetoothGattService = (*env)->FindClass(env,
+            "android/bluetooth/BluetoothGattService");
+    jmethodID jni_mid_bluetoothGattService = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
+            "<init>", "(Ljava/util/UUID;I)V");
+
+    // service uuid object
+    jobject jni_obj_serviceUUID = getUuidFromString(env, OIC_GATT_SERVICE_UUID);
+
+    // service type object
+    jfieldID jni_fid_serviceType = (*env)->GetStaticFieldID(env, jni_cid_bluetoothGattService,
+            "SERVICE_TYPE_PRIMARY", "I");
+    jobject jni_obj_serviceType = (*env)->GetStaticObjectField(env, jni_cid_bluetoothGattService,
+            jni_fid_serviceType);
+
+    jobject jni_bluetoothGattService = (*env)->NewObject(env, jni_cid_bluetoothGattService,
+            jni_mid_bluetoothGattService, jni_obj_serviceUUID, jni_obj_serviceType);
+    if (!jni_bluetoothGattService)
+    {
+        LOGI("[BLE Server] fail to create gatt service instance!");
+        return NULL;
+    }
+
+    jclass jni_cid_bluetoothGattCharacteristic = (*env)->FindClass(env,
+            "android/bluetooth/BluetoothGattCharacteristic");
+    jmethodID jni_mid_bluetoothGattCharacteristic = (*env)->GetMethodID(env,
+            jni_cid_bluetoothGattCharacteristic, "<init>", "(Ljava/util/UUID;II)V");
+
+    // characteristic uuid for response
+    jobject jni_obj_readUuid = getUuidFromString(env, OIC_GATT_CHARACTERISTIC_RESPONSE_UUID);
+
+    // characteristic properties
+    jfieldID jni_fid_readProperties = (*env)->GetStaticFieldID(env,
+            jni_cid_bluetoothGattCharacteristic, "PROPERTY_READ", "I");
+    jobject jni_obj_readProperties = (*env)->GetStaticObjectField(env,
+            jni_cid_bluetoothGattCharacteristic, jni_fid_readProperties);
+
+    // characteristic permissions
+    jfieldID jni_fid_readPermissions = (*env)->GetStaticFieldID(env,
+            jni_cid_bluetoothGattCharacteristic, "PERMISSION_READ", "I");
+    jobject jni_obj_readPermissions = (*env)->GetStaticObjectField(env,
+            jni_cid_bluetoothGattCharacteristic, jni_fid_readPermissions);
+
+    jobject jni_readCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
+            jni_mid_bluetoothGattCharacteristic, jni_obj_readUuid, jni_obj_readProperties,
+            jni_obj_readPermissions);
+    if (!jni_readCharacteristic)
+    {
+        LOGI("[BLE Server] fail to create Response Characteristic");
+        return NULL;
+    }
+
+    jobject jni_obj_writeUuid = getUuidFromString(env, OIC_GATT_CHARACTERISTIC_REQUEST_UUID);
+
+    // characteristic properties
+    jfieldID jni_fid_writeProperties = (*env)->GetStaticFieldID(env,
+            jni_cid_bluetoothGattCharacteristic, "PROPERTY_WRITE", "I");
+    jobject jni_obj_writeProperties = (*env)->GetStaticObjectField(env,
+            jni_cid_bluetoothGattCharacteristic, jni_fid_writeProperties);
+
+    // characteristic permissions
+    jfieldID jni_fid_writePermissions = (*env)->GetStaticFieldID(env,
+            jni_cid_bluetoothGattCharacteristic, "PERMISSION_WRITE", "I");
+    jobject jni_obj_writePermissions = (*env)->GetStaticObjectField(env,
+            jni_cid_bluetoothGattCharacteristic, jni_fid_writePermissions);
+
+    jobject jni_writeCharacteristic = (*env)->NewObject(env, jni_cid_bluetoothGattCharacteristic,
+            jni_mid_bluetoothGattCharacteristic, jni_obj_writeUuid, jni_obj_writeProperties,
+            jni_obj_writePermissions);
+    if (!jni_writeCharacteristic)
+    {
+        LOGI("[BLE Server] fail to create Request Characteristic");
+        return NULL;
+    }
+
+    jmethodID jni_mid_addCharacteristic = (*env)->GetMethodID(env, jni_cid_bluetoothGattService,
+            "addCharacteristic", "(Landroid/bluetooth/BluetoothGattCharacteristic;)Z");
+    jboolean jni_boolean_addReadCharacteristic = (*env)->CallBooleanMethod(env,
+            jni_bluetoothGattService, jni_mid_addCharacteristic, jni_readCharacteristic);
+    if (jni_boolean_addReadCharacteristic == JNI_FALSE)
+    {
+        LOGI("[BLE Server] fail to add jni_boolean_addReadCharacteristic!!");
+        return NULL;
+    }
+
+    jboolean jni_boolean_addWriteCharacteristic = (*env)->CallBooleanMethod(env,
+            jni_bluetoothGattService, jni_mid_addCharacteristic, jni_writeCharacteristic);
+    if (jni_boolean_addWriteCharacteristic == JNI_FALSE)
+    {
+        LOGI("[BLE Server] fail to add jni_boolean_addReadCharacteristic!!");
+        return NULL;
+    }
+
+    LOGI("[BLE Server] jni gatt characteristic added!!");
+    return jni_bluetoothGattService;
+}
+
+void startGattServer(JNIEnv *env, jobject gattServerCallback)
+{
+
+    gBluetoothGattServerCallback = (*env)->NewGlobalRef(env, gattServerCallback);
+
+    // open gatt server
+    jobject bluetoothGattServer = openGattServer(env);
+
+    gBluetoothGattServer = (*env)->NewGlobalRef(env, bluetoothGattServer);
+    LOGI("[BLE Server] Bluetooth Gatt Server started!!");
+
+    // get bluetooth gatt service
+    jobject bluetoothGattService = createGattService(env);
+
+    jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
+            "android/bluetooth/BluetoothGattServer");
+    jmethodID jni_mid_addService = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
+            "addService", "(Landroid/bluetooth/BluetoothGattService;)Z");
+    jboolean jni_boolean_addService = (*env)->CallBooleanMethod(env, bluetoothGattServer,
+            jni_mid_addService, bluetoothGattService);
+
+    LOGI("[BLE Server] jni gatt service added!!");
+}
+
+void connect(JNIEnv *env, jobject bluetoothDevice)
+{
+
+    jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
+            "android/bluetooth/BluetoothGattServer");
+    jmethodID jni_mid_connect = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer, "connect",
+            "(Landroid/bluetooth/BluetoothDevice;Z)Z");
+    jboolean jni_boolean_connect = (*env)->CallBooleanMethod(env, gBluetoothGattServer,
+            jni_mid_connect, bluetoothDevice, JNI_FALSE);
+    LOGI("[BLE Server] connection requested!!");
+}
+
+void disconnect(JNIEnv *env, jobject bluetoothDevice)
+{
+
+    jclass jni_cid_bluetoothGattServer = (*env)->FindClass(env,
+            "android/bluetooth/BluetoothGattServer");
+    jmethodID jni_mid_cancelConnection = (*env)->GetMethodID(env, jni_cid_bluetoothGattServer,
+            "cancelConnection", "(Landroid/bluetooth/BluetoothDevice;)V");
+    (*env)->CallVoidMethod(env, gBluetoothGattServer, jni_mid_cancelConnection, bluetoothDevice);
+    LOGI("[BLE Server] disconnection requested!!");
+}
+
diff --git a/resource/csdk/connectivity/src/bt_le_adapter/linux/README.txt b/resource/csdk/connectivity/src/bt_le_adapter/linux/README.txt
deleted file mode 100644 (file)
index e69de29..0000000
index 0b35ffe..d2f2162 100644 (file)
 #include <gio/gio.h>
 
 #include "umutex.h"
+#include "uarraylist.h"
 #include "camessagequeue.h"
 #include "caadapterutils.h"
+#include "camsgparser.h"
 
 /**
  * @def TZ_BLE_CLIENT_TAG
@@ -44,7 +46,7 @@
  * @var BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG
  * @brief Its the constant value for characteristic descriptor from spec.
  */
-#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG 0x2902
+#define BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG "2902"
 
 /**
  * @var gBLEServiceList
@@ -109,6 +111,24 @@ static u_cond gBleClientSendCondWait = NULL;
 static u_mutex gBleClientReceiveDataMutex = NULL;
 
 /**
+ * @var gReceiverDataCond
+ * @brief Condition used for notifying handler the presence of data in recv queue.
+ */
+static u_cond gReceiverDataCond = NULL;
+
+/**
+ * @var gDataReceiverHandlerState
+ * @brief Stop condition of redvhandler.
+ */
+static bool gDataReceiverHandlerState = false;
+
+/**
+ * @var isHeaderAvailable
+ * @brief to differentiate btw header and data packet.
+ */
+static CABool_t isHeaderAvailable = false;
+
+/**
  * @var gBleClientThreadPoolMutex
  * @brief Mutex to synchronize the task to be pushed to thread pool.
  */
@@ -150,150 +170,111 @@ typedef struct gattService
     char *address;                                  /**< BD Address of */
 } stGattServiceInfo_t;
 
-void CABleGattCharacteristicWriteCb(int result, void *user_data)
-{
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
+///TODO: gRemoteAddress is defined here temporarily.
+///TODO: It will be removed once UUID based service discovery Implemented in tizen BLE platform
+/**
+ * @struct gRemoteAddress
+ * @brief Remote address of Gatt Server
+ *
+ */
+static const char *gRemoteAddress = "E4:12:1D:99:F3:57";
+//static const char *gRemoteAddress = "DB:F7:EB:B5:0F:07";
 
+static u_arraylist_t *gNonOicDeviceList = NULL;
 
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
-}
+static CABool_t gIsOicDeviceFound = CA_FALSE;
+/**
+ * @fn CABLEDataReceiverHandler
+ * @brief This function handles data from recv message queue.
+ */
+static void CABLEDataReceiverHandler(void *context);
 
-void *CABleClientSenderQueueProcessor()
+CAResult_t CABLEPushDataToReceiverQueue(const char *remoteAddress, const char *serviceUUID,
+                                        void *data, uint32_t dataLength, uint32_t *sentLength)
 {
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
-
-    while (gClientUp)
-    {
-        CAAdapterMessage_t *senderData = NULL;
-
-        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, " Waiting for the data ... ");
-
-        u_mutex_lock(gBleClientSendDataMutex);
-        u_cond_wait(gBleClientSendCondWait, gBleClientSendDataMutex);
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Data got pushed to the queue...");
+    //Input validation
+    VERIFY_NON_NULL(serviceUUID, TZ_BLE_CLIENT_TAG, "service UUID is null");
+    VERIFY_NON_NULL(data, TZ_BLE_CLIENT_TAG, "Data is null");
+    VERIFY_NON_NULL(sentLength, TZ_BLE_CLIENT_TAG, "Sent data length holder is null");
 
-        CAResult_t result = CA_STATUS_FAILED;
+    //Add message to data queue
+    CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_LE, remoteAddress,
+                                         serviceUUID);
+    if (NULL == remoteEndpoint)
+    {
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "Failed to create remote endpoint !");
+        return CA_STATUS_FAILED;
+    }
 
-        while (CA_STATUS_OK == CAAdapterDequeueMessage(gCABleClientSenderQueue,
-                &senderData))
-        {
-            if (NULL == senderData)
-            {
-                OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "senderData is NULL");
-                continue;
-            }
-            if (NULL != senderData->remoteEndpoint)
-            {
-                OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending Unicast data");
-                const char *bdAddress = senderData->remoteEndpoint->addressInfo.LE.leMacAddress;
+    if (CA_STATUS_OK != CAAdapterEnqueueMessage(gCABleClientReceiverQueue, remoteEndpoint, data,
+            dataLength))
+    {
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "Failed to add message to queue !");
 
-                VERIFY_NON_NULL_RET(bdAddress, TZ_BLE_CLIENT_TAG, "bdAddress is NULL", NULL);
+        CAAdapterFreeRemoteEndpoint(remoteEndpoint);
+        return CA_STATUS_FAILED;
+    }
 
-                result = CAUpdateCharacteristicsToGattServer(bdAddress, senderData->data,
-                         senderData->dataLen,
-                         UNICAST, 0);
-                if (CA_STATUS_OK != result)
-                {
-                    OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
-                              "Failed to UpdateCharacteristicsToGattServer [%s]", bdAddress);
-                }
-            }
-            else
-            {
-                OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending Multicast data");
-                result = CAUpdateCharacteristicsToAllGattServers(senderData->data,
-                         senderData->dataLen);
-                if (CA_STATUS_OK != result)
-                {
-                    OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
-                              "Failed to UpdateCharacteristicsToAllGattServers !");
-                }
-            }
+    *sentLength = dataLength;
 
-            CAAdapterFreeMessage(senderData);
-        }
+    OICFree(data);
+    data = NULL;
 
-        u_mutex_unlock(gBleClientSendDataMutex);
-    }
+    //Signal message handler for processing data for sending
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Signalling message send handler");
+    u_mutex_lock(gBleClientReceiveDataMutex);
+    u_cond_signal(gReceiverDataCond);
+    u_mutex_unlock(gBleClientReceiveDataMutex);
 
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
-    return NULL;
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
-
-CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattCharDescriptorInfo)
+void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic,
+                                      unsigned char *value,
+                                      int32_t valueLen, void *userData)
 {
-
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    uint8_t desc[stGattCharDescriptorInfo->total];
-    unsigned char noti[4] = {0,};
-    char *strUUID = NULL;
-
-    memcpy(desc, (uint8_t *)stGattCharDescriptorInfo->descriptor,
-           stGattCharDescriptorInfo->total);
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic is  [%s]", (char *)characteristic);
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic value length [%d]", valueLen);
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic value [%s]", value);
 
-    strUUID =  (char *)OICMalloc(sizeof(char) * 5);
+    char *data = (char *)OICMalloc(sizeof(char) * valueLen + 1);
+    if (NULL == data)
+    {
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Malloc failed!");
+        return;
+    }
 
-    VERIFY_NON_NULL_RET(strUUID, TZ_BLE_CLIENT_TAG, "malloc failed", CA_STATUS_FAILED);
+    memset(data, 0x0, valueLen + 1);
+    strncpy(data, value, valueLen);
 
-    memset(strUUID, 0x0, sizeof(char) * 5);
-    snprintf(strUUID, 4, "%x%x", desc[3], desc[2]);
-    noti[0] = desc[0];
-    noti[1] = desc[1];
-    noti[2] = 0x01;
-    noti[3] = 0x00;
+    uint32_t sentLength = 0;
 
-    if (!strncmp(strUUID, BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG, 2))
+    CAResult_t res = CABLEPushDataToReceiverQueue(gRemoteAddress, OIC_BLE_SERVICE_ID,
+                     data, strlen(data), &sentLength);
+    if (CA_STATUS_OK != res)
     {
-
-        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "setting notification/indication for descriptor");
-
-        int32_t ret =  bt_gatt_set_characteristic_desc_value_request(
-                           stGattCharDescriptorInfo->characteristic,
-                           noti,  4, CABleGattCharacteristicWriteCb);
-        if (BT_ERROR_NONE != ret)
-        {
-            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
-                      "bt_gatt_set_characteristic_desc_value_request failed with return[%s] \n",
-                      CABTGetErrorMsg(ret));
-            OICFree(strUUID);
-            return CA_STATUS_FAILED;
-        }
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CABLEPushDataToReceiverQueue failed");
+        OICFree(data);
+        return ;
     }
-    bt_gatt_destroy_attribute_handle(stGattCharDescriptorInfo->characteristic);
-    bt_gatt_destroy_attribute_handle(stGattCharDescriptorInfo->descriptor);
-    OICFree(stGattCharDescriptorInfo);
-    OICFree(strUUID);
 
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-    return CA_STATUS_OK;
+    return;
 }
 
-void *CASetCharacteristicDescriptorValueThread(void *stServiceInfo)
+void CABleGattCharacteristicWriteCb(bt_gatt_attribute_h handle)
 {
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
-
-    VERIFY_NON_NULL_RET(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL", NULL);
-
-    stGattCharDescriptor_t *stTemp  = (stGattCharDescriptor_t *)stServiceInfo;
-
-    VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "stTemp is NULL", NULL);
-
-    CAResult_t  result = CASetCharacteristicDescriptorValue(stTemp);
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
 
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CASetCharacteristicDescriptorValue failed!");
-        return NULL;
-    }
 
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-    return NULL;
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
 }
 
-
 void CABleGattDescriptorDiscoveredCb(int32_t result, unsigned char format, int32_t total,
                                      bt_gatt_attribute_h descriptor,
                                      bt_gatt_attribute_h characteristic, void *userData)
@@ -303,17 +284,35 @@ void CABleGattDescriptorDiscoveredCb(int32_t result, unsigned char format, int32
     stGattCharDescriptor_t *stTemp = (stGattCharDescriptor_t *)OICMalloc(sizeof(
                                          stGattCharDescriptor_t));
 
-    VERIFY_NON_NULL_VOID(stTemp, TZ_BLE_CLIENT_TAG, "stTemp is NULL");
+    VERIFY_NON_NULL_VOID(stTemp, TZ_BLE_CLIENT_TAG, "malloc failed!");
 
-    bt_gatt_clone_attribute_handle(&(stTemp->descriptor), descriptor);
+    memset(stTemp, 0x0, sizeof(stGattCharDescriptor_t));
 
-    bt_gatt_clone_attribute_handle(&(stTemp->characteristic), characteristic);
+    stTemp->desc = (uint8_t *)OICMalloc(total + 1);
+    if (NULL == stTemp->desc)
+    {
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "malloc failed");
+        OICFree(stTemp);
+        return;
+    }
 
+    memset(stTemp->desc, 0x0, total + 1);
+
+    memcpy(stTemp->desc, (uint8_t *)descriptor, total);
+
+    OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "result [%d] format [%d] total [%d]", result, format, total);
+    OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "characteristic [%s]", (const char *) characteristic);
+
+
+    bt_gatt_clone_attribute_handle(&(stTemp->characteristic), characteristic);
     stTemp->total = total;
+
     u_mutex_lock(gBleClientThreadPoolMutex);
     if (NULL == gBleClientThreadPool)
     {
         OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL");
+        bt_gatt_destroy_attribute_handle(stTemp->characteristic);
+        OICFree(stTemp->desc);
         OICFree(stTemp);
         u_mutex_unlock(gBleClientThreadPoolMutex);
         return ;
@@ -324,12 +323,18 @@ void CABleGattDescriptorDiscoveredCb(int32_t result, unsigned char format, int32
                                             (void *) stTemp);
     if (CA_STATUS_OK != ret)
     {
-        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", ret);
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed");
+        bt_gatt_destroy_attribute_handle(stTemp->characteristic);
+        OICFree(stTemp->desc);
         OICFree(stTemp);
         u_mutex_unlock(gBleClientThreadPoolMutex);
         return ;
     }
 
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG,
+            "LE Client initialization flow complete. Enabling gClientUp state to TRUE ");
+    gClientUp = CA_TRUE;
+
     ret = u_thread_pool_add_task(gBleClientThreadPool,
                                  (void *) CABleClientSenderQueueProcessor,
                                  (void *) NULL);
@@ -339,65 +344,127 @@ void CABleGattDescriptorDiscoveredCb(int32_t result, unsigned char format, int32
         u_mutex_unlock(gBleClientThreadPoolMutex);
         return ;
     }
-    u_mutex_unlock(gBleClientThreadPoolMutex);
 
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG,
-            "LE Client initialization complete. Enabling gClientUp state to TRUE ");
-    gClientUp = CA_TRUE;
+    gDataReceiverHandlerState = true;
+    if (CA_STATUS_OK != u_thread_pool_add_task(gBleClientThreadPool, CABLEDataReceiverHandler, NULL))
+    {
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "Failed to start data send handler!");
+        return ;
+    }
+
+    u_mutex_unlock(gBleClientThreadPoolMutex);
 
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-    return;
 }
 
-void *CADiscoverDescriptorThread(void *stServiceInfo)
+CABool_t CABleGattCharacteristicsDiscoveredCb(int32_t result,
+        int32_t inputIndex, int32_t total,
+        bt_gatt_attribute_h characteristic, void *userData)
 {
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, " IN");
 
-    VERIFY_NON_NULL_RET(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL", NULL);
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    stGattServiceInfo_t *stTemp  = (stGattServiceInfo_t *)stServiceInfo;
+    VERIFY_NON_NULL_RET(characteristic, TZ_BLE_CLIENT_TAG, "Param characteristic is NULL", false);
 
-    int32_t ret = bt_gatt_discover_characteristic_descriptor(stTemp->serviceInfo,
-                  CABleGattDescriptorDiscoveredCb, NULL);
+    VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);
 
-    if (BT_ERROR_NONE != ret)
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
+              "result [%d] input_index [%d] total [%d]",
+              result, inputIndex, total);
+
+    char *bdAddress = (char *) userData;
+
+    BLEServiceInfo *bleServiceInfo = NULL;
+
+    u_mutex_lock(gBleServiceListMutex);
+
+    CAGetBLEServiceInfo(gBLEServiceList, bdAddress, &bleServiceInfo);
+
+    u_mutex_unlock(gBleServiceListMutex);
+
+
+    if ( READ_CHAR_INDEX == inputIndex) // Server will read on this characteristics.
     {
-        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
-                  "bt_gatt_discover_characteristic_descriptor failed with returns[%s] \n",
-                  CABTGetErrorMsg(ret));
-        return NULL;
+        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "new read Characteristics is obtained [%s]",
+                  (char *)characteristic);
+
+        CAResult_t retVal = CAAppendBLECharInfo(characteristic, READ_CHAR, bleServiceInfo);
+        if (CA_STATUS_OK != retVal)
+        {
+            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed ");
+            return false;
+        }
+        char *uuid = NULL;
+
+        bt_gatt_get_service_uuid(characteristic, &uuid);
+        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "new read Characteristics uuid is obtained [%s]",
+                  uuid);
     }
+    else if ( WRITE_CHAR_INDEX == inputIndex) // Server will write on this characterisctics
+    {
+        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "new write Characteristics is obtained [%s]",
+                  (char *)characteristic);
 
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-    return NULL;
-}
+        CAResult_t retVal = CAAppendBLECharInfo(characteristic, WRITE_CHAR, bleServiceInfo);
+        if (CA_STATUS_OK != retVal)
+        {
+            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed! ");
+            return false;
+        }
+        char *uuid = NULL;
 
-void *CADiscoverCharThread(void *stServiceInfo)
-{
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
+        bt_gatt_get_service_uuid(characteristic, &uuid);
+        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "new write Characteristics uuid is obtained [%s]",
+                  uuid);
 
-    VERIFY_NON_NULL_RET(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL", NULL);
+        stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICMalloc(sizeof(stGattServiceInfo_t));
 
-    stGattServiceInfo_t *stTemp  = (stGattServiceInfo_t *)stServiceInfo;
+        VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "malloc failed!", false);
 
-    VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "stTemp is NULL", NULL);
+        memset(stTemp, 0x0, sizeof(stGattServiceInfo_t));
 
-    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address [%s]", stTemp->address);
+        int32_t len = strlen(bdAddress);
 
-    CAResult_t  result = CABleDiscoverCharacteristics(stTemp->serviceInfo, stTemp->address);
-    bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
+        stTemp->address = (char *)OICMalloc(sizeof(char) * len + 1);
+        if (NULL == stTemp->address)
+        {
+            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc  failed! ");
+            OICFree(stTemp);
+            return false;
+        }
+        memset(stTemp->address, 0x0, len + 1);
+        strncpy(stTemp->address, bdAddress, len);
 
-    OICFree(stTemp->address);
+        bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), characteristic);
 
-    OICFree(stTemp);
+        u_mutex_lock(gBleClientThreadPoolMutex);
+        if (NULL == gBleClientThreadPool)
+        {
+            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL");
+            bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
+            OICFree(stTemp->address);
+            OICFree(stTemp);
+            u_mutex_unlock(gBleClientThreadPoolMutex);
+            return false;
+        }
 
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CABleDiscoverCharacteristics failed!");
-        return NULL;
+        retVal = u_thread_pool_add_task(gBleClientThreadPool,
+                                        (void *) CADiscoverDescriptorThread,
+                                        (void *) stTemp);
+        if (CA_STATUS_OK != retVal)
+        {
+            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", retVal);
+            bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
+            OICFree(stTemp->address);
+            OICFree(stTemp);
+            u_mutex_unlock(gBleClientThreadPoolMutex);
+            return false;
+        }
+        u_mutex_unlock(gBleClientThreadPoolMutex);
     }
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-    return NULL;
+    return true;
+
 }
 
 void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void *user_data)
@@ -410,36 +477,31 @@ void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void *
     }
     else
     {
-        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "A bond with chat_server is created.");
+        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "bond with remote device is created.");
         OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Callback: The number of service : %d.",
                   device_info->service_count);
 
-        char *bdAddress = device_info->remote_address;
-
-        int32_t len = strlen(bdAddress);
-
-        char *addr = (char *)OICMalloc(sizeof(char) * len + 1);
-
-        VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc  failed!");
-
-        memset(addr, 0x0, len + 1);
+        VERIFY_NON_NULL_VOID(device_info, TZ_BLE_CLIENT_TAG,
+                             "device_info is NULL");
+        VERIFY_NON_NULL_VOID(device_info->remote_address, TZ_BLE_CLIENT_TAG,
+                             "device_info->remote_address is NULL");
 
-        strncpy(addr, bdAddress, len);
+        char *bdAddress = device_info->remote_address;
 
         BLEServiceInfo *bleServiceInfo = NULL;
 
         u_mutex_lock(gBleServiceListMutex);
-        CAResult_t retVal = CAGetBLEServiceInfo(gBLEServiceList, addr, &bleServiceInfo);
-
-        u_mutex_unlock(gBleServiceListMutex);
-        OICFree(addr);
-
+        CAResult_t retVal = CAGetBLEServiceInfo(gBLEServiceList, bdAddress, &bleServiceInfo);
         if (CA_STATUS_OK != retVal)
         {
             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CAGetBLEServiceInfo failed! ");
             bleServiceInfo = NULL;
-            return ;
+            return;
         }
+        u_mutex_unlock(gBleServiceListMutex);
+
+        VERIFY_NON_NULL_VOID(bleServiceInfo, TZ_BLE_CLIENT_TAG,
+                             "bleServiceInfo is NULL");
 
         int32_t ret = CAVerifyOICService(bleServiceInfo->service_clone);
         if (CA_STATUS_OK != ret)
@@ -460,7 +522,7 @@ void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void *
 
             bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), bleServiceInfo->service_clone);
 
-            len = strlen(bleServiceInfo->bdAddress);
+            int32_t len = strlen(bleServiceInfo->bdAddress);
 
             stTemp->address = (char *)OICMalloc(sizeof(char) * len + 1);
             if (NULL == stTemp->address)
@@ -468,7 +530,7 @@ void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void *
                 OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc  failed! ");
                 bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
                 OICFree(stTemp);
-                return ;
+                return;
             }
             memset(stTemp->address, 0x0, len + 1);
 
@@ -482,7 +544,7 @@ void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void *
                 OICFree(stTemp->address);
                 OICFree(stTemp);
                 u_mutex_unlock(gBleClientThreadPoolMutex);
-                return ;
+                return;
             }
 
             CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool,
@@ -495,7 +557,7 @@ void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void *
                 OICFree(stTemp->address);
                 OICFree(stTemp);
                 u_mutex_unlock(gBleClientThreadPoolMutex);
-                return ;
+                return;
             }
             u_mutex_unlock(gBleClientThreadPoolMutex);
         }
@@ -504,140 +566,112 @@ void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void *
                   "Callback: is_bonded - %d.", device_info->is_bonded);
         OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
                   "Callback: is_connected - %d.", device_info->is_connected);
-
     }
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
 }
 
-void *CAGATTCreateBondThread(void *stServiceInfo)
+CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int32_t index, int32_t count,
+                                   void *userData)
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    VERIFY_NON_NULL_RET(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL", NULL);
-
-    stGattServiceInfo_t *stTemp  = (stGattServiceInfo_t *)stServiceInfo;
-
-    VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "stTemp is NULL", NULL);
+    VERIFY_NON_NULL_RET(service, TZ_BLE_CLIENT_TAG, "Param service is NULL", false);
 
-    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address [%s]",
-              stTemp->address);
+    VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "Param userData is NULL", false);
 
-    CAResult_t  result = CABleGATTCreateBond(stTemp->address);
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Service info [%s] index [%d] count [%d]", (char *)service,
+              index, count);
 
-    OICFree(stTemp->address);
-    OICFree(stTemp);
+    CAResult_t result = CAVerifyOICService(service);
 
     if (CA_STATUS_OK != result)
     {
-        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG ,
-                  "CABleDiscoverCharacteristics failed!");
-        return NULL;
-    }
-
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-    return NULL;
-}
-
-void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic,
-                                      unsigned char *value,
-                                      int32_t valueLen, void *userData)
-{
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
-
-    int32_t i = 0;
-
-    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic is  [%s]", (char *)characteristic);
-
-    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic value length [%d]", valueLen);
-
-    for (i = 0; i < valueLen; i++)
-    {
-        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Changed characteristic  value %c", value[i]);
-    }
-
-    CARemoteEndpoint_t  *remoteEndPoint = (CARemoteEndpoint_t *) OICMalloc(sizeof(CARemoteEndpoint_t));
-
-    VERIFY_NON_NULL_VOID(remoteEndPoint, TZ_BLE_CLIENT_TAG, "malloc failed");
-
-    memset(remoteEndPoint, 0x0, sizeof(CARemoteEndpoint_t));
+        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "No need to process the service ");
 
-    ///TODO: Currently Empty endpoint is being sent.
-    ///TODO:Later proper remote address has to be added when tizen team changed their code
+        if ((index + 1) == count && CA_FALSE == gIsOicDeviceFound)
+        {
+            char *bdAddress = (char *)userData;
+            OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "OIC service is not available in remote address [%s]",
+                      bdAddress);
+            int32_t len = strlen(bdAddress);
+
+            char *addr = (char *)OICMalloc(sizeof(char) * len + 1);
+            VERIFY_NON_NULL_RET(userData, TZ_BLE_CLIENT_TAG, "malloc failed!", false);
+            memset(addr, 0x0, len + 1);
+            strncpy(addr, bdAddress, len);
+
+            uint32_t listLen = u_arraylist_length(gNonOicDeviceList);
+            int32_t indexValue = 0;
+            CABool_t found = CA_FALSE;
+            for (indexValue = 0; indexValue < listLen; indexValue++)
+            {
+                char *storedAddr = u_arraylist_get(gNonOicDeviceList, indexValue);
+                if (strcmp(storedAddr, addr) == 0)
+                {
+                    found = CA_TRUE;
+                    break;
+                }
+            }
+            if (found == CA_FALSE)
+            {
+                OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Adding device [%s] to gNonOicDeviceList", addr);
+                u_arraylist_add(gNonOicDeviceList, addr);
+            }
 
-    char *data = (char *)OICMalloc(sizeof(char) * valueLen + 1);
-    if (NULL == data)
-    {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Malloc failed!");
-        OICFree(remoteEndPoint);
-        return;
+            CAResult_t result = CABleGattDisConnect(bdAddress);
+            if (CA_STATUS_OK != result)
+            {
+                OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+                          "CABleGattDisConnect failed!");
+                return false;
+            }
+        }
     }
-
-    memset(data, 0x0, valueLen + 1);
-    strncpy(data, value, valueLen);
-
-    u_mutex_lock(gBleReqRespClientCbMutex);
-    if (NULL == gNetworkPacketReceivedClientCallback)
+    else
     {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gReqRespCallback is NULL!");
-        OICFree(value);
-        OICFree(remoteEndPoint);
-        OICFree(data);
-        u_mutex_unlock(gBleReqRespClientCbMutex);
-        return;
-    }
-
-    gNetworkPacketReceivedClientCallback(remoteEndPoint, data, valueLen);
+        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service");
 
-    u_mutex_unlock(gBleReqRespClientCbMutex);
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-    return;
-}
+        gIsOicDeviceFound = CA_TRUE;
 
-CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, void *userData)
-{
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
+        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG , "Registering to watch characteristics changes  \n");
 
-    if (NULL == service || NULL == userData)
-    {
-        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Param service or userData is NULL");
-        return false;
-    }
+        result = CABleGattWatchCharacteristicChanges(service);
+        if (CA_STATUS_OK != result)
+        {
+            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+                      "CABleGattWatchCharacteristicChanges failed!");
+            return false;
+        }
 
-    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Service info [%s]", (char *)service);
+        char *bdAddress = (char *)userData;
 
-    int32_t ret = CAVerifyOICService(service);
+        stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICMalloc(sizeof(stGattServiceInfo_t));
 
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "No need to process the service ");
-    }
-    else
-    {
-        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Its OIC service");
+        VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "Malloc Failed", false);
 
-        char *bdAddress = (char *)userData;
+        memset(stTemp, 0x0, sizeof(stGattServiceInfo_t));
 
         int32_t len = strlen(bdAddress);
 
-        char *addr = (char *)OICMalloc(sizeof(char) * len + 1);
-        if (NULL == addr)
+        stTemp->address = (char *)OICMalloc(sizeof(char) * len + 1);
+
+        if (NULL == stTemp->address)
         {
-            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "malloc failed! ");
+            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc  failed! ");
+            OICFree(stTemp);
             return false;
         }
-        memset(addr, 0x0, len + 1);
-
-        strncpy(addr, bdAddress, len);
+        memset(stTemp->address, 0x0, len + 1);
+        strncpy(stTemp->address, bdAddress, len);
 
         BLEServiceInfo *bleServiceInfo = NULL;
 
-        CAResult_t result = CACreateBLEServiceInfo(addr, service, &bleServiceInfo);
-
-        OICFree(addr);
-
+        CAResult_t result = CACreateBLEServiceInfo(bdAddress, service, &bleServiceInfo);
         if (CA_STATUS_OK != result)
         {
             OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "CACreateBLEServiceInfo failed! ");
+            OICFree(stTemp);
+            OICFree(stTemp->address);
             bleServiceInfo = NULL;
             return false;
         }
@@ -647,64 +681,18 @@ CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, void *userData)
 
         u_mutex_lock(gBleServiceListMutex);
         result = CAAddBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo);
-
         if (CA_STATUS_OK != result)
         {
             OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CAAddBLEServiceInfoToList failed!");
+            OICFree(stTemp);
+            OICFree(stTemp->address);
+            CAFreeBLEServiceInfo(bleServiceInfo);
             bleServiceInfo = NULL;
             u_mutex_unlock(gBleServiceListMutex);
             return false;
         }
         u_mutex_unlock(gBleServiceListMutex);
 
-        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG , "Registering to watch characteristics changes  \n");
-
-        int32_t ret = bt_gatt_watch_characteristic_changes(bleServiceInfo->service_clone);
-
-        if (BT_ERROR_NONE != ret)
-        {
-            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
-                      "bt_gatt_watch_characteristic_changes failed  with [%s] \n", CABTGetErrorMsg(ret));
-            u_mutex_lock(gBleServiceListMutex);
-            CARemoveBLEServiceInfoToList(&gBLEServiceList,
-                                         bleServiceInfo, bleServiceInfo->bdAddress);
-            u_mutex_unlock(gBleServiceListMutex);
-            return false;
-        }
-
-        stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICMalloc(sizeof(stGattServiceInfo_t));
-
-        if (NULL == stTemp)
-        {
-            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc  failed! ");
-            u_mutex_lock(gBleServiceListMutex);
-            CARemoveBLEServiceInfoToList(&gBLEServiceList,
-                                         bleServiceInfo, bleServiceInfo->bdAddress);
-            u_mutex_unlock(gBleServiceListMutex);
-            return false;
-        }
-
-        memset(stTemp, 0x0, sizeof(stGattServiceInfo_t));
-
-        len = strlen(bleServiceInfo->bdAddress);
-
-        stTemp->address = (char *)OICMalloc(sizeof(char) * len + 1);
-
-        if (NULL == stTemp->address)
-        {
-            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc  failed! ");
-            u_mutex_lock(gBleServiceListMutex);
-            CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo,
-                                         bleServiceInfo->bdAddress);
-            u_mutex_unlock(gBleServiceListMutex);
-            OICFree(stTemp);
-            return false;
-        }
-
-        memset(stTemp->address, 0x0, len + 1);
-
-        strncpy(stTemp->address, bleServiceInfo->bdAddress, len);
-
         u_mutex_lock(gBleClientThreadPoolMutex);
         if (NULL == gBleClientThreadPool)
         {
@@ -742,395 +730,904 @@ CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, void *userData)
     return true;;
 }
 
-
-CABool_t CABleGattCharacteristicsDiscoveredCb(int32_t result,
-        int32_t inputIndex, int32_t total,
-        bt_gatt_attribute_h characteristic, void *userData)
+void CABleGattConnectionStateChangedCb(int32_t result, bool connected, const char *remoteAddress,
+                                       void *userData)
 {
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
 
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "CABleGattConnectionStateChangedCb result[%d] ", result);
 
-    if (NULL == characteristic || NULL == userData)
-    {
-        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Param characteristic and userData is NULL");
-        return false;
-    }
+    VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
 
-    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
-              "result [%d] input_index [%d] total [%d]",
-              result, inputIndex, total);
+    if (!connected)
+    {
+        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "DisConnected from [%s] ", remoteAddress);
 
-    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
-              "new characteristic found is [%s]", (char *)characteristic);
+        CAResult_t result = CABleGattStartDeviceDiscovery();
+        if (CA_STATUS_OK != result)
+        {
+            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattStartDeviceDiscovery failed");
+            return;
+        }
+    }
+    else
+    {
+        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Connected to [%s] ", remoteAddress);
 
-    char *bdAddress = (char *) userData;
+        int32_t len = strlen(remoteAddress);
 
-    BLEServiceInfo *bleServiceInfo = NULL;
+        char *addr = (char *)OICMalloc(sizeof(char) * len + 1);
 
-    u_mutex_lock(gBleServiceListMutex);
+        VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");
 
-    CAGetBLEServiceInfo(gBLEServiceList, bdAddress, &bleServiceInfo);
+        memset(addr, 0x0, len + 1);
 
-    u_mutex_unlock(gBleServiceListMutex);
+        strncpy(addr, remoteAddress, len);
 
-    if ( READ_CHAR_INDEX == inputIndex)
-    {
-        CAResult_t retVal = CAAppendBLECharInfo(characteristic, READ_CHAR, bleServiceInfo);
-        if (CA_STATUS_OK != retVal)
+        u_mutex_lock(gBleClientThreadPoolMutex);
+        if (NULL == gBleClientThreadPool)
         {
-            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed ");
-            return false;
+            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL");
+            OICFree(addr);
+            u_mutex_unlock(gBleClientThreadPoolMutex);
+            return;
         }
-    }
-    else if ( WRITE_CHAR_INDEX == inputIndex)
-    {
-        CAResult_t retVal = CAAppendBLECharInfo(characteristic, WRITE_CHAR, bleServiceInfo);
-        if (CA_STATUS_OK != retVal)
+
+        CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool, (void *) CADiscoverBLEServicesThread,
+                                                (void *) addr);
+        if (CA_STATUS_OK != ret)
         {
-            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CAAppendBLECharInfo failed! ");
-            return false;
+            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", ret);
+            OICFree(addr);
+            u_mutex_unlock(gBleClientThreadPoolMutex);
+            return;
         }
-
-    }
-
-    stGattServiceInfo_t *stTemp = (stGattServiceInfo_t *)OICMalloc(sizeof(stGattServiceInfo_t));
-
-    if (NULL == stTemp)
-    {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc  failed! ");
-        return false;
+        u_mutex_unlock(gBleClientThreadPoolMutex);
     }
 
-    memset(stTemp, 0x0, sizeof(stGattServiceInfo_t));
-
-    bt_gatt_clone_attribute_handle(&(stTemp->serviceInfo), characteristic);
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+}
 
-    int32_t len = strlen(bleServiceInfo->bdAddress);
+void CABtAdapterLeDeviceDiscoveryStateChangedCb(int32_t result,
+        bt_adapter_le_device_discovery_state_e discoveryState,
+        bt_adapter_le_device_discovery_info_s *discoveryInfo,
+        void *userData)
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    stTemp->address = (char *)OICMalloc(sizeof(char) * len + 1);
-    if (NULL == stTemp->address)
+    if (NULL  == discoveryInfo && BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND == discoveryState)
     {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG , "Malloc  failed! ");
-        bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
-        OICFree(stTemp);
-        return false;
+        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL");
+        return;
     }
-    memset(stTemp->address, 0x0, len + 1);
-
-    strncpy(stTemp->address, bleServiceInfo->bdAddress, len);
 
-    u_mutex_lock(gBleClientThreadPoolMutex);
-    if (NULL == gBleClientThreadPool)
+    if (BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND != discoveryState)
     {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL");
-        bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
-        OICFree(stTemp->address);
-        OICFree(stTemp);
-        u_mutex_unlock(gBleClientThreadPoolMutex);
-        //CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo, bleServiceInfo->bdAddress);
-        return false;
+        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
+                  " LE Discovery state is [%s]",
+                  discoveryState == BT_ADAPTER_LE_DEVICE_DISCOVERY_STARTED ? "Started" : "Finished" );
     }
-
-    CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool,
-                                            (void *) CADiscoverDescriptorThread,
-                                            (void *) stTemp);
-    if (CA_STATUS_OK != ret)
+    else
     {
-        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", ret);
-        bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
-        OICFree(stTemp->address);
-        OICFree(stTemp);
-        u_mutex_unlock(gBleClientThreadPoolMutex);
-        //CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo, bleServiceInfo->bdAddress);
-        return false;
-    }
-    u_mutex_unlock(gBleClientThreadPoolMutex);
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-    return true;
+        CAPrintDiscoveryInformation(discoveryInfo);
 
-}
+        VERIFY_NON_NULL_VOID(discoveryInfo->remote_address, TZ_BLE_CLIENT_TAG,
+                             "discoveryInfo->remote_address is NULL");
+        ///TODO: Below check is for filtering to make connection with our intended device(hardcoded one)
+        ///TODO: Later it will be removed once Service UUID based implementation is done.
 
-CAResult_t CABleClientSenderQueueEnqueueMessage(const CARemoteEndpoint_t *remoteEndpoint, void *data,
-        uint32_t dataLen)
+        if (NULL != gNonOicDeviceList)
+        {
+            uint32_t listLen = u_arraylist_length(gNonOicDeviceList);
+            int32_t index = 0;
+            for (index = 0; index < listLen; index++)
+            {
+                char *storedAddr = u_arraylist_get(gNonOicDeviceList, index);
+                if (strcmp(storedAddr, discoveryInfo->remote_address) == 0)
+                {
+                    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Discovered Device is NON OIC Device. Ignore.");
+                    return;
+                }
+            }
+        }
+
+        int32_t len = strlen(discoveryInfo->remote_address);
+
+        char *addr = (char *)OICMalloc(sizeof(char) * len + 1);
+
+        VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");
+
+        memset(addr, 0x0, len + 1);
+        strncpy(addr, discoveryInfo->remote_address, len);
+
+        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
+                  "Trying to do Gatt connection to [%s] ", addr);
+
+        u_mutex_lock(gBleClientThreadPoolMutex);
+        if (NULL == gBleClientThreadPool)
+        {
+            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL");
+            OICFree(addr);
+            u_mutex_unlock(gBleClientThreadPoolMutex);
+            return;
+        }
+
+        CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool, (void *) CAGattConnectThread,
+                                                (void *) addr);
+        if (CA_STATUS_OK != ret)
+        {
+            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", ret);
+            OICFree(addr);
+            u_mutex_unlock(gBleClientThreadPoolMutex);
+            return;
+        }
+        u_mutex_unlock(gBleClientThreadPoolMutex);
+        if (discoveryInfo->adv_data_len > 31 || discoveryInfo->scan_data_len > 31)
+        {
+            bt_adapter_le_stop_device_discovery();
+            return;
+        }
+
+    }
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+}
+
+void CABLEDataReceiverHandler(void *context)
 {
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    VERIFY_NON_NULL(data, NULL, "Param data is NULL");
+    CAAdapterMessage_t *message = NULL;
+    const char *remoteAddress = NULL;
+    const char *serviceUUID = NULL;
+    uint32_t recvDataLen = 0;
+    uint32_t totalDataLen = 0;
+    char *dataSegment = NULL;
+    char *defragData = NULL;
+    CARemoteEndpoint_t *remoteEndpoint = NULL;
 
-    VERIFY_NON_NULL_RET(gCABleClientSenderQueue, TZ_BLE_CLIENT_TAG,
-                        "BleClientReceiverQueue is  NULL",
-                        CA_STATUS_FAILED);
-    VERIFY_NON_NULL_RET(gBleClientSendDataMutex, TZ_BLE_CLIENT_TAG,
-                        "BleClientSendDataMutex is NULL",
-                        CA_STATUS_FAILED);
-    VERIFY_NON_NULL_RET(gBleClientSendCondWait, TZ_BLE_CLIENT_TAG,
-                        "BleClientSendCondWait is NULL",
-                        CA_STATUS_FAILED);
+    u_mutex_lock(gBleClientReceiveDataMutex);
+
+    while (gDataReceiverHandlerState)
+    {
+
+        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, " waiting for the data");
+
+        u_cond_wait(gReceiverDataCond, gBleClientReceiveDataMutex);
+
+        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "wait unlocked");
+
+        //Extract the message from queue and send to remote ble device
+        while (CA_STATUS_OK == CAAdapterDequeueMessage(gCABleClientReceiverQueue, &message))
+        {
+            OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "checking for DE Fragmentation");
+
+            if (!isHeaderAvailable)
+            {
+                char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
+                memcpy(header, message->data, CA_HEADER_LENGTH);
+                totalDataLen = CAParseHeader(header);
+                OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Total data to be accumulated [%d] bytes", totalDataLen);
+                defragData = (char *) OICMalloc(sizeof(char) * totalDataLen);
+                OICFree(header);
+
+                remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
+                serviceUUID = message->remoteEndpoint->resourceUri;
+
+                remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
+                                 serviceUUID);
+
+                memcpy(defragData + recvDataLen, message->data + CA_HEADER_LENGTH,
+                       message->dataLen - CA_HEADER_LENGTH);
+                recvDataLen += message->dataLen - CA_HEADER_LENGTH;
+                isHeaderAvailable = true;
+            }
+            else
+            {
+                memcpy(defragData + recvDataLen, message->data, message->dataLen);
+                recvDataLen += message->dataLen ;
+            }
+            CAAdapterFreeMessage(message);
+            if (totalDataLen == recvDataLen)
+            {
+                u_mutex_lock(gBleReqRespClientCbMutex);
+                if (NULL == gNetworkPacketReceivedClientCallback)
+                {
+                    OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gReqRespCallback is NULL!");
+                    u_mutex_unlock(gBleReqRespClientCbMutex);
+                    return;
+                }
+                OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Sending data up !");
+                gNetworkPacketReceivedClientCallback(remoteEndpoint, defragData, recvDataLen);
+                OICFree(remoteEndpoint);
+                OICFree(defragData);
+                recvDataLen = 0;
+                totalDataLen = 0;
+                isHeaderAvailable = false;
+                u_mutex_unlock(gBleReqRespClientCbMutex);
+            }
+
+        }
+
+        if (false == gDataReceiverHandlerState)
+        {
+            break;
+        }
+
+
+    }
+    u_mutex_unlock(gBleClientReceiveDataMutex);
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+}
+
+void CAPrintDiscoveryInformation(bt_adapter_le_device_discovery_info_s *discoveryInfo)
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
+
+    if (NULL == discoveryInfo)
+    {
+        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL ");
+        return;
+    }
+
+    if (discoveryInfo->remote_address)
+    {
+        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Remote Address [%s]", discoveryInfo->remote_address);
+    }
+
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
+              " Adv data len [%d] Scan data len[%d]RSSI [%d] Addr_type [%d] ",
+              discoveryInfo->adv_data_len, discoveryInfo->scan_data_len, discoveryInfo->rssi,
+              discoveryInfo->address_type);
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+}
+
+void CASetBleClientThreadPoolHandle(u_thread_pool_t handle)
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
+
+    u_mutex_unlock(gBleClientThreadPoolMutex);
+    gBleClientThreadPool = handle;
+    u_mutex_unlock(gBleClientThreadPoolMutex);
+
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+}
+
+void CASetBLEReqRespClientCallback(CANetworkPacketReceivedCallback callback)
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
+
+    u_mutex_lock(gBleReqRespClientCbMutex);
+
+    gNetworkPacketReceivedClientCallback = callback;
+
+    u_mutex_unlock(gBleReqRespClientCbMutex);
+
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+}
+
+CAResult_t CAStartBLEGattClient()
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
+
+    CAResult_t retVal = CAInitGattClientMutexVaraibles();
+
+    if (CA_STATUS_OK != retVal)
+    {
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAInitGattClientMutexVaraibles failed!");
+        CATerminateGattClientMutexVariables();
+        return CA_STATUS_FAILED;
+    }
+    gNonOicDeviceList = u_arraylist_create();
+    u_mutex_unlock(gBleClientThreadPoolMutex);
+    if (NULL == gBleClientThreadPool)
+    {
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleServerThreadPool is NULL");
+        CATerminateGattClientMutexVariables();
+        u_mutex_unlock(gBleClientThreadPoolMutex);
+        return CA_STATUS_FAILED;
+    }
+
+    retVal = u_thread_pool_add_task(gBleClientThreadPool, (void *) CAStartBleGattClientThread,
+                                    (void *) NULL);
+    if (CA_STATUS_OK != retVal)
+    {
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed");
+        CATerminateGattClientMutexVariables();
+        u_mutex_unlock(gBleClientThreadPoolMutex);
+        return CA_STATUS_FAILED;
+    }
+    u_mutex_unlock(gBleClientThreadPoolMutex);
+
+    return CA_STATUS_OK;
+}
+
+void *CAStartBleGattClientThread(void *data)
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
+
+    u_mutex_lock(gBleClientStateMutex);
+
+    if (CA_TRUE  == gIsBleGattClientStarted)
+    {
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is already running!!");
+        u_mutex_unlock(gBleClientStateMutex);
+        return NULL;
+    }
+
+    CAResult_t  ret = CAInitBleQueues();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CAInitBleQueues failed");
+        CATerminateBleQueues();
+        u_mutex_unlock(gBleClientStateMutex);
+        return NULL;
+    }
+
+    ret = CABleGattSetScanParameter();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleSetScanParameter Failed");
+        u_mutex_unlock(gBleClientStateMutex);
+        CATerminateBLEGattClient();
+        return NULL;
+    }
+
+    ret = CABleGattSetCallbacks();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattSetCallbacks Failed");
+        u_mutex_unlock(gBleClientStateMutex);
+        CATerminateBLEGattClient();
+        return NULL;
+    }
+
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Starting LE device discovery");
+
+    ret = CABleGattStartDeviceDiscovery();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed");
+        u_mutex_unlock(gBleClientStateMutex);
+        CATerminateBLEGattClient();
+        return NULL;
+    }
+
+    gIsBleGattClientStarted = CA_TRUE;
+
+    u_mutex_unlock(gBleClientStateMutex);
+
+    GMainContext *thread_context = NULL;
+
+    thread_context = g_main_context_new();
+
+    g_event_loop = g_main_loop_new(thread_context, FALSE);
+
+    g_main_context_push_thread_default(thread_context);
+
+    g_main_loop_run(g_event_loop);
+
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+
+    return NULL;
+}
+
+void CAStopBLEGattClient()
+{
+    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
+
+    u_mutex_lock(gBleClientStateMutex);
+
+    if (CA_FALSE == gIsBleGattClientStarted)
+    {
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is not running to stop");
+        u_mutex_unlock(gBleClientStateMutex);
+        return;
+    }
+    u_mutex_unlock(gBleClientStateMutex);
+
+    //Stop data send and receive handlers
+    if (gBleClientReceiveDataMutex && gReceiverDataCond && gDataReceiverHandlerState)
+    {
+        u_mutex_lock(gBleClientReceiveDataMutex);
+        gDataReceiverHandlerState = CA_FALSE;
+        u_cond_signal(gReceiverDataCond);
+        u_mutex_unlock(gBleClientReceiveDataMutex);
+    }
+
+    CATerminateBLEGattClient();
+
+    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
+}
+
+void CATerminateBLEGattClient()
+{
+    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
+
+    gClientUp = CA_FALSE;
+    gIsOicDeviceFound = CA_FALSE;
+
+    u_cond_signal(gBleClientSendCondWait);
+
+    u_mutex_lock(gBleClientStateMutex);
+    // Required for waking up the thread which is running in gmain loop
+    GMainContext  *context_event_loop = g_main_loop_get_context(g_event_loop);
+
+    if (context_event_loop)
+    {
+        OIC_LOG_V(DEBUG,  TZ_BLE_CLIENT_TAG, "g_event_loop context %x", context_event_loop);
+        g_main_context_wakeup(context_event_loop);
+    }
+    else
+    {
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_event_loop context is NULL");
+    }
+
+    // Kill g main loops and kill threads
+    g_main_loop_quit(g_event_loop);
+
+    CABleGattUnWatchCharacteristicChanges();
+
+    CABleGattUnSetCallbacks();
+
+    CABleGattStopDeviceDiscovery();
+
+    CAClearNonOICDeviceList();
+
+    u_mutex_lock(gBleServiceListMutex);
+    CAFreeBLEServiceList(gBLEServiceList);
+    gBLEServiceList = NULL;
+    u_mutex_unlock(gBleServiceListMutex);
+
+    CAResetRegisteredServiceCount();
+
+    CATerminateBleQueues();
+
+    gIsBleGattClientStarted = CA_FALSE;
+    u_mutex_unlock(gBleClientStateMutex);
+
+    CATerminateGattClientMutexVariables();
+
+    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
+}
+
+
+CAResult_t CAInitGattClientMutexVaraibles()
+{
+    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
+    u_mutex_init();
+    if (NULL == gBleClientStateMutex)
+    {
+        gBleClientStateMutex = u_mutex_new();
+        if (NULL == gBleClientStateMutex)
+        {
+            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (!gReceiverDataCond)
+    {
+        gReceiverDataCond = u_cond_new();
+        if (NULL == gReceiverDataCond)
+        {
+            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_cond_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == gBleServiceListMutex)
+    {
+        gBleServiceListMutex = u_mutex_new();
+        if (NULL == gBleServiceListMutex)
+        {
+            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == gBleReqRespClientCbMutex)
+    {
+        gBleReqRespClientCbMutex = u_mutex_new();
+        if (NULL == gBleReqRespClientCbMutex)
+        {
+            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == gBleClientSendDataMutex)
+    {
+        gBleClientSendDataMutex = u_mutex_new();
+        if (NULL == gBleClientSendDataMutex)
+        {
+            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == gBleClientReceiveDataMutex)
+    {
+        gBleClientReceiveDataMutex = u_mutex_new();
+        if (NULL == gBleClientReceiveDataMutex)
+        {
+            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == gBleClientThreadPoolMutex)
+    {
+        gBleClientThreadPoolMutex = u_mutex_new();
+        if (NULL == gBleClientThreadPoolMutex)
+        {
+            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    if (NULL == gBleClientSendCondWait)
+    {
+        gBleClientSendCondWait = u_cond_new();
+        if (NULL == gBleClientSendCondWait)
+        {
+            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_cond_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
+    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CATerminateGattClientMutexVariables()
+{
+    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
+
+    u_mutex_free(gBleClientStateMutex);
+    gBleClientStateMutex = NULL;
+
+    u_mutex_free(gBleServiceListMutex);
+    gBleServiceListMutex = NULL;
+
+    u_mutex_free(gBleReqRespClientCbMutex);
+    gBleReqRespClientCbMutex = NULL;
+
+    u_mutex_free(gBleClientSendDataMutex);
+    gBleClientSendDataMutex = NULL;
+
+    u_mutex_free(gBleClientReceiveDataMutex);
+    gBleClientReceiveDataMutex = NULL;
+
+    u_mutex_free(gBleClientThreadPoolMutex);
+    gBleClientThreadPoolMutex = NULL;
+
+    u_cond_free(gBleClientSendCondWait);
+    gBleClientSendCondWait = NULL;
+
+    if (gReceiverDataCond)
+    {
+        u_cond_free(gReceiverDataCond);
+        gReceiverDataCond = NULL;
+    }
+
+    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
+}
+
+CAResult_t CAInitBleQueues()
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
     u_mutex_lock(gBleClientSendDataMutex);
-    CAResult_t retVal = CAAdapterEnqueueMessage(gCABleClientSenderQueue,
-                        remoteEndpoint, data, dataLen);
+    CAResult_t retVal = CAAdapterInitializeMessageQueue(&gCABleClientSenderQueue);
     if (CA_STATUS_OK != retVal )
     {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAAdapterEnqueueMessage failed!");
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAAdapterInitializeMessageQueue failed!");
         u_mutex_unlock(gBleClientSendDataMutex);
         return CA_STATUS_FAILED;
     }
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending signal for the sender processor ");
     u_mutex_unlock(gBleClientSendDataMutex);
-    u_cond_signal(gBleClientSendCondWait);
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
 
+    u_mutex_lock(gBleClientReceiveDataMutex);
+    retVal = CAAdapterInitializeMessageQueue(&gCABleClientReceiverQueue);
+    if (CA_STATUS_OK != retVal)
+    {
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAAdapterInitializeMessageQueue failed!");
+        u_mutex_unlock(gBleClientReceiveDataMutex);
+        return CA_STATUS_FAILED;
+    }
+    u_mutex_unlock(gBleClientReceiveDataMutex);
+
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-
-CAResult_t CALEReadDataFromLEClient()
+void CATerminateBleQueues()
 {
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
-
-    ///TODO: If CA layer request for the data, this function ll be implemented.
+    u_mutex_lock(gBleClientSendDataMutex);
+    if (NULL != gCABleClientSenderQueue)
+    {
+        CAAdapterTerminateMessageQueue(gCABleClientSenderQueue);
+        gCABleClientSenderQueue = NULL;
+    }
+    u_mutex_unlock(gBleClientSendDataMutex);
 
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
+    u_mutex_lock(gBleClientReceiveDataMutex);
+    if (NULL != gCABleClientReceiverQueue)
+    {
+        CAAdapterTerminateMessageQueue(gCABleClientReceiverQueue);
+        gCABleClientReceiverQueue = NULL;
+    }
+    u_mutex_unlock(gBleClientReceiveDataMutex);
 
-    return CA_STATUS_OK;
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
 }
 
-
-void *CAGattConnectThread (void *remoteAddress)
+void CAClearNonOICDeviceList()
 {
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    if (NULL == remoteAddress)
+    if (NULL != gNonOicDeviceList)
     {
-        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Param remoteAddress is NULL ");
-        return NULL;
+        uint32_t listLen = u_arraylist_length(gNonOicDeviceList);
+        int32_t index = 0;
+        for (index = 0; index < listLen; index++)
+        {
+            char *storedAddr = u_arraylist_remove(gNonOicDeviceList, index);
+            free(storedAddr);
+        }
+        u_arraylist_free(gNonOicDeviceList);
+        gNonOicDeviceList = NULL;
     }
 
-    char *address  = (char *)remoteAddress;
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+}
 
-    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address is [%s]", address);
+CAResult_t CABleGattSetScanParameter()
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    CAResult_t result = bt_gatt_connect(address, true);
+    bt_adapter_le_scan_params_s scan_param = { 0, };
+    scan_param.type = BT_ADAPTER_LE_PASSIVE_SCAN;
+    scan_param.interval = 1560;
+    scan_param.window = 160;
 
-    if (CA_STATUS_OK != result)
+    int32_t  ret = bt_adapter_le_set_scan_parameter(&scan_param);
+    if (BT_ERROR_NONE != ret)
     {
-        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect failed for [%s]", address);
-        return NULL;
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_set_scan_parameter Failed with ret [%d]", ret);
+        return CA_STATUS_FAILED;
     }
 
-    OICFree(address);
-    address = NULL;
-
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-    return NULL;
+    return CA_STATUS_OK;
 }
 
-void CAPrintDiscoveryInformation(bt_adapter_le_device_discovery_info_s *discoveryInfo)
+CAResult_t CABleGattSetCallbacks()
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    if (NULL == discoveryInfo)
+    int32_t ret = bt_gatt_set_connection_state_changed_cb(CABleGattConnectionStateChangedCb, NULL);
+    if (BT_ERROR_NONE != ret)
     {
-        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL ");
-        return;
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+                  "bt_gatt_set_connection_state_changed_cb Failed with return as [%s ]",
+                  CABTGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
     }
 
-    if (discoveryInfo->remote_address)
+    ret = bt_adapter_le_set_device_discovery_state_changed_cb(
+              CABtAdapterLeDeviceDiscoveryStateChangedCb, NULL);
+    if (BT_ERROR_NONE != ret)
     {
-        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Remote Address [%s]", discoveryInfo->remote_address);
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+                  "bt_adapter_le_set_device_discovery_state_changed_cb Failed with return as [%s ]",
+                  CABTGetErrorMsg(ret));;
+        return CA_STATUS_FAILED;
+    }
+
+    ret = bt_gatt_set_characteristic_changed_cb(CABleGattCharacteristicChangedCb, NULL);
+    if (BT_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_set_characteristic_changed_cb Failed as [%s ]",
+                  CABTGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Setting bt_device_set_bond_created_cb \n");
+
+    ret = bt_device_set_bond_created_cb(CABtGattBondCreatedCb, NULL);
+    if (BT_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, " bt_device_set_bond_created_cb Failed as [%s ]",
+                  CABTGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
     }
 
-    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
-              " Adv data len [%d] Scan data len[%d]RSSI [%d] Addr_type [%d] ",
-              discoveryInfo->adv_data_len, discoveryInfo->scan_data_len, discoveryInfo->rssi,
-              discoveryInfo->address_type);
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
-void CABtAdapterLeDeviceDiscoveryStateChangedCb(int32_t result,
-        bt_adapter_le_device_discovery_state_e discoveryState,
-        bt_adapter_le_device_discovery_info_s *discoveryInfo,
-        void *userData)
+void CABleGattUnSetCallbacks()
 {
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
+
+    bt_gatt_unset_characteristic_changed_cb();
+
+    bt_device_unset_bond_created_cb();
 
+    bt_gatt_unset_connection_state_changed_cb();
+
+    bt_adapter_le_unset_device_discovery_state_changed_cb();
+
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+}
+
+CAResult_t CABleGattWatchCharacteristicChanges(bt_gatt_attribute_h service)
+{
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    if (NULL  == discoveryInfo && BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND == discoveryState)
-    {
-        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "discoveryInfo is NULL");
-        return;
-    }
 
-    if (BT_ADAPTER_LE_DEVICE_DISCOVERY_FOUND != discoveryState)
-    {
-        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
-                  " LE Discovery state is [%s]",
-                  discoveryState == BT_ADAPTER_LE_DEVICE_DISCOVERY_STARTED ? "Started" : "Finished" );
-    }
-    else
+    int32_t ret = bt_gatt_watch_characteristic_changes(service);
+    if (BT_ERROR_NONE != ret)
     {
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+                  "bt_gatt_watch_characteristic_changes failed  with [%s] \n", CABTGetErrorMsg(ret));
 
-        CAPrintDiscoveryInformation(discoveryInfo);
-
-        VERIFY_NON_NULL_VOID(discoveryInfo->remote_address, TZ_BLE_CLIENT_TAG,
-                        "discoveryInfo->remote_address is NULL");
+        return CA_STATUS_FAILED;
+    }
 
-        int32_t len = strlen(discoveryInfo->remote_address);
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+    return CA_STATUS_OK;
+}
 
-        char *addr = (char *)OICMalloc(sizeof(char) * len + 1);
+void CABleGattUnWatchCharacteristicChanges()
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-        VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");
+    int32_t count = CAGetRegisteredServiceCount();
 
-        memset(addr, 0x0, len + 1);
-        strncpy(addr, discoveryInfo->remote_address, len);
+    int32_t index = 0;
 
-        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG,
-                  "Trying to do Gatt connection to [%s] ", addr);
+    for (index = 0; index < count; index++)
+    {
+        BLEServiceInfo *bleServiceInfo = NULL;
 
-        u_mutex_lock(gBleClientThreadPoolMutex);
-        if (NULL == gBleClientThreadPool)
-        {
-            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL");
-            OICFree(addr);
-            u_mutex_unlock(gBleClientThreadPoolMutex);
-            return;
-        }
+        u_mutex_lock(gBleServiceListMutex);
 
-        CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool, (void *) CAGattConnectThread,
-                                                (void *) addr);
-        if (CA_STATUS_OK != ret)
-        {
-            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", ret);
-            OICFree(addr);
-            u_mutex_unlock(gBleClientThreadPoolMutex);
-            return;
-        }
-        u_mutex_unlock(gBleClientThreadPoolMutex);
-        if (discoveryInfo->adv_data_len > 31 || discoveryInfo->scan_data_len > 31)
+        CAResult_t  result = CAGetBLEServiceInfoByPosition(gBLEServiceList, index, &bleServiceInfo);
+        if (CA_STATUS_OK == result && NULL != bleServiceInfo && NULL != bleServiceInfo->service_clone)
         {
-            bt_adapter_le_stop_device_discovery();
-            return;
+            bt_gatt_unwatch_characteristic_changes(bleServiceInfo->service_clone);
+            OIC_LOG(INFO, TZ_BLE_CLIENT_TAG, "bt_gatt_unwatch_characteristic_changes done");
         }
 
+        u_mutex_unlock(gBleServiceListMutex);
     }
+
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
 }
 
+CAResult_t CABleGattStartDeviceDiscovery()
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-void *CADiscoverBLEServicesThread (void *remoteAddress)
+    int32_t ret = bt_adapter_le_start_device_discovery();
+    if (BT_ERROR_NONE != ret)
+    {
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CABleGattStopDeviceDiscovery()
 {
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
+    bt_adapter_le_stop_device_discovery();
+
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+}
+
+void *CAGattConnectThread (void *remoteAddress)
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
+
     VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL", NULL);
 
     char *address  = (char *)remoteAddress;
 
-    CAResult_t result = CABleDiscoverServices(remoteAddress);
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address is [%s]", address);
 
-    OICFree(address);
-    address = NULL;
+    CAResult_t result = CABleGattConnect(address);
 
     if (CA_STATUS_OK != result)
     {
-        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CABleDiscoverServices Failed");
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect failed for [%s]", address);
+        OICFree(address);
+        address = NULL;
         return NULL;
     }
 
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
+    OICFree(address);
+    address = NULL;
+
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
     return NULL;
 }
 
-void CABleGattConnectionStateChangedCb(int32_t result, bool connected, const char *remoteAddress,
-                                       void *userData)
+CAResult_t CABleGattConnect(const char *remoteAddress)
 {
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
-
-    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "CABleGattConnectionStateChangedCb result[%d] ", result);
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    VERIFY_NON_NULL_VOID(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL");
+    VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL", CA_STATUS_FAILED);
 
-    if (!connected)
+    int32_t ret = bt_gatt_connect(remoteAddress, true);
 
+    if (BT_ERROR_NONE != ret)
     {
-        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "DisConnected from [%s] ", remoteAddress);
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_connect Failed with ret value [%s] ",
+                  CABTGetErrorMsg(ret));
+        return CA_STATUS_FAILED;
     }
-    else
-    {
-
-        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Connected to [%s] ", remoteAddress);
 
-        int32_t len = strlen(remoteAddress);
-
-        char *addr = (char *)OICMalloc(sizeof(char) * len + 1);
-
-        VERIFY_NON_NULL_VOID(addr, TZ_BLE_CLIENT_TAG, "Malloc failed");
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+    return CA_STATUS_OK;
+}
 
-        memset(addr, 0x0, len + 1);
+CAResult_t CABleGattDisConnect(const char *remoteAddress)
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-        strncpy(addr, remoteAddress, len);
+    VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL", CA_STATUS_FAILED);
 
-        u_mutex_lock(gBleClientThreadPoolMutex);
-        if (NULL == gBleClientThreadPool)
-        {
-            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleClientThreadPool is NULL");
-            OICFree(addr);
-            u_mutex_unlock(gBleClientThreadPoolMutex);
-            return;
-        }
+    int32_t ret = bt_gatt_disconnect(remoteAddress);
 
-        CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool, (void *) CADiscoverBLEServicesThread,
-                                                (void *) addr);
-        if (CA_STATUS_OK != ret)
-        {
-            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", ret);
-            OICFree(addr);
-            u_mutex_unlock(gBleClientThreadPoolMutex);
-            return;
-        }
-        u_mutex_unlock(gBleClientThreadPoolMutex);
+    if (BT_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_disconnect Failed with ret value [%d] ",
+                  ret);
+        return CA_STATUS_FAILED;
     }
 
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
-CAResult_t CABleGATTCreateBond(const char *remoteAddress)
+void *CADiscoverBLEServicesThread (void *remoteAddress)
 {
-
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
-                        "remote address is NULL", CA_STATUS_FAILED);
-
-    sleep(2);
+    VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG, "remote address is NULL", NULL);
 
-    int32_t ret = bt_device_create_bond(remoteAddress);
+    char *address  = (char *)remoteAddress;
 
-    if (BT_ERROR_NONE != ret)
-    {
-        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_device_create_bond Failed with ret value [%d] ", ret);
-        return CA_STATUS_FAILED;
-    }
-    else
+    CAResult_t result = CABleGattDiscoverServices(address);
+    if (CA_STATUS_OK != result)
     {
-        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
-                  " bt_device_create_bond query success for address [%s]", remoteAddress);
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CABleGattDiscoverServices failed");
+        OICFree(address);
+        address = NULL;
+        return NULL;
     }
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
 
-    return CA_STATUS_OK;
+    OICFree(address);
+    address = NULL;
 
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
+    return NULL;
 }
 
-CAResult_t CABleDiscoverServices(const char *remoteAddress)
+CAResult_t CABleGattDiscoverServices(const char *remoteAddress)
 {
-
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
     VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
                         "remote address is NULL", CA_STATUS_FAILED);
-    sleep(2);
 
     int32_t len = strlen(remoteAddress);
 
@@ -1158,14 +1655,40 @@ CAResult_t CABleDiscoverServices(const char *remoteAddress)
     }
 
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-
     return CA_STATUS_OK;
-
 }
 
-CAResult_t CABleDiscoverCharacteristics(bt_gatt_attribute_h service, const char *remoteAddress)
+void *CADiscoverCharThread(void *stServiceInfo)
 {
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
+
+    VERIFY_NON_NULL_RET(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL", NULL);
+
+    stGattServiceInfo_t *stTemp  = (stGattServiceInfo_t *)stServiceInfo;
+
+    VERIFY_NON_NULL_RET(stTemp->address, TZ_BLE_CLIENT_TAG, "stTemp->address is NULL", NULL);
+
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address [%s]", stTemp->address);
+
+    CAResult_t  result = CABleGattDiscoverCharacteristics(stTemp->serviceInfo, stTemp->address);
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CABleGattDiscoverCharacteristics failed!");
+        bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
+        OICFree(stTemp->address);
+        OICFree(stTemp);
+        return NULL;
+    }
+    bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
+    OICFree(stTemp->address);
+    OICFree(stTemp);
+
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+    return NULL;
+}
 
+CAResult_t CABleGattDiscoverCharacteristics(bt_gatt_attribute_h service, const char *remoteAddress)
+{
     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
     VERIFY_NON_NULL_RET(service, NULL, "service is NULL", CA_STATUS_FAILED);
@@ -1192,376 +1715,325 @@ CAResult_t CABleDiscoverCharacteristics(bt_gatt_attribute_h service, const char
     }
 
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-
-    return CA_STATUS_OK;
-
-}
-
-CAResult_t CAStartBLEGattClient()
-{
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
-
-    CAResult_t retVal = CAInitGattClientMutexVaraibles();
-
-    if (CA_STATUS_OK != retVal)
-    {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAInitGattClientMutexVaraibles failed!");
-        CATerminateGattClientMutexVariables();
-        return CA_STATUS_FAILED;
-    }
-
-    u_mutex_unlock(gBleClientThreadPoolMutex);
-    if (NULL == gBleClientThreadPool)
-    {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "gBleServerThreadPool is NULL");
-        u_mutex_unlock(gBleClientThreadPoolMutex);
-        return CA_STATUS_FAILED;
-    }
-
-    CAResult_t ret = u_thread_pool_add_task(gBleClientThreadPool, (void *) CAStartBleGattClientThread,
-                                            (void *) NULL);
-    if (CA_STATUS_OK != ret)
-    {
-        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "u_thread_pool_add_task failed with ret [%d]", ret);
-        u_mutex_unlock(gBleClientThreadPoolMutex);
-        return CA_STATUS_FAILED;
-    }
-    u_mutex_unlock(gBleClientThreadPoolMutex);
     return CA_STATUS_OK;
 }
 
-void *CAStartBleGattClientThread(void *data)
+void *CADiscoverDescriptorThread(void *stServiceInfo)
 {
-    u_mutex_lock(gBleClientStateMutex);
-
-    if (CA_TRUE  == gIsBleGattClientStarted)
-    {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is already running");
-        u_mutex_unlock(gBleClientStateMutex);
-        CATerminateBLEGattClient();
-        return NULL;
-    }
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, " IN");
 
-    bt_adapter_le_scan_params_s scan_param = { 0, };
-    scan_param.type = BT_ADAPTER_LE_PASSIVE_SCAN;
-    scan_param.interval = 1560;
-    scan_param.window = 160;
+    VERIFY_NON_NULL_RET(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL", NULL);
 
-    int32_t  ret = bt_adapter_le_set_scan_parameter(&scan_param);
-    if (BT_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_set_scan_parameter Failed");
-        u_mutex_unlock(gBleClientStateMutex);
-        CATerminateBLEGattClient();
-        return NULL;
-    }
+    stGattServiceInfo_t *stTemp  = (stGattServiceInfo_t *)stServiceInfo;
 
-    ret = bt_gatt_set_connection_state_changed_cb(CABleGattConnectionStateChangedCb, NULL);
-    if (BT_ERROR_NONE != ret)
+    CAResult_t result = CABleGattDiscoverDescriptor(stTemp->serviceInfo, NULL);
+    if (CA_STATUS_OK != result)
     {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG,
-                "bt_gatt_set_connection_state_changed_cb Failed");
-        u_mutex_unlock(gBleClientStateMutex);
-        CATerminateBLEGattClient();
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+                  "bt_gatt_discover_characteristic_descriptor failed");
+        bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
+        OICFree(stTemp->address);
+        OICFree(stTemp);
         return NULL;
     }
 
-    ret = bt_adapter_le_set_device_discovery_state_changed_cb(
-              CABtAdapterLeDeviceDiscoveryStateChangedCb, NULL);
-    if (BT_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG,
-                "bt_adapter_le_set_device_discovery_state_changed_cb Failed");
-        u_mutex_unlock(gBleClientStateMutex);
-        CATerminateBLEGattClient();
-        return NULL;
-    }
+    bt_gatt_destroy_attribute_handle(stTemp->serviceInfo);
+    OICFree(stTemp->address);
+    OICFree(stTemp);
 
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Setting characteristic_changed cb \n");
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+    return NULL;
+}
 
-    ret = bt_gatt_set_characteristic_changed_cb(CABleGattCharacteristicChangedCb, NULL);
-    if (BT_ERROR_NONE != ret)
-    {
-        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_gatt_set_characteristic_changed_cb Failed as [%s ]",
-                  CABTGetErrorMsg(ret));
-        u_mutex_unlock(gBleClientStateMutex);
-        CATerminateBLEGattClient();
-        return NULL;
-    }
+CAResult_t CABleGattDiscoverDescriptor(bt_gatt_attribute_h service, const char *remoteAddress)
+{
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Setting bt_device_set_bond_created_cb \n");
+    VERIFY_NON_NULL_RET(service, NULL, "service is NULL", CA_STATUS_FAILED);
 
-    ret = bt_device_set_bond_created_cb(CABtGattBondCreatedCb, NULL);
+    int32_t ret = bt_gatt_discover_characteristic_descriptor(service,
+                  CABleGattDescriptorDiscoveredCb, NULL);
     if (BT_ERROR_NONE != ret)
     {
-        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, " bt_device_set_bond_created_cb Failed as [%s ]",
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+                  "bt_gatt_discover_characteristic_descriptor failed with returns[%s] \n",
                   CABTGetErrorMsg(ret));
-        return NULL;
-    }
-
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Starting LE device discovery");
-
-    ret = bt_adapter_le_start_device_discovery();
-    if (BT_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "bt_adapter_le_start_device_discovery Failed");
-        u_mutex_unlock(gBleClientStateMutex);
-        CATerminateBLEGattClient();
-        return NULL;
-    }
-    else
-    {
-        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG,
-                "bt_adapter_le_start_device_discovery Success");
+        return CA_STATUS_FAILED;
     }
 
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+    return CA_STATUS_OK;
+}
 
-    u_mutex_unlock(gBleClientStateMutex);
+void *CASetCharacteristicDescriptorValueThread(void *stServiceInfo)
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    CAResult_t retVal = CAAdapterInitializeMessageQueue(&gCABleClientSenderQueue);
-    if (CA_STATUS_OK != retVal )
-    {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAAdapterInitializeMessageQueue failed!");
-        CATerminateBLEGattClient();
-        return NULL;
-    }
+    VERIFY_NON_NULL_RET(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL", NULL);
 
-    retVal = CAAdapterInitializeMessageQueue(&gCABleClientReceiverQueue);
-    if (CA_STATUS_OK != retVal)
+    stGattCharDescriptor_t *stTemp  = (stGattCharDescriptor_t *)stServiceInfo;
+
+    CAResult_t  result = CASetCharacteristicDescriptorValue(stTemp);
+    if (CA_STATUS_OK != result)
     {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAAdapterInitializeMessageQueue failed!");
-        CATerminateBLEGattClient();
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG , "CASetCharacteristicDescriptorValue failed!");
+        bt_gatt_destroy_attribute_handle(stTemp->characteristic);
+        OICFree(stTemp->desc);
+        OICFree(stTemp);
         return NULL;
     }
-    gIsBleGattClientStarted = CA_TRUE;
-    GMainContext *thread_context = NULL;
-
-    thread_context = g_main_context_new();
-
-    g_event_loop = g_main_loop_new(thread_context, FALSE);
-
-    g_main_context_push_thread_default(thread_context);
-
-    g_main_loop_run(g_event_loop);
+    bt_gatt_destroy_attribute_handle(stTemp->characteristic);
+    OICFree(stTemp->desc);
+    OICFree(stTemp);
 
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
     return NULL;
-
 }
 
-void CAStopBLEGattClient()
+CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattCharDescriptorInfo)
 {
-    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
-
-    u_mutex_lock(gBleClientStateMutex);
-
-    if (CA_FALSE == gIsBleGattClientStarted)
-    {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "Gatt Client is not running to stop");
-
-        u_mutex_unlock(gBleClientStateMutex);
-        return;
-    }
-    u_mutex_unlock(gBleClientStateMutex);
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    CATerminateBLEGattClient();
+    unsigned char noti[4] = {0,};
+    char *strUUID = NULL;
 
-    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
-}
+    strUUID =  (char *)OICMalloc(sizeof(char) * 5);
 
-void CATerminateBLEGattClient()
-{
-    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
+    VERIFY_NON_NULL_RET(strUUID, TZ_BLE_CLIENT_TAG, "malloc failed", CA_STATUS_FAILED);
 
-    u_mutex_lock(gBleClientStateMutex);
+    memset(strUUID, 0x0, sizeof(char) * 5);
+    snprintf(strUUID, 4, "%x%x", stGattCharDescriptorInfo->desc[3], stGattCharDescriptorInfo->desc[2]);
+    noti[0] = stGattCharDescriptorInfo->desc[0];
+    noti[1] = stGattCharDescriptorInfo->desc[1];
+    noti[2] = 0x01;
+    noti[3] = 0x00;
 
-    // Required for waking up the thread which is running in gmain loop
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x0  [%x]", stGattCharDescriptorInfo->desc[0]);
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x1 [%x]", stGattCharDescriptorInfo->desc[1]);
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x2 [%x]", stGattCharDescriptorInfo->desc[2]);
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "desc x3 [%x]", stGattCharDescriptorInfo->desc[3]);
 
-    GMainContext  *context_event_loop = g_main_loop_get_context(g_event_loop);
 
-    if (context_event_loop)
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG strUUID is [%s]",
+              strUUID);
+    //if (!strncmp(strUUID, BLE_UUID_DESCRIPTOR_CLIENT_CHAR_CONFIG, 2))
     {
+        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "setting notification/indication for descriptor");
 
-        OIC_LOG_V(DEBUG,  TZ_BLE_CLIENT_TAG, "g_event_loop context %x", context_event_loop);
-
-        g_main_context_wakeup(context_event_loop);
-
-    }
-    else
-    {
-        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "g_event_loop context is NULL");
+        int32_t ret =  bt_gatt_set_characteristic_desc_value_request(
+                           stGattCharDescriptorInfo->characteristic,
+                           noti,  4, CABleGattCharacteristicWriteCb);
+        if (BT_ERROR_NONE != ret)
+        {
+            OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+                      "bt_gatt_set_characteristic_desc_value_request failed with return[%s] \n",
+                      CABTGetErrorMsg(ret));
+            OICFree(strUUID);
+            return CA_STATUS_FAILED;
+        }
     }
+    OICFree(strUUID);
 
-    // Kill g main loops and kill threads
-    g_main_loop_quit(g_event_loop);
-
-    gClientUp = CA_FALSE;
-
-    bt_gatt_unset_connection_state_changed_cb();
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+    return CA_STATUS_OK;
+}
 
-    bt_adapter_le_stop_device_discovery();
+void *CAGATTCreateBondThread(void *stServiceInfo)
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    bt_gatt_unset_characteristic_changed_cb();
+    VERIFY_NON_NULL_RET(stServiceInfo, TZ_BLE_CLIENT_TAG, "stServiceInfo is NULL", NULL);
 
-    bt_adapter_le_unset_device_discovery_state_changed_cb();
+    stGattServiceInfo_t *stTemp  = (stGattServiceInfo_t *)stServiceInfo;
 
-    bt_gatt_unset_connection_state_changed_cb();
+    VERIFY_NON_NULL_RET(stTemp, TZ_BLE_CLIENT_TAG, "stTemp is NULL", NULL);
 
-    bt_adapter_le_disable();
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "remote address [%s]",
+              stTemp->address);
 
-    bt_device_unset_bond_created_cb();
-    bt_gatt_unset_characteristic_changed_cb();
+    CAResult_t  result = CABleGATTCreateBond(stTemp->address);
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG ,
+                  "CABleGattDiscoverCharacteristics failed!");
+        OICFree(stTemp->address);
+        OICFree(stTemp);
+        return NULL;
+    }
+    OICFree(stTemp->address);
+    OICFree(stTemp);
 
-    u_mutex_lock(gBleServiceListMutex);
-    CAFreeBLEServiceList(gBLEServiceList);
-    gBLEServiceList = NULL;
-    u_mutex_unlock(gBleServiceListMutex);
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+    return NULL;
+}
 
-    gIsBleGattClientStarted = CA_FALSE;
+CAResult_t CABleGATTCreateBond(const char *remoteAddress)
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
-    u_mutex_unlock(gBleClientStateMutex);
+    VERIFY_NON_NULL_RET(remoteAddress, TZ_BLE_CLIENT_TAG,
+                        "remote address is NULL", CA_STATUS_FAILED);
 
-    CAResetRegisteredServiceCount();
+    int32_t ret = bt_device_create_bond(remoteAddress);
 
-    u_mutex_lock(gBleClientSendDataMutex);
-    if (NULL != gCABleClientSenderQueue)
+    if (BT_ERROR_NONE != ret)
     {
-        CAAdapterTerminateMessageQueue(gCABleClientSenderQueue);
-        gCABleClientSenderQueue = NULL;
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "bt_device_create_bond Failed with ret value [%d] ", ret);
+        return CA_STATUS_FAILED;
     }
-    u_mutex_unlock(gBleClientSendDataMutex);
-
-    u_mutex_lock(gBleClientReceiveDataMutex);
-    if (NULL != gCABleClientReceiverQueue)
+    else
     {
-        CAAdapterTerminateMessageQueue(gCABleClientReceiverQueue);
-        gCABleClientReceiverQueue = NULL;
-
+        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+                  " bt_device_create_bond query success for address [%s]", remoteAddress);
     }
-    u_mutex_unlock(gBleClientReceiveDataMutex);
-
-    CATerminateGattClientMutexVariables();
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
 
-    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
-CAResult_t CAInitGattClientMutexVaraibles()
+CAResult_t CABleClientSenderQueueEnqueueMessage(const CARemoteEndpoint_t *remoteEndpoint,
+        void *data,
+        uint32_t dataLen)
 {
-    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
-    u_mutex_init();
-    if (NULL == gBleClientStateMutex)
-    {
-        gBleClientStateMutex = u_mutex_new();
-        if (NULL == gBleClientStateMutex)
-        {
-            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
-            return CA_STATUS_FAILED;
-        }
-    }
-
-    if (NULL == gBleServiceListMutex)
-    {
-        gBleServiceListMutex = u_mutex_new();
-        if (NULL == gBleServiceListMutex)
-        {
-            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
-            return CA_STATUS_FAILED;
-        }
-    }
-
-    if (NULL == gBleReqRespClientCbMutex)
-    {
-        gBleReqRespClientCbMutex = u_mutex_new();
-        if (NULL == gBleReqRespClientCbMutex)
-        {
-            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
-            return CA_STATUS_FAILED;
-        }
-    }
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
 
-    if (NULL == gBleClientSendDataMutex)
-    {
-        gBleClientSendDataMutex = u_mutex_new();
-        if (NULL == gBleClientSendDataMutex)
-        {
-            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
-            return CA_STATUS_FAILED;
-        }
-    }
+    VERIFY_NON_NULL(data, NULL, "Param data is NULL");
 
-    if (NULL == gBleClientReceiveDataMutex)
-    {
-        gBleClientReceiveDataMutex = u_mutex_new();
-        if (NULL == gBleClientReceiveDataMutex)
-        {
-            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
-            return CA_STATUS_FAILED;
-        }
-    }
+    VERIFY_NON_NULL_RET(gCABleClientSenderQueue, TZ_BLE_CLIENT_TAG,
+                        "BleClientReceiverQueue is  NULL",
+                        CA_STATUS_FAILED);
+    VERIFY_NON_NULL_RET(gBleClientSendDataMutex, TZ_BLE_CLIENT_TAG,
+                        "BleClientSendDataMutex is NULL",
+                        CA_STATUS_FAILED);
+    VERIFY_NON_NULL_RET(gBleClientSendCondWait, TZ_BLE_CLIENT_TAG,
+                        "BleClientSendCondWait is NULL",
+                        CA_STATUS_FAILED);
 
-    if (NULL == gBleClientThreadPoolMutex)
+    u_mutex_lock(gBleClientSendDataMutex);
+    CAResult_t retVal = CAAdapterEnqueueMessage(gCABleClientSenderQueue,
+                        remoteEndpoint, data, dataLen);
+    if (CA_STATUS_OK != retVal )
     {
-        gBleClientThreadPoolMutex = u_mutex_new();
-        if (NULL == gBleClientThreadPoolMutex)
-        {
-            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_mutex_new failed");
-            return CA_STATUS_FAILED;
-        }
+        OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "CAAdapterEnqueueMessage failed!");
+        u_mutex_unlock(gBleClientSendDataMutex);
+        return CA_STATUS_FAILED;
     }
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending signal for the sender processor ");
+    u_mutex_unlock(gBleClientSendDataMutex);
+    u_cond_signal(gBleClientSendCondWait);
 
-    if (NULL == gBleClientSendCondWait)
-    {
-        gBleClientSendCondWait = u_cond_new();
-        if (NULL == gBleClientSendCondWait)
-        {
-            OIC_LOG(ERROR, TZ_BLE_CLIENT_TAG, "u_cond_new failed");
-            return CA_STATUS_FAILED;
-        }
-    }
-    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
     return CA_STATUS_OK;
 }
 
-void CATerminateGattClientMutexVariables()
+void *CABleClientSenderQueueProcessor()
 {
-    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
-    u_mutex_free(gBleClientReceiveDataMutex);
-    gBleClientReceiveDataMutex = NULL;
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
 
-    u_mutex_free(gBleClientStateMutex);
-    gBleClientStateMutex = NULL;
+    while (gClientUp)
+    {
+        CAAdapterMessage_t *message = NULL;
+        const char *remoteAddress = NULL;
+        const char *serviceUUID = NULL;
+        uint32_t sentLength = 0;
+        int32_t headerAdded = 0;
 
-    u_mutex_free(gBleServiceListMutex);
-    gBleServiceListMutex = NULL;
 
-    u_mutex_free(gBleReqRespClientCbMutex);
-    gBleReqRespClientCbMutex = NULL;
+        OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, " Waiting for the data ... ");
 
-    u_mutex_free(gBleClientSendDataMutex);
-    gBleClientSendDataMutex = NULL;
+        u_mutex_lock(gBleClientSendDataMutex);
+        u_cond_wait(gBleClientSendCondWait, gBleClientSendDataMutex);
 
-    u_mutex_free(gBleClientThreadPoolMutex);
-    gBleClientThreadPoolMutex = NULL;
+        OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Data got pushed to the queue...");
 
-    u_mutex_free(gBleClientSendCondWait);
-    gBleClientSendCondWait = NULL;
+        CAResult_t result = CA_STATUS_FAILED;
 
-    OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "OUT");
-}
+        while (CA_STATUS_OK == CAAdapterDequeueMessage(gCABleClientSenderQueue,
+                &message))
+        {
+            if (NULL == message)
+            {
+                OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "senderData is NULL");
+                continue;
+            }
+            char *dataSegment = NULL;
+            uint32_t offset = 0, ret = 1;
+            int datalen = message->dataLen;
+            while ( 1)
+            {
+                OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "fragmenting the data DataLen [%d] Offset [%d]", datalen,
+                          offset);
+                ret = CAFragmentData(message->data, &dataSegment, datalen, offset);
+                sleep(1);
+                if (0 == ret)
+                {
+                    break;
+                }
+                if (NULL != message->remoteEndpoint)
+                {
+                    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending Unicast data");
+                    const char *bdAddress = message->remoteEndpoint->addressInfo.LE.leMacAddress;
+
+                    VERIFY_NON_NULL_RET(bdAddress, TZ_BLE_CLIENT_TAG, "bdAddress is NULL", NULL);
+
+                    result = CAUpdateCharacteristicsToGattServer(bdAddress, dataSegment,
+                             ret,
+                             UNICAST, 0);
+                    if (CA_STATUS_OK != result)
+                    {
+                        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+                                  "Failed to UpdateCharacteristicsToGattServer [%s]", bdAddress);
+                    }
+                }
+                else
+                {
+                    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "Sending Multicast data");
+                    result = CAUpdateCharacteristicsToAllGattServers(dataSegment, ret);
+                    if (CA_STATUS_OK != result)
+                    {
+                        OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
+                                  "Failed to UpdateCharacteristicsToAllGattServers !");
+                    }
+                }
+                OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "freeing dataSegment");
 
-void CASetBleClientThreadPoolHandle(u_thread_pool_t handle)
-{
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
-    u_mutex_unlock(gBleClientThreadPoolMutex);
-    gBleClientThreadPool = handle;
-    u_mutex_unlock(gBleClientThreadPoolMutex);
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+                OICFree(dataSegment);
+                dataSegment = NULL;
+                offset += ret;
+                if (headerAdded == 0)
+                {
+                    datalen -= offset - CA_HEADER_LENGTH;
+                    offset = offset - CA_HEADER_LENGTH;
+                    headerAdded = 1;
+                }
+                else
+                {
+                    datalen -= ret;
+                }
+
+                if (datalen < 0)
+                {
+                    datalen += ret ;
+                }
+                if (datalen == message->dataLen)
+                {
+                    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "All data has been fragmented and sent");
+                    break;
+                }
+            }
+
+            CAAdapterFreeMessage(message);
+        }
+        u_mutex_unlock(gBleClientSendDataMutex);
+    }
+
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
+    return NULL;
 }
 
 CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char  *data,
         int32_t dataLen, TRANSFER_TYPE type, int32_t position)
 {
-
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
 
     VERIFY_NON_NULL(data, NULL, "data is NULL");
@@ -1586,6 +2058,7 @@ CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const
     {
         ret = CAGetBLEServiceInfoByPosition(gBLEServiceList, position, &bleServiceInfo);
     }
+
     if (CA_STATUS_OK != ret)
     {
         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG, "CAGetBLEServiceInfoByPosition is failed");
@@ -1599,35 +2072,37 @@ CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const
     OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating the data of length [%d] to [%s] ", dataLen,
               bleServiceInfo->bdAddress);
 
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating to write char [%s]",
+              bleServiceInfo->read_char);
+
     unsigned char *value = (unsigned char *) OICMalloc(sizeof(char) * (dataLen + 1));
     VERIFY_NON_NULL_RET(value, TZ_BLE_CLIENT_TAG, "malloc failed", CA_STATUS_FAILED);
 
     memset(value, 0x0, (dataLen + 1));
     strncpy(value, data, dataLen);
 
-    int32_t result = bt_gatt_set_characteristic_value_request(bleServiceInfo->write_char, value,
+    OIC_LOG_V(DEBUG, TZ_BLE_CLIENT_TAG, "Updating the data of length [%d] to [%s] ", dataLen,
+              bleServiceInfo->bdAddress);
+
+    int32_t result = bt_gatt_set_characteristic_value_request(bleServiceInfo->read_char, value,
                      dataLen,
                      CABleGattCharacteristicWriteCb);
-
-    OICFree(value);
-
     if (BT_ERROR_NONE != result)
     {
         OIC_LOG_V(ERROR, TZ_BLE_CLIENT_TAG,
                   "bt_gatt_set_characteristic_value_request Failed with return val [%d]",
                   result);
+        OICFree(value);
         return CA_STATUS_FAILED;
     }
+    OICFree(value);
 
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
-
     return CA_STATUS_OK;
 }
 
-
 CAResult_t  CAUpdateCharacteristicsToAllGattServers(const char  *data, int32_t dataLen)
 {
-
     OIC_LOG(DEBUG,  TZ_BLE_CLIENT_TAG, "IN");
 
     VERIFY_NON_NULL(data, NULL, "data is NULL");
@@ -1657,19 +2132,16 @@ CAResult_t  CAUpdateCharacteristicsToAllGattServers(const char  *data, int32_t d
     }
 
     OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
-
     return CA_STATUS_OK;
 }
-void CASetBLEReqRespClientCallback(CANetworkPacketReceivedCallback callback)
-{
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN");
-
-    u_mutex_lock(gBleReqRespClientCbMutex);
 
-    gNetworkPacketReceivedClientCallback = callback;
+CAResult_t CALEReadDataFromLEClient()
+{
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "IN ");
 
-    u_mutex_unlock(gBleReqRespClientCbMutex);
+    ///TODO: If CA layer request for the data, this function ll be implemented.
 
-    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT");
+    OIC_LOG(DEBUG, TZ_BLE_CLIENT_TAG, "OUT ");
+    return CA_STATUS_OK;
 }
 
index c491c3a..213dcda 100644 (file)
 #include "uthreadpool.h"
 
 
+
+/**
+* @fn  CABleGattCharacteristicChangedCb
+* @brief  This is the callback which will be called after the characteristic value changes happen.
+*
+* @param[in]  characteristic  The attribute handle of characteristic
+* @param[in]  value  Value of the characteristics of a service.
+* @param[in]  valueLen  length of data.
+* @param[in]  userData  The user data passed from the request function
+*
+* @return  0 on failure and 1 on success.
+*
+*/
+void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic, unsigned char *value,
+                                      int32_t valueLen, void *userData);
+/**
+* @fn  CABleGattCharacteristicWriteCb
+* @brief  This is the callback which will be called after the characteristics changed.
+*
+* @param[in]  handle  The attribute handle of characteristic
+*
+* @return  void
+*
+*/
+void CABleGattCharacteristicWriteCb(bt_gatt_attribute_h handle);
+
+/**
+* @fn  CABleGattDescriptorDiscoveredCb
+* @brief  This is the callback which will be called when descriptor of characteristics is found.
+*
+* @param[in]  result  The result of discovering
+* @param[in]  format  format of descriptor.
+* @param[in]  total  The total number of descriptor in a characteristic
+* @param[in]  descriptor  The attribute handle of descriptor
+* @param[in]  characteristic  The attribute handle of characteristic
+* @param[in]  userData  The user data passed from the request function
+*
+* @return  void
+*
+*/
+void CABleGattDescriptorDiscoveredCb(int32_t result, unsigned char format, int32_t total,
+                                     bt_gatt_attribute_h descriptor, bt_gatt_attribute_h characteristic, void *userData);
+
+/**
+* @fn  CABleGattCharacteristicsDiscoveredCb
+* @brief  This is the callback which will be called after the characteristics are discovered by bt_gatt_discover_characteristics()
+*
+* @param[in]  result  The result of discovering
+* @param[in]  inputIndex  The index of characteristics in a service, starts from 0
+* @param[in]  total  The total number of characteristics in a service
+* @param[in]  characteristic  The attribute handle of characteristic
+* @param[in]  userData  The user data passed from the request function
+*
+* @return  0 on failure and 1 on success.
+*
+*/
+CABool_t CABleGattCharacteristicsDiscoveredCb(int32_t result, int32_t inputIndex, int32_t total,
+        bt_gatt_attribute_h characteristic, void *userData);
+
+/**
+* @fn  CABtGattBondCreatedCb
+* @brief  This is the callback which will be called when bond created with remote device.
+*
+* @param[in]  result  The result of bond creation.
+* @param[in]  device_info  remote device information
+* @param[in]  userData  The user data passed from the request function
+*
+* @return  void
+*
+*/
+void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void *user_data);
+
+/**
+* @fn  CABleGattPrimaryServiceCb
+* @brief  This is the callback which will be called when we get the primary services repeatedly.
+*
+* @param[in] service -The attribute handle of service. Unique identifier for service.
+* @param[in] index -The current index of the service
+* @param[in] count -Total number of services available in remote device
+* @param[in] userData - user data
+*
+* @return  0 on failure and 1 on success.
+*
+*/
+CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, int32_t index, int32_t count,
+                                   void *userData);
+
+/**
+* @fn  CABleGattConnectionStateChangedCb
+* @brief  This is the callback which will be called whenever there is change in gatt connection with server(Connected/Disconnected)
+*
+* @param[in]  result  The result of discovering
+* @param[in]  connected  State of connection
+* @param[in]  remoteAddress  Mac address of the remote device in which we made connection.
+* @param[in]  userData  The user data passed from the request function
+*
+* @return  void
+*
+*/
+void CABleGattConnectionStateChangedCb(int32_t result, bool connected, const char *remoteAddress,
+                                       void *userData);
+
+/**
+* @fn  CABtAdapterLeDeviceDiscoveryStateChangedCb
+* @brief  This is the callback which will be called when the device discovery state changes.
+*
+* @param[in]  result  The result of discovering
+* @param[in]  discoveryState  State of the discovery(FOUND/STARTED/ FINISHED)
+* @param[in]  discoveryInfo  Remote Device information.
+* @param[in]  userData  The user data passed from the request function
+*
+* @return  void
+*
+*/
+void CABtAdapterLeDeviceDiscoveryStateChangedCb(int32_t result,
+        bt_adapter_le_device_discovery_state_e discoveryState,
+        bt_adapter_le_device_discovery_info_s *discoveryInfo,
+        void *userData);
+
+/**
+* @fn  CAPrintDiscoveryInformation
+* @brief  Used to print device information(Util method)
+*
+* @param[in]  discoveryInfo  Device information structure.
+*
+* @return  void
+*
+*/
+void CAPrintDiscoveryInformation(bt_adapter_le_device_discovery_info_s *discoveryInfo);
+
+/**
+* @fn  CASetBleClientThreadPoolHandle
+* @brief  Used to Set the gThreadPool handle which is required for spawning new thread.
+*
+* @param[in] handle - Thread pool handle which is given by above layer for using thread creation task.
+*
+* @return  void
+*
+*/
+void CASetBleClientThreadPoolHandle(u_thread_pool_t handle);
+
+/**
+ * @fn  CASetBLEReqRespClientCallback
+ * @brief  used to store upper layer callback locally which will be used to send the data to application
+ *
+ * @param[in]  CANetworkPacketReceivedCallback  -  upper layer callback function to pass the data to CA layer.
+ *
+ * @return  void
+ *
+ */
+void CASetBLEReqRespClientCallback(CANetworkPacketReceivedCallback callback);
+
 /**
 * @fn  CAStartBLEGattClient
 * @brief  Used to start CAStartBleGattClientThread for initializing Gatt Client
@@ -100,22 +252,35 @@ CAResult_t CAInitGattClientMutexVaraibles();
 void CATerminateGattClientMutexVariables();
 
 /**
-* @fn  CASetBleClientThreadPoolHandle
-* @brief  Used to Set the gThreadPool handle which is required for spawning new thread.
-*
-* @param[in] handle - Thread pool handle which is given by above layer for using thread creation task.
+* @fn  CAInitBleQueues
+* @brief  Used to initiate sender and receiver queues which will be used for data processing.
 *
 * @return  void
 *
 */
-void CASetBleClientThreadPoolHandle(u_thread_pool_t handle);
+CAResult_t CAInitBleQueues();
 
+/**
+* @fn  CATerminateBleQueues
+* @brief  Used to terminate sender and receiver queues which will be used for data processing.
+*
+* @return  void
+*
+*/
+void CATerminateBleQueues();
 
 /**
-* @fn  CABleGATTCreateBond
-* @brief  Used to make LE bond with remote device(pairng the device) using bt_device_create_bond api.
+* @fn  CAClearNonOICDeviceList
+* @brief  Used to clear NonOICDeviceList
 *
-* @param[in] remoteAddress - mac address of remote device which we want to bond with
+* @return  void
+*
+*/
+void CAClearNonOICDeviceList();
+
+/**
+* @fn  CABleGattSetScanParameter
+* @brief  Used to set scan parameter of starting discovery.
 *
 * @return  0 on success otherwise a positive error value.
 * @retval  CA_STATUS_OK  Successful
@@ -123,14 +288,11 @@ void CASetBleClientThreadPoolHandle(u_thread_pool_t handle);
 * @retval  CA_STATUS_FAILED Operation failed
 *
 */
-CAResult_t CABleGATTCreateBond(const char *remoteAddress);
-
+CAResult_t CABleGattSetScanParameter();
 
 /**
-* @fn  CABleDiscoverServices
-* @brief  Used to discover the services that is advertised by Gatt Server asynchrounously.
-*
-* @param[in] remoteAddress - mac address of remote device inwhich we want to discover the services.
+* @fn  CABleGattSetCallbacks
+* @brief  Used to register required callbacks to BLE platform(connection, discovery, bond and etc).
 *
 * @return  0 on success otherwise a positive error value.
 * @retval  CA_STATUS_OK  Successful
@@ -138,14 +300,22 @@ CAResult_t CABleGATTCreateBond(const char *remoteAddress);
 * @retval  CA_STATUS_FAILED Operation failed
 *
 */
-CAResult_t CABleDiscoverServices(const char *remoteAddress);
+CAResult_t CABleGattSetCallbacks();
 
 /**
-* @fn  CABleDiscoverCharacteristics
-* @brief  Used to discover the characteristics in specific service in remote device.
+* @fn  CABleGattUnSetCallbacks
+* @brief  Used to unset all the registerd callbacks to BLE platform
 *
-* @param[in] service -The attribute handle of service. Unique identifier for service.
-* @param[in] remoteAddress - mac address of remote device inwhich we want to discover the services.
+* @return  void
+*
+*/
+void CABleGattUnSetCallbacks();
+
+/**
+* @fn  CABleGattWatchCharacteristicChanges
+* @brief  Used to watch all the changes happening in characteristics of the service.
+*
+* @param[in] service -  The attribute handle of the service.
 *
 * @return  0 on success otherwise a positive error value.
 * @retval  CA_STATUS_OK  Successful
@@ -153,11 +323,20 @@ CAResult_t CABleDiscoverServices(const char *remoteAddress);
 * @retval  CA_STATUS_FAILED Operation failed
 *
 */
-CAResult_t CABleDiscoverCharacteristics(bt_gatt_attribute_h service, const char *remoteAddress);
+CAResult_t CABleGattWatchCharacteristicChanges(bt_gatt_attribute_h service);
+
+/**
+* @fn  CABleGattUnWatchCharacteristicChanges
+* @brief  Used to unwatch characteristics changes using bt_gatt_unwatch_characteristic_changes
+*
+* @return  void
+*
+*/
+void CABleGattUnWatchCharacteristicChanges();
 
 /**
-* @fn  CARegisterForChangeInCharacterstics
-* @brief  Used to register a callback function that will be invoked when a characteristic value is changed.
+* @fn  CABleGattStartDeviceDiscovery
+* @brief  Used to start LE discovery for BLE  devices
 *
 * @return  0 on success otherwise a positive error value.
 * @retval  CA_STATUS_OK  Successful
@@ -165,83 +344,47 @@ CAResult_t CABleDiscoverCharacteristics(bt_gatt_attribute_h service, const char
 * @retval  CA_STATUS_FAILED Operation failed
 *
 */
-CAResult_t CARegisterForChangeInCharacterstics();
+CAResult_t CABleGattStartDeviceDiscovery();
 
 /**
-* @fn  CABleGattPrimaryServiceCb
-* @brief  This is the callback which will be called when we get the primary services repeatedly.
+* @fn  CABleGattStopDeviceDiscovery
+* @brief  Used to stop LE discovery for BLE  devices
 *
-* @param[in] service -The attribute handle of service. Unique identifier for service.
-* @param[in] userData - user data
-*
-* @return  0 on failure and 1 on success.
+* @return  void
 *
 */
-CABool_t CABleGattPrimaryServiceCb(bt_gatt_attribute_h service, void *userData);
+void CABleGattStopDeviceDiscovery();
 
 /**
-* @fn  CABtGattCharacteristicsDiscoveredCb
-* @brief  This is the callback which will be called after the characteristics are discovered by bt_gatt_discover_characteristics()
+* @fn  CAGattConnectThread
+* @brief  This is the thread  which will be used for making gatt connection with remote devices
 *
-* @param[in]  result  The result of discovering
-* @param[in]  inputIndex  The index of characteristics in a service, starts from 0
-* @param[in]  total  The total number of characteristics in a service
-* @param[in]  characteristic  The attribute handle of characteristic
-* @param[in]  userData  The user data passed from the request function
+* @param[in]  remoteAddress  Mac address of remote device which wants to connect with.
 *
-* @return  0 on failure and 1 on success.
+* @return  NULL on success or failure.
 *
 */
-int32_t  CABtGattCharacteristicsDiscoveredCb(int32_t result, int32_t inputIndex, int32_t total,
-        bt_gatt_attribute_h characteristic, void *userData);
-
+void *CAGattConnectThread (void *remoteAddress);
 
 /**
-* @fn  CAUpdateCharacteristicsToGattServer
-* @brief  Sets the value of characteristic and update the value to GATTServer(unicast).
+* @fn  CABleGattConnect
+* @brief  Used to do connection with remote device
 *
-* @param[in]  remoteAddress  The address of the remote device
-* @param[in]  data  The value of characteristic (byte array)
-* @param[in]  dataLen  The length of value
-* @param[in]  TRANSFER_TYPE (UNICAST/MULTICAST)
-* @param[in]  position  The unique index of each ble server. Used for multicast feature.
+* @param[in] remoteAddress -  Remote address inwhich we wants to connect with
 *
 * @return  0 on success otherwise a positive error value.
 * @retval  CA_STATUS_OK  Successful
 * @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
 * @retval  CA_STATUS_FAILED Operation failed
+*
 */
-CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char  *data,
-        int32_t dataLen, TRANSFER_TYPE type, int32_t position);
-
-/**
- * @fn  CAUpdateCharacteristicsToGattServer
- * @brief  Sets the value of characteristic and update the value to All registered GATTServer -> Multicast
- *
- * @param[in]  data  The value of characteristic (byte array)
- * @param[in]  dataLen  The length of value
- *
- * @return  0 on success otherwise a positive error value.
- * @retval  CA_STATUS_OK  Successful
- * @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
- * @retval  CA_STATUS_FAILED Operation failed
- */
-CAResult_t  CAUpdateCharacteristicsToAllGattServers(const char  *data, int32_t dataLen);
-
-/**
- * @fn  CASetBLEReqRespClientCallback
- * @brief  used to store upper layer callback locally which will be used to send the data to application
- *
- * @param[in]  CANetworkPacketReceivedCallback  -  upper layer callback function to pass the data to CA layer.
- *
- * @return  void
- *
- */
-void CASetBLEReqRespClientCallback(CANetworkPacketReceivedCallback callback);
+CAResult_t CABleGattConnect(const char *remoteAddress);
 
 /**
-* @fn  CALEReadDataFromLEClient
-* @brief  synchronous function for reading characteristic value.
+* @fn  CABleGattDisConnect
+* @brief  Used to do disconnection with remote device
+*
+* @param[in] remoteAddress -  Remote address inwhich we wants to disconnect with
 *
 * @return  0 on success otherwise a positive error value.
 * @retval  CA_STATUS_OK  Successful
@@ -249,61 +392,59 @@ void CASetBLEReqRespClientCallback(CANetworkPacketReceivedCallback callback);
 * @retval  CA_STATUS_FAILED Operation failed
 *
 */
-CAResult_t CALEReadDataFromLEClient();
+CAResult_t CABleGattDisConnect(const char *remoteAddress);
 
 /**
-* @fn  CABleClientSenderQueueEnqueueMessage
-* @brief  Used to enqueue the message into sender queue using CAAdapterEnqueueMessage and make signal to the thread to process.
+* @fn  CADiscoverBLEServicesThread
+* @brief  This is thread which will be spawned for discovering ble services. Once called discover api, then it will be terminated.
 *
-* @param[in]  remoteEndpoint  Remote device information
-* @param[in]  data  data which we wants to send to remote device
-* @param[in]  dataLen  Length of data.
+* @param[in]  remoteAddress  Mac address of the remote device in which we want to search services.
 *
-* @return  0 on success otherwise a positive error value.
-* @retval  CA_STATUS_OK  Successful
-* @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
-* @retval  CA_STATUS_FAILED Operation failed
+* @return  NULL for success or failure.
 *
 */
-CAResult_t CABleClientSenderQueueEnqueueMessage(const CARemoteEndpoint_t *remoteEndpoint,
-        void *data, uint32_t dataLen);
+void *CADiscoverBLEServicesThread (void *remoteAddress);
 
 /**
-* @fn  CABleGattCharacteristicWriteCb
-* @brief  This is the callback which will be called after the characteristics changed.
+* @fn  CABleGattDiscoverServices
+* @brief  Used to discover the services that is advertised by Gatt Server asynchrounously.
 *
-* @param[in]  handle  The attribute handle of characteristic
+* @param[in] remoteAddress - mac address of remote device inwhich we want to discover the services.
 *
-* @return  void
+* @return  0 on success otherwise a positive error value.
+* @retval  CA_STATUS_OK  Successful
+* @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
+* @retval  CA_STATUS_FAILED Operation failed
 *
 */
-void CABleGattCharacteristicWriteCb(int result, void *user_data);
+CAResult_t CABleGattDiscoverServices(const char *remoteAddress);
 
 /**
-* @fn  CABleClientSenderQueueProcessor
-* @brief  This is the thread which will be used for processing sender queue.
+* @fn  CADiscoverCharThread
+* @brief  This is the thread which will be used for finding characteristic of a service.
+*
+* @param[in]  stServiceInfo  Service Information which contains the remote address and service handle, characteristic handle.
 *
 * @return  NULL on success or failure.
 *
 */
-void *CABleClientSenderQueueProcessor();
+void *CADiscoverCharThread(void *stServiceInfo);
 
 /**
-* @fn  CABleGattDescriptorDiscoveredCb
-* @brief  This is the callback which will be called when descriptor of characteristics is found.
+* @fn  CABleGattDiscoverCharacteristics
+* @brief  Used to discover characteristics of service using  bt_gatt_discover_characteristics api.
 *
-* @param[in]  result  The result of discovering
-* @param[in]  format  format of descriptor.
-* @param[in]  total  The total number of descriptor in a characteristic
-* @param[in]  descriptor  The attribute handle of descriptor
-* @param[in]  characteristic  The attribute handle of characteristic
-* @param[in]  userData  The user data passed from the request function
+* @param[in] service -  The attribute handle for service.
+* @param[in] remoteAddress -  Remote address inwhich we wants to discover characteristics of given service handle.
 *
-* @return  void
+* @return  0 on success otherwise a positive error value.
+* @retval  CA_STATUS_OK  Successful
+* @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
+* @retval  CA_STATUS_FAILED Operation failed
 *
 */
-void CABleGattDescriptorDiscoveredCb(int32_t result, unsigned char format, int32_t total,
-                                     bt_gatt_attribute_h descriptor, bt_gatt_attribute_h characteristic, void *userData);
+CAResult_t CABleGattDiscoverCharacteristics(bt_gatt_attribute_h service, const char *remoteAddress);
+
 /**
 * @fn  CADiscoverDescriptorThread
 * @brief  This is the thread which will be used for finding descriptor of characteristic.
@@ -316,28 +457,44 @@ void CABleGattDescriptorDiscoveredCb(int32_t result, unsigned char format, int32
 void *CADiscoverDescriptorThread(void *stServiceInfo);
 
 /**
-* @fn  CADiscoverCharThread
-* @brief  This is the thread which will be used for finding characteristic of a service.
+* @fn  CABleGattDiscoverDescriptor
+* @brief  This is thread which will be used for calling CASetCharacteristicDescriptorValue api.
 *
-* @param[in]  stServiceInfo  Service Information which contains the remote address and service handle, characteristic handle.
+* @param[in] service -  The attribute handle for characteristics.
+* @param[in] remoteAddress -  Remote address inwhich we wants to discover descriptor of given char handle.
 *
-* @return  NULL on success or failure.
+* @return  0 on success otherwise a positive error value.
+* @retval  CA_STATUS_OK  Successful
+* @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
+* @retval  CA_STATUS_FAILED Operation failed
 *
 */
-void *CADiscoverCharThread(void *stServiceInfo);
+CAResult_t CABleGattDiscoverDescriptor(bt_gatt_attribute_h service, const char *remoteAddress);
 
 /**
-* @fn  CABtGattBondCreatedCb
-* @brief  This is the callback which will be called when bond created with remote device.
+* @fn  CASetCharacteristicDescriptorValueThread
+* @brief  This is thread which will be used for calling CASetCharacteristicDescriptorValue api.
 *
-* @param[in]  result  The result of bond creation.
-* @param[in]  device_info  remote device information
-* @param[in]  userData  The user data passed from the request function
+* @param[in] stServiceInfo -  Service Information which contains the remote address and service handle, characteristic handle.
 *
-* @return  void
+* @return NULL on sucess or failure.
 *
 */
-void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void *user_data);
+void *CASetCharacteristicDescriptorValueThread(void *stServiceInfo);
+
+/**
+* @fn  CASetCharacteristicDescriptorValue
+* @brief  Used to set characteristic descriptor value using bt_gatt_set_characteristic_desc_value_request api.
+*
+* @param[in]  stGattCharDescriptor_t  structure which contains char handle and descriptor handle.
+*
+* @return  0 on success otherwise a positive error value.
+* @retval  CA_STATUS_OK  Successful
+* @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
+* @retval  CA_STATUS_FAILED Operation failed
+*
+*/
+CAResult_t CASetCharacteristicDescriptorValue(stGattCharDescriptor_t *stGattCharDescriptorInfo);
 
 /**
 * @fn  CAGATTCreateBondThread
@@ -351,98 +508,87 @@ void CABtGattBondCreatedCb(int32_t result, bt_device_info_s *device_info, void *
 void *CAGATTCreateBondThread(void *stServiceInfo);
 
 /**
-* @fn  CABleGattCharacteristicChangedCb
-* @brief  This is the callback which will be called after the characteristic value changes happen.
+* @fn  CABleGATTCreateBond
+* @brief  Used to make LE bond with remote device(pairng the device) using bt_device_create_bond api.
 *
-* @param[in]  characteristic  The attribute handle of characteristic
-* @param[in]  value  Value of the characteristics of a service.
-* @param[in]  valueLen  length of data.
-* @param[in]  userData  The user data passed from the request function
+* @param[in] remoteAddress - mac address of remote device which we want to bond with
 *
-* @return  0 on failure and 1 on success.
+* @return  0 on success otherwise a positive error value.
+* @retval  CA_STATUS_OK  Successful
+* @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
+* @retval  CA_STATUS_FAILED Operation failed
 *
 */
-void CABleGattCharacteristicChangedCb(bt_gatt_attribute_h characteristic, unsigned char *value,
-                                      int32_t valueLen, void *userData);
+CAResult_t CABleGATTCreateBond(const char *remoteAddress);
 
 /**
-* @fn  CABleGattCharacteristicsDiscoveredCb
-* @brief  This is the callback which will be called after the characteristics are discovered by bt_gatt_discover_characteristics()
+* @fn  CABleClientSenderQueueEnqueueMessage
+* @brief  Used to enqueue the message into sender queue using CAAdapterEnqueueMessage and make signal to the thread to process.
 *
-* @param[in]  result  The result of discovering
-* @param[in]  inputIndex  The index of characteristics in a service, starts from 0
-* @param[in]  total  The total number of characteristics in a service
-* @param[in]  characteristic  The attribute handle of characteristic
-* @param[in]  userData  The user data passed from the request function
+* @param[in]  remoteEndpoint  Remote device information
+* @param[in]  data  data which we wants to send to remote device
+* @param[in]  dataLen  Length of data.
 *
-* @return  0 on failure and 1 on success.
+* @return  0 on success otherwise a positive error value.
+* @retval  CA_STATUS_OK  Successful
+* @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
+* @retval  CA_STATUS_FAILED Operation failed
 *
 */
-CABool_t CABleGattCharacteristicsDiscoveredCb(int32_t result, int32_t inputIndex, int32_t total,
-        bt_gatt_attribute_h characteristic, void *userData);
+CAResult_t CABleClientSenderQueueEnqueueMessage(const CARemoteEndpoint_t *remoteEndpoint,
+        void *data, uint32_t dataLen);
 
 /**
-* @fn  CAGATTCreateBondThread
-* @brief  This is the thread  which will be used for making gatt connection with remote devices
-*
-* @param[in]  remoteAddress  Mac address of remote device which wants to connect with.
+* @fn  CABleClientSenderQueueProcessor
+* @brief  This is the thread which will be used for processing sender queue.
 *
 * @return  NULL on success or failure.
 *
 */
-void *CAGattConnectThread (void *remoteAddress);
-/**
-* @fn  CAPrintDiscoveryInformation
-* @brief  Used to print device information(Util method)
-*
-* @param[in]  discoveryInfo  Device information structure.
-*
-* @return  void
-*
-*/
-void CAPrintDiscoveryInformation(bt_adapter_le_device_discovery_info_s *discoveryInfo);
+void *CABleClientSenderQueueProcessor();
+
 /**
-* @fn  CABtAdapterLeDeviceDiscoveryStateChangedCb
-* @brief  This is the callback which will be called when the device discovery state changes.
-*
-* @param[in]  result  The result of discovering
-* @param[in]  discoveryState  State of the discovery(FOUND/STARTED/ FINISHED)
-* @param[in]  discoveryInfo  Remote Device information.
-* @param[in]  userData  The user data passed from the request function
+* @fn  CAUpdateCharacteristicsToGattServer
+* @brief  Sets the value of characteristic and update the value to GATTServer(unicast).
 *
-* @return  void
+* @param[in]  remoteAddress  The address of the remote device
+* @param[in]  data  The value of characteristic (byte array)
+* @param[in]  dataLen  The length of value
+* @param[in]  TRANSFER_TYPE (UNICAST/MULTICAST)
+* @param[in]  position  The unique index of each ble server. Used for multicast feature.
 *
+* @return  0 on success otherwise a positive error value.
+* @retval  CA_STATUS_OK  Successful
+* @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
+* @retval  CA_STATUS_FAILED Operation failed
 */
-void CABtAdapterLeDeviceDiscoveryStateChangedCb(int32_t result,
-        bt_adapter_le_device_discovery_state_e discoveryState,
-        bt_adapter_le_device_discovery_info_s *discoveryInfo,
-        void *userData);
+CAResult_t  CAUpdateCharacteristicsToGattServer(const char *remoteAddress, const char  *data,
+        int32_t dataLen, TRANSFER_TYPE type, int32_t position);
+
 /**
-* @fn  CADiscoverBLEServicesThread
-* @brief  This is thread which will be spawned for discovering ble services. Once called discover api, then it will be terminated.
-*
-* @param[in]  remoteAddress  Mac address of the remote device in which we want to search services.
-*
-* @return  NULL for success or failure.
-*
-*/
-void *CADiscoverBLEServicesThread (void *remoteAddress);
+ * @fn  CAUpdateCharacteristicsToAllGattServers
+ * @brief  Sets the value of characteristic and update the value to All registered GATTServer -> Multicast
+ *
+ * @param[in]  data  The value of characteristic (byte array)
+ * @param[in]  dataLen  The length of value
+ *
+ * @return  0 on success otherwise a positive error value.
+ * @retval  CA_STATUS_OK  Successful
+ * @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
+ * @retval  CA_STATUS_FAILED Operation failed
+ */
+CAResult_t  CAUpdateCharacteristicsToAllGattServers(const char  *data, int32_t dataLen);
 
 /**
-* @fn  CABleGattConnectionStateChangedCb
-* @brief  This is the callback which will be called whenever there is change in gatt connection with server(Connected/Disconnected)
-*
-* @param[in]  result  The result of discovering
-* @param[in]  connected  State of connection
-* @param[in]  remoteAddress  Mac address of the remote device in which we made connection.
-* @param[in]  userData  The user data passed from the request function
+* @fn  CALEReadDataFromLEClient
+* @brief  synchronous function for reading characteristic value.
 *
-* @return  void
+* @return  0 on success otherwise a positive error value.
+* @retval  CA_STATUS_OK  Successful
+* @retval  CA_STATUS_INVALID_PARAM  Invalid input argumets
+* @retval  CA_STATUS_FAILED Operation failed
 *
 */
-void CABleGattConnectionStateChangedCb(int32_t result, bool connected, const char *remoteAddress,
-                                       void *userData);
-
-
+CAResult_t CALEReadDataFromLEClient();
 
 #endif //#ifndef _BLE_CLIENT_
index 8f37630..70f2d10 100644 (file)
 
 #define TZ_BLE_CLIENT_UTIL_TAG "TZ_BLE_GATT_CLIENT_UTIL"
 
-#define OIC_BLE_SERVICE_ID "000018f3-0000-1000-8000-00805f9b34fb"
-///TODO: OIC_BLE_SERVICE_ID  will be generated by invoking API in future.
-
-
 static int32_t gNumberOfServiceConnected = 0;
 
 void CAIncrementRegisteredServiceCount()
index 39471b0..1019561 100644 (file)
@@ -37,9 +37,9 @@ typedef struct
 {
     bt_gatt_attribute_h service_clone;         /**< gatt_attribute handler for the OIC service. */
     bt_gatt_attribute_h
-    read_char;               /**< gatt_attribute handler for the OIC read characteristic. */
+    read_char;               /**< gatt_attribute handler for the OIC read characteristic. Server will read. */
     bt_gatt_attribute_h
-    write_char;              /**< gatt_attribute handler for the OIC write characteristic. */
+    write_char;              /**< gatt_attribute handler for the OIC write characteristic. server will write */
     char *bdAddress;                                /**< BD address where OIC service is running. */
 } BLEServiceInfo;
 
@@ -98,11 +98,13 @@ typedef enum
 
 typedef struct gattCharDescriptor
 {
-    bt_gatt_attribute_h descriptor;
     bt_gatt_attribute_h characteristic;
+    uint8_t *desc;
     int total;
 } stGattCharDescriptor_t;
 
+#define OIC_BLE_SERVICE_ID "713d0000-503e-4c75-ba94-3148f18d941e"
+///TODO: OIC_BLE_SERVICE_ID  will be generated by invoking API in future.
 /**
 * @fn  CAIncrementRegisteredServiceCount
 * @brief  Used to increment the registered service count.
index da9cd2a..1ba782f 100644 (file)
@@ -26,6 +26,8 @@
 #include "umutex.h"
 #include "camessagequeue.h"
 #include "caadapterutils.h"
+#include "camsgparser.h"
+#include "cableclientutil.h"
 
 /**
  * @def TZ_BLE_SERVER_TAG
@@ -129,6 +131,31 @@ static u_mutex gBleServerThreadPoolMutex = NULL;
 static u_cond gBleServerSendCondWait = NULL;
 
 /**
+ * @var gReceiverDataCond
+ * @brief Condition used for notifying handler the presence of data in recv queue.
+ */
+static u_cond gReceiverDataCond = NULL;
+
+/**
+ * @var gDataReceiverHandlerState
+ * @brief Stop condition of redvhandler.
+ */
+static bool gDataReceiverHandlerState = false;
+
+/**
+ * @var isHeaderAvailable
+ * @brief to differentiate btw header and data packet.
+ */
+static CABool_t isHeaderAvailable = false;
+
+/**
+ * @struct gRemoteAddress
+ * @brief Remote address of Gatt client
+ *
+ */
+static const char *gRemoteClientAddress = "DB:F7:EB:B5:0F:07";
+///TODO: later this will be replaced with the platform apis.
+/**
  * @var gBleServerReceiveDataMutex
  * @brief Mutex to synchronize the queing of the data from ReceiverQueue.
  */
@@ -152,14 +179,65 @@ static u_thread_pool_t gBleServerThreadPool = NULL;
  */
 static CABool_t gServerUp = CA_FALSE;
 
+/**
+ * @fn CABLEDataReceiverHandler
+ * @brief This function handles data from recv message queue.
+ */
+static void CABLEDataReceiverHandler(void *context);
+
+CAResult_t CABLEPushDataToServerReceiverQueue(const char *remoteAddress, const char *serviceUUID,
+        void *data, uint32_t dataLength, uint32_t *sentLength)
+{
+    OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "IN");
+
+    //Input validation
+    VERIFY_NON_NULL(serviceUUID, TZ_BLE_SERVER_TAG, "service UUID is null");
+    VERIFY_NON_NULL(data, TZ_BLE_SERVER_TAG, "Data is null");
+    VERIFY_NON_NULL(sentLength, TZ_BLE_SERVER_TAG, "Sent data length holder is null");
+
+    //Add message to data queue
+    CARemoteEndpoint_t *remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_LE, remoteAddress,
+                                         serviceUUID);
+    if (NULL == remoteEndpoint)
+    {
+        OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "Failed to create remote endpoint !");
+        return CA_STATUS_FAILED;
+    }
+
+    if (CA_STATUS_OK != CAAdapterEnqueueMessage(gCABleServerReceiverQueue, remoteEndpoint, data,
+            dataLength))
+    {
+        OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "Failed to add message to queue !");
+
+        CAAdapterFreeRemoteEndpoint(remoteEndpoint);
+        return CA_STATUS_FAILED;
+    }
 
+    *sentLength = dataLength;
+
+    OICFree(data);
+    data = NULL;
+
+    //Signal message handler for processing data for sending
+    OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Signalling message send handler");
+    u_mutex_lock(gBleServerReceiveDataMutex);
+    u_cond_signal(gReceiverDataCond);
+    u_mutex_unlock(gBleServerReceiveDataMutex);
+
+    OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
 void *CABleServerSenderQueueProcessor()
 {
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN ");
 
     while (gServerUp)
     {
-        CAAdapterMessage_t *senderData = NULL;
+        CAAdapterMessage_t *message = NULL;
+        const char *remoteAddress = NULL;
+        const char *serviceUUID = NULL;
+        uint32_t sentLength = 0;
+        int32_t headerAdded = 0;
 
         OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, " conditional wait");
 
@@ -170,23 +248,62 @@ void *CABleServerSenderQueueProcessor()
 
         CAResult_t result = CA_STATUS_FAILED;
 
-        while (CA_STATUS_OK == CAAdapterDequeueMessage(gCABleServerSenderQueue, &senderData))
+        while (CA_STATUS_OK == CAAdapterDequeueMessage(gCABleServerSenderQueue, &message))
         {
-            if (senderData == NULL)
+            if (message == NULL)
             {
                 OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "senderData is NULL");
                 continue;
             }
-            result = CAUpdateCharacteristicsInGattServer(senderData->data, senderData->dataLen);
-            if (CA_STATUS_OK != result)
-            {
-                OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Failed to CAUpdateCharacteristicsInGattServer");
-            }
-            else
+            char *dataSegment = NULL;
+            uint32_t offset = 0, ret = 1;
+            int32_t datalen = message->dataLen;
+            while ( 1)
             {
-                OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Failed to CAUpdateCharacteristicsInGattServer !");
+                OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "fragmenting the data DataLen [%d] Offset [%d]", datalen,
+                          offset);
+                ret = CAFragmentData(message->data, &dataSegment, datalen, offset);
+                sleep(1);
+                if (0 == ret)
+                {
+                    break;
+                }
+
+                OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "Sending Multicast data");
+                result = CAUpdateCharacteristicsInGattServer(dataSegment, ret);
+                if (CA_STATUS_OK != result)
+                {
+                    OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG,
+                              "Failed to CAUpdateCharacteristicsInGattServer !");
+                }
+
+                OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "freeing dataSegment");
+
+                OICFree(dataSegment);
+                dataSegment = NULL;
+                offset += ret;
+                if (headerAdded == 0)
+                {
+                    datalen -= offset - CA_HEADER_LENGTH;
+                    offset = offset - CA_HEADER_LENGTH;
+                    headerAdded = 1;
+                }
+                else
+                {
+                    datalen -= ret;
+                }
+
+                if (datalen < 0)
+                {
+                    datalen += ret ;
+                }
+                if (datalen == message->dataLen)
+                {
+                    OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "All data has been fragmented and sent");
+                    break;
+                }
             }
-            CAAdapterFreeMessage(senderData);
+            CAAdapterFreeMessage(message);
         }
 
         u_mutex_unlock(gBleServerSendDataMutex);
@@ -196,6 +313,97 @@ void *CABleServerSenderQueueProcessor()
     return NULL;
 }
 
+void CABLEDataReceiverHandler(void *context)
+{
+    OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "IN");
+
+    CAAdapterMessage_t *message = NULL;
+    const char *remoteAddress = NULL;
+    const char *serviceUUID = NULL;
+    uint32_t recvDataLen = 0;
+    uint32_t totalDataLen = 0;
+    char *dataSegment = NULL;
+    char *defragData = NULL;
+    isHeaderAvailable = false;
+    CARemoteEndpoint_t *remoteEndpoint = NULL;
+
+    u_mutex_lock(gBleServerReceiveDataMutex);
+
+    while (gDataReceiverHandlerState)
+    {
+
+        OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, " waiting for the data");
+
+        u_cond_wait(gReceiverDataCond, gBleServerReceiveDataMutex);
+
+        OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "wait unlocked");
+
+        //Extract the message from queue and send to remote ble device
+        while (CA_STATUS_OK == CAAdapterDequeueMessage(gCABleServerReceiverQueue, &message))
+        {
+            OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "checking for DE Fragmentation");
+
+            if (!isHeaderAvailable)
+            {
+                OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Parsing the header");
+                char *header = (char *) OICMalloc(sizeof(char) * CA_HEADER_LENGTH);
+                memcpy(header, message->data, CA_HEADER_LENGTH);
+                totalDataLen = CAParseHeader(header);
+                OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Total data to be accumulated [%d] bytes", totalDataLen);
+                defragData = (char *) OICMalloc(sizeof(char) * totalDataLen);
+                OICFree(header);
+
+                remoteAddress = message->remoteEndpoint->addressInfo.BT.btMacAddress;
+                serviceUUID = message->remoteEndpoint->resourceUri;
+
+                remoteEndpoint = CAAdapterCreateRemoteEndpoint(CA_EDR, remoteAddress,
+                                 serviceUUID);
+
+                memcpy(defragData + recvDataLen, message->data + CA_HEADER_LENGTH,
+                       message->dataLen - CA_HEADER_LENGTH);
+                recvDataLen += message->dataLen - CA_HEADER_LENGTH;
+                isHeaderAvailable = true;
+            }
+            else
+            {
+                OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Copying the data of length [%d]", message->dataLen);
+                memcpy(defragData + recvDataLen, message->data, message->dataLen);
+                recvDataLen += message->dataLen ;
+                OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "totalDatalength  [%d] recveived Datalen [%d]",
+                          totalDataLen, recvDataLen);
+            }
+            CAAdapterFreeMessage(message);
+            if (totalDataLen == recvDataLen)
+            {
+                u_mutex_lock(gBleReqRespCbMutex);
+                if (NULL == gNetworkPacketReceivedServerCallback)
+                {
+                    OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "gReqRespCallback is NULL!");
+                    u_mutex_unlock(gBleReqRespCbMutex);
+                    return;
+                }
+                OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "Sending data up !");
+                gNetworkPacketReceivedServerCallback(remoteEndpoint, defragData, recvDataLen);
+                OICFree(remoteEndpoint);
+                OICFree(defragData);
+                recvDataLen = 0;
+                totalDataLen = 0;
+                isHeaderAvailable = false;
+                u_mutex_unlock(gBleReqRespCbMutex);
+            }
+
+        }
+
+        if (false == gDataReceiverHandlerState)
+        {
+            break;
+        }
+
+
+    }
+    u_mutex_unlock(gBleServerReceiveDataMutex);
+    OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
+}
 
 CAResult_t CAStartBleGattServer()
 {
@@ -254,10 +462,15 @@ CAResult_t CAStartBleGattServer()
     {
         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "u_thread_pool_add_task failed with ret [%d]", ret);
 
-        //CARemoveBLEServiceInfoToList(&gBLEServiceList, bleServiceInfo, bleServiceInfo->bdAddress);
         u_mutex_unlock(gBleServerThreadPoolMutex);
         return CA_STATUS_FAILED;
     }
+    gDataReceiverHandlerState = true;
+    if (CA_STATUS_OK != u_thread_pool_add_task(gBleServerThreadPool, CABLEDataReceiverHandler, NULL))
+    {
+        OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "Failed to start data send handler!");
+        return ;
+    }
     u_mutex_unlock(gBleServerThreadPoolMutex);
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
     return CA_STATUS_OK;
@@ -287,7 +500,7 @@ void *CAStartBleGattServerThread(void *data)
 
     sleep(5); // Sleep is must. otherwise its crashing
 
-    char *serviceUUID = "000018f3-0000-1000-8000-00805f9b34fb";
+    char *serviceUUID = "713d0000-503e-4c75-ba94-3148f18d941e";
 
     ret  = CAAddNewBleServiceInGattServer(serviceUUID);
 
@@ -350,7 +563,6 @@ void *CAStartBleGattServerThread(void *data)
     }
 
     int32_t retVal = bt_adapter_le_start_advertising(hAdvertiser, NULL, NULL, NULL);
-
     if (BT_ERROR_NONE != retVal)
     {
         OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "bt_adapter_le_start_advertising failed with ret [%d] ",
@@ -399,6 +611,15 @@ CAResult_t CAStopBleGattServer()
     }
     u_mutex_unlock(gBleServerStateMutex);
 
+    //Stop data send and receive handlers
+    if (gBleServerReceiveDataMutex && gReceiverDataCond && gDataReceiverHandlerState)
+    {
+        u_mutex_lock(gBleServerReceiveDataMutex);
+        gDataReceiverHandlerState = CA_FALSE;
+        u_cond_signal(gReceiverDataCond);
+        u_mutex_unlock(gBleServerReceiveDataMutex);
+    }
+
     CATerminateBleGattServer();
 
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
@@ -410,7 +631,9 @@ void CATerminateBleGattServer()
 {
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "IN");
 
-    int32_t ret = 0;
+    gIsBleGattServerStarted = CA_FALSE;
+    gServerUp = CA_FALSE;
+    u_cond_signal(gBleServerSendCondWait);
 
     u_mutex_lock(gBleServerStateMutex);
     // Required for waking up the thread which is running in gmain loop
@@ -429,6 +652,8 @@ void CATerminateBleGattServer()
     // Kill g main loops and kill threads
     g_main_loop_quit(g_event_loop);
 
+    int32_t ret = 0;
+
     if (NULL != hAdvertiser )
     {
         ret  = bt_adapter_le_stop_advertising(hAdvertiser);
@@ -471,8 +696,6 @@ void CATerminateBleGattServer()
     gGattWriteCharPath = NULL;
     u_mutex_unlock(gBleCharacteristicMutex);
 
-    gIsBleGattServerStarted = CA_FALSE;
-    gServerUp = CA_FALSE;
     u_mutex_unlock(gBleServerStateMutex);
 
     // Terminating gCABleServerSenderQueue
@@ -572,6 +795,16 @@ CAResult_t CAInitGattServerMutexVaraibles()
         }
     }
 
+    if (!gReceiverDataCond)
+    {
+        gReceiverDataCond = u_cond_new();
+        if (NULL == gReceiverDataCond)
+        {
+            OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "u_cond_new failed");
+            return CA_STATUS_FAILED;
+        }
+    }
+
     return CA_STATUS_OK;
 }
 void CATerminateGattServerMutexVaraibles()
@@ -593,9 +826,15 @@ void CATerminateGattServerMutexVaraibles()
     u_mutex_free(gBleReqRespCbMutex);
     gBleReqRespCbMutex = NULL;
 
-    u_mutex_free(gBleServerSendCondWait);
+    u_cond_free(gBleServerSendCondWait);
     gBleServerSendCondWait = NULL;
 
+    if (gReceiverDataCond)
+    {
+        u_cond_free(gReceiverDataCond);
+        gReceiverDataCond = NULL;
+    }
+
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
 }
 CAResult_t CAInitBleGattService()
@@ -733,32 +972,12 @@ void CABleGattRemoteCharacteristicWriteCb(char *charPath,
 
     OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "charPath = [%s] charValue = [%s] len [%d]", charPath,
               charValue, charValueLen);
-    CARemoteEndpoint_t  *remoteEndPoint = (CARemoteEndpoint_t *) OICMalloc(sizeof(CARemoteEndpoint_t));
-    if (NULL == remoteEndPoint)
-    {
-        OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Malloc Failure!");
-        return;
-    }
-    memset(remoteEndPoint, 0x0, sizeof(CARemoteEndpoint_t));
-    ///TODO: Currently Empty endpoint is being sent.
-    ///TODO:Later proper remote address has to be added when tizen team changed their code
-#if 0
-    VERIFY_NON_NULL(gCABleServerReceiverQueue, TZ_BLE_SERVER_TAG, "BleServerReceiverQueue is  NULL");
-
-    CAResult_t retVal = CAAdapterEnqueueMessage(gCABleServerReceiverQueue, remoteEndPoint, charValue,
-                        charValueLen);
-    if (CA_STATUS_OK != retVal )
-    {
-        OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "CAAdapterEnqueueMessage failed!");
-        return;
-    }
-#endif
 
     char *data = (char *)OICMalloc(sizeof(char) * charValueLen + 1);
     if (NULL == data)
     {
         OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "Malloc failed!");
-        OICFree(remoteEndPoint);
+        //    OICFree(remoteEndPoint);
         return;
     }
 
@@ -766,19 +985,17 @@ void CABleGattRemoteCharacteristicWriteCb(char *charPath,
 
     strncpy(data, charValue, charValueLen);
 
-    u_mutex_lock(gBleReqRespCbMutex);
-    if (NULL == gNetworkPacketReceivedServerCallback)
+    uint32_t sentLength = 0;
+
+    CAResult_t res = CABLEPushDataToServerReceiverQueue(gRemoteClientAddress, OIC_BLE_SERVICE_ID,
+                     data, strlen(data), &sentLength);
+    if (CA_STATUS_OK != res)
     {
-        OIC_LOG(ERROR, TZ_BLE_SERVER_TAG, "gNetworkPacketReceivedServerCallback is NULL!");
-        OICFree(charValue);
-        OICFree(remoteEndPoint);
+        OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "CABLEPushDataToReceiverQueue failed");
         OICFree(data);
-        u_mutex_unlock(gBleReqRespCbMutex);
-        return;
+        return ;
     }
 
-    gNetworkPacketReceivedServerCallback(remoteEndPoint, data, charValueLen);
-    u_mutex_unlock(gBleReqRespCbMutex);
     OIC_LOG(DEBUG, TZ_BLE_SERVER_TAG, "OUT");
 }
 
@@ -919,17 +1136,20 @@ CAResult_t CAUpdateCharacteristicsInGattServer(const char *charValue, int32_t ch
 
     strncpy(data, charValue, charValueLen);
 
-    int32_t ret =  bt_gatt_update_characteristic(gGattWriteCharPath, data, charValueLen);
-
-    OICFree(data);
-    data = NULL;
+    OIC_LOG_V(DEBUG, TZ_BLE_SERVER_TAG, "updating characteristics char [%s] data [%s] dataLen [%d]",
+              (const char *)gGattWriteCharPath, data, charValueLen);
 
+    int32_t ret =  bt_gatt_update_characteristic(gGattWriteCharPath, data, charValueLen);
     if (0 != ret)
     {
         OIC_LOG_V(ERROR, TZ_BLE_SERVER_TAG, "bt_gatt_update_characteristic failed with return [%d]", ret);
+        OICFree(data);
+        data = NULL;
         u_mutex_unlock(gBleCharacteristicMutex);
         return CA_STATUS_FAILED;
     }
+    OICFree(data);
+    data = NULL;
 
     u_mutex_unlock(gBleCharacteristicMutex);
 
index 127361d..86310e9 100644 (file)
@@ -133,6 +133,14 @@ CAResult_t CASendRequest(const CARemoteEndpoint_t* object, CARequestInfo_t* requ
     return CADetachRequestMessage(object, requestInfo);
 }
 
+CAResult_t CASendRequestToAll(const CAGroupEndpoint_t* object, 
+    const CARequestInfo_t* requestInfo)
+{
+    OIC_LOG_V(DEBUG, TAG, "CASendRequestToAll");
+
+    return CADetachRequestToAllMessage(object, requestInfo);
+}
+
 CAResult_t CASendNotification(const CARemoteEndpoint_t* object, CAResponseInfo_t* responseInfo)
 {
     OIC_LOG_V(DEBUG, TAG, "CASendNotification");
@@ -149,8 +157,8 @@ CAResult_t CASendResponse(const CARemoteEndpoint_t* object, CAResponseInfo_t* re
 
 }
 
-CAResult_t CAAdvertiseResource(const CAURI_t resourceUri, CAToken_t token, CAHeaderOption_t* options,
-        uint8_t numOptions)
+CAResult_t CAAdvertiseResource(const CAURI_t resourceUri, CAToken_t token, 
+    CAHeaderOption_t* options,uint8_t numOptions)
 {
     OIC_LOG_V(DEBUG, TAG, "CAAdvertiseResource");
 
index ad37f36..d304bbd 100644 (file)
@@ -249,9 +249,7 @@ CAResult_t CAUnSelectNetwork(const uint32_t nonInterestedNetwork)
 
 CAResult_t CAHandleRequestResponse()
 {
-    //OIC_LOG(DEBUG, TAG, "IN");
     CAHandleRequestResponseCallbacks();
-    //OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
 
index 33124b8..3f36e5b 100644 (file)
@@ -38,7 +38,8 @@
 
 #define TAG PCF("CA")
 
-#define CA_MEMORY_ALLOC_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(DEBUG, TAG, "memory error"); goto memory_error_exit;} }
+#define CA_MEMORY_ALLOC_CHECK(arg) {if (arg == NULL) \
+    {OIC_LOG_V(DEBUG, TAG, "memory error");goto memory_error_exit;} }
 
 #define CA_CONNECTIVITY_TYPE_NUM   4
 
@@ -82,7 +83,8 @@ static void CARegisterCallback(CAConnectivityHandler_t handler, CAConnectivityTy
     OIC_LOG_V(DEBUG, TAG, "%d type adapter, register complete!", cType);
 }
 
-static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
+static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, 
+    uint32_t dataLen)
 {
     OIC_LOG(DEBUG, TAG, "receivedPacketCallback in interface controller");
 
@@ -93,7 +95,8 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
     }
 }
 
-static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status)
+static void CANetworkChangedCallback(CALocalConnectivity_t *info, 
+    CANetworkStatus_t status)
 {
     OIC_LOG(DEBUG, TAG, "Network Changed callback");
 
@@ -117,15 +120,18 @@ void CAInitializeAdapters(u_thread_pool_t handle)
 #endif /* ETHERNET_ADAPTER */
 
 #ifdef WIFI_ADAPTER
-    CAInitializeWifi(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, handle);
+    CAInitializeWifi(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, 
+    handle);
 #endif /* WIFI_ADAPTER */
 
 #ifdef EDR_ADAPTER
-    CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, handle);
+    CAInitializeEDR(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, 
+    handle);
 #endif /* EDR_ADAPTER */
 
 #ifdef LE_ADAPTER
-    CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, handle);
+    CAInitializeLE(CARegisterCallback, CAReceivedPacketCallback, CANetworkChangedCallback, 
+    handle);
 #endif /* LE_ADAPTER */
 
 }
@@ -269,7 +275,7 @@ memory_error_exit:
     return CA_MEMORY_ALLOC_FAILED;
 }
 
-CAResult_t CASendUnicastData(CARemoteEndpoint_t* endpoint, void* data, uint32_t length)
+CAResult_t CASendUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t length)
 {
     OIC_LOG(DEBUG, TAG, "Send unicast data to enabled interface..");
 
@@ -296,9 +302,6 @@ CAResult_t CASendUnicastData(CARemoteEndpoint_t* endpoint, void* data, uint32_t
     {
         res = gAdapterHandler[index].sendData(endpoint, data, length);
     }
-    //For Unicast , data will be deleted by adapters
-
-    CADestroyRemoteEndpointInternal(endpoint);
 
     return res;
 }
@@ -333,6 +336,11 @@ CAResult_t CASendMulticastData(void *data, uint32_t length)
         if (gAdapterHandler[index].sendDataToAll != NULL)
         {
             void* payload = (void*) OICMalloc(length);
+            if (!payload)
+            {
+                OIC_LOG_V(ERROR, TAG, "Out of memory!");
+                return CA_MEMORY_ALLOC_FAILED;
+            }
             memcpy(payload, data, length);
             res = gAdapterHandler[index].sendDataToAll(payload, length);
         }
@@ -420,7 +428,8 @@ void CATerminateAdapters()
     {
         if (gAdapterHandler[index].terminate != NULL)
         {
-            gAdapterHandler[index].terminate();
+           gAdapterHandler[index].stopAdapter(); 
+           gAdapterHandler[index].terminate();
         }
     }
 }
index dd559de..ff88e54 100644 (file)
@@ -48,7 +48,6 @@ static CANetworkChangeCallback gNetworkChangeCallback = NULL;
 
 static int8_t CAGetAdapterIndex(CAConnectivityType_t cType)
 {
-    //OIC_LOG(DEBUG, TAG, "IN");
     switch (cType)
     {
         case CA_ETHERNET:
@@ -60,7 +59,6 @@ static int8_t CAGetAdapterIndex(CAConnectivityType_t cType)
         case CA_LE:
             return 3;
     }
-    //OIC_LOG(DEBUG, TAG, "OUT");
     return -1;
 }
 
@@ -431,7 +429,6 @@ void CATerminateAdapters()
 
 CAResult_t CAReadData()
 {
-    //OIC_LOG(DEBUG, TAG, "IN");
 
     uint8_t i, type;
     int8_t index = -1;
@@ -462,6 +459,5 @@ CAResult_t CAReadData()
         }
     }
 
-    //OIC_LOG(DEBUG, TAG, "OUT");
     return CA_STATUS_OK;
 }
index ef53e18..b39ee81 100644 (file)
@@ -39,7 +39,8 @@
 
 #define TAG PCF("CA")
 
-#define MEMORY_ALLOCK_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(DEBUG, TAG, "memory error"); goto memory_error_exit;} }
+#define MEMORY_ALLOCK_CHECK(arg) { if (arg == NULL) {OIC_LOG_V(DEBUG, TAG, "memory error"); \
+goto memory_error_exit;} }
 
 #define MAX_THREAD_POOL_SIZE    10
 
@@ -105,14 +106,14 @@ static void CASendThreadProcess(void *threadData)
             OIC_LOG_V(DEBUG, TAG, "requestInfo is available..");
 
             pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri,
-                    data->requestInfo->method, data->requestInfo->info);
+                                               data->requestInfo->method, data->requestInfo->info);
         }
         else if (data->responseInfo != NULL)
         {
             OIC_LOG_V(DEBUG, TAG, "responseInfo is available..");
 
             pdu = (coap_pdu_t *) CAGeneratePdu(data->remoteEndpoint->resourceUri,
-                    data->responseInfo->result, data->responseInfo->info);
+                                          data->responseInfo->result, data->responseInfo->info);
         }
         else
         {
@@ -124,11 +125,20 @@ static void CASendThreadProcess(void *threadData)
         {
             OIC_LOG_V(DEBUG, TAG, "PDU Maker - payload : %s", pdu->data);
 
+            OIC_LOG_V(DEBUG, TAG, "PDU Maker - type : %d", pdu->hdr->type);
+
             OIC_LOG_V(DEBUG, TAG, "PDU Maker - code : %d", pdu->hdr->code);
 
+            OIC_LOG_V(DEBUG, TAG, "PDU Maker - id : %d", pdu->hdr->id);
+
+            OIC_LOG_V(DEBUG, TAG, "PDU Maker - token : %s", pdu->hdr->token);
+
             OIC_LOG_V(DEBUG, TAG, "PDU Maker - buffer data : %s", pdu->hdr);
 
             res = CASendUnicastData(data->remoteEndpoint, pdu->hdr, pdu->length);
+
+            //For Unicast , data will be deleted by adapters
+            CADestroyRemoteEndpointInternal(data->remoteEndpoint);
         }
 
     }
@@ -167,10 +177,11 @@ static void CASendThreadProcess(void *threadData)
     {
         OIC_LOG(DEBUG, TAG, "unknown type!");
     }
-    OIC_LOG_V(DEBUG, TAG, " Result :%d", res);
+    OIC_LOG_V(DEBUG, TAG, " Result :%d",res);
 }
 
-static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, uint32_t dataLen)
+static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, 
+    uint32_t dataLen)
 {
     OIC_LOG(DEBUG, TAG, "receivedPacketCallback in message handler!!");
 
@@ -195,6 +206,12 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
     {
         CARequestInfo_t *ReqInfo;
         ReqInfo = (CARequestInfo_t *) OICMalloc(sizeof(CARequestInfo_t));
+        if (ReqInfo == NULL)
+        {
+            OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
+            coap_delete_pdu(pdu);
+            return;
+        }
         memset(ReqInfo, 0, sizeof(CARequestInfo_t));
         CAGetRequestInfoFromPdu(pdu, ReqInfo, uri);
 
@@ -212,13 +229,20 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
         if (NULL != ReqInfo->info.payload)
         {
             OIC_LOG_V(DEBUG, TAG, "Request- payload: %s", ReqInfo->info.payload);
-        }
-        OIC_LOG_V(DEBUG, TAG, "Request- code: %d", ReqInfo->method);
+        } 
+        OIC_LOG_V(DEBUG, TAG, "Request- code: %d", ReqInfo->method); 
         OIC_LOG_V(DEBUG, TAG, "Request- token : %s", ReqInfo->info.token);
 
         if (NULL != endpoint)
         {
             endpoint->resourceUri = (char *) OICMalloc(strlen(uri) + 1);
+            if (endpoint->resourceUri == NULL)
+            {
+                OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
+                OICFree(ReqInfo);
+                coap_delete_pdu(pdu);
+                return;
+            }
             memset(endpoint->resourceUri, 0, strlen(uri) + 1);
             memcpy(endpoint->resourceUri, uri, strlen(uri));
             OIC_LOG_V(DEBUG, TAG, "added resource URI : %s", endpoint->resourceUri);
@@ -226,6 +250,14 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
         // store the data at queue.
         CAData_t *cadata = NULL;
         cadata = (CAData_t *) OICMalloc(sizeof(CAData_t));
+        if (cadata == NULL)
+        {
+            OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
+            OICFree(endpoint->resourceUri);
+            OICFree(ReqInfo);
+            coap_delete_pdu(pdu);
+            return;
+        }
         memset(cadata, 0, sizeof(CAData_t));
 
         cadata->type = SEND_TYPE_UNICAST;
@@ -238,6 +270,12 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
     {
         CAResponseInfo_t *ResInfo;
         ResInfo = (CAResponseInfo_t *) OICMalloc(sizeof(CAResponseInfo_t));
+        if (ResInfo == NULL)
+        {
+            OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
+            coap_delete_pdu(pdu);
+            return;
+        }
         memset(ResInfo, 0, sizeof(CAResponseInfo_t));
         CAGetResponseInfoFromPdu(pdu, ResInfo, uri);
 
@@ -253,13 +291,19 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
             if (NULL != ResInfo->info.payload)
             {
                 OIC_LOG_V(DEBUG, TAG, "Response- payload: %s", ResInfo->info.payload);
-            }
-            OIC_LOG_V(DEBUG, TAG, "Response- code: %d", ResInfo->result);
+            } OIC_LOG_V(DEBUG, TAG, "Response- code: %d", ResInfo->result);
         }
 
         if (NULL != endpoint)
         {
             endpoint->resourceUri = (char *) OICMalloc(strlen(uri) + 1);
+            if (endpoint->resourceUri == NULL)
+            {
+                OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
+                OICFree(ResInfo);
+                coap_delete_pdu(pdu);
+                return;
+            }
             memset(endpoint->resourceUri, 0, strlen(uri) + 1);
             memcpy(endpoint->resourceUri, uri, strlen(uri));
             OIC_LOG_V(DEBUG, TAG, "added resource URI : %s", endpoint->resourceUri);
@@ -268,6 +312,14 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
         // store the data at queue.
         CAData_t *cadata = NULL;
         cadata = (CAData_t *) OICMalloc(sizeof(CAData_t));
+        if (cadata == NULL)
+        {
+            OIC_LOG(DEBUG, TAG, "CAReceivedPacketCallback, Memory allocation failed !");
+            OICFree(endpoint->resourceUri);
+            OICFree(ResInfo);
+            coap_delete_pdu(pdu);
+            return;
+        }
         memset(cadata, 0, sizeof(CAData_t));
 
         cadata->type = SEND_TYPE_UNICAST;
@@ -282,6 +334,8 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
 static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatus_t status)
 {
     OIC_LOG(DEBUG, TAG, "networkChangeCallback in message handler!!");
+
+    OIC_LOG_V(DEBUG, TAG, "Changed Network Status: %d", status);
 }
 
 void CAHandleRequestResponseCallbacks()
@@ -369,7 +423,8 @@ void CAHandleRequestResponseCallbacks()
     OICFree(rep);
 }
 
-CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequestInfo_t *request)
+CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, 
+    const CARequestInfo_t *request)
 {
     OIC_LOG_V(DEBUG, TAG, "CADetachRequestMessage");
 
@@ -404,6 +459,59 @@ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequ
     return CA_STATUS_OK;
 
     // memory error label.
+memory_error_exit:
+
+    CADestroyRemoteEndpointInternal(remoteEndpoint);
+
+    CADestroyRequestInfoInternal(requestInfo);
+
+    if (data != NULL)
+    {
+        OICFree(data);
+    }
+
+    return CA_MEMORY_ALLOC_FAILED;
+}
+
+CAResult_t CADetachRequestToAllMessage(const CAGroupEndpoint_t* object, 
+    const CARequestInfo_t* request)
+{
+    // ToDo
+    OIC_LOG_V(DEBUG, TAG, "CADetachRequestToAllMessage");
+    
+
+    if (object == NULL || request == NULL)
+    {
+        return CA_STATUS_FAILED;
+    }
+
+    CAData_t* data = (CAData_t*) OICMalloc(sizeof(CAData_t));
+    MEMORY_ALLOCK_CHECK(data);
+
+    // initialize
+    memset(data, 0, sizeof(CAData_t));
+
+    CAAddress_t addr;
+    memset(&addr, 0, sizeof(CAAddress_t));
+    CARemoteEndpoint_t* remoteEndpoint = CACreateRemoteEndpointInternal(object->resourceUri, addr, 
+        object->connectivityType);
+
+    // clone request info
+    CARequestInfo_t* requestInfo = CACloneRequestInfo(request);
+    MEMORY_ALLOCK_CHECK(requestInfo);
+
+    // save data
+    data->type = SEND_TYPE_MULTICAST;
+    data->remoteEndpoint = remoteEndpoint;
+    data->requestInfo = requestInfo;
+    data->responseInfo = NULL;
+
+    // add thread
+    CAQueueingThreadAddData(&gSendThread, data, sizeof(CAData_t));
+
+    return CA_STATUS_OK;
+
+    // memory error label.
     memory_error_exit:
 
     CADestroyRemoteEndpointInternal(remoteEndpoint);
@@ -419,7 +527,7 @@ CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequ
 }
 
 CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object,
-        const CAResponseInfo_t *response)
+                                   const CAResponseInfo_t *response)
 {
     OIC_LOG_V(DEBUG, TAG, "CADetachResponseMessage");
 
@@ -454,7 +562,7 @@ CAResult_t CADetachResponseMessage(const CARemoteEndpoint_t *object,
     return CA_STATUS_OK;
 
     // memory error label.
-    memory_error_exit:
+memory_error_exit:
 
     CADestroyRemoteEndpointInternal(remoteEndpoint);
 
@@ -475,7 +583,6 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t
     {
         return CA_STATUS_FAILED;
     }
-
     CAData_t *data = (CAData_t *) OICMalloc(sizeof(CAData_t));
     MEMORY_ALLOCK_CHECK(data);
 
@@ -485,13 +592,19 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t
     CAAddress_t addr;
     memset(&addr, 0, sizeof(CAAddress_t));
     CARemoteEndpoint_t *remoteEndpoint = CACreateRemoteEndpointInternal(resourceUri, addr,
-            CA_ETHERNET | CA_WIFI | CA_EDR | CA_LE);
+                                         CA_ETHERNET | CA_WIFI | CA_EDR | CA_LE);
 
     // save data
     data->type = SEND_TYPE_MULTICAST;
     data->remoteEndpoint = remoteEndpoint;
     CARequestInfo_t* ReqInfo;
     ReqInfo = (CARequestInfo_t*) OICMalloc(sizeof(CARequestInfo_t));
+    if (ReqInfo == NULL)
+    {
+        OIC_LOG(DEBUG, TAG, "CADetachMessageResourceUri, Memory allocation failed !");
+        OICFree(data);
+        return CA_MEMORY_ALLOC_FAILED;
+    }
     memset(ReqInfo, 0, sizeof(CARequestInfo_t));
     ReqInfo->method = CA_GET;
     ReqInfo->info.token = token;
@@ -505,7 +618,7 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t
     {
         // copy data
         CAHeaderOption_t *temp = (CAHeaderOption_t *) OICMalloc(
-                sizeof(CAHeaderOption_t) * numOptions);
+                                     sizeof(CAHeaderOption_t) * numOptions);
 
         MEMORY_ALLOCK_CHECK(temp);
 
@@ -522,7 +635,7 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t
     return CA_STATUS_OK;
 
     // memory error label.
-    memory_error_exit:
+memory_error_exit:
 
     CADestroyRemoteEndpointInternal(remoteEndpoint);
 
@@ -534,7 +647,8 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t
     return CA_MEMORY_ALLOC_FAILED;
 }
 
-void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, CAResponseCallback RespHandler)
+void CASetRequestResponseCallbacks(CARequestCallback ReqHandler, 
+    CAResponseCallback RespHandler)
 {
     OIC_LOG_V(DEBUG, TAG, "set request, response handler callback.");
 
index 9eb1571..6955f69 100644 (file)
@@ -158,7 +158,7 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
 
     coap_pdu_t *pdu;
     uint32_t code = CA_NOT_FOUND;
-    pdu = (coap_pdu_t *) CAParsePDU((const char *) data,dataLen, &code);
+    pdu = (coap_pdu_t *) CAParsePDU((const char *) data, dataLen, &code);
     //OICFree(data);
 
     char uri[CA_MAX_URI_LENGTH] = { 0, };
@@ -167,6 +167,12 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
     {
         CARequestInfo_t *ReqInfo;
         ReqInfo = (CARequestInfo_t *) OICMalloc(sizeof(CARequestInfo_t));
+        if (ReqInfo == NULL)
+        {
+            OIC_LOG(DEBUG, TAG1, "CAReceivedPacketCallback, Memory allocation failed !");
+            coap_delete_pdu(pdu);
+            return;
+        }
         VERIFY_NON_NULL_VOID(ReqInfo, TAG1, "reqInfo");
         memset(ReqInfo, 0, sizeof(CARequestInfo_t));
         CAGetRequestInfoFromPdu(pdu, ReqInfo, uri);
@@ -193,6 +199,13 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
         if (NULL != endpoint)
         {
             endpoint->resourceUri = (char *) OICMalloc(strlen(uri) + 1);
+            if (endpoint->resourceUri == NULL)
+            {
+                OIC_LOG(DEBUG, TAG1, "CAReceivedPacketCallback, Memory allocation failed !");
+                coap_delete_pdu(pdu);
+                OICFree(ReqInfo);
+                return;
+            }
             memset(endpoint->resourceUri, 0, strlen(uri) + 1);
             memcpy(endpoint->resourceUri, uri, strlen(uri));
             OIC_LOG_V(DEBUG, TAG1, "URI : %s", endpoint->resourceUri);
@@ -211,6 +224,12 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
     else
     {
         CAResponseInfo_t *ResInfo = (CAResponseInfo_t *) OICMalloc(sizeof(CAResponseInfo_t));
+        if (ResInfo == NULL)
+        {
+            OIC_LOG(DEBUG, TAG1, "CAReceivedPacketCallback, Memory allocation failed !");
+            coap_delete_pdu(pdu);
+            return;
+        }
         VERIFY_NON_NULL_VOID(ResInfo, TAG1, "ResInfo");
         memset(ResInfo, 0, sizeof(CAResponseInfo_t));
         CAGetResponseInfoFromPdu(pdu, ResInfo, uri);
@@ -236,6 +255,13 @@ static void CAReceivedPacketCallback(CARemoteEndpoint_t *endpoint, void *data, u
         if (NULL != endpoint)
         {
             endpoint->resourceUri = (char *) OICMalloc(strlen(uri) + 1);
+            if (endpoint->resourceUri == NULL)
+            {
+                OIC_LOG(DEBUG, TAG1, "CAReceivedPacketCallback, Memory allocation failed !");
+                coap_delete_pdu(pdu);
+                OICFree(ResInfo);
+                return;
+            }
             memset(endpoint->resourceUri, 0, strlen(uri) + 1);
             memcpy(endpoint->resourceUri, uri, strlen(uri));
             OIC_LOG_V(DEBUG, TAG1, "URI : %s", endpoint->resourceUri);
@@ -266,11 +292,7 @@ static void CANetworkChangedCallback(CALocalConnectivity_t *info, CANetworkStatu
 
 void CAHandleRequestResponseCallbacks()
 {
-    //OIC_LOG(DEBUG, TAG1, "IN");
-
     CAReadData();
-
-    //OIC_LOG(DEBUG, TAG1, "OUT");
 }
 
 CAResult_t CADetachRequestMessage(const CARemoteEndpoint_t *object, const CARequestInfo_t *request)
@@ -395,6 +417,11 @@ CAResult_t CADetachMessageResourceUri(const CAURI_t resourceUri, const CAToken_t
     data->type = SEND_TYPE_MULTICAST;
     data->remoteEndpoint = remoteEndpoint;
     CARequestInfo_t* ReqInfo = (CARequestInfo_t*) OICMalloc(sizeof(CARequestInfo_t));
+    if (ReqInfo == NULL)
+    {
+        OIC_LOG(DEBUG, TAG1, "CADetachMessageResourceUri, Memory allocation failed !");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
     memset(ReqInfo, 0, sizeof(CARequestInfo_t));
     ReqInfo->method = CA_GET;
     ReqInfo->info.token = token;
index 72b0d07..027f095 100644 (file)
@@ -53,8 +53,10 @@ CAResult_t CAAddNetworkType(uint32_t ConnectivityType)
 #endif /* ETHERNET_ADAPTER */
 
             OIC_LOG_V(DEBUG, TAG, "Add network type(ETHERNET)");
-            u_arraylist_add(gSelectedNetworkList, &NETWORK_ETHERNET);
-
+            if (!u_arraylist_contains(gSelectedNetworkList, &NETWORK_ETHERNET))
+            {
+                u_arraylist_add(gSelectedNetworkList, &NETWORK_ETHERNET);
+            }
             break;
 
         case CA_WIFI:
@@ -65,8 +67,10 @@ CAResult_t CAAddNetworkType(uint32_t ConnectivityType)
 #endif /* WIFI_ADAPTER */
 
             OIC_LOG_V(DEBUG, TAG, "Add network type(WIFI)");
-            u_arraylist_add(gSelectedNetworkList, &NETWORK_WIFI);
-
+            if (!u_arraylist_contains(gSelectedNetworkList, &NETWORK_WIFI))
+            {
+                u_arraylist_add(gSelectedNetworkList, &NETWORK_WIFI);
+            }
             break;
 
         case CA_EDR:
@@ -77,7 +81,10 @@ CAResult_t CAAddNetworkType(uint32_t ConnectivityType)
 #endif /* EDR_ADAPTER */
 
             OIC_LOG_V(DEBUG, TAG, "Add network type(EDR)");
-            u_arraylist_add(gSelectedNetworkList, &NETWORK_EDR);
+            if (!u_arraylist_contains(gSelectedNetworkList, &NETWORK_EDR))
+            {
+                u_arraylist_add(gSelectedNetworkList, &NETWORK_EDR);
+            }
             break;
 
         case CA_LE:
@@ -88,7 +95,10 @@ CAResult_t CAAddNetworkType(uint32_t ConnectivityType)
 #endif /* LE_ADAPTER */
 
             OIC_LOG_V(DEBUG, TAG, "Add network type(LE)");
-            u_arraylist_add(gSelectedNetworkList, &NETWORK_LE);
+            if (!u_arraylist_contains(gSelectedNetworkList, &NETWORK_LE))
+            {
+                u_arraylist_add(gSelectedNetworkList, &NETWORK_LE);
+            }
             break;
 
     }
index 7a61234..0ec26a5 100644 (file)
@@ -177,14 +177,12 @@ CAResult_t CARemoveNetworkType(uint32_t ConnectivityType)
 
 u_arraylist_t *CAGetSelectedNetworkList()
 {
-    //OIC_LOG(DEBUG, TAG, "IN");
     if (gSelectedNetworkList == NULL)
     {
         OIC_LOG_V(DEBUG, TAG, "Selected network not found");
 
         return NULL;
     }
-    //OIC_LOG(DEBUG, TAG, "OUT");
     return gSelectedNetworkList;
 }
 
index a6f37d6..988d700 100644 (file)
-/******************************************************************
- *
- * Copyright 2014 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "caprotocolmessage.h"
-#include "logger.h"
-#include "oic_malloc.h"
-
-#define TAG "CA"
-
-#define CA_MAX_TOKEN_LEN   (8)
-#define CA_FLAGS_BLOCK 0x01
-#define CA_BUFSIZE 128
-#define CA_COAP_MESSAGE_CON 0
-
-#ifdef __ARDUINO__
-#include "util.h"
-#else
-#include <time.h>
-#endif //#ifdef __ARDUINO__\ruint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, char *outUri)\r{
-    OIC_LOG(DEBUG, TAG, "CAGetRequestInfoFromPdu IN");
-    if (NULL == pdu)
-    return 0;
-
-    uint32_t code = CA_NOT_FOUND;
-    CAGetRequestPDUInfo(pdu, &code, &(outReqInfo->info), outUri);
-    outReqInfo->method = code;
-    OIC_LOG(DEBUG, TAG, "CAGetRequestInfoFromPdu OUT");
-    return 1;
-}
-
-uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo, char *outUri)
-{
-    OIC_LOG(DEBUG, TAG, "CAGetResponseInfoFromPdu IN");
-    if (NULL == pdu)
-        return 0;
-
-    uint32_t code = CA_NOT_FOUND;
-    CAGetRequestPDUInfo(pdu, &code, &(outResInfo->info), outUri);
-    outResInfo->result = code;
-    OIC_LOG(DEBUG, TAG, "CAGetResponseInfoFromPdu OUT");
-    return 1;
-}
-
-coap_pdu_t *CAGeneratePdu(const char *uri, const uint32_t code, const CAInfo_t info)
-{
-    OIC_LOG(DEBUG, TAG, "CAGeneratePdu IN");
-
-    coap_pdu_t *pdu;
-    char *coapUri = NULL;
-    uint32_t coapHeaderLength = 12;
-    uint32_t length;
-    coap_list_t *optlist = NULL;
-
-    if (NULL == uri)
-        return NULL;
-
-    length = strlen(uri);
-    if (CA_MAX_URI_LENGTH < length)
-    {
-        OIC_LOG(DEBUG, TAG, "check URI length..");
-        return NULL;
-    }
-
-    coapUri = (char *) OICMalloc(length + coapHeaderLength + 1);
-    memset(coapUri, 0, length + coapHeaderLength + 1);
-
-    if (NULL != coapUri)
-    {
-        memcpy(coapUri, "coap://[::]/", coapHeaderLength);
-        memcpy(coapUri + coapHeaderLength, uri, length);
-
-        // parsing options in URI
-        CAParseURI(coapUri, &optlist);
-
-        // parsing options in HeadOption
-        CAParseHeadOption(code, info, &optlist);
-
-        OICFree(coapUri);
-    }
-
-    if (NULL != info.payload) // payload is include in request / response
-    {
-        if (!(pdu = CACreatePDUforRequestWithPayload((code_t) code, optlist, info.payload, info)))
-            return NULL;
-    }
-    else // payload is not include in request / response
-    {
-        if (!(pdu = CACreatePDUforRequest((code_t) code, optlist, info)))
-            return NULL;
-    }
-
-    // pdu print method : coap_show_pdu(pdu);
-    OIC_LOG(DEBUG, TAG, "CAGeneratePdu OUT");
-    return pdu;
-}
-
-coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode)
-{
-    OIC_LOG(DEBUG, TAG, "CAParsePDU IN");
-    coap_pdu_t *outpdu = coap_new_pdu();
-
-    coap_pdu_parse((unsigned char *) data, length, outpdu);
-    (*outCode) = (uint32_t) outpdu->hdr->code;
-    OIC_LOG(DEBUG, TAG, "CAParsePDU OUT");
-    return outpdu;
-}
-
-coap_pdu_t *CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *options,
-        const char* payload, const CAInfo_t info)
-{
-    OIC_LOG(DEBUG, TAG, "CACreatePDUforRequestWithPayload IN");
-
-    coap_pdu_t *pdu;
-    coap_list_t *opt;
-
-    uint32_t CAFlags = 0;
-    coap_block_t CABlock =
-    { .num = 0, .m = 0, .szx = 6 };
-
-    if (!(pdu = coap_new_pdu()))
-        return NULL;
-
-    /* initialize message id */
-    unsigned short message_id;
-    prng((unsigned char *) &message_id, sizeof(unsigned short));
-
-    pdu->hdr->type = CA_COAP_MESSAGE_CON;
-    ++message_id;
-    pdu->hdr->id = htons(message_id);
-    pdu->hdr->code = code;
-
-    if (info.token)
-    {
-        pdu->hdr->token_length = CA_MAX_TOKEN_LEN;
-        if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char*) info.token))
-        {
-            OIC_LOG(DEBUG, TAG, "cannot add token to request");
-        }
-    }
-    for (opt = options; opt; opt = opt->next)
-    {
-        coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option *) opt->data),
-                COAP_OPTION_LENGTH(*(coap_option *) opt->data),
-                COAP_OPTION_DATA(*(coap_option *) opt->data));
-    }
-
-    if (NULL != payload)
-    {
-        uint32_t len = strlen(payload);
-        if ((CAFlags & CA_FLAGS_BLOCK) == 0)
-        {
-            OIC_LOG_V(DEBUG, TAG, "coap_add_data, payload: %s", payload);
-            coap_add_data(pdu, len, (const unsigned char *) payload);
-        }
-        else
-        {
-            OIC_LOG_V(DEBUG, TAG, "coap_add_block, payload: %s", payload);
-            coap_add_block(pdu, len, (const unsigned char *) payload, CABlock.num, CABlock.szx);
-        }
-    }
-    OIC_LOG(DEBUG, TAG, "CACreatePDUforRequestWithPayload OUT");
-    return pdu;
-}
-
-coap_pdu_t* CACreatePDUforRequest(const code_t code, coap_list_t *options, const CAInfo_t info)
-{
-    OIC_LOG(DEBUG, TAG, "CACreatePDUforRequest IN");
-
-    coap_pdu_t *pdu;
-    coap_list_t *opt;
-
-    if (!(pdu = coap_new_pdu()))
-    {
-        OIC_LOG(DEBUG, TAG, "Out of memory");
-        return NULL;
-    }
-
-    /* initialize message id */
-    unsigned short message_id;
-    prng((unsigned char *) &message_id, sizeof(unsigned short));
-
-    pdu->hdr->type = CA_COAP_MESSAGE_CON;
-    ++message_id;
-    pdu->hdr->id = htons(message_id);
-    pdu->hdr->code = code;
-
-    OIC_LOG_V(DEBUG, TAG, "token info : %s, %d", info.token, strlen(info.token));
-    pdu->hdr->token_length = CA_MAX_TOKEN_LEN;
-    if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char*) info.token))
-    {
-        OIC_LOG(DEBUG, TAG, "cannot add token to request");
-    }
-
-    for (opt = options; opt; opt = opt->next)
-    {
-        coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option *) opt->data),
-                COAP_OPTION_LENGTH(*(coap_option *) opt->data),
-                COAP_OPTION_DATA(*(coap_option *) opt->data));
-    }
-    OIC_LOG(DEBUG, TAG, "CACreatePDUforRequest OUT");
-    return pdu;
-}
-
-void CAParseURI(const char *uriInfo, coap_list_t **optlist)
-{
-    OIC_LOG(DEBUG, TAG, "CAParseURI IN");
-
-    unsigned char portbuf[2];
-    unsigned char _buf[CA_BUFSIZE];
-    unsigned char *buf = _buf;
-    coap_uri_t uri;
-    size_t buflen;
-    uint32_t res;
-
-    OIC_LOG_V(DEBUG, TAG, "url : %s", uriInfo);
-
-    /* split arg into Uri-* options */
-    coap_split_uri((unsigned char *) uriInfo, strlen(uriInfo), &uri);
-
-    if (uri.port != COAP_DEFAULT_PORT)
-    {
-        coap_insert(optlist,
-                CACreateNewOptionNode(COAP_OPTION_URI_PORT,
-                        coap_encode_var_bytes(portbuf, uri.port), portbuf), CAOrderOpts);
-    }
-
-    if (uri.path.length)
-    {
-        buflen = CA_BUFSIZE;
-        res = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);
-
-        while (res--)
-        {
-            coap_insert(optlist,
-                    CACreateNewOptionNode(COAP_OPTION_URI_PATH, COAP_OPT_LENGTH(buf),
-                            COAP_OPT_VALUE(buf)), CAOrderOpts);
-            buf += COAP_OPT_SIZE(buf);
-        }
-    }
-
-    if (uri.query.length)
-    {
-        buflen = CA_BUFSIZE;
-        buf = _buf;
-        res = coap_split_query(uri.query.s, uri.query.length, buf, &buflen);
-
-        while (res--)
-        {
-            coap_insert(optlist,
-                    CACreateNewOptionNode(COAP_OPTION_URI_QUERY, COAP_OPT_LENGTH(buf),
-                            COAP_OPT_VALUE(buf)), CAOrderOpts);
-
-            buf += COAP_OPT_SIZE(buf);
-        }
-    }
-    OIC_LOG(DEBUG, TAG, "CAParseURI OUT");
-}
-
-void CAParseHeadOption(const uint32_t code, const CAInfo_t info, coap_list_t **optlist)
-{
-    OIC_LOG(DEBUG, TAG, "CAParseHeadOption IN");
-    OIC_LOG_V(DEBUG, TAG, "start parse Head Option : %d", info.numOptions);
-
-    uint32_t i;
-    for (i = 0; i < info.numOptions; i++)
-    {
-        uint32_t id = info.options[i].optionID;
-        if (COAP_OPTION_URI_PATH == id || COAP_OPTION_URI_QUERY == id)
-        {
-            OIC_LOG_V(DEBUG, TAG, "it is not Header Option : %d", id);
-        }
-        else
-        {
-            OIC_LOG_V(DEBUG, TAG, "Head Option ID: %d", info.options[i].optionID);
-            OIC_LOG_V(DEBUG, TAG, "Head Option data: %s", info.options[i].optionData);
-            OIC_LOG_V(DEBUG, TAG, "Head Option length: %d", info.options[i].optionLength);
-
-            coap_insert(optlist,
-                    CACreateNewOptionNode(info.options[i].optionID, info.options[i].optionLength,
-                            info.options[i].optionData), CAOrderOpts);
-        }
-    }
-    OIC_LOG(DEBUG, TAG, "CAParseHeadOption OUT");
-}
-
-coap_list_t *CACreateNewOptionNode(const uint16_t key, const uint32_t length, const uint8_t *data)
-{
-    OIC_LOG(DEBUG, TAG, "CACreateNewOptionNode IN");
-    coap_option *option;
-    coap_list_t *node;
-
-    option = coap_malloc(sizeof(coap_option) + length);
-    if (!option)
-    {
-        OIC_LOG(DEBUG, TAG, "Out of memory");
-        return NULL;
-    }
-    memset(option, 0, sizeof(coap_option) + length);
-
-    COAP_OPTION_KEY (*option) = key;
-    COAP_OPTION_LENGTH (*option) = length;
-    memcpy(COAP_OPTION_DATA(*option), data, length);
-
-    /* we can pass NULL here as delete function since option is released automatically  */
-    node = coap_new_listnode(option, NULL);
-
-    if (!node)
-    {
-        OIC_LOG(DEBUG, TAG, "coap_new_listnode returns NULL");
-        coap_free(option);
-        return NULL;
-    }
-    //coap_free(option);
-    OIC_LOG(DEBUG, TAG, "CACreateNewOptionNode OUT");
-    return node;
-}
-
-int CAOrderOpts(void *a, void *b)
-{
-    OIC_LOG(DEBUG, TAG, "CAOrderOpts IN");
-    if (!a || !b)
-    {
-        return a < b ? -1 : 1;
-    }
-
-    if (COAP_OPTION_KEY(*(coap_option *) a) < COAP_OPTION_KEY(*(coap_option *) b))
-    {
-        return -1;
-    }
-    OIC_LOG(DEBUG, TAG, "CAOrderOpts OUT");
-    return COAP_OPTION_KEY(*(coap_option *) a) == COAP_OPTION_KEY(*(coap_option *) b);
-}
-
-uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter)
-{
-    OIC_LOG(DEBUG, TAG, "CAGetOptionCount IN");
-    uint32_t count = 0;
-    coap_opt_t *option;
-
-    while ((option = coap_option_next(&opt_iter)))
-    {
-        if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type)
-        {
-
-        }
-        else
-        {
-            count++;
-        }
-    }
-    OIC_LOG(DEBUG, TAG, "CAGetOptionCount OUT");
-    return count;
-}
-
-void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo, char *outUri)
-{
-    OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo IN");
-    char buf[COAP_MAX_PDU_SIZE]; /* need some space for output creation */
-    uint32_t encode = 0;
-    coap_opt_iterator_t opt_iter;
-    coap_opt_t *option;
-    char optionResult[CA_MAX_URI_LENGTH] =
-    { 0, };
-    uint32_t count = 0, idx = 0;
-    uint32_t optionLength = 0;
-    uint32_t isfirstsetflag = 0;
-
-    coap_option_iterator_init((coap_pdu_t *) pdu, &opt_iter, COAP_OPT_ALL);
-
-    memset(optionResult, 0, sizeof(optionResult));
-
-    // set code
-    (*outCode) = (uint32_t) pdu->hdr->code;
-
-    // init HeaderOption list
-    count = CAGetOptionCount(opt_iter);
-
-    memset(outInfo, 0, sizeof(CAInfo_t));
-    outInfo->numOptions = count;
-    if (count > 0)
-    {
-        outInfo->options = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * count);
-        memset(outInfo->options, 0, sizeof(CAHeaderOption_t) * count);
-    }
-
-    while ((option = coap_option_next(&opt_iter)))
-    {
-
-        if (CAGetOptionData((uint8_t*) (COAP_OPT_VALUE(option)), COAP_OPT_LENGTH(option),
-                (uint8_t*) buf, sizeof(buf), encode))
-        {
-            if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type)
-            {
-                if (0 == isfirstsetflag)
-                {
-                    isfirstsetflag = 1;
-                    memcpy(optionResult + optionLength, buf, strlen((const char *) buf));
-                    optionLength += strlen((const char *) buf);
-
-                }
-                else
-                {
-                    if (COAP_OPTION_URI_PATH == opt_iter.type)
-                    {
-                        memcpy(optionResult + optionLength, "/", 1);
-                        optionLength++;
-                    }
-                    else if (COAP_OPTION_URI_QUERY == opt_iter.type)
-                    {
-                        memcpy(optionResult + optionLength, "?", 1);
-                        optionLength++;
-                    }
-                    memcpy(optionResult + optionLength, buf, strlen((const char *) buf));
-                    optionLength += strlen((const char *) buf);
-                }
-            }
-            else
-            {
-
-                if (idx < count)
-                {
-                    uint32_t length = (uint32_t) strlen((const char *) buf);
-
-                    if (length <= CA_MAX_HEADER_OPTION_DATA_LENGTH)
-                    {
-                        outInfo->options[idx].optionID = opt_iter.type;
-                        outInfo->options[idx].optionLength = length;
-                        outInfo->options[idx].protocolID = CA_COAP_ID;
-                        memcpy(outInfo->options[idx].optionData, buf, length);
-                        idx++;
-                    }
-                }
-            }
-        }
-    }
-
-    // set token data
-    if (pdu->hdr->token_length > 0)
-    {
-        OIC_LOG(DEBUG, TAG, "inside pdu->hdr->token_length");
-        outInfo->token = (char *) OICMalloc(CA_MAX_TOKEN_LEN);
-        memcpy(outInfo->token, pdu->hdr->token, CA_MAX_TOKEN_LEN);
-    }
-
-    // set payload data
-    if (NULL != pdu->data)
-    {
-        OIC_LOG(DEBUG, TAG, "inside pdu->data");
-        outInfo->payload = (char *) OICMalloc(strlen((const char *) pdu->data) + 1);
-        memcpy(outInfo->payload, pdu->data, strlen((const char *) pdu->data) + 1);
-    }
-
-    OIC_LOG_V(DEBUG, TAG, "made URL : %s\n", optionResult);
-    // set uri info
-    memcpy(outUri, optionResult, strlen(optionResult));
-    OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo OUT");
-}
-
-CAResult_t CAGenerateTokenInternal(CAToken_t *token)
-{
-    OIC_LOG(DEBUG, TAG, "CAGenerateTokenInternal IN");
-    if (token == NULL)
-    {
-        return CA_STATUS_FAILED;
-    }
-
-    // memory allocation
-    char *temp = (char *) OICMalloc(sizeof(char) * (CA_MAX_TOKEN_LEN + 1));
-
-    if (temp == NULL)
-    {
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-    memset(temp, 0, sizeof(char) * (CA_MAX_TOKEN_LEN + 1));
-
-    // set random byte
-    uint32_t index;
-
-#ifndef __ARDUINO__
-    srand(time(NULL));
-#endif //#ifndef __ARDUINO__\r    for (index = 0; index < CA_MAX_TOKEN_LEN; index++)\r    {\r    // use valid characters
-    temp[index] = (rand() % 94 + 33) & 0xFF;
-}
-
-temp[index] = '\0';
-// save token
-*token = temp;
-
-OIC_LOG_V(DEBUG, TAG, "generate the token(%s)!!", *token);
-OIC_LOG(DEBUG, TAG, "CAGenerateTokenInternal OUT");
-return CA_STATUS_OK;
-}
-
-void CADestroyTokenInternal(CAToken_t token)
-{
-OIC_LOG(DEBUG, TAG, "CADestroyTokenInternal IN");
-if (token != NULL)
-{
-    OIC_LOG_V(DEBUG, TAG, "destroy the token(%s)!!", token);
-
-    OICFree(token);
-}
-OIC_LOG(DEBUG, TAG, "CADestroyTokenInternal OUT");
-}
-
-void CADeinitialize(CAInfo_t *info)
-{
-OIC_LOG(DEBUG, TAG, "CADeinitialize IN");
-
-if (NULL != info)
-{
-    if (NULL != info->options)
-    {
-        OIC_LOG(DEBUG, TAG, "free options in CAInfo");
-        OICFree(info->options);
-    }
-
-    if (NULL != info->token)
-    {
-        OIC_LOG(DEBUG, TAG, "free token in CAInfo");
-        OICFree(info->token);
-    }
-
-    if (NULL != info->payload)
-    {
-        OIC_LOG(DEBUG, TAG, "free payload in CAInfo");
-        OICFree(info->payload);
-    }
-}
-OIC_LOG(DEBUG, TAG, "CADeinitialize OUT");
-}
-
-uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *result, uint32_t buflen,
-    uint32_t encode_always)
-{
-const unsigned char hex[] = "0123456789ABCDEF";
-uint32_t cnt = 0;
-assert(data || len == 0);
-
-if (buflen == 0 || len == 0)
-    return 0;
-
-while (len)
-{
-    if (!encode_always)
-    {
-        if (cnt == buflen)
-            break;
-        *result++ = *data;
-        ++cnt;
-    }
-    else
-    {
-        if (cnt + 4 < buflen)
-        {
-            *result++ = '\\';
-            *result++ = 'x';
-            *result++ = hex[(*data & 0xf0) >> 4];
-            *result++ = hex[*data & 0x0f];
-            cnt += 4;
-        }
-        else
-            break;
-    }
-
-    ++data;
-    --len;
-}
-
-*result = '\0';
-return cnt;
-}
+/******************************************************************\r
+ *\r
+ * Copyright 2014 Samsung Electronics All Rights Reserved.\r
+ *\r
+ *\r
+ *\r
+ * Licensed under the Apache License, Version 2.0 (the "License");\r
+ * you may not use this file except in compliance with the License.\r
+ * You may obtain a copy of the License at\r
+ *\r
+ *      http://www.apache.org/licenses/LICENSE-2.0\r
+ *\r
+ * Unless required by applicable law or agreed to in writing, software\r
+ * distributed under the License is distributed on an "AS IS" BASIS,\r
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
+ * See the License for the specific language governing permissions and\r
+ * limitations under the License.\r
+ *\r
+ ******************************************************************/\r
+\r
+#include <stdio.h>\r
+#include <stdlib.h>\r
+#include <string.h>\r
+\r
+\r
+#include "caprotocolmessage.h"\r
+#include "logger.h"\r
+#include "oic_malloc.h"\r
+\r
+#define TAG "CA"\r
+\r
+#define CA_MAX_TOKEN_LEN   (8)\r
+#define CA_FLAGS_BLOCK 0x01\r
+#define CA_BUFSIZE 128\r
+#define CA_COAP_MESSAGE_CON 0\r
+\r
+#ifdef __ARDUINO__\r
+#include "util.h"\r
+#else\r
+#include <time.h>\r
+#endif //#ifdef __ARDUINO__\r
+\r
+uint32_t CAGetRequestInfoFromPdu(const coap_pdu_t *pdu, CARequestInfo_t *outReqInfo, \r
+                                            char *outUri)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CAGetRequestInfoFromPdu IN");\r
+\r
+    if (NULL == pdu)\r
+        return 0;\r
+\r
+    uint32_t code = CA_NOT_FOUND;\r
+    CAGetRequestPDUInfo(pdu, &code, &(outReqInfo->info), outUri);\r
+    outReqInfo->method = code;\r
+    OIC_LOG(DEBUG, TAG, "CAGetRequestInfoFromPdu OUT");\r
+    return 1;\r
+}\r
+\r
+uint32_t CAGetResponseInfoFromPdu(const coap_pdu_t *pdu, CAResponseInfo_t *outResInfo, \r
+                                            char *outUri)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CAGetResponseInfoFromPdu IN");\r
+    if (NULL == pdu)\r
+        return 0;\r
+\r
+    uint32_t code = CA_NOT_FOUND;\r
+    CAGetRequestPDUInfo(pdu, &code, &(outResInfo->info), outUri);\r
+    outResInfo->result = code;\r
+    OIC_LOG(DEBUG, TAG, "CAGetResponseInfoFromPdu OUT");\r
+    return 1;\r
+}\r
+\r
+coap_pdu_t *CAGeneratePdu(const char *uri, const uint32_t code, const CAInfo_t info)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CAGeneratePdu IN");\r
+\r
+    coap_pdu_t *pdu;\r
+    char *coapUri = NULL;\r
+    uint32_t coapHeaderLength = 12;\r
+    uint32_t length;\r
+    coap_list_t *optlist = NULL;\r
+\r
+    if (NULL == uri)\r
+        return NULL;\r
+\r
+    length = strlen(uri);\r
+    if (CA_MAX_URI_LENGTH < length)\r
+    {\r
+        OIC_LOG(DEBUG, TAG, "check URI length..");\r
+        return NULL;\r
+    }\r
+\r
+    coapUri = (char *) OICMalloc(length + coapHeaderLength + 1);\r
+    if (coapUri == NULL)\r
+    {\r
+        OIC_LOG(DEBUG, TAG, "CAGeneratePdu, Memory allocation failed !");\r
+        return NULL;\r
+    }\r
+    memset(coapUri, 0, length + coapHeaderLength + 1);\r
+\r
+    if (NULL != coapUri)\r
+    {\r
+        memcpy(coapUri, "coap://[::]/", coapHeaderLength);\r
+        memcpy(coapUri + coapHeaderLength, uri, length);\r
+\r
+        // parsing options in URI\r
+        CAParseURI(coapUri, &optlist);\r
+\r
+        // parsing options in HeadOption\r
+        CAParseHeadOption(code, info, &optlist);\r
+\r
+        OICFree(coapUri);\r
+    }\r
+\r
+    if (NULL != info.payload) // payload is include in request / response\r
+    {\r
+        if (!(pdu = CACreatePDUforRequestWithPayload((code_t) code, optlist, info.payload, info)))\r
+            return NULL;\r
+    }\r
+    else // payload is not include in request / response\r
+    {\r
+        if (!(pdu = CACreatePDUforRequest((code_t) code, optlist, info)))\r
+            return NULL;\r
+    }\r
+\r
+    // pdu print method : coap_show_pdu(pdu);\r
+    OIC_LOG(DEBUG, TAG, "CAGeneratePdu OUT");\r
+    return pdu;\r
+}\r
+\r
+coap_pdu_t *CAParsePDU(const char *data, uint32_t length, uint32_t *outCode)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CAParsePDU IN");\r
+    coap_pdu_t *outpdu = coap_new_pdu();\r
+\r
+    coap_pdu_parse((unsigned char *) data, length, outpdu);\r
+    (*outCode) = (uint32_t) outpdu->hdr->code;\r
+    OIC_LOG(DEBUG, TAG, "CAParsePDU OUT");\r
+    return outpdu;\r
+}\r
+\r
+coap_pdu_t *CACreatePDUforRequestWithPayload(const code_t code, coap_list_t *options,\r
+        const char* payload, const CAInfo_t info)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CACreatePDUforRequestWithPayload IN");\r
+\r
+    coap_pdu_t *pdu;\r
+    coap_list_t *opt;\r
+\r
+    uint32_t CAFlags = 0;\r
+    coap_block_t CABlock =\r
+    { .num = 0, .m = 0, .szx = 6 };\r
+\r
+    if (!(pdu = coap_new_pdu()))\r
+        return NULL;\r
+\r
+    /* initialize message id */\r
+    unsigned short message_id;\r
+    prng((unsigned char * )&message_id, sizeof(unsigned short));\r
+\r
+    pdu->hdr->type = info.type;\r
+    ++message_id;\r
+    pdu->hdr->id = htons(message_id);\r
+    pdu->hdr->code = code;\r
+\r
+    if (info.token)\r
+    {\r
+        pdu->hdr->token_length = CA_MAX_TOKEN_LEN;\r
+        if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char*) info.token))\r
+        {\r
+            OIC_LOG(DEBUG, TAG, "cannot add token to request");\r
+        }\r
+    }\r
+    for (opt = options; opt; opt = opt->next)\r
+    {\r
+        coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option * )opt->data),\r
+                        COAP_OPTION_LENGTH(*(coap_option * )opt->data),\r
+                        COAP_OPTION_DATA(*(coap_option * )opt->data));\r
+    }\r
+\r
+    if (NULL != payload)\r
+    {\r
+        uint32_t len = strlen(payload);\r
+        if ((CAFlags & CA_FLAGS_BLOCK) == 0)\r
+        {\r
+            OIC_LOG_V(DEBUG, TAG, "coap_add_data, payload: %s", payload);\r
+            coap_add_data(pdu, len, (const unsigned char *) payload);\r
+        }\r
+        else\r
+        {\r
+            OIC_LOG_V(DEBUG, TAG, "coap_add_block, payload: %s", payload);\r
+            coap_add_block(pdu, len, (const unsigned char *) payload, CABlock.num, CABlock.szx);\r
+        }\r
+    }\r
+    OIC_LOG(DEBUG, TAG, "CACreatePDUforRequestWithPayload OUT");\r
+    return pdu;\r
+}\r
+\r
+coap_pdu_t* CACreatePDUforRequest(const code_t code, coap_list_t *options, \r
+    const CAInfo_t info)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CACreatePDUforRequest IN");\r
+\r
+    coap_pdu_t *pdu;\r
+    coap_list_t *opt;\r
+\r
+    if (!(pdu = coap_new_pdu()))\r
+    {\r
+        OIC_LOG(DEBUG, TAG, "Out of memory");\r
+        return NULL;\r
+    }\r
+\r
+    /* initialize message id */\r
+    unsigned short message_id;\r
+    prng((unsigned char * )&message_id, sizeof(unsigned short));\r
+\r
+    pdu->hdr->type = info.type;\r
+    ++message_id;\r
+    pdu->hdr->id = htons(message_id);\r
+    pdu->hdr->code = code;\r
+\r
+    OIC_LOG_V(DEBUG, TAG, "token info : %s, %d", info.token, strlen(info.token));\r
+    pdu->hdr->token_length = CA_MAX_TOKEN_LEN;\r
+\r
+    if (!coap_add_token(pdu, CA_MAX_TOKEN_LEN, (unsigned char*) info.token))\r
+    {\r
+        OIC_LOG(DEBUG, TAG, "cannot add token to request");\r
+    }\r
+\r
+    for (opt = options; opt; opt = opt->next)\r
+    {\r
+        coap_add_option(pdu, COAP_OPTION_KEY(*(coap_option * )opt->data),\r
+                        COAP_OPTION_LENGTH(*(coap_option * )opt->data),\r
+                        COAP_OPTION_DATA(*(coap_option * )opt->data));\r
+    }\r
+    OIC_LOG(DEBUG, TAG, "CACreatePDUforRequest OUT");\r
+    return pdu;\r
+}\r
+\r
+void CAParseURI(const char *uriInfo, coap_list_t **optlist)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CAParseURI IN");\r
+\r
+    unsigned char portbuf[2];\r
+    unsigned char _buf[CA_BUFSIZE];\r
+    unsigned char *buf = _buf;\r
+    coap_uri_t uri;\r
+    size_t buflen;\r
+    uint32_t res;\r
+\r
+    OIC_LOG_V(DEBUG, TAG, "url : %s", uriInfo);\r
+\r
+    /* split arg into Uri-* options */\r
+    coap_split_uri((unsigned char *) uriInfo, strlen(uriInfo), &uri);\r
+\r
+    if (uri.port != COAP_DEFAULT_PORT)\r
+    {\r
+        coap_insert(optlist,\r
+                    CACreateNewOptionNode(COAP_OPTION_URI_PORT,\r
+                                          coap_encode_var_bytes(portbuf, uri.port), portbuf), \r
+                                          CAOrderOpts);\r
+    }\r
+\r
+    if (uri.path.length)\r
+    {\r
+        buflen = CA_BUFSIZE;\r
+        res = coap_split_path(uri.path.s, uri.path.length, buf, &buflen);\r
+\r
+        while (res--)\r
+        {\r
+            coap_insert(optlist,\r
+                        CACreateNewOptionNode(COAP_OPTION_URI_PATH, COAP_OPT_LENGTH(buf),\r
+                                              COAP_OPT_VALUE(buf)), CAOrderOpts);\r
+            buf += COAP_OPT_SIZE(buf);\r
+        }\r
+    }\r
+\r
+    if (uri.query.length)\r
+    {\r
+        buflen = CA_BUFSIZE;\r
+        buf = _buf;\r
+        res = coap_split_query(uri.query.s, uri.query.length, buf, &buflen);\r
+\r
+        while (res--)\r
+        {\r
+            coap_insert(optlist,\r
+                        CACreateNewOptionNode(COAP_OPTION_URI_QUERY, COAP_OPT_LENGTH(buf),\r
+                                              COAP_OPT_VALUE(buf)), CAOrderOpts);\r
+\r
+            buf += COAP_OPT_SIZE(buf);\r
+        }\r
+    }\r
+    OIC_LOG(DEBUG, TAG, "CAParseURI OUT");\r
+}\r
+\r
+void CAParseHeadOption(const uint32_t code, const CAInfo_t info, coap_list_t **optlist)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CAParseHeadOption IN");\r
+    OIC_LOG_V(DEBUG, TAG, "start parse Head Option : %d", info.numOptions);\r
+\r
+    uint32_t i;\r
+    for (i = 0; i < info.numOptions; i++)\r
+    {\r
+        uint32_t id = info.options[i].optionID;\r
+        if (COAP_OPTION_URI_PATH == id || COAP_OPTION_URI_QUERY == id)\r
+        {\r
+            OIC_LOG_V(DEBUG, TAG, "it is not Header Option : %d", id);\r
+        }\r
+        else\r
+        {\r
+            OIC_LOG_V(DEBUG, TAG, "Head Option ID: %d", info.options[i].optionID);\r
+            OIC_LOG_V(DEBUG, TAG, "Head Option data: %s", info.options[i].optionData);\r
+            OIC_LOG_V(DEBUG, TAG, "Head Option length: %d", info.options[i].optionLength);\r
+\r
+            coap_insert(optlist,\r
+                        CACreateNewOptionNode(info.options[i].optionID, \r
+                                            info.options[i].optionLength,\r
+                                              info.options[i].optionData), CAOrderOpts);\r
+        }\r
+    }\r
+    OIC_LOG(DEBUG, TAG, "CAParseHeadOption OUT");\r
+}\r
+\r
+coap_list_t *CACreateNewOptionNode(const uint16_t key, const uint32_t length, \r
+                                           const uint8_t *data)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CACreateNewOptionNode IN");\r
+    coap_option *option;\r
+    coap_list_t *node;\r
+\r
+    option = coap_malloc(sizeof(coap_option) + length);\r
+    if (!option)\r
+    {\r
+        OIC_LOG(DEBUG, TAG, "Out of memory");\r
+        return NULL;\r
+    }\r
+    memset(option, 0, sizeof(coap_option)+length);\r
+\r
+    COAP_OPTION_KEY(*option) = key;\r
+    COAP_OPTION_LENGTH(*option) = length;\r
+    memcpy(COAP_OPTION_DATA(*option), data, length);\r
+\r
+    /* we can pass NULL here as delete function since option is released automatically  */\r
+    node = coap_new_listnode(option, NULL);\r
+\r
+    if (!node)\r
+    {\r
+        OIC_LOG(DEBUG, TAG, "coap_new_listnode returns NULL");\r
+        coap_free(option);\r
+        return NULL;\r
+    }\r
+    //coap_free(option);\r
+    OIC_LOG(DEBUG, TAG, "CACreateNewOptionNode OUT");\r
+    return node;\r
+}\r
+\r
+int CAOrderOpts(void *a, void *b)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CAOrderOpts IN");\r
+    if (!a || !b)\r
+    {\r
+        return a < b ? -1 : 1;\r
+    }\r
+\r
+    if (COAP_OPTION_KEY(*(coap_option *)a) < COAP_OPTION_KEY(*(coap_option * )b))\r
+    {\r
+        return -1;\r
+    }\r
+    OIC_LOG(DEBUG, TAG, "CAOrderOpts OUT");\r
+    return COAP_OPTION_KEY(*(coap_option *)a) == COAP_OPTION_KEY(*(coap_option * )b);\r
+}\r
+\r
+uint32_t CAGetOptionCount(coap_opt_iterator_t opt_iter)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CAGetOptionCount IN");\r
+    uint32_t count = 0;\r
+    coap_opt_t *option;\r
+\r
+    while ((option = coap_option_next(&opt_iter)))\r
+    {\r
+        if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type)\r
+        {\r
+\r
+        } else {\r
+            count++;\r
+        }\r
+    }\r
+    OIC_LOG(DEBUG, TAG, "CAGetOptionCount OUT");\r
+    return count;\r
+}\r
+\r
+void CAGetRequestPDUInfo(const coap_pdu_t *pdu, uint32_t *outCode, CAInfo_t *outInfo, \r
+                                char *outUri)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo IN");\r
+    char buf[COAP_MAX_PDU_SIZE]; /* need some space for output creation */\r
+    uint32_t encode = 0;\r
+    coap_opt_iterator_t opt_iter;\r
+    coap_opt_t *option;\r
+    char optionResult[CA_MAX_URI_LENGTH] =\r
+    { 0, };\r
+    uint32_t count = 0, idx = 0;\r
+    uint32_t optionLength = 0;\r
+    uint32_t isfirstsetflag = 0;\r
+\r
+    coap_option_iterator_init((coap_pdu_t *) pdu, &opt_iter, COAP_OPT_ALL);\r
+\r
+    memset(optionResult, 0, sizeof(optionResult));\r
+\r
+    // set code\r
+    (*outCode) = (uint32_t) pdu->hdr->code;\r
+\r
+    // init HeaderOption list\r
+    count = CAGetOptionCount(opt_iter);\r
+\r
+    memset(outInfo, 0, sizeof(CAInfo_t));\r
+    outInfo->numOptions = count;\r
+    // set type\r
+    outInfo->type = pdu->hdr->type;\r
+\r
+    if(count > 0)\r
+    {\r
+        outInfo->options = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t) * count);\r
+        if (outInfo->options == NULL)\r
+        {\r
+            OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo, Memory allocation failed !");\r
+            return;\r
+        }\r
+        memset(outInfo->options, 0, sizeof(CAHeaderOption_t) * count);\r
+    }\r
+\r
+    while ((option = coap_option_next(&opt_iter)))\r
+    {\r
+\r
+        if (CAGetOptionData((uint8_t*)(COAP_OPT_VALUE(option)), \r
+            COAP_OPT_LENGTH(option), (uint8_t*)buf, sizeof(buf),\r
+                           encode))\r
+        {\r
+            if (COAP_OPTION_URI_PATH == opt_iter.type || COAP_OPTION_URI_QUERY == opt_iter.type)\r
+            {\r
+                if (0 == isfirstsetflag)\r
+                {\r
+                    isfirstsetflag = 1;\r
+                    memcpy(optionResult + optionLength, buf, strlen((const char *) buf));\r
+                    optionLength += strlen((const char *) buf);\r
+\r
+                }\r
+                else\r
+                {\r
+                    if (COAP_OPTION_URI_PATH == opt_iter.type)\r
+                    {\r
+                        memcpy(optionResult + optionLength, "/", 1);\r
+                        optionLength++;\r
+                    }\r
+                    else if (COAP_OPTION_URI_QUERY == opt_iter.type)\r
+                    {\r
+                        memcpy(optionResult + optionLength, "?", 1);\r
+                        optionLength++;\r
+                    }\r
+                    memcpy(optionResult + optionLength, buf, strlen((const char *) buf));\r
+                    optionLength += strlen((const char *) buf);\r
+                }\r
+            } else {\r
+\r
+                if (idx < count)\r
+                {\r
+                    uint32_t length = (uint32_t) strlen((const char *) buf);\r
+\r
+                if (length <= CA_MAX_HEADER_OPTION_DATA_LENGTH)\r
+                {\r
+                        outInfo->options[idx].optionID = opt_iter.type;\r
+                        outInfo->options[idx].optionLength = length;\r
+                        outInfo->options[idx].protocolID = CA_COAP_ID;\r
+                        memcpy(outInfo->options[idx].optionData, buf, length);\r
+                        idx++;\r
+                    }\r
+                }\r
+            }\r
+        }\r
+    }\r
+\r
+    // set token data\r
+    if (pdu->hdr->token_length > 0)\r
+    {\r
+        OIC_LOG(DEBUG, TAG, "inside pdu->hdr->token_length");\r
+        outInfo->token = (char *) OICMalloc(CA_MAX_TOKEN_LEN);\r
+        if (outInfo->token == NULL)\r
+         {\r
+             OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo, Memory allocation failed !");\r
+             OICFree(outInfo->options);\r
+             return;\r
+         }\r
+        memcpy(outInfo->token, pdu->hdr->token, CA_MAX_TOKEN_LEN);\r
+    }\r
+\r
+    // set payload data\r
+    if (NULL != pdu->data)\r
+    {\r
+        OIC_LOG(DEBUG, TAG, "inside pdu->data");\r
+        outInfo->payload = (char *) OICMalloc(strlen((const char *) pdu->data) + 1);\r
+        if (outInfo->payload == NULL)\r
+        {\r
+            OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo, Memory allocation failed !");\r
+            OICFree(outInfo->options);\r
+            OICFree(outInfo->token);\r
+            return;\r
+        }\r
+        memcpy(outInfo->payload, pdu->data, strlen((const char *) pdu->data) + 1);\r
+    }\r
+\r
+\r
+    memcpy(outUri, optionResult, strlen(optionResult));\r
+    OIC_LOG_V(DEBUG, TAG, "made URL : %s\n", optionResult);\r
+    OIC_LOG(DEBUG, TAG, "CAGetRequestPDUInfo OUT");\r
+\r
+}\r
+\r
+CAResult_t CAGenerateTokenInternal(CAToken_t *token)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CAGenerateTokenInternal IN");\r
+    if (token == NULL)\r
+    {\r
+        return CA_STATUS_FAILED;\r
+    }\r
+\r
+    // memory allocation\r
+    char *temp = (char *) OICMalloc(sizeof(char) * (CA_MAX_TOKEN_LEN + 1));\r
+    if (temp == NULL)\r
+    {\r
+        OIC_LOG(DEBUG, TAG, "CAGenerateTokenInternal, Memory allocation failed !");\r
+        return CA_MEMORY_ALLOC_FAILED;\r
+    }\r
+    memset(temp, 0, sizeof(char) * (CA_MAX_TOKEN_LEN + 1));\r
+\r
+    // set random byte\r
+    uint32_t index;\r
+\r
+#ifndef __ARDUINO__\r
+    srand(time(NULL));\r
+#endif //#ifndef __ARDUINO__\r
+    for (index = 0; index < CA_MAX_TOKEN_LEN; index++)\r
+    {\r
+        // use valid characters\r
+        temp[index] = (rand() % 94 + 33) & 0xFF;\r
+    }\r
+\r
+    temp[index] = '\0';\r
+    // save token\r
+    *token = temp;\r
+\r
+    OIC_LOG_V(DEBUG, TAG, "generate the token(%s)!!", *token);\r
+    OIC_LOG(DEBUG, TAG, "CAGenerateTokenInternal OUT");\r
+    return CA_STATUS_OK;\r
+}\r
+\r
+void CADestroyTokenInternal(CAToken_t token)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CADestroyTokenInternal IN");\r
+    if (token != NULL)\r
+    {\r
+        OIC_LOG_V(DEBUG, TAG, "destroy the token(%s)!!", token);\r
+\r
+        OICFree(token);\r
+    }\r
+    OIC_LOG(DEBUG, TAG, "CADestroyTokenInternal OUT");\r
+}\r
+\r
+void CADeinitialize(CAInfo_t *info)\r
+{\r
+    OIC_LOG(DEBUG, TAG, "CADeinitialize IN");\r
+\r
+    if (NULL != info)\r
+    {\r
+        if (NULL != info->options)\r
+        {\r
+            OIC_LOG(DEBUG, TAG, "free options in CAInfo");\r
+            OICFree(info->options);\r
+        }\r
+\r
+        if (NULL != info->token)\r
+        {\r
+            OIC_LOG(DEBUG, TAG, "free token in CAInfo");\r
+            OICFree(info->token);\r
+        }\r
+\r
+        if (NULL != info->payload)\r
+        {\r
+            OIC_LOG(DEBUG, TAG, "free payload in CAInfo");\r
+            OICFree(info->payload);\r
+        }\r
+    }\r
+    OIC_LOG(DEBUG, TAG, "CADeinitialize OUT");\r
+}\r
+\r
+uint32_t CAGetOptionData(const uint8_t *data, uint32_t len, uint8_t *result,\r
+        uint32_t buflen, uint32_t encode_always)\r
+{\r
+    const unsigned char hex[] = "0123456789ABCDEF";\r
+    uint32_t cnt = 0;\r
+    assert(data || len == 0);\r
+\r
+    if (buflen == 0 || len == 0)\r
+        return 0;\r
+\r
+    while (len)\r
+    {\r
+        if (!encode_always)\r
+        {\r
+            if (cnt == buflen)\r
+                break;\r
+            *result++ = *data;\r
+            ++cnt;\r
+        }\r
+        else\r
+        {\r
+            if (cnt + 4 < buflen)\r
+            {\r
+                *result++ = '\\';\r
+                *result++ = 'x';\r
+                *result++ = hex[(*data & 0xf0) >> 4];\r
+                *result++ = hex[*data & 0x0f];\r
+                cnt += 4;\r
+            }\r
+            else\r
+                break;\r
+        }\r
+\r
+        ++data;\r
+        --len;\r
+    }\r
+\r
+    *result = '\0';\r
+    return cnt;\r
+}\r
index 11fbee2..18da00d 100644 (file)
@@ -53,6 +53,7 @@ static void CAQueueingThreadBaseRoutine(void *threadValue)
         if (u_queue_get_size(thread->dataQueue) <= 0)
         {
             OIC_LOG_V(DEBUG, TAG, "wait..");
+            
             // wait
             u_cond_wait(thread->threadCond, thread->threadMutex);
 
@@ -109,7 +110,7 @@ CAResult_t CAQueueingThreadInitialize(CAQueueingThread_t *thread, u_thread_pool_
     thread->dataQueue = u_queue_create();
     thread->threadMutex = u_mutex_new();
     thread->threadCond = u_cond_new();
-    thread->isStop = CA_FALSE;
+    thread->isStop = CA_TRUE;
     thread->threadTask = task;
 
     return CA_STATUS_OK;
@@ -138,6 +139,8 @@ CAResult_t CAQueueingThreadStart(CAQueueingThread_t *thread)
         return res;
     }
 
+    thread->isStop = CA_FALSE;
+
     return res;
 }
 
@@ -212,19 +215,22 @@ CAResult_t CAQueueingThreadStop(CAQueueingThread_t *thread)
 
     OIC_LOG_V(DEBUG, TAG, "thread stop request!!");
 
-    // mutex lock
-    u_mutex_lock(thread->threadMutex);
+    if (!thread->isStop)
+    {
+        // mutex lock
+        u_mutex_lock(thread->threadMutex);
 
-    // set stop flag
-    thread->isStop = CA_TRUE;
+        // set stop flag
+        thread->isStop = CA_TRUE;
 
-    // notity the thread
-    u_cond_signal(thread->threadCond);
+        // notity the thread
+        u_cond_signal(thread->threadCond);
 
-    u_cond_wait(thread->threadCond, thread->threadMutex);    
+        u_cond_wait(thread->threadCond, thread->threadMutex);
 
-    // mutex unlock
-    u_mutex_unlock(thread->threadMutex);
+        // mutex unlock
+        u_mutex_unlock(thread->threadMutex);
+    }
 
     return CA_STATUS_OK;
 }
index 9538eb8..b0addc6 100644 (file)
@@ -27,7 +27,7 @@
 CARemoteEndpoint_t *CACloneRemoteEndpoint(const CARemoteEndpoint_t *rep)
 {
     char *temp = NULL;
-    int len = 0;
+    uint32_t len = 0;
 
     if (rep == NULL)
         return NULL;
@@ -309,6 +309,13 @@ CARequestInfo_t *CACloneRequestInfo(const CARequestInfo_t *rep)
     {
         // save the options
         clone->info.options = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t));
+        if (clone->info.options == NULL)
+        {
+            OIC_LOG_V(DEBUG, TAG, "CACloneRequestInfo Out of memory");
+            OICFree(clone->info.token);
+            OICFree(clone);
+            return NULL;
+        }
         memset(clone->info.options, 0, sizeof(CAHeaderOption_t));
         memcpy(clone->info.options, rep->info.options, sizeof(CAHeaderOption_t));
     }
@@ -380,6 +387,13 @@ CAResponseInfo_t *CACloneResponseInfo(const CAResponseInfo_t *rep)
     {
         // save the options
         clone->info.options = (CAHeaderOption_t *) OICMalloc(sizeof(CAHeaderOption_t));
+        if (clone->info.options == NULL)
+        {
+            OIC_LOG_V(DEBUG, TAG, "CACloneResponseInfo Out of memory");
+            OICFree(clone->info.token);
+            OICFree(clone);
+            return NULL;
+        }
         memset(clone->info.options, 0, sizeof(CAHeaderOption_t));
         memcpy(clone->info.options, rep->info.options, sizeof(CAHeaderOption_t));
     }
diff --git a/resource/csdk/connectivity/src/ethernet_adapter/arduino/README.txt b/resource/csdk/connectivity/src/ethernet_adapter/arduino/README.txt
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter.c b/resource/csdk/connectivity/src/ethernet_adapter/caethernetadapter.c
new file mode 100644 (file)
index 0000000..2bc6d3f
--- /dev/null
@@ -0,0 +1,674 @@
+/******************************************************************
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+#include "caethernetadapter.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "caethernetinterface.h"
+#include "caqueueingthread.h"
+#include "caadapterutils.h"
+#include "umutex.h"
+#include "logger.h"
+#include "oic_malloc.h"
+
+/**
+ * @def WIFI_ETHERNET_ADAPTER_TAG
+ * @brief Logging tag for module name
+ */
+#define ETHERNET_ADAPTER_TAG "ETHERNET_ADAP"
+
+/**
+ * @def CA_PORT
+ * @brief Port to listen for incoming data
+ */
+#define CA_PORT   5283
+
+/**
+ * @def CA_MCAST_PORT
+ * @brief Multicast Port Number
+ */
+#define CA_MCAST_PORT   5298
+
+/**
+ * @def CA_MULTICAST_IP
+ * @brief Multicast IP Address
+ */
+#define CA_MULTICAST_IP "224.0.1.187"
+
+
+typedef struct
+{
+    CARemoteEndpoint_t *remoteEndpoint;
+    void *data;
+    uint32_t dataLen;
+} CAEthernetData;
+
+/**
+ * @var gNetworkPacketCallback
+ * @brief Network Packet Received Callback to CA
+ */
+static CANetworkPacketReceivedCallback gNetworkPacketCallback = NULL;
+
+/**
+ * @var gEthernetNetworkChangeCallback
+ * @brief Network Changed Callback to CA
+ */
+CANetworkChangeCallback gEthernetNetworkChangeCallback = NULL;
+
+/**
+ * @var gIsMulticastServerStarted
+ * @brief Flag to check if multicast server is started
+ */
+static bool gIsMulticastServerStarted = false;
+
+/**
+ * @var gIsStartServerCalled
+ * @brief Flag to check if server start requested by CA.
+ */
+static bool gStartUnicastServerRequested = false;
+
+/**
+ * @var gUnicastServerport
+ * @brief port number on which unicast server is running.
+ */
+static int16_t gUnicastServerport = 0;
+
+/**
+ * @var gIsStartServerCalled
+ * @brief Flag to check if server start requested by CA.
+ */
+static bool gStartMulticastServerRequested = false;
+
+/**
+ * @var gSendQueueHandle
+ * @brief Queue handle for Send Data
+ */
+static CAQueueingThread_t *gSendQueueHandle = NULL;
+
+/**
+ * @var gThreadPool
+ * @brief ThreadPool for storing u_thread_pool_t handle passed from CA
+ */
+static u_thread_pool_t gThreadPool = NULL;
+
+static CAResult_t CAEthernetInitializeQueueHandles();
+static void CAEthernetDeinitializeQueueHandles();
+static void CAEthernetNotifyNetworkChange(const char *address, const int16_t port,
+                                      const CANetworkStatus_t status);
+static void CAEthernetConnectionStateCB(const char *ipAddress,
+                                    const CANetworkStatus_t status);
+static void CAEthernetPacketReceivedCB(const char *ipAddress, const uint32_t port,
+                                   const void *data, const uint32_t dataLength);
+static CAResult_t CAEthernetStopServers();
+static void CAEthernetSendDataThread(void *threadData);
+static CAEthernetData *CACreateEthernetData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+                                    uint32_t dataLength);
+void CAFreeEthernetData(CAEthernetData *ethernetData);
+
+
+CAResult_t CAEthernetInitializeQueueHandles()
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+    // Check if the message queue is already initialized
+    if (gSendQueueHandle)
+    {
+        OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "Already queue is initialized!");
+        return CA_STATUS_OK;
+    }
+
+    // Create send message queue
+    gSendQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
+    if (!gSendQueueHandle)
+    {
+        OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Memory allocation failed!");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    if (CA_STATUS_OK != CAQueueingThreadInitialize(gSendQueueHandle, gThreadPool,
+            CAEthernetSendDataThread))
+    {
+        OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Initialize send queue thread");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAEthernetDeinitializeQueueHandles()
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+    CAQueueingThreadDestroy(gSendQueueHandle);
+    OICFree(gSendQueueHandle);
+    gSendQueueHandle = NULL;
+
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+}
+
+void CAEthernetNotifyNetworkChange(const char *address, const int16_t port,
+                               const CANetworkStatus_t status)
+{
+    CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_ETHERNET, address, "Ethernet");
+    if (!localEndpoint)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Out of memory");
+        return;
+    }
+    localEndpoint->addressInfo.IP.port = port;
+
+    if (NULL != gEthernetNetworkChangeCallback)
+    {
+        gEthernetNetworkChangeCallback(localEndpoint, status);
+    }
+
+    CAAdapterFreeLocalEndpoint(localEndpoint);
+}
+
+void CAEthernetConnectionStateCB(const char *ipAddress,
+                             const CANetworkStatus_t status)
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+    CAResult_t ret = CA_STATUS_FAILED;
+    /* If Ethernet is connected, then get the latest IP from the Ethernet Interface
+      * and start unicast and multicast servers if requested earlier */
+    if (CA_INTERFACE_UP == status)
+    {
+        int16_t port = CA_PORT;
+        int32_t serverFd = -1;
+        /* Start Unicast server if requested earlier */
+        if (gStartUnicastServerRequested)
+        {
+            ret = CAEthernetStartUnicastServer("0.0.0.0", &port, false, &serverFd);
+            if (CA_STATUS_OK == ret)
+            {
+                OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Unicast server started on %d port", port);
+                CAEthernetSetUnicastSocket(serverFd);
+                gUnicastServerport = port;
+            }
+            else
+            {
+                OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to start Unicast server [%d]", ret);
+            }
+        }
+
+        /* Start Multicast server if requested earlier */
+        if (gStartMulticastServerRequested)
+        {
+            int16_t multicastPort = CA_MCAST_PORT;
+            int32_t multicastFd = 0;
+            ret = CAEthernetStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort,
+                &multicastFd);
+            if (CA_STATUS_OK == ret)
+            {
+                OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Multicast server started on %d port",
+                    multicastPort);
+                gIsMulticastServerStarted = true;
+            }
+            else
+            {
+                OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to start Multicast server [%d]", ret);
+            }
+        }
+
+        char *ipAddress = NULL;
+        char *ifcName = NULL;
+        ret = CAEthernetGetInterfaceInfo(&ifcName, &ipAddress);
+        if (CA_STATUS_OK != ret)
+        {
+            OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
+            return;
+        }
+
+        /* Notify network change to CA */
+        CAEthernetNotifyNetworkChange(ipAddress, port, status);
+        OICFree(ipAddress);
+        OICFree(ifcName);
+    }
+    else
+    {
+        CAEthernetNotifyNetworkChange("", 0, status);
+        /* Stop both Unicast and Multicast servers */
+        ret = CAEthernetStopServers();
+        if (CA_STATUS_OK != ret)
+        {
+            OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Stop Servers![%d]", ret);
+            return;
+        }
+    }
+
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+}
+
+void CAEthernetPacketReceivedCB(const char *ipAddress, const uint32_t port,
+                            const void *data, const uint32_t dataLength)
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+    OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Address: %s, port:%d, data:%s", ipAddress, port, data);
+
+    /* CA is freeing this memory */
+    CARemoteEndpoint_t *endPoint = CAAdapterCreateRemoteEndpoint(CA_ETHERNET, ipAddress, NULL);
+    if (NULL == endPoint)
+    {
+        OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Out of memory");
+        return;
+    }
+    endPoint->addressInfo.IP.port = port;
+
+    void *buf = OICMalloc(dataLength + 1);
+    if (NULL == buf)
+    {
+        OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Out of memory");
+        CAAdapterFreeRemoteEndpoint(endPoint);
+        return;
+    }
+    memcpy(buf, data, dataLength);
+    memset(buf + dataLength, 0, 1);
+    if (gNetworkPacketCallback)
+    {
+        gNetworkPacketCallback(endPoint, buf, dataLength);
+    }
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+}
+
+CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
+                            CANetworkPacketReceivedCallback networkPacketCallback,
+                            CANetworkChangeCallback netCallback, u_thread_pool_t handle)
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+    VERIFY_NON_NULL(registerCallback, ETHERNET_ADAPTER_TAG, "registerCallback");
+    VERIFY_NON_NULL(networkPacketCallback, ETHERNET_ADAPTER_TAG, "networkPacketCallback");
+    VERIFY_NON_NULL(netCallback, ETHERNET_ADAPTER_TAG, "netCallback");
+    VERIFY_NON_NULL(handle, ETHERNET_ADAPTER_TAG, "thread pool handle");
+
+    gThreadPool  = handle;
+    gEthernetNetworkChangeCallback = netCallback;
+    gNetworkPacketCallback = networkPacketCallback;
+
+    CAResult_t ret = CAEthernetInitializeNetworkMonitor(gThreadPool);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to initialize n/w monitor![%d]", ret);
+        return ret;
+    }
+    CAEthernetSetConnectionStateChangeCallback(CAEthernetConnectionStateCB);
+
+    ret = CAEthernetInitializeServer(gThreadPool);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to initialize server![%d]", ret);
+        CATerminateEthernet();
+        return ret;
+    }
+    CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCB);
+
+    CAConnectivityHandler_t ethernetHandler;
+    ethernetHandler.startAdapter = CAStartEthernet;
+    ethernetHandler.startListenServer = CAStartEthernetListeningServer;
+    ethernetHandler.startDiscoverServer = CAStartEthernetDiscoveryServer;
+    ethernetHandler.sendData = CASendEthernetUnicastData;
+    ethernetHandler.sendDataToAll = CASendEthernetMulticastData;
+    ethernetHandler.GetnetInfo = CAGetEthernetInterfaceInformation;
+    ethernetHandler.readData = CAReadEthernetData;
+    ethernetHandler.stopAdapter = CAStopEthernet;
+    ethernetHandler.terminate = CATerminateEthernet;
+    registerCallback(ethernetHandler, CA_ETHERNET);
+
+    if (CA_STATUS_OK != CAEthernetInitializeQueueHandles())
+    {
+        OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Initialize Queue Handle");
+        CATerminateEthernet();
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "IntializeEthernet is Success");
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStartEthernet()
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+    /* Start monitoring Ethernet network */
+    CAResult_t ret = CAEthernetStartNetworkMonitor();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Start n/w monitor");
+    }
+
+    gStartUnicastServerRequested = true;
+    bool retVal = CAEthernetIsConnected();
+    if (false == retVal)
+    {
+        OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Ethernet is not Connected");
+        return ret;
+    }
+
+    int16_t unicastPort = CA_PORT;
+    int32_t serverFd = 0;
+    // Address is hardcoded as we are using Single Interface
+    ret = CAEthernetStartUnicastServer("0.0.0.0", &unicastPort, false, &serverFd);
+    if (CA_STATUS_OK == ret)
+    {
+        OIC_LOG_V(DEBUG, ETHERNET_ADAPTER_TAG, "Unicast server started on %d port", unicastPort);
+        CAEthernetSetUnicastSocket(serverFd);
+        gUnicastServerport = unicastPort;
+    }
+
+    // Start send queue thread
+    if (CA_STATUS_OK != CAQueueingThreadStart(gSendQueueHandle))
+    {
+        OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Start Send Data Thread");
+        CAStopEthernet();
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+    return ret;
+}
+
+CAResult_t CAStartEthernetListeningServer()
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+    CAResult_t ret = CA_STATUS_OK;
+    int16_t multicastPort = CA_MCAST_PORT;
+
+    if (gIsMulticastServerStarted == true)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG,
+                  "Failed to Start Multicast Server, Already Started!");
+        return CA_SERVER_STARTED_ALREADY;
+    }
+
+    gStartMulticastServerRequested = true;
+    bool retVal = CAEthernetIsConnected();
+    if (false == retVal)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG,
+                  "Failed to Start Multicast Server, Ethernet not Connected");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    int32_t multicastFd = 0;
+    ret = CAEthernetStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, &multicastFd);
+    if (CA_STATUS_OK == ret)
+    {
+        OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "Multicast Server is Started Successfully");
+        gIsMulticastServerStarted = true;
+    }
+
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+    return ret;
+}
+
+CAResult_t CAStartEthernetDiscoveryServer()
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+    /* Both listening and discovery server are same */
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+    return CAStartEthernetListeningServer();
+}
+
+uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+                               uint32_t dataLength)
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+    uint32_t dataSize = 0;
+    VERIFY_NON_NULL_RET(remoteEndpoint, ETHERNET_ADAPTER_TAG, "remoteEndpoint", dataSize);
+    VERIFY_NON_NULL_RET(data, ETHERNET_ADAPTER_TAG, "data", dataSize);
+    VERIFY_NON_NULL_RET(gSendQueueHandle, ETHERNET_ADAPTER_TAG, "sendQueueHandle", dataSize);
+
+    if (0 == dataLength)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Invalid Data Length");
+        return dataSize;
+    }
+
+    // Create EthernetData to add to queue
+    CAEthernetData *ethernetData = CACreateEthernetData(remoteEndpoint, data, dataLength);
+    if (!ethernetData)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to create ethernetData!");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    // Add message to send queue
+    CAQueueingThreadAddData(gSendQueueHandle, ethernetData, sizeof(CAEthernetData));
+
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+    return dataLength;
+}
+
+uint32_t CASendEthernetMulticastData(void *data, uint32_t dataLength)
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+    uint32_t dataSize = 0;
+    VERIFY_NON_NULL_RET(data, ETHERNET_ADAPTER_TAG, "data", dataSize);
+    VERIFY_NON_NULL_RET(gSendQueueHandle, ETHERNET_ADAPTER_TAG, "sendQueueHandle", dataSize);
+
+    if (0 == dataLength)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Invalid Data Length");
+        return dataSize;
+    }
+
+    // Create ethernetData to add to queue
+    CAEthernetData *ethernetData = CACreateEthernetData(NULL, data, dataLength);
+    if (!ethernetData)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to create ethernetData!");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    // Add message to send queue
+    CAQueueingThreadAddData(gSendQueueHandle, ethernetData, sizeof(CAEthernetData));
+
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+    return dataLength;
+}
+
+CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+    VERIFY_NON_NULL(info, ETHERNET_ADAPTER_TAG, "info");
+    VERIFY_NON_NULL(size, ETHERNET_ADAPTER_TAG, "size");
+
+    bool retVal = CAEthernetIsConnected();
+    if (false == retVal)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG,
+                  "Failed to get interface address, Ethernet not Connected", CA_ADAPTER_NOT_ENABLED);
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    char *ipAddress = NULL;
+    char *ifcName = NULL;
+    CAResult_t ret = CAEthernetGetInterfaceInfo(&ifcName, &ipAddress);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
+        return ret;
+    }
+
+    // Create local endpoint using util function
+    (*info) = CAAdapterCreateLocalEndpoint(CA_ETHERNET, ipAddress, ifcName);
+    if (NULL == (*info))
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to create Local Endpoint!",
+                  CA_MEMORY_ALLOC_FAILED);
+        OICFree(ipAddress);
+        OICFree(ifcName);
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    (*info)->addressInfo.IP.port = gUnicastServerport;
+    (*size) = 1;
+
+    OICFree(ipAddress);
+    OICFree(ifcName);
+
+    OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "GetEthernetInterfaceInformation success");
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAReadEthernetData()
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAEthernetStopServers()
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+    CAResult_t result = CAEthernetStopUnicastServer();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Stop Unicast Server![%d]", result);
+        return result;
+    }
+    CAEthernetSetUnicastSocket(-1);
+    gUnicastServerport = -1;
+
+    result = CAEthernetStopMulticastServer();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Stop Multicast Server![%d]", result);
+        return result;
+    }
+    gIsMulticastServerStarted = false;
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+    return result;
+}
+
+CAResult_t CAStopEthernet()
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+    gStartUnicastServerRequested = false;
+    gStartMulticastServerRequested = false;
+
+    // Stop Ethernet network monitor
+    CAEthernetStopNetworkMonitor();
+
+    //Stop send queue thread
+    CAQueueingThreadStop(gSendQueueHandle);
+
+    // Stop unicast/multicast servers running
+    CAResult_t result = CAEthernetStopServers();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_ADAPTER_TAG, "Failed to Stop Servers![%d]", result);
+    }
+
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+    return result;
+}
+
+void CATerminateEthernet()
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+    CAEthernetSetConnectionStateChangeCallback(NULL);
+    CAEthernetTerminateNetworkMonitor();
+    OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "nw monitor terminated");
+    CAEthernetDeinitializeQueueHandles();
+    OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "sendQueue terminated");
+
+    CAEthernetSetPacketReceiveCallback(NULL);
+    OIC_LOG(INFO, ETHERNET_ADAPTER_TAG, "TerminateEthernet Success");
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+    return;
+}
+
+void CAEthernetSendDataThread(void *threadData)
+{
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
+
+    CAEthernetData *ethernetData = (CAEthernetData *) threadData;
+    if (!ethernetData)
+    {
+        OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "Invalid ethernetdata!");
+        return;
+    }
+
+    if (NULL != ethernetData->remoteEndpoint)
+    {
+        OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "Send Unicast Data is called");
+        CAEthernetSendData(ethernetData->remoteEndpoint->addressInfo.IP.ipAddress,
+                            ethernetData->remoteEndpoint->addressInfo.IP.port, ethernetData->data,
+                            ethernetData->dataLen, false);
+    }
+    else
+    {
+        OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "Send Multicast Data is called");
+        CAEthernetSendData(CA_MULTICAST_IP, CA_MCAST_PORT, ethernetData->data, ethernetData->dataLen, true);
+    }
+
+    //Free Ethernet data
+    CAFreeEthernetData(ethernetData);
+
+    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
+    return ;
+}
+
+CAEthernetData *CACreateEthernetData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+                             uint32_t dataLength)
+{
+    CAEthernetData *ethernetData = (CAEthernetData *) OICMalloc(sizeof(CAEthernetData));
+    if (!ethernetData)
+    {
+        OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Memory allocation failed!");
+        return NULL;
+    }
+
+    ethernetData->remoteEndpoint = CAAdapterCopyRemoteEndpoint(remoteEndpoint);
+    ethernetData->data = (void *)OICMalloc(dataLength);
+    if (NULL == ethernetData->data)
+    {
+        OIC_LOG(ERROR, ETHERNET_ADAPTER_TAG, "Memory allocation failed!");
+        CAFreeEthernetData(ethernetData);
+        return NULL;
+    }
+    memcpy(ethernetData->data, data, dataLength);
+    ethernetData->dataLen = dataLength;
+
+    return ethernetData;
+}
+
+void CAFreeEthernetData(CAEthernetData *ethernetData)
+{
+    if (!ethernetData)
+        return;
+
+    CAAdapterFreeRemoteEndpoint(ethernetData->remoteEndpoint);
+    OICFree(ethernetData->data);
+    OICFree(ethernetData);
+}
diff --git a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetadapter.c b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetadapter.c
deleted file mode 100644 (file)
index faf8299..0000000
+++ /dev/null
@@ -1,183 +0,0 @@
-/******************************************************************
- *
- * Copyright 2014 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "caethernetadapter.h"
-//#include "config.h"
-//#include "coap.h"
-#include "caethernetcore.h"
-#include "logger.h"
-#include "oic_malloc.h"
-
-#define TAG PCF("CA")
-
-// received packet callback
-static CANetworkPacketReceivedCallback gEthernetReceivedCallback = NULL;
-static u_thread_pool_t gThreadPoolHandle = NULL;
-
-static void CAEthernetPacketReceiveCallback(char* address, const char* data, uint32_t dataLen)
-{
-    OIC_LOG_V(DEBUG, TAG, "CAethernetPacketReceiveCallback, from: %s, data: %s", address, data);
-
-    // call the callback
-    if (gEthernetReceivedCallback != NULL)
-    {
-        CARemoteEndpoint_t* endpoint = NULL;
-        endpoint = (CARemoteEndpoint_t*) OICMalloc(sizeof(CARemoteEndpoint_t));
-
-        // set address
-        memset((void*) endpoint->addressInfo.IP.ipAddress, 0, CA_IPADDR_SIZE);
-        if (CA_IPADDR_SIZE > strlen(address))
-        {
-            strcpy((char*) endpoint->addressInfo.IP.ipAddress, address);
-        }
-        OICFree(address);
-
-        // set connectivity type
-        endpoint->connectivityType = CA_ETHERNET;
-
-        gEthernetReceivedCallback(endpoint, (void *) data, dataLen);
-    }
-}
-
-CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
-        CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback,
-        u_thread_pool_t handle)
-{
-    OIC_LOG(DEBUG, TAG, "IntializeEthernet");
-
-    gEthernetReceivedCallback = reqRespCallback;
-    gThreadPoolHandle = handle;
-
-    // register handlers
-    CAConnectivityHandler_t handler;
-    memset(&handler, 0, sizeof(CAConnectivityHandler_t));
-
-    handler.startAdapter = CAStartEthernet;
-    handler.startListenServer = CAStartEthernetListeningServer;
-    handler.startDiscoverServer = CAStartEthernetDiscoveryServer;
-    handler.sendData = CASendEthernetUnicastData;
-    handler.sendDataToAll = CASendEthernetMulticastData;
-    handler.GetnetInfo = CAGetEthernetInterfaceInformation;
-    handler.readData = CAReadEthernetData;
-    handler.stopAdapter = CAStopEthernet;
-    handler.terminate = CATerminateEthernet;
-
-    registerCallback(handler, CA_ETHERNET);
-
-    CAEthernetSetCallback(CAEthernetPacketReceiveCallback);
-
-    return CA_STATUS_OK;
-}
-
-void CATerminateEthernet()
-{
-    OIC_LOG(DEBUG, TAG, "TerminateEthernet");
-
-    CAEthernetTerminate();
-}
-
-CAResult_t CAStartEthernet()
-{
-    OIC_LOG(DEBUG, TAG, "CAStartEthernet");
-    //CAEthernetInitialize();
-    CAEthernetInitialize(gThreadPoolHandle);
-
-    OIC_LOG(DEBUG, TAG, "CAEthernetStartUnicastServer");
-    int32_t res = CAEthernetStartUnicastServer();
-
-    if (res < 0)
-        return CA_STATUS_FAILED;
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStopEthernet()
-{
-    OIC_LOG(DEBUG, TAG, "CAStopEthernet");
-
-    // ToDo:
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartEthernetListeningServer()
-{
-    OIC_LOG(DEBUG, TAG, "StartEthernetListeningServer");
-
-    int32_t res = CAEthernetStartMulticastServer();
-
-    if (res < 0)
-        return CA_STATUS_FAILED;
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartEthernetDiscoveryServer()
-{
-    OIC_LOG(DEBUG, TAG, "StartEthernetDiscoveryServer");
-
-    int32_t res = CAEthernetStartMulticastServer();
-
-    if (res < 0)
-        return CA_STATUS_FAILED;
-
-    return CA_STATUS_OK;
-}
-
-uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen)
-{
-    OIC_LOG(DEBUG, TAG, "SendEthernetUnicastData");
-
-    CAEthernetSendUnicastMessage(endpoint->addressInfo.IP.ipAddress, data, dataLen);
-
-    return 0;
-}
-
-uint32_t CASendEthernetMulticastData(void* data, uint32_t dataLen)
-{
-    OIC_LOG(DEBUG, TAG, "CASendEthernetMulticastData");
-
-    CAEthernetSendMulticastMessage("0.0.0.0", (char*) data, dataLen);
-
-    return 0;
-}
-
-CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t** info, uint32_t* size)
-{
-    OIC_LOG(DEBUG, TAG, "GetEthernetInterfaceInformation");
-
-    CAGetEthernetInterfaceInfo(info, size);
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAReadEthernetData()
-{
-    OIC_LOG(DEBUG, TAG, "Read Ethernet Data");
-
-    // ToDo:
-
-    return CA_STATUS_OK;
-}
-
diff --git a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetclient.c b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetclient.c
new file mode 100644 (file)
index 0000000..744de99
--- /dev/null
@@ -0,0 +1,94 @@
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+#include "caethernetinterface.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <errno.h>
+
+#include "caadapterutils.h"
+
+/**
+ * @def ETHERNET_CLIENT_TAG
+ * @brief Logging tag for module name
+ */
+#define ETHERNET_CLIENT_TAG "ETHERNET_CLIENT"
+
+/**
+ * @var gUnicastServerSocketDescClient
+ * @brief socket descriptor for unicast server
+ */
+static int32_t gUnicastServerSocketDescClient = -1;
+
+void CAEthernetSetUnicastSocket(const int32_t socketFD)
+{
+    OIC_LOG(DEBUG, ETHERNET_CLIENT_TAG, "IN");
+
+    gUnicastServerSocketDescClient = socketFD;
+}
+
+uint32_t CAEthernetSendData(const char *remoteAddress, const uint32_t port,
+                        const void *data, const uint32_t dataLength, bool isMulticast)
+{
+    OIC_LOG(DEBUG, ETHERNET_CLIENT_TAG, "IN");
+
+    VERIFY_NON_NULL_RET(remoteAddress, ETHERNET_CLIENT_TAG, "IP address is NULL", 0);
+    VERIFY_NON_NULL_RET(data, ETHERNET_CLIENT_TAG, "data is NULL", 0);
+
+    if (dataLength == 0)
+    {
+        OIC_LOG(ERROR, ETHERNET_CLIENT_TAG, "Data length is 0 !");
+        return 0;
+    }
+
+    if (0 > gUnicastServerSocketDescClient)
+    {
+        OIC_LOG(ERROR, ETHERNET_CLIENT_TAG, "Unicast Server is not running !");
+        return 0;
+    }
+
+    struct sockaddr_in destAddr;
+    memset((char *)&destAddr, 0, sizeof(destAddr));
+    destAddr.sin_family = AF_INET;
+    destAddr.sin_port = htons(port);
+
+    // Conversion from ASCII format to Network format
+    if (inet_aton(remoteAddress, &destAddr.sin_addr) == 0)
+    {
+        OIC_LOG(ERROR, ETHERNET_CLIENT_TAG, "Failed to convert from ASCII to Network Address");
+        return 0;
+    }
+
+    int32_t sendDataLength = sendto(gUnicastServerSocketDescClient, data, dataLength, 0,
+                                    (struct sockaddr *)&destAddr, sizeof(destAddr));
+    if (sendDataLength == -1)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_CLIENT_TAG, "Failed to Send Data, Error code: %s", strerror(errno));
+        return 0;
+    }
+
+    OIC_LOG_V(INFO, ETHERNET_CLIENT_TAG, "Sending data is successful, sent bytes[%d]", sendDataLength);
+
+    OIC_LOG(DEBUG, ETHERNET_CLIENT_TAG, "OUT");
+    return sendDataLength;
+}
+
diff --git a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetcore.c b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetcore.c
deleted file mode 100644 (file)
index 0d75f95..0000000
+++ /dev/null
@@ -1,701 +0,0 @@
-#include <stdio.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <string.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <ifaddrs.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <arpa/inet.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-
-#include "caethernetcore.h"
-#include "logger.h"
-#include "uthreadpool.h" /* for thread pool */
-#include "umutex.h"
-#include "caqueueingthread.h"
-#include "oic_malloc.h"
-
-#define TAG PCF("CA")
-
-#define REQ_CNT 20
-#define CA_MAX_BUFFER_SIZE 512  // Max length of buffer\r#define CA_UNICAST_PORT 5383 // The port on which to listen for incoming data\r#define CA_MULTICAST_ADDR "224.0.1.187"\r#define CA_MULTICAST_PORT 5683\rtypedef enum\r{\rCA_UNICAST = 1, CA_MULTICAST
-} CATransmissionType_t;
-
-typedef struct
-{
-CATransmissionType_t transmissionType; // 0: none, 1: unicast, 2: multicast
-char* address;
-int port;
-void* data;
-uint32_t len;
-} CAThreadData_t;
-
-typedef struct
-{
-u_mutex threadMutex;
-u_cond threadCond;
-CABool_t isStop;
-int32_t status; // 0: stopped, 1: running
-} CATask_t;
-
-int32_t unicast_receive_socket;
-struct sockaddr_in multicast_send_interface_addr;
-int32_t multicast_receive_socket;
-struct sockaddr_in multicast_receive_interface_addr;
-
-static CAPacketReceiveCallback gPacketReceiveCallback = NULL;
-
-static u_thread_pool_t gThreadPoolHandle = NULL;
-
-// message handler main thread
-static CAQueueingThread_t gSendThread;
-static CAQueueingThread_t gReceiveThread;
-
-CATask_t unicastListenTask;
-CATask_t multicastListenTask;
-
-static void CAEthernetSendProcess(void* threadData)
-{
-OIC_LOG(DEBUG, TAG, "CAEthernetSendThreadProcess");
-
-CAThreadData_t* data = (CAThreadData_t*) threadData;
-if (data == NULL)
-{
-    OIC_LOG(DEBUG, TAG, "thread data is error!");
-    return;
-}
-
-if (data->transmissionType == CA_UNICAST)
-{
-    // unicast
-    CAEthernetSendUnicastMessageImpl(data->address, (char*) (data->data), data->len);
-}
-else if (data->transmissionType == CA_MULTICAST)
-{
-    // multicast
-    CAEthernetSendMulticastMessageImpl((char*) (data->data), data->len);
-}
-}
-
-static void CAEthernetReceiveProcess(void* threadData)
-{
-OIC_LOG(DEBUG, TAG, "CAEthernetReceiveProcess");
-
-CAThreadData_t* data = (CAThreadData_t*) threadData;
-if (data == NULL)
-{
-    OIC_LOG(DEBUG, TAG, "thread data is error!");
-    return;
-}
-
-if (gPacketReceiveCallback != NULL)
-{
-    gPacketReceiveCallback(data->address, (char*) (data->data), data->len);
-}
-}
-
-static void CAUnicastListenThread(void* threadData)
-{
-OIC_LOG(DEBUG, TAG, "CAUnicastListenThread");
-
-char buf[CA_MAX_BUFFER_SIZE];
-int32_t recv_len;
-
-struct sockaddr_in si_other;
-int32_t slen = sizeof(si_other);
-
-while (!unicastListenTask.isStop)
-{
-    OIC_LOG(DEBUG, TAG, "CAUnicastListenThread, Waiting for data...");
-    fflush(stdout);
-
-    memset(buf, 0, sizeof(char) * CA_MAX_BUFFER_SIZE);
-
-    // try to receive some data, this is a blocking call
-    if ((recv_len = recvfrom(unicast_receive_socket, buf, CA_MAX_BUFFER_SIZE, 0,
-            (struct sockaddr *) &si_other, (socklen_t *) &slen)) == -1)
-    {
-        OIC_LOG(DEBUG, TAG, "CAUnicastListenThread, recv_len() error");
-        continue;
-    }
-
-    // print details of the client/peer and the data received
-    OIC_LOG_V(DEBUG, TAG, "CAUnicastListenThread, Received packet from %s:%d",
-            inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
-    OIC_LOG_V(DEBUG, TAG, "CAUnicastListenThread, Data: %s", buf);
-
-    // store the data at queue.
-    CAThreadData_t* td = NULL;
-    td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t));
-    memset(td, 0, sizeof(CAThreadData_t));
-    td->transmissionType = 1; // unicast
-
-    char* _address = inet_ntoa(si_other.sin_addr);
-    int len = strlen(_address);
-    td->address = (char*) OICMalloc(sizeof(char) * (len + 1));
-    memset(td->address, 0, len + 1);
-    memcpy(td->address, _address, len);
-    td->port = ntohs(si_other.sin_port);
-
-    td->data = (void*) OICMalloc(sizeof(void) * CA_MAX_BUFFER_SIZE);
-    memset(td->data, 0, CA_MAX_BUFFER_SIZE);
-    memcpy(td->data, buf, sizeof(buf));
-    td->len = recv_len;
-
-    CAQueueingThreadAddData(&gReceiveThread, td, sizeof(CAThreadData_t));
-}
-
-OIC_LOG(DEBUG, TAG, "end of CAUnicastListenThread");
-}
-
-static void CAMulticastListenThread(void* threadData)
-{
-OIC_LOG(DEBUG, TAG, "CAMulticastListenThread");
-
-char msgbuf[CA_MAX_BUFFER_SIZE];
-
-struct sockaddr_in client;
-int32_t addrlen = sizeof(client);
-
-OIC_LOG(DEBUG, TAG, "CAMulticastListenThread, waiting for input...");
-
-while (!multicastListenTask.isStop)
-{
-    int32_t recv_bytes = recvfrom(multicast_receive_socket, msgbuf, CA_MAX_BUFFER_SIZE, 0,
-            (struct sockaddr *) &client, (socklen_t *) &addrlen);
-    if (recv_bytes < 0)
-    {
-        if (errno != EAGAIN)
-        {
-            OIC_LOG(DEBUG, TAG, "CAMulticastListenThread, error recvfrom");
-
-            return;
-        }
-
-        continue;
-    }
-
-    msgbuf[recv_bytes] = 0;
-
-    OIC_LOG_V(DEBUG, TAG, "Received msg: %s, size: %d", msgbuf, recv_bytes);
-
-    char* sender = inet_ntoa(client.sin_addr);
-    char local[INET_ADDRSTRLEN];
-    CAEthernetGetLocalAddress(local);
-    if (strcmp(sender, local) == 0)
-    {
-        OIC_LOG_V(DEBUG, TAG, "skip the local request (via multicast)");
-        continue;
-    }
-    else
-    {
-        // store the data at queue.
-        CAThreadData_t* td = NULL;
-        td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t));
-        memset(td, 0, sizeof(CAThreadData_t));
-        td->transmissionType = 2; // multicast
-
-        char* _address = inet_ntoa(client.sin_addr);
-        int len = strlen(_address);
-        td->address = (char*) OICMalloc(sizeof(char) * (len + 1));
-        memset(td->address, 0, len + 1);
-        memcpy(td->address, _address, len);
-        td->port = ntohs(client.sin_port);
-
-        td->data = (void*) OICMalloc(sizeof(void) * CA_MAX_BUFFER_SIZE);
-        memset(td->data, 0, CA_MAX_BUFFER_SIZE);
-        memcpy(td->data, msgbuf, sizeof(msgbuf));
-        td->len = recv_bytes;
-
-        CAQueueingThreadAddData(&gReceiveThread, td, sizeof(CAThreadData_t));
-    }
-
-}
-
-OIC_LOG(DEBUG, TAG, "end of CAMulticastListenThread");
-}
-void CAEthernetInitialize(u_thread_pool_t handle)
-{
-OIC_LOG(DEBUG, TAG, "CAEthernetInitialize");
-
-gThreadPoolHandle = handle;
-
-// unicast/multicast send queue
-CAQueueingThreadInitialize(&gSendThread, gThreadPoolHandle, CAEthernetSendProcess);
-
-// start send thread
-CAResult_t res = CAQueueingThreadStart(&gSendThread);
-if (res != CA_STATUS_OK)
-{
-    OIC_LOG(DEBUG, TAG, "thread start is error (send thread)");
-    // return res;
-    return;
-}
-
-// unicast/multicast receive queue
-CAQueueingThreadInitialize(&gReceiveThread, gThreadPoolHandle, CAEthernetReceiveProcess);
-
-// start send thread
-res = CAQueueingThreadStart(&gReceiveThread);
-if (res != CA_STATUS_OK)
-{
-    OIC_LOG(DEBUG, TAG, "thread start is error (receive thread)");
-
-    return;
-}
-
-unicastListenTask.threadMutex = u_mutex_new();
-unicastListenTask.threadCond = u_cond_new();
-unicastListenTask.isStop = CA_FALSE;
-unicastListenTask.status = 0; // stopped
-
-multicastListenTask.threadMutex = u_mutex_new();
-multicastListenTask.threadCond = u_cond_new();
-multicastListenTask.isStop = CA_FALSE;
-multicastListenTask.status = 0; // stopped
-
-// [UDP Server]
-struct sockaddr_in si_me;
-
-// create a UDP socket
-if ((unicast_receive_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
-{
-    OIC_LOG_V(DEBUG, TAG, "CAEthernetInit, creating socket failed");
-    return;
-}
-
-OIC_LOG_V(DEBUG, TAG, "CAEthernetInit, socket created");
-
-// [multicast sender]
-uint32_t multiTTL = 1;
-
-// zero out the structure
-memset((char *) &si_me, 0, sizeof(si_me));
-
-si_me.sin_family = AF_INET;
-si_me.sin_port = htons(CA_UNICAST_PORT);
-si_me.sin_addr.s_addr = htonl(INADDR_ANY);
-
-int32_t ret_val = setsockopt(unicast_receive_socket, SOL_SOCKET, SO_REUSEADDR, &multiTTL,
-        sizeof(multiTTL));
-if (ret_val < 0)
-{
-    OIC_LOG(DEBUG, TAG, "CAEthernetInit, Failed to set REUSEADDR");
-}
-
-// bind socket to port
-if (bind(unicast_receive_socket, (struct sockaddr*) &si_me, sizeof(si_me)) == -1)
-{
-    OIC_LOG(DEBUG, TAG, "CAEthernetInit, binding socket failed");
-    close(unicast_receive_socket);
-    return;
-}
-
-OIC_LOG(DEBUG, TAG, "CAEthernetInit, socket binded");
-
-memset(&multicast_send_interface_addr, 0, sizeof(multicast_send_interface_addr));
-multicast_send_interface_addr.sin_family = AF_INET;
-multicast_send_interface_addr.sin_addr.s_addr = inet_addr(CA_MULTICAST_ADDR);
-multicast_send_interface_addr.sin_port = htons(CA_MULTICAST_PORT);
-
-// [multicast receiver]
-// 1. Create a typical UDP socket and set Non-blocking for reading
-multicast_receive_socket = socket(AF_INET, SOCK_DGRAM, 0);
-if (multicast_receive_socket < 0)
-{
-    OIC_LOG(DEBUG, TAG, "CAEthernetInit, Socket error");
-    close(unicast_receive_socket);
-    return;
-}
-
-// 2. Allow multiple sockets to use the same port number
-ret_val = setsockopt(multicast_receive_socket, SOL_SOCKET, SO_REUSEADDR, &multiTTL,
-        sizeof(multiTTL));
-if (ret_val < 0)
-{
-    OIC_LOG(DEBUG, TAG, "CAEthernetInit, Failed to set REUSEADDR");
-}
-
-// 3. Set up the interface
-memset(&multicast_receive_interface_addr, 0, sizeof(multicast_receive_interface_addr));
-multicast_receive_interface_addr.sin_family = AF_INET;
-multicast_receive_interface_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-multicast_receive_interface_addr.sin_port = htons(CA_MULTICAST_PORT);
-
-// 4. Bind to the interface
-ret_val = bind(multicast_receive_socket, (struct sockaddr *) &multicast_receive_interface_addr,
-        sizeof(multicast_receive_interface_addr));
-if (ret_val < 0)
-{
-    OIC_LOG(DEBUG, TAG, "CAEthernetInit, Failed to bind socket");
-
-    return;
-}
-
-// 5. Join the multicast group
-struct ip_mreq mreq;
-memset(&mreq, 0, sizeof(mreq));
-mreq.imr_multiaddr.s_addr = inet_addr(CA_MULTICAST_ADDR);
-mreq.imr_interface.s_addr = htonl(INADDR_ANY);
-ret_val = setsockopt(multicast_receive_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq, sizeof(mreq));
-if (ret_val < 0)
-{
-    OIC_LOG(DEBUG, TAG, "CAEthernetInit, Failed to join multicast group");
-
-    return;
-}
-}
-
-void CAEthernetTerminate()
-{
-OIC_LOG(DEBUG, TAG, "CAEthernetTerminate");
-
-close(unicast_receive_socket);
-close(multicast_receive_socket);
-
-shutdown(unicast_receive_socket, 2);
-shutdown(multicast_receive_socket, 2);
-
-CAEthernetStopUnicastServer(0);
-
-CAEthernetStopMulticastServer(0);
-
-// stop thread
-CAQueueingThreadStop(&gSendThread);
-// delete thread data
-CAQueueingThreadDestroy(&gSendThread);
-
-// stop thread
-CAQueueingThreadStop(&gReceiveThread);
-// delete thread data
-CAQueueingThreadDestroy(&gReceiveThread);
-
-u_mutex_free(unicastListenTask.threadMutex);
-u_cond_free(unicastListenTask.threadCond);
-
-u_mutex_free(multicastListenTask.threadMutex);
-u_cond_free(multicastListenTask.threadCond);
-
-}
-
-int32_t CAEthernetSendUnicastMessage(const char* address, char* data, uint32_t length)
-{
-// store the data at queue.
-CAThreadData_t* td = NULL;
-td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t));
-if (td == NULL)
-{
-    OICFree(data);
-    return 0;
-}
-memset(td, 0, sizeof(CAThreadData_t));
-td->transmissionType = CA_UNICAST; // unicast type
-int len = strlen(address);
-td->address = (char*) OICMalloc(sizeof(char) * (len + 1));
-if (td->address != NULL)
-{
-    memset(td->address, 0, len + 1);
-    memcpy(td->address, address, len);
-}
-else
-{
-    OIC_LOG_V(DEBUG, TAG, "Memory Full");
-    OICFree(td);
-    OICFree(data);
-    return 0;
-}
-td->data = data;
-td->len = length;
-
-CAQueueingThreadAddData(&gSendThread, td, sizeof(CAThreadData_t));
-
-return 0;
-}
-
-int32_t CAEthernetSendMulticastMessage(const char* m_address, char* data, uint32_t length)
-{
-// store the data at queue.
-CAThreadData_t* td = NULL;
-td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t));
-if (td == NULL)
-{
-    OIC_LOG_V(DEBUG, TAG, "Memory Full");
-    OICFree(data);
-    return 0;
-}
-memset(td, 0, sizeof(CAThreadData_t));
-td->transmissionType = CA_MULTICAST; // unicast
-td->address = NULL;
-td->data = data;
-td->len = length;
-
-CAQueueingThreadAddData(&gSendThread, td, sizeof(CAThreadData_t));
-
-return 0;
-}
-
-int32_t CAEthernetStartUnicastServer()
-{
-OIC_LOG_V(DEBUG, TAG, "CAEthernetStartUnicastServer(%s, %d)", "0.0.0.0", CA_UNICAST_PORT);
-
-// check the server status
-if (unicastListenTask.status == 1)
-{
-    OIC_LOG(DEBUG, TAG, "CAEthernetStartUnicastServer, already running");
-
-    return 0;
-}
-
-// unicast listen thread
-CAResult_t res = u_thread_pool_add_task(gThreadPoolHandle, CAUnicastListenThread, NULL);
-if (res != CA_STATUS_OK)
-{
-    OIC_LOG(DEBUG, TAG, "adding task to thread pool is error (unicast listen thread)");
-    return res;
-}
-
-unicastListenTask.status = 1; // running
-
-return 0;
-}
-
-int32_t CAEthernetStartMulticastServer()
-{
-OIC_LOG_V(DEBUG, TAG, "CAEthernetStartMulticastServer(%s, %d)", "0.0.0.0", CA_MULTICAST_PORT);
-
-// check the server status
-if (multicastListenTask.status == 1)
-{
-    OIC_LOG(DEBUG, TAG, "CAEthernetStartMulticastServer, already running");
-
-    return 0;
-}
-
-// multicast listen thread
-CAResult_t res = u_thread_pool_add_task(gThreadPoolHandle, CAMulticastListenThread, NULL);
-if (res != CA_STATUS_OK)
-{
-    OIC_LOG(DEBUG, TAG, "adding task to thread pool is error (multicast listen thread)");
-    return res;
-}
-
-multicastListenTask.status = 1;
-
-return 0;
-}
-
-int32_t CAEthernetStopUnicastServer()
-{
-OIC_LOG(DEBUG, TAG, "CAEthernetStopUnicastServer");
-
-// mutex lock
-u_mutex_lock(unicastListenTask.threadMutex);
-
-// set stop flag
-unicastListenTask.isStop = CA_TRUE;
-
-// notity the thread
-u_cond_signal(unicastListenTask.threadCond);
-
-// mutex unlock
-u_mutex_unlock(unicastListenTask.threadMutex);
-
-unicastListenTask.status = 0; // stopped
-
-return 0;
-}
-
-int32_t CAEthernetStopMulticastServer()
-{
-OIC_LOG(DEBUG, TAG, "CAEthernetStopMulticastServer");
-
-// mutex lock
-u_mutex_lock(multicastListenTask.threadMutex);
-
-// set stop flag
-multicastListenTask.isStop = CA_TRUE;
-
-// notity the thread
-u_cond_signal(multicastListenTask.threadCond);
-
-// mutex unlock
-u_mutex_unlock(multicastListenTask.threadMutex);
-
-multicastListenTask.status = 0; // stopped
-
-return 0;
-}
-
-void CAEthernetSetCallback(CAPacketReceiveCallback callback)
-{
-gPacketReceiveCallback = callback;
-}
-
-void CAEthernetGetLocalAddress(char* addressBuffer)
-{
-//char addressBuffer[INET_ADDRSTRLEN];
-memset(addressBuffer, 0, INET_ADDRSTRLEN);
-
-struct ifaddrs* ifAddrStruct = NULL;
-struct ifaddrs* ifa = NULL;
-void* tmpAddrPtr = NULL;
-
-getifaddrs(&ifAddrStruct);
-
-for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
-{
-    if (!ifa->ifa_addr)
-    {
-        continue;
-    }
-
-    if (ifa->ifa_addr->sa_family == AF_INET)
-    { // check it is IP4
-      // is a valid IP4 Address
-        tmpAddrPtr = &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr;
-
-        memset(addressBuffer, 0, INET_ADDRSTRLEN);
-        inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
-
-        if (strcmp(addressBuffer, "127.0.0.1") == 0)
-            continue;
-    }
-}
-
-if (ifAddrStruct != NULL)
-    freeifaddrs(ifAddrStruct);
-}
-
-int32_t CAEthernetSendUnicastMessageImpl(const char* address, const char* data, uint32_t length)
-{
-OIC_LOG_V(DEBUG, TAG, "CAEthernetSendUnicastMessageImpl, address: %s, data: %s", address, data);
-
-// [UDP Client]
-
-struct sockaddr_in si_other;
-int32_t slen = sizeof(si_other);
-
-memset((char *) &si_other, 0, sizeof(si_other));
-
-si_other.sin_family = AF_INET;
-si_other.sin_port = htons(CA_UNICAST_PORT);
-if (inet_aton(address, &si_other.sin_addr) == 0)
-{
-    OIC_LOG(DEBUG, TAG, "CAEthernetSendUnicastMessageImpl, inet_aton, error...");
-    return 0;
-}
-
-OIC_LOG_V(DEBUG, TAG, "CAEthernetSendUnicastMessageImpl, sendto, to: %s, data: %s", address, data);
-if (sendto(unicast_receive_socket, data, length, 0, (struct sockaddr *) &si_other, slen) == -1)
-{
-    OIC_LOG(DEBUG, TAG, "CAEthernetSendUnicastMessageImpl, sendto, error...");
-
-    return 0;
-}
-
-return 0;
-}
-
-int32_t CAEthernetSendMulticastMessageImpl(const char* msg, uint32_t length)
-{
-OIC_LOG_V(DEBUG, TAG, "CAEthernetSendMulticastMessageImpl, sendto, data: %s", msg);
-
-int32_t result = sendto(unicast_receive_socket, msg, length, 0,
-        (struct sockaddr *) &multicast_send_interface_addr, sizeof(multicast_send_interface_addr));
-if (result < 0)
-{
-    OIC_LOG(DEBUG, TAG, "CAEthernetSendMulticastMessageImpl, sending message error...");
-
-    return -1;
-}
-
-return 0;
-}
-
-CAResult_t CAGetEthernetInterfaceInfo(CALocalConnectivity_t **info, uint32_t* size)
-{
-uint32_t cnt, req_cnt = REQ_CNT;
-int32_t fd;
-uint32_t cmd = SIOCGIFCONF;
-uint32_t resSize = 0;
-char* localIPAddress;
-struct sockaddr_in *sock;
-struct ifconf ifc;
-struct ifreq *ifr;
-
-memset((void *) &ifc, 0, sizeof(struct ifconf));
-ifc.ifc_len = sizeof(struct ifconf) * req_cnt;
-ifc.ifc_buf = NULL;
-ifc.ifc_buf = malloc(ifc.ifc_len);
-
-if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-{
-    OIC_LOG(DEBUG, TAG, "create socket error!");
-    return CA_STATUS_FAILED;
-}
-
-if (ioctl(fd, cmd, &ifc) < 0)
-{
-    OIC_LOG(DEBUG, TAG, "SIOCGIFCONF fail");
-    close(fd);
-    return CA_STATUS_FAILED;
-}
-
-close(fd);
-
-if (ifc.ifc_len > (sizeof(struct ifreq) * req_cnt))
-{
-    req_cnt = ifc.ifc_len;
-    ifc.ifc_buf = realloc(ifc.ifc_buf, req_cnt);
-}
-
-ifr = ifc.ifc_req;
-for (cnt = 0; cnt < ifc.ifc_len; cnt += sizeof(struct ifreq), ifr++)
-{
-    sock = (struct sockaddr_in *) &ifr->ifr_addr;
-
-    // except loopback address
-    if (ntohl(sock->sin_addr.s_addr) == INADDR_LOOPBACK)
-        continue;
-
-    // get local address
-    localIPAddress = inet_ntoa(sock->sin_addr);
-
-    CALocalConnectivity_t* localInfo;
-
-    // memory allocation
-    localInfo = (CALocalConnectivity_t*) OICMalloc(sizeof(CALocalConnectivity_t));
-    if (localInfo == NULL)
-    {
-        OIC_LOG_V(DEBUG, TAG, "memory alloc error!!");
-        free(localInfo);
-        return CA_STATUS_FAILED;
-    }
-    memset(localInfo, 0, sizeof(CALocalConnectivity_t));
-
-    if (strlen(localIPAddress) > CA_IPADDR_SIZE)
-    {
-        OIC_LOG_V(DEBUG, TAG, "address size is wrong!!");
-        free(localInfo);
-        return CA_STATUS_FAILED;
-    }
-    // set local ip address
-    strncpy(localInfo->addressInfo.IP.ipAddress, localIPAddress, strlen(localIPAddress));
-
-    // set network type
-    localInfo->type = CA_ETHERNET;
-
-    *info = localInfo;
-
-    resSize++;
-}
-
-*size = resSize;
-
-return CA_STATUS_OK;
-}
diff --git a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetnwmonitor.c b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetnwmonitor.c
new file mode 100644 (file)
index 0000000..b4b7527
--- /dev/null
@@ -0,0 +1,304 @@
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+
+#include "caethernetinterface.h"
+
+#include <string.h>
+#include <ifaddrs.h>
+#include <netdb.h>
+
+#include "caadapterutils.h"
+#include "umutex.h"
+#include "logger.h"
+#include "oic_malloc.h"
+
+#define ETHERNET_MONITOR_TAG "ETHERNET_MONITOR"
+
+/**
+ * @var nwConnectivityStatus
+ * @brief  Maintains network status.
+ */
+static CANetworkStatus_t nwConnectivityStatus;
+
+/**
+ * @var gEthernetNetInfoMutex
+ * @brief  Mutex for synchronizing access to cached interface and IP address information.
+ */
+static u_mutex gEthernetNetInfoMutex = NULL;
+
+/**
+ * @var gEthernetInterfaceName
+ * @brief  Maintains interface name.
+ */
+static char *gEthernetInterfaceName = NULL;
+
+/**
+ * @var gEthernetIPAddress
+ * @brief  Maintains interface IP address.
+ */
+static char *gEthernetIPAddress = NULL;
+
+/**
+ * @var gThreadPool
+ * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
+ */
+static u_thread_pool_t gThreadPool = NULL;
+
+/**
+ * @var gStopNetworkMonitor
+ * @brief Flag to control the Network Monitor Thread
+ */
+static bool gStopNetworkMonitor = false;
+
+/**
+ * @var gNetworkChangeCb
+ * @brief  Maintains network connection state change callback.
+ */
+static CAEthernetConnectionStateChangeCallback gNetworkChangeCb = NULL;
+
+/**
+ * @fn CAEthernetGetInterfaceInformation
+ * @brief This methods gets local interface name and IP address information.
+ */
+static void CAEthernetGetInterfaceInformation(char **interfaceName, char **ipAddress);
+
+static void CANetworkMonitorThread(void* threadData);
+
+CAResult_t CAEthernetInitializeNetworkMonitor(const u_thread_pool_t threadPool)
+{
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "IN");
+
+    gThreadPool = threadPool;
+
+    if (!gEthernetNetInfoMutex)
+    {
+        gEthernetNetInfoMutex = u_mutex_new();
+    }
+
+    u_mutex_lock(gEthernetNetInfoMutex);
+    CAEthernetGetInterfaceInformation(&gEthernetInterfaceName, &gEthernetIPAddress);
+    u_mutex_unlock(gEthernetNetInfoMutex);
+
+    nwConnectivityStatus = (gEthernetIPAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
+
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAEthernetTerminateNetworkMonitor(void)
+{
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "IN");
+
+    gThreadPool = NULL;
+
+    if (gEthernetInterfaceName)
+    {
+        OICFree(gEthernetInterfaceName);
+        gEthernetInterfaceName = NULL;
+    }
+
+    if (gEthernetIPAddress)
+    {
+        OICFree(gEthernetIPAddress);
+        gEthernetIPAddress = NULL;
+    }
+
+    if (gEthernetNetInfoMutex)
+    {
+        u_mutex_free(gEthernetNetInfoMutex);
+        gEthernetNetInfoMutex = NULL;
+    }
+
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "OUT");
+}
+
+CAResult_t CAEthernetStartNetworkMonitor(void)
+{
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "IN");
+
+    u_mutex_lock(gEthernetNetInfoMutex);
+    gStopNetworkMonitor = false;
+    u_mutex_unlock(gEthernetNetInfoMutex);
+
+    if (gStopNetworkMonitor)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_MONITOR_TAG, "Network Monitor Thread is already running!");
+        return CA_SERVER_STARTED_ALREADY;
+    }
+
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CANetworkMonitorThread,
+            (void *)NULL))
+    {
+        OIC_LOG(ERROR, ETHERNET_MONITOR_TAG, "[ThreadPool] thread_pool_add_task failed!");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, ETHERNET_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAEthernetStopNetworkMonitor(void)
+{
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "IN");
+
+    if (gStopNetworkMonitor)
+    {
+        OIC_LOG(DEBUG, ETHERNET_MONITOR_TAG, "CAEthernetStopNetworkMonitor, already stopped");
+
+        return CA_STATUS_OK;
+    }
+
+    u_mutex_lock(gEthernetNetInfoMutex);
+    gStopNetworkMonitor = true;
+    u_mutex_unlock(gEthernetNetInfoMutex);
+
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAEthernetGetInterfaceInfo(char **interfaceName, char **ipAddress)
+{
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "IN");
+
+    u_mutex_lock(gEthernetNetInfoMutex);
+
+    if (gEthernetInterfaceName && strlen(gEthernetInterfaceName))
+    {
+        *interfaceName = (gEthernetInterfaceName) ? strndup(gEthernetInterfaceName, strlen(gEthernetInterfaceName)) :
+                                NULL;
+    }
+
+    if (gEthernetIPAddress && strlen(gEthernetIPAddress))
+    {
+        *ipAddress = (gEthernetIPAddress) ? strndup(gEthernetIPAddress, strlen(gEthernetIPAddress)) :
+                                NULL;
+    }
+
+    u_mutex_unlock(gEthernetNetInfoMutex);
+
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+bool CAEthernetIsConnected(void)
+{
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "IN");
+
+    if (nwConnectivityStatus == CA_INTERFACE_DOWN)
+        return false;
+
+    return true;
+}
+
+void CAEthernetSetConnectionStateChangeCallback(CAEthernetConnectionStateChangeCallback callback)
+{
+    OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "IN");
+
+    gNetworkChangeCb = callback;
+}
+
+void CAEthernetGetInterfaceInformation(char **interfaceName, char **ipAddress)
+{
+    struct ifaddrs *ifa = NULL;
+    struct ifaddrs *ifp = NULL;
+
+    if (getifaddrs(&ifp) < 0)
+    {
+        OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "Get network interface list error");
+    }
+
+    for (ifa = ifp; ifa; ifa = ifa->ifa_next)
+    {
+        char localIPAddress[CA_IPADDR_SIZE];
+        socklen_t len;
+
+        if (ifa->ifa_addr == NULL)
+            continue;
+
+        if (ifa->ifa_addr->sa_family == AF_INET)
+            len = sizeof(struct sockaddr_in);
+        else if (ifa->ifa_addr->sa_family == AF_INET6)
+            continue;
+        else
+            continue;
+
+        if (getnameinfo(ifa->ifa_addr, len, localIPAddress,
+                        sizeof(localIPAddress), NULL, 0, NI_NUMERICHOST) < 0)
+        {
+            OIC_LOG_V(DEBUG, ETHERNET_MONITOR_TAG, "Get IPAddress fail");
+        }
+
+        // except loopback address
+        if (strcmp(localIPAddress, "127.0.0.1") == 0)
+            continue;
+
+        // set interface name
+        *interfaceName = strndup(ifa->ifa_name, strlen(ifa->ifa_name));
+
+        // set local ip address
+        *ipAddress = strndup(localIPAddress, strlen(localIPAddress));
+    }
+
+    freeifaddrs(ifp);
+}
+
+void CANetworkMonitorThread(void* threadData)
+{
+    while (!gStopNetworkMonitor)
+    {
+        if (gStopNetworkMonitor)
+        {
+            OIC_LOG(DEBUG, ETHERNET_MONITOR_TAG, "Stop Network Monitor Thread is called");
+            break;
+        }
+
+        // Get network information
+        CANetworkStatus_t currNetworkStatus;
+        char *interfaceName = NULL;
+        char *ipAddress = NULL;
+        CAEthernetGetInterfaceInformation(&interfaceName, &ipAddress);
+
+        // check current network status
+        currNetworkStatus = (ipAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
+
+        // if network status is changed
+        if (currNetworkStatus != nwConnectivityStatus)
+        {
+            // set current network information
+            u_mutex_lock(gEthernetNetInfoMutex);
+
+            nwConnectivityStatus = currNetworkStatus;
+
+            OICFree(gEthernetInterfaceName);
+            OICFree(gEthernetIPAddress);
+            gEthernetInterfaceName = (interfaceName) ? strndup(interfaceName, strlen(interfaceName)) : NULL;
+            gEthernetIPAddress = (ipAddress) ? strndup(ipAddress, strlen(ipAddress)) : NULL;
+
+            u_mutex_unlock(gEthernetNetInfoMutex);
+
+            if (gNetworkChangeCb)
+            {
+                gNetworkChangeCb(gEthernetIPAddress, nwConnectivityStatus);
+            }
+        }
+        OICFree(interfaceName);
+        OICFree(ipAddress);
+    }
+}
diff --git a/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetserver.c b/resource/csdk/connectivity/src/ethernet_adapter/linux/caethernetserver.c
new file mode 100644 (file)
index 0000000..94afc43
--- /dev/null
@@ -0,0 +1,825 @@
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+#include "caethernetinterface.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/select.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <errno.h>
+
+#include "pdu.h"
+#include "caadapterutils.h"
+#include "umutex.h"
+
+/**
+ * @def ETHERNET_SERVER_TAG
+ * @brief Logging tag for module name
+ */
+#define ETHERNET_SERVER_TAG "ETHERNET_SERVER"
+
+/**
+ * @def CA_UDP_BIND_RETRY_COUNT
+ * @brief Retry count in case of socket bind failure.
+ */
+#define CA_UDP_BIND_RETRY_COUNT 10
+
+/**
+ * @var gUnicastServerSocketDescriptor
+ * @brief socket descriptor for unicast server
+ */
+static int32_t gUnicastServerSocketDescriptor = -1;
+
+/**
+ * @var gUnicastServerSocketDescriptor
+ * @brief socket descriptor for unicast server
+ */
+static char *gUnicastServerAddress = NULL;
+
+/**
+ * @var gUnicastServerSocketDescriptor
+ * @brief socket descriptor for unicast server
+ */
+static int16_t gUnicastServerPort = -1;
+
+/**
+ * @var gMutexUnicastServerSocketDescriptor
+ * @brief Mutex for socket descriptor for unicast server
+ */
+static u_mutex gMutexUnicastServerSocketDescriptor = NULL;
+/**
+ * @var gMulticastServerSocketDescriptor
+ * @brief socket descriptor for multicast server
+ */
+static int32_t gMulticastServerSocketDescriptor = -1;
+
+/**
+ * @var gMutexMulticastServerSocketDescriptor
+ * @brief Mutex for socket descriptor for Multicast server
+ */
+static u_mutex gMutexMulticastServerSocketDescriptor = NULL;
+
+/**
+ * @var gThreadPool
+ * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
+ */
+static u_thread_pool_t gThreadPool = NULL;
+
+/**
+ * @var gMReq
+ * @brief ip_mreq structure passed to join a multicast group
+ */
+static struct ip_mreq gMReq;
+
+/**
+ * @var gStopUnicast
+ * @brief Flag to control the Receive Unicast Data Thread
+ */
+static bool gStopUnicast = false;
+
+/**
+ * @var gMutexStopUnicast
+ * @brief Mutex for gStopUnicast
+ */
+static u_mutex gMutexStopUnicast = NULL;
+
+/**
+ * @var gStopMulticast
+ * @brief Flag to control the Receive Multicast Data Thread
+ */
+static bool gStopMulticast = false;
+
+/**
+ * @var gMutexStopMulticast
+ * @brief Mutex for gStopMulticast
+ */
+static u_mutex gMutexStopMulticast = NULL;
+
+/**
+ * @var gPacketReceivedCallback
+ * @brief Callback for notifying the upper layer on receival data from remote OIC device
+ */
+static CAEthernetPacketReceivedCallback gPacketReceivedCallback = NULL;
+
+/**
+ * @var gExceptionCallback
+ * @brief Callback for notifying the upper layer when unicast/multicast server encounters exception
+ */
+static CAEthernetExceptionCallback gExceptionCallback = NULL;
+
+/**
+ * @var gUnicastRecvBuffer
+ * @brief Character buffer used for receiving unicast data from network
+ */
+static char gUnicastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
+
+/**
+ * @var gMulticastRecvBuffer
+ * @brief Character buffer used for receiving multicast data from network
+ */
+static char gMulticastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
+
+/**
+ * @fn CAEthernetServerCreateMutex
+ * @brief Creates and initializes mutex
+ */
+static CAResult_t CAEthernetServerCreateMutex(void);
+
+/**
+ * @fn CAEthernetServerDestroyMutex
+ * @brief Releases all created mutex
+ */
+static void CAEthernetServerDestroyMutex(void);
+
+/**
+ * @fn CAReceiveThreadForMulticast
+ * @brief Handler thread for receiving data on multicast server
+ */
+static void *CAReceiveThreadForMulticast(void *data);
+
+/**
+ * @fn CAEthernetReceiveThreadForUnicast
+ * @brief Handler thread for receiving data on unicast server
+ */
+static void *CAEthernetReceiveThreadForUnicast(void *data);
+
+CAResult_t CAEthernetInitializeServer(const u_thread_pool_t threadPool)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+
+    //Input validation
+    VERIFY_NON_NULL(threadPool, ETHERNET_SERVER_TAG, "Thread pool handle is NULL");
+
+    //Initialize mutex
+    if (CA_STATUS_OK != CAEthernetServerCreateMutex())
+    {
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to create mutex!");
+        return CA_STATUS_FAILED;
+    }
+
+    gThreadPool = threadPool;
+
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAEthernetTerminateServer(void)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+
+    gThreadPool = NULL;
+
+    //Destroy mutex
+    CAEthernetServerDestroyMutex();
+
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
+}
+
+CAResult_t CAEthernetStartMulticastServer(const char *localAddress, const char *multicastAddress,
+                                      const int16_t multicastPort, int32_t *serverFD)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+
+    if (gMulticastServerSocketDescriptor != -1)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Multicast Server is already running!");
+        return CA_SERVER_STARTED_ALREADY;
+    }
+
+    VERIFY_NON_NULL(localAddress, ETHERNET_SERVER_TAG, "Local address is NULL");
+    VERIFY_NON_NULL(multicastAddress, ETHERNET_SERVER_TAG, "Multicast address is NULL");
+
+    if (0 >= multicastPort)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Invalid input: Multicast port is invalid!");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    // Create a datagram socket on which to recv/send.
+    u_mutex_lock(gMutexStopMulticast);
+    gStopMulticast = false;
+    u_mutex_unlock(gMutexStopMulticast);
+
+    u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+
+    // create a UDP socket
+    if ((gMulticastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to Create Socket, Error code: %s",
+                  strerror(errno));
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    // Make the socket non-blocking
+    if (-1 == fcntl(gMulticastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
+                  strerror(errno));
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "socket creation success");
+
+    int32_t setOptionOn = 1;
+    if (-1 == setsockopt(gMulticastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
+                         (char *) &setOptionOn,
+                         sizeof(setOptionOn)))
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to setsockopt for SO_REUSEADDR, Error code: %s",
+                  strerror(errno));
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    struct sockaddr_in sockAddr;
+    memset((char *) &sockAddr, 0, sizeof(sockAddr));
+
+    sockAddr.sin_family = AF_INET;
+    sockAddr.sin_port = htons(multicastPort);
+    sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    //bind socket to multicast port
+    if (-1 == bind(gMulticastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
+                   sizeof(sockAddr)))
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to Bind Socket! Return Code[%d]",
+                  CA_SOCKET_OPERATION_FAILED);
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "socket bind success");
+
+    //Add membership to receiving socket (join group)
+    memset(&gMReq, 0, sizeof(struct ip_mreq));
+    gMReq.imr_interface.s_addr = htonl(INADDR_ANY);
+    inet_aton(multicastAddress, &gMReq.imr_multiaddr);
+
+    if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+                         (char *) &gMReq,
+                         sizeof(struct ip_mreq)))
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n",
+                  strerror(errno));
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    /**
+      * The task to listen to data from multicastcast socket is added to the thread pool.
+      * This is a blocking call is made where we try to receive some data.. We will keep waiting until some data is received.
+      * This task will be terminated when thread pool is freed on stopping the adapters.
+      */
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAReceiveThreadForMulticast,
+            (void *)NULL))
+    {
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_STATUS_FAILED;
+    }
+
+    *serverFD = gMulticastServerSocketDescriptor;
+    u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+
+    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "thread_pool_add_task done");
+    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Multicast Server Started Successfully");
+
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+
+}
+
+CAResult_t CAEthernetStartUnicastServer(const char *localAddress, int16_t *port,
+                                    const bool forceStart, int32_t *serverFD)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+
+    if (gUnicastServerSocketDescriptor != -1)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Unicast Server is Started Already! Return Code[%d]",
+                  CA_SERVER_STARTED_ALREADY);
+        return CA_SERVER_STARTED_ALREADY;
+    }
+
+    VERIFY_NON_NULL(localAddress, ETHERNET_SERVER_TAG, "Invalid argument : localAddress is NULL");
+    VERIFY_NON_NULL(port, ETHERNET_SERVER_TAG, "Invalid argument : port is NULL");
+
+    if (*port < 0)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Invalid input: port is invalid!");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    u_mutex_lock(gMutexStopUnicast);
+    gStopUnicast = false;
+    u_mutex_unlock(gMutexStopUnicast);
+
+    u_mutex_lock(gMutexUnicastServerSocketDescriptor);
+    // Create a UDP socket
+    if ((gUnicastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to Create Socket, Error code: %s",
+                  strerror(errno));
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    // Make the socket non-blocking
+    if (-1 == fcntl(gUnicastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
+                  strerror(errno));
+        close(gUnicastServerSocketDescriptor);
+        gUnicastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "socket creation success");
+
+    if (true == forceStart)
+    {
+        int32_t setOptionOn = 1;
+        if (-1 == setsockopt(gUnicastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
+                             (char *) &setOptionOn,
+                             sizeof(setOptionOn)))
+        {
+            OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
+                      strerror(errno));
+            close(gUnicastServerSocketDescriptor);
+            gUnicastServerSocketDescriptor = -1;
+            u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+            return CA_SOCKET_OPERATION_FAILED;
+        }
+    }
+
+    struct sockaddr_in sockAddr;
+    bool isBound = false;
+    int16_t serverPort = *port;
+
+    memset((char *) &sockAddr, 0, sizeof(sockAddr));
+    sockAddr.sin_family = AF_INET;
+    sockAddr.sin_port = htons(serverPort);
+    sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    //Trying for bind in a loop
+    int16_t i;
+    for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
+    {
+        if (-1 == bind(gUnicastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
+                       sizeof(sockAddr)))
+        {
+            if (false == forceStart)
+            {
+                OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to bind socket[%s]. Trying again... ",
+                          strerror(errno));
+
+                //Set the port to next one
+                serverPort += 1;
+                sockAddr.sin_port = htons(serverPort);
+                continue;
+            }
+            else
+            {
+                OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to bind socket[%s]!",
+                          strerror(errno));
+                break;
+            }
+        }
+
+        isBound = true;
+        break;
+    }
+
+    if (false == isBound)
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Failed to bind Socket! Return code[%d]",
+                  CA_SOCKET_OPERATION_FAILED);
+        close(gUnicastServerSocketDescriptor);
+        gUnicastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "socket bind success");
+
+    socklen_t len = 0;
+    char *serverAddress = NULL;
+    if (-1 != getsockname(gUnicastServerSocketDescriptor, (struct sockaddr *)&sockAddr, &len))
+    {
+        serverPort = ntohs(sockAddr.sin_port);
+        serverAddress = inet_ntoa(sockAddr.sin_addr);
+    }
+
+    /**
+      * The task to listen for data from unicast socket is added to the thread pool.
+      * This is a blocking call is made where we try to receive some data..
+      * We will keep waiting until some data is received.
+      * This task will be terminated when thread pool is freed on stopping the adapters.
+      */
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAEthernetReceiveThreadForUnicast,
+            (void *) NULL))
+    {
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+
+        close(gUnicastServerSocketDescriptor);
+        gUnicastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_STATUS_FAILED;
+    }
+
+    //Free the server address previously stored
+    OICFree(gUnicastServerAddress);
+    gUnicastServerAddress = NULL;
+    gUnicastServerPort = serverPort;
+    gUnicastServerAddress = (serverAddress) ? strndup(serverAddress, strlen(serverAddress)) :
+                            NULL;
+    *port = serverPort;
+    *serverFD = gUnicastServerSocketDescriptor;
+    u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+
+    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Unicast Server Started Successfully");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAEthernetStopMulticastServer(void)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+
+    u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+
+    if (gMulticastServerSocketDescriptor == -1)
+    {
+        OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Multicast Server is not yet Started");
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SERVER_NOT_STARTED;
+    }
+
+    u_mutex_lock(gMutexStopMulticast);
+    gStopMulticast = true;
+
+    // leave the group after you are done
+    if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+                         (char *)&gMReq,
+                         sizeof(struct ip_mreq)))
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "cannot leave multicast group, Error code: %s\n",
+                  strerror(errno));
+    }
+
+    // close the socket
+    if (-1 == close(gMulticastServerSocketDescriptor))
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Multicast Server socket close failed, Error code: %s\n",
+                  strerror(errno));
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        u_mutex_unlock(gMutexStopMulticast);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    u_mutex_unlock(gMutexStopMulticast);
+
+    gMulticastServerSocketDescriptor = -1;
+    u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+
+    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Multicast Server Stopped Successfully");
+
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+
+}
+
+CAResult_t CAEthernetStopUnicastServer()
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+    u_mutex_lock(gMutexUnicastServerSocketDescriptor);
+
+    if (gUnicastServerSocketDescriptor == -1)
+    {
+        OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Unicast Server is not yet Started");
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_SERVER_NOT_STARTED;
+    }
+    u_mutex_lock(gMutexStopUnicast);
+    gStopUnicast = true;
+
+    // close the socket
+    if (-1 == close(gUnicastServerSocketDescriptor))
+    {
+        OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Unicast Server socket close failed, Error code: %s\n",
+                  strerror(errno));
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        u_mutex_unlock(gMutexStopUnicast);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    u_mutex_unlock(gMutexStopUnicast);
+    gUnicastServerSocketDescriptor = -1;
+
+    u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+
+    OIC_LOG(INFO, ETHERNET_SERVER_TAG, "Unicast Server Stopped Successfully");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAEthernetGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+
+    //Input validation
+    VERIFY_NON_NULL(ipAddress, ETHERNET_SERVER_TAG, "ipAddress holder is NULL");
+    VERIFY_NON_NULL(port, ETHERNET_SERVER_TAG, "port holder is NULL");
+    VERIFY_NON_NULL(serverFD, ETHERNET_SERVER_TAG, "serverID holder is NULL");
+
+    *ipAddress = gUnicastServerAddress;
+    *port = gUnicastServerPort;
+    *serverFD = gUnicastServerSocketDescriptor;
+
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAEthernetSetPacketReceiveCallback(CAEthernetPacketReceivedCallback callback)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+
+    gPacketReceivedCallback = callback;
+}
+
+void CAEthernetSetExceptionCallback(CAEthernetExceptionCallback callback)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+
+    gExceptionCallback = callback;
+}
+
+CAResult_t CAEthernetServerCreateMutex(void)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+
+    gMutexUnicastServerSocketDescriptor = u_mutex_new();
+    if (!gMutexUnicastServerSocketDescriptor)
+    {
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
+        return CA_STATUS_FAILED;
+    }
+
+    gMutexMulticastServerSocketDescriptor = u_mutex_new();
+    if (!gMutexMulticastServerSocketDescriptor)
+    {
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
+
+        CAEthernetServerDestroyMutex();
+        return CA_STATUS_FAILED;
+    }
+
+    gMutexStopUnicast = u_mutex_new();
+    if (!gMutexStopUnicast)
+    {
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
+
+        CAEthernetServerDestroyMutex();
+        return CA_STATUS_FAILED;
+    }
+
+    gMutexStopMulticast = u_mutex_new();
+    if (!gMutexStopMulticast)
+    {
+        OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Failed to created mutex!");
+
+        CAEthernetServerDestroyMutex();
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAEthernetServerDestroyMutex(void)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+
+    if (gMutexUnicastServerSocketDescriptor)
+    {
+        u_mutex_free(gMutexUnicastServerSocketDescriptor);
+        gMutexUnicastServerSocketDescriptor = NULL;
+    }
+
+    if (gMutexMulticastServerSocketDescriptor)
+    {
+        u_mutex_free(gMutexMulticastServerSocketDescriptor);
+        gMutexMulticastServerSocketDescriptor = NULL;
+    }
+
+    if (gMutexStopUnicast)
+    {
+        u_mutex_free(gMutexStopUnicast);
+        gMutexStopUnicast = NULL;
+    }
+
+    if (gMutexStopMulticast)
+    {
+        u_mutex_free(gMutexStopMulticast);
+        gMutexStopMulticast = NULL;
+    }
+
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
+}
+
+void *CAEthernetReceiveThreadForUnicast(void *data)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+
+    fd_set reads;
+    struct timeval timeout;
+
+    //keep listening for data
+    while (!gStopUnicast)
+    {
+        //OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "Waiting for data..");
+
+        timeout.tv_sec = 1;
+        timeout.tv_usec = 0;
+
+        FD_ZERO(&reads);
+        FD_SET(gUnicastServerSocketDescriptor, &reads);
+
+        int32_t ret = select(gUnicastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
+        if (gStopUnicast)
+        {
+            OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "Stop Unicast is called");
+            break;
+        }
+        if (ret < 0)
+        {
+            OIC_LOG_V(FATAL, ETHERNET_SERVER_TAG, "select returned error %s", strerror(errno));
+            continue;
+        }
+        if (!FD_ISSET(gUnicastServerSocketDescriptor, &reads))
+        {
+            //OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "No data to read");
+            continue;
+        }
+
+        memset(gUnicastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
+
+        //Read data from socket
+        struct sockaddr_in srcSockAddress;
+        int32_t recvLen;
+        socklen_t srcAddressLen = sizeof(srcSockAddress);
+        if (-1 == (recvLen = recvfrom(gUnicastServerSocketDescriptor, gUnicastRecvBuffer,
+                                      COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
+                                      &srcAddressLen)))
+        {
+            OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "%s", strerror(errno));
+            continue;
+        }
+        else if (0 == recvLen)
+        {
+            OIC_LOG(ERROR, ETHERNET_SERVER_TAG, "Unicast server socket is shutdown !");
+
+            //Notify upper layer this exception
+            if (gExceptionCallback)
+            {
+                gExceptionCallback(CA_UNICAST_SERVER);
+            }
+            return NULL;
+        }
+
+        const char *srcIPAddress = NULL;
+        int32_t srcPort = -1;
+
+        srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
+        srcPort = ntohs(srcSockAddress.sin_port);
+
+        OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Received packet from %s:%d\n",
+                  srcIPAddress, srcPort);
+        OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
+                  gUnicastRecvBuffer, recvLen);
+
+        //Notify data to upper layer
+        if (gPacketReceivedCallback)
+        {
+            gPacketReceivedCallback(srcIPAddress, srcPort, gUnicastRecvBuffer, recvLen);
+        }
+    }
+
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
+    return NULL;
+}
+
+void *CAReceiveThreadForMulticast(void *data)
+{
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "IN");
+
+    fd_set reads;
+    struct timeval timeout;
+
+    //keep listening for data
+    while (!gStopMulticast)
+    {
+        timeout.tv_sec = 1;
+        timeout.tv_usec = 0;
+
+        FD_ZERO(&reads);
+        FD_SET(gMulticastServerSocketDescriptor, &reads);
+
+        int32_t ret = select(gMulticastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
+        if (gStopMulticast)
+        {
+            OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "Stop Multicast is called");
+            break;
+        }
+        if ( ret < 0)
+        {
+            OIC_LOG_V(FATAL, ETHERNET_SERVER_TAG, "select returned error %s", strerror(errno));
+            continue;
+        }
+        if (!FD_ISSET(gMulticastServerSocketDescriptor, &reads))
+        {
+            continue;
+        }
+
+        memset(gMulticastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
+
+        //Read data from socket
+        struct sockaddr_in srcSockAddress;
+        int32_t recvLen;
+        socklen_t srcAddressLen = sizeof(srcSockAddress);
+        if (-1 == (recvLen = recvfrom(gMulticastServerSocketDescriptor, gMulticastRecvBuffer,
+                                      COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
+                                      &srcAddressLen)))
+        {
+            OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "%s", strerror(errno));
+            continue;
+        }
+        else if (0 == recvLen)
+        {
+            OIC_LOG_V(ERROR, ETHERNET_SERVER_TAG, "Multicast socket is shutdown, returning from \
+                thread\n");
+
+            //Notify upper layer this exception
+            if (gExceptionCallback)
+            {
+                gExceptionCallback(CA_MULTICAST_SERVER);
+            }
+            return NULL;
+        }
+
+        const char *srcIPAddress = NULL;
+        int32_t srcPort = -1;
+
+        srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
+        srcPort = ntohs(srcSockAddress.sin_port);
+
+        OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Received packet from %s:%d\n",
+                  srcIPAddress, srcPort);
+        OIC_LOG_V(DEBUG, ETHERNET_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
+                  gMulticastRecvBuffer, recvLen);
+
+
+        //Notify data to upper layer
+        if (gPacketReceivedCallback)
+        {
+            gPacketReceivedCallback(srcIPAddress, srcPort, gMulticastRecvBuffer, recvLen);
+        }
+    }
+
+    OIC_LOG(DEBUG, ETHERNET_SERVER_TAG, "OUT");
+    return NULL;
+}
+
+
diff --git a/resource/csdk/connectivity/src/wifi_adapter/android/cawificlient.c b/resource/csdk/connectivity/src/wifi_adapter/android/cawificlient.c
new file mode 100644 (file)
index 0000000..e2cc90b
--- /dev/null
@@ -0,0 +1,94 @@
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+#include "cawifiinterface.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <errno.h>
+
+#include "caadapterutils.h"
+
+/**
+ * @def WIFI_CLIENT_TAG
+ * @brief Logging tag for module name
+ */
+#define WIFI_CLIENT_TAG "WIFI_CLIENT"
+
+/**
+ * @var gUnicastServerSocketDescClient
+ * @brief socket descriptor for unicast server
+ */
+static int gUnicastServerSocketDescClient = -1;
+
+void CAWiFiSetUnicastSocket(const int32_t socketFD)
+{
+    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
+
+    gUnicastServerSocketDescClient = socketFD;
+}
+
+uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
+                        const void *data, const uint32_t dataLength, bool isMulticast)
+{
+    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
+
+    VERIFY_NON_NULL_RET(remoteAddress, WIFI_CLIENT_TAG, "IP address is NULL", 0);
+    VERIFY_NON_NULL_RET(data, WIFI_CLIENT_TAG, "data is NULL", 0);
+
+    if (dataLength == 0)
+    {
+        OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Data length is 0 !");
+        return 0;
+    }
+
+    if (0 > gUnicastServerSocketDescClient)
+    {
+        OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Unicast Server is not running !");
+        return 0;
+    }
+
+    struct sockaddr_in destAddr;
+    memset((char *)&destAddr, 0, sizeof(destAddr));
+    destAddr.sin_family = AF_INET;
+    destAddr.sin_port = htons(port);
+
+    // Conversion from ASCII format to Network format
+    if (inet_aton(remoteAddress, &destAddr.sin_addr) == 0)
+    {
+        OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Failed to convert from ASCII to Network Address");
+        return 0;
+    }
+
+    int32_t sendDataLength = sendto(gUnicastServerSocketDescClient, data, dataLength, 0,
+                                    (struct sockaddr *)&destAddr, sizeof(destAddr));
+    if (sendDataLength == -1)
+    {
+        OIC_LOG_V(ERROR, WIFI_CLIENT_TAG, "Failed to Send Data, Error code: %s", strerror(errno));
+        return 0;
+    }
+
+    OIC_LOG_V(INFO, WIFI_CLIENT_TAG, "Sending data is successful, sent bytes[%d]", sendDataLength);
+
+    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT");
+    return sendDataLength;
+}
+
diff --git a/resource/csdk/connectivity/src/wifi_adapter/android/cawifinwmonitor.c b/resource/csdk/connectivity/src/wifi_adapter/android/cawifinwmonitor.c
new file mode 100644 (file)
index 0000000..a741486
--- /dev/null
@@ -0,0 +1,440 @@
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+
+#include "cawifiinterface.h"
+
+#include <string.h>
+//#include <ifaddrs.h>
+#include <arpa/inet.h>
+#include <linux/if.h>
+#include <netdb.h>
+
+#include "caadapterutils.h"
+#include "umutex.h"
+#include "logger.h"
+#include "oic_malloc.h"
+#include "com_iotivity_jar_CAWiFiInterface.h"
+
+#define WIFI_MONITOR_TAG "WIFI_MONITOR"
+
+/**
+ * @var nwConnectivityStatus
+ * @brief  Maintains network status.
+ */
+static CANetworkStatus_t nwConnectivityStatus;
+
+/**
+ * @var gWifiNetInfoMutex
+ * @brief  Mutex for synchronizing access to cached interface and IP address information.
+ */
+static u_mutex gWifiNetInfoMutex = NULL;
+
+/**
+ * @var gWifiInterfaceName
+ * @brief  Maintains interface name.
+ */
+static char *gWifiInterfaceName = NULL;
+
+/**
+ * @var gWifiIPAddress
+ * @brief  Maintains interface IP address.
+ */
+static char *gWifiIPAddress = NULL;
+
+/**
+ * @var gThreadPool
+ * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
+ */
+static u_thread_pool_t gThreadPool = NULL;
+
+/**
+ * @var gStopNetworkMonitor
+ * @brief Flag to control the Network Monitor Thread
+ */
+static bool gStopNetworkMonitor = false;
+
+/**
+ * @var g_jvm
+ * @brief pointer to store JavaVM
+ */
+static JavaVM *g_jvm = NULL;
+
+/**
+ * @var g_context
+ * @brief pointer to store Application Context
+ */
+static jobject g_context = NULL;
+
+/**
+ * @var gNetworkChangeCb
+ * @brief  Maintains network connection state change callback.
+ */
+static CAWiFiConnectionStateChangeCallback gNetworkChangeCb = NULL;
+
+/**
+ * @fn CAWiFiGetInterfaceInformation
+ * @brief Gets local interface name and IP address information.
+ */
+static void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress);
+
+/**
+ * @fn CACreateWiFiJNIInterfaceObject
+ * @brief creates new instance of CAWiFiInterface through JNI
+ */
+static void CACreateWiFiJNIInterfaceObject(jobject context);
+
+/**
+ * @fn CASendNetworkChangeCallback
+ * @brief updates network status to wifi adapter
+ */
+void CASendNetworkChangeCallback(CANetworkStatus_t currNetworkStatus);
+
+CAResult_t CAWiFiInitializeNetworkMonitor(const u_thread_pool_t threadPool)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    gThreadPool = threadPool;
+
+    if (!gWifiNetInfoMutex)
+    {
+        gWifiNetInfoMutex = u_mutex_new();
+    }
+
+    CACreateWiFiJNIInterfaceObject(g_context);
+
+    u_mutex_lock(gWifiNetInfoMutex);
+    CAWiFiGetInterfaceInformation(&gWifiInterfaceName, &gWifiIPAddress);
+    u_mutex_unlock(gWifiNetInfoMutex);
+
+    nwConnectivityStatus = (gWifiIPAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAWiFiTerminateNetworkMonitor(void)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    gThreadPool = NULL;
+
+    if (gWifiInterfaceName)
+    {
+        OICFree(gWifiInterfaceName);
+        gWifiInterfaceName = NULL;
+    }
+
+    if (gWifiIPAddress)
+    {
+        OICFree(gWifiIPAddress);
+        gWifiIPAddress = NULL;
+    }
+
+    if (gWifiNetInfoMutex)
+    {
+        u_mutex_free(gWifiNetInfoMutex);
+        gWifiNetInfoMutex = NULL;
+    }
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+}
+
+CAResult_t CAWiFiStartNetworkMonitor(void)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    u_mutex_lock(gWifiNetInfoMutex);
+    gStopNetworkMonitor = false;
+    u_mutex_unlock(gWifiNetInfoMutex);
+
+    if (gStopNetworkMonitor)
+    {
+        OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Network Monitor Thread is already running!");
+        return CA_SERVER_STARTED_ALREADY;
+    }
+
+    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiStopNetworkMonitor(void)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    if (gStopNetworkMonitor)
+    {
+        OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "CAWiFiStopNetworkMonitor, already stopped");
+
+        return CA_STATUS_OK;
+    }
+
+    u_mutex_lock(gWifiNetInfoMutex);
+    gStopNetworkMonitor = true;
+    u_mutex_unlock(gWifiNetInfoMutex);
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    u_mutex_lock(gWifiNetInfoMutex);
+
+    if (gWifiInterfaceName && strlen(gWifiInterfaceName))
+    {
+        *interfaceName = (gWifiInterfaceName) ? strndup(gWifiInterfaceName, strlen(gWifiInterfaceName)) :
+                                NULL;
+    }
+
+    if (gWifiIPAddress && strlen(gWifiIPAddress))
+    {
+        *ipAddress = (gWifiIPAddress) ? strndup(gWifiIPAddress, strlen(gWifiIPAddress)) :
+                                NULL;
+    }
+
+    u_mutex_unlock(gWifiNetInfoMutex);
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+bool CAWiFiIsConnected(void)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    if (nwConnectivityStatus == CA_INTERFACE_DOWN)
+        return false;
+
+    return true;
+}
+
+void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback callback)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    gNetworkChangeCb = callback;
+}
+
+void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress)
+{
+    char buf[1024] =  { 0, };
+    struct ifconf ifc;
+    struct ifreq* ifr;
+    struct ifreq* item;
+    int32_t sck;
+    int32_t interfaces;
+    int32_t i;
+
+    /* Get a socket handle. */
+    sck = socket(AF_INET, SOCK_DGRAM, 0);
+    if (sck < 0)
+    {
+        return;
+    }
+
+    /* Query available interfaces. */
+    ifc.ifc_len = sizeof(buf);
+    ifc.ifc_buf = buf;
+
+    if (ioctl(sck, SIOCGIFCONF, &ifc) < 0)
+    {
+        close(sck);
+        return;
+    }
+
+    /* Iterate through the list of interfaces. */
+    ifr = ifc.ifc_req;
+    interfaces = ifc.ifc_len / sizeof(struct ifreq);
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "CAWiFiGetInterfaceInformation : %d", interfaces);
+
+    for (i = 0; i < interfaces; i++)
+    {
+        struct ifreq temp_ifr;
+        struct ifreq* item = &ifr[i];
+
+        memset(&temp_ifr, 0, sizeof(temp_ifr));
+        strcpy(temp_ifr.ifr_name, item->ifr_name);
+
+        if (ioctl((int)sck, SIOCGIFFLAGS, &temp_ifr))
+        {
+            OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "CAWiFiGetInterfaceInformation, SIOCGIFFLAGS Failed");
+            continue;
+        }
+
+        if (!((temp_ifr.ifr_flags & IFF_UP) && (temp_ifr.ifr_flags & IFF_RUNNING)))
+        {
+            continue;
+        }
+
+        if(((struct sockaddr_in*) &item->ifr_addr)->sin_family != AF_INET)
+        {
+            continue;
+        }
+
+        char* ip = inet_ntoa(((struct sockaddr_in*) &item->ifr_addr)->sin_addr);
+
+        if(strcmp(ip, "127.0.0.1") == 0)
+        {
+            continue;
+        }
+
+        // set interface name
+        *interfaceName = strndup(item->ifr_name, strlen(item->ifr_name));
+
+        // set local ip address
+        *ipAddress = strndup(ip, strlen(ip));
+
+       OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "ipAddress : %s, interfaceName : %s", *ipAddress, *interfaceName);
+       break;
+    }
+
+    close(sck);
+    return;
+}
+
+void CAWiFiJniInit(JavaVM* jvm)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] CAWiFiJniInit");
+    g_jvm = jvm;
+}
+
+void CAJniSetContext(jobject context)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "caWifiSetObject");
+       g_context = context;
+}
+
+void CACreateWiFiJNIInterfaceObject(jobject context)
+{
+    JNIEnv* env;
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] CACreateWiFiJNIInterfaceObject");
+
+    if ((*g_jvm)->GetEnv(g_jvm, (void**) &env, JNI_VERSION_1_6) != JNI_OK)
+    {
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] Could not get JNIEnv pointer");
+        return;
+    }
+
+    //getApplicationContext
+    jclass contextClass = (*env)->FindClass(env, "android/content/Context");
+    if (contextClass == 0)
+    {
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] Could not get context object class");
+        return;
+    }
+
+    jmethodID getApplicationContextMethod = (*env)->GetMethodID(env, contextClass,
+            "getApplicationContext", "()Landroid/content/Context;");
+    if (getApplicationContextMethod == 0)
+    {
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] Could not get getApplicationContext method");
+        return;
+    }
+
+    jobject gApplicationContext = (*env)->CallObjectMethod(env, context, getApplicationContextMethod);
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] Saving Android application context object %p", gApplicationContext);
+
+   //Create WiFiInterface instance
+    jclass WiFiJniInterface = (*env)->FindClass(env, "com/iotivity/jar/CAWiFiInterface");
+    if (!WiFiJniInterface)
+    {
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] Could not get CAWiFiInterface class");
+        return;
+    }
+
+    jmethodID WiFiInterfaceConstructorMethod = (*env)->GetMethodID(env,
+               WiFiJniInterface, "<init>", "(Landroid/content/Context;)V");
+    if (!WiFiInterfaceConstructorMethod)
+    {
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] Could not get CAWiFiInterface constructor method");
+        return;
+    }
+
+    (*env)->NewObject(env, WiFiJniInterface, WiFiInterfaceConstructorMethod, gApplicationContext);
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore]Create CAWiFiInterface instance");
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WIFICore] NewObject Successs");
+
+}
+
+void CASendNetworkChangeCallback(CANetworkStatus_t currNetworkStatus)
+{
+    // Get network information
+    char *interfaceName = NULL;
+    char *ipAddress = NULL;
+
+    if (gStopNetworkMonitor)
+    {
+        OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Stop Network Monitor Thread is called");
+        return;
+    }
+
+    if(NULL == gNetworkChangeCb)
+    {
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WiFiCore] gNetworkChangeCb is NULL");
+        return;
+    }
+
+    // if network status is changed
+    if (currNetworkStatus != nwConnectivityStatus)
+    {
+        CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress);
+
+        // set current network information
+        u_mutex_lock(gWifiNetInfoMutex);
+
+        nwConnectivityStatus = currNetworkStatus;
+
+        gWifiInterfaceName = (interfaceName) ? strndup(interfaceName, strlen(interfaceName)) : NULL;
+        gWifiIPAddress = (ipAddress) ? strndup(ipAddress, strlen(ipAddress)) : NULL;
+
+        u_mutex_unlock(gWifiNetInfoMutex);
+
+        gNetworkChangeCb(gWifiIPAddress, nwConnectivityStatus);
+    }
+}
+
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CAWiFiInterface_CAWiFiStateEnabled
+  (JNIEnv *env, jclass class)
+{
+    CALocalConnectivity_t info;
+
+    CANetworkStatus_t currNetworkStatus = CA_INTERFACE_UP;
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WiFiCore] CAWiFiStateEnabled");
+
+    CASendNetworkChangeCallback(currNetworkStatus);
+    return;
+}
+
+
+JNIEXPORT void JNICALL Java_com_iotivity_jar_CAWiFiInterface_CAWiFiStateDisabled
+  (JNIEnv *env, jclass class)
+{
+    CALocalConnectivity_t info;
+
+    CANetworkStatus_t currNetworkStatus = CA_INTERFACE_DOWN;
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "[WiFiCore] CAWiFiStateDisabled");
+
+    CASendNetworkChangeCallback(currNetworkStatus);
+    return;
+}
+
diff --git a/resource/csdk/connectivity/src/wifi_adapter/android/cawifiserver.c b/resource/csdk/connectivity/src/wifi_adapter/android/cawifiserver.c
new file mode 100644 (file)
index 0000000..dd3ebc2
--- /dev/null
@@ -0,0 +1,825 @@
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+#include "cawifiinterface.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/select.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <errno.h>
+
+#include "pdu.h"
+#include "caadapterutils.h"
+#include "umutex.h"
+
+/**
+ * @def WIFI_SERVER_TAG
+ * @brief Logging tag for module name
+ */
+#define WIFI_SERVER_TAG "WIFI_SERVER"
+
+/**
+ * @def CA_UDP_BIND_RETRY_COUNT
+ * @brief Retry count in case of socket bind failure.
+ */
+#define CA_UDP_BIND_RETRY_COUNT 10
+
+/**
+ * @var gUnicastServerSocketDescriptor
+ * @brief socket descriptor for unicast server
+ */
+static int32_t gUnicastServerSocketDescriptor = -1;
+
+/**
+ * @var gUnicastServerSocketDescriptor
+ * @brief socket descriptor for unicast server
+ */
+static char *gUnicastServerAddress = NULL;
+
+/**
+ * @var gUnicastServerSocketDescriptor
+ * @brief socket descriptor for unicast server
+ */
+static int16_t gUnicastServerPort = -1;
+
+/**
+ * @var gMutexUnicastServerSocketDescriptor
+ * @brief Mutex for socket descriptor for unicast server
+ */
+static u_mutex gMutexUnicastServerSocketDescriptor = NULL;
+/**
+ * @var gMulticastServerSocketDescriptor
+ * @brief socket descriptor for multicast server
+ */
+static int32_t gMulticastServerSocketDescriptor = -1;
+
+/**
+ * @var gMutexMulticastServerSocketDescriptor
+ * @brief Mutex for socket descriptor for Multicast server
+ */
+static u_mutex gMutexMulticastServerSocketDescriptor = NULL;
+
+/**
+ * @var gThreadPool
+ * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
+ */
+static u_thread_pool_t gThreadPool = NULL;
+
+/**
+ * @var gMReq
+ * @brief ip_mreq structure passed to join a multicast group
+ */
+static struct ip_mreq gMReq;
+
+/**
+ * @var gStopUnicast
+ * @brief Flag to control the Receive Unicast Data Thread
+ */
+static bool gStopUnicast = false;
+
+/**
+ * @var gMutexStopUnicast
+ * @brief Mutex for gStopUnicast
+ */
+static u_mutex gMutexStopUnicast = NULL;
+
+/**
+ * @var gStopMulticast
+ * @brief Flag to control the Receive Multicast Data Thread
+ */
+static bool gStopMulticast = false;
+
+/**
+ * @var gMutexStopMulticast
+ * @brief Mutex for gStopMulticast
+ */
+static u_mutex gMutexStopMulticast = NULL;
+
+/**
+ * @var gPacketReceivedCallback
+ * @brief Callback for notifying the upper layer on receival data from remote OIC device
+ */
+static CAWiFiPacketReceivedCallback gPacketReceivedCallback = NULL;
+
+/**
+ * @var gExceptionCallback
+ * @brief Callback for notifying the upper layer when unicast/multicast server encounters exception
+ */
+static CAWiFiExceptionCallback gExceptionCallback = NULL;
+
+/**
+ * @var gUnicastRecvBuffer
+ * @brief Character buffer used for receiving unicast data from network
+ */
+static char gUnicastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
+
+/**
+ * @var gMulticastRecvBuffer
+ * @brief Character buffer used for receiving multicast data from network
+ */
+static char gMulticastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
+
+/**
+ * @fn CAWiFiServerCreateMutex
+ * @brief Creates and initializes mutex
+ */
+static CAResult_t CAWiFiServerCreateMutex(void);
+
+/**
+ * @fn CAWiFiServerDestroyMutex
+ * @brief Releases all created mutex
+ */
+static void CAWiFiServerDestroyMutex(void);
+
+/**
+ * @fn CAReceiveThreadForMulticast
+ * @brief Handler thread for receiving data on multicast server
+ */
+static void *CAReceiveThreadForMulticast(void *data);
+
+/**
+ * @fn CAWiFiReceiveThreadForUnicast
+ * @brief Handler thread for receiving data on unicast server
+ */
+static void *CAWiFiReceiveThreadForUnicast(void *data);
+
+CAResult_t CAWiFiInitializeServer(const u_thread_pool_t threadPool)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    //Input validation
+    VERIFY_NON_NULL(threadPool, WIFI_SERVER_TAG, "Thread pool handle is NULL");
+
+    //Initialize mutex
+    if (CA_STATUS_OK != CAWiFiServerCreateMutex())
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create mutex!");
+        return CA_STATUS_FAILED;
+    }
+
+    gThreadPool = threadPool;
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAWiFiTerminateServer(void)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    gThreadPool = NULL;
+
+    //Destroy mutex
+    CAWiFiServerDestroyMutex();
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+}
+
+CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *multicastAddress,
+                                      const int16_t multicastPort, int32_t *serverFD)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    if (gMulticastServerSocketDescriptor != -1)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server is already running!");
+        return CA_SERVER_STARTED_ALREADY;
+    }
+
+    VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Local address is NULL");
+    VERIFY_NON_NULL(multicastAddress, WIFI_SERVER_TAG, "Multicast address is NULL");
+
+    if (0 >= multicastPort)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: Multicast port is invalid!");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    // Create a datagram socket on which to recv/send.
+    u_mutex_lock(gMutexStopMulticast);
+    gStopMulticast = false;
+    u_mutex_unlock(gMutexStopMulticast);
+
+    u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+
+    // create a UDP socket
+    if ((gMulticastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s",
+                  strerror(errno));
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    // Make the socket non-blocking
+    if (-1 == fcntl(gMulticastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
+                  strerror(errno));
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "socket creation success");
+
+    int32_t setOptionOn = 1;
+    if (-1 == setsockopt(gMulticastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
+                         (char *) &setOptionOn,
+                         sizeof(setOptionOn)))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to setsockopt for SO_REUSEADDR, Error code: %s",
+                  strerror(errno));
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    struct sockaddr_in sockAddr;
+    memset((char *) &sockAddr, 0, sizeof(sockAddr));
+
+    sockAddr.sin_family = AF_INET;
+    sockAddr.sin_port = htons(multicastPort);
+    sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    //bind socket to multicast port
+    if (-1 == bind(gMulticastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
+                   sizeof(sockAddr)))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Bind Socket! Return Code[%d]",
+                  CA_SOCKET_OPERATION_FAILED);
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "socket bind success");
+
+    //Add membership to receiving socket (join group)
+    memset(&gMReq, 0, sizeof(struct ip_mreq));
+    gMReq.imr_interface.s_addr = htonl(INADDR_ANY);
+    inet_aton(multicastAddress, &gMReq.imr_multiaddr);
+
+    if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+                         (char *) &gMReq,
+                         sizeof(struct ip_mreq)))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n",
+                  strerror(errno));
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    /**
+      * The task to listen to data from multicastcast socket is added to the thread pool.
+      * This is a blocking call is made where we try to receive some data.. We will keep waiting until some data is received.
+      * This task will be terminated when thread pool is freed on stopping the adapters.
+      */
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAReceiveThreadForMulticast,
+            (void *)NULL))
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_STATUS_FAILED;
+    }
+
+    *serverFD = gMulticastServerSocketDescriptor;
+    u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "thread_pool_add_task done");
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server Started Successfully");
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+
+}
+
+CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
+                                    const bool forceStart, int32_t *serverFD)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    if (gUnicastServerSocketDescriptor != -1)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server is Started Already! Return Code[%d]",
+                  CA_SERVER_STARTED_ALREADY);
+        return CA_SERVER_STARTED_ALREADY;
+    }
+
+    VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Invalid argument : localAddress is NULL");
+    VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "Invalid argument : port is NULL");
+
+    if (0 >= port)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: port is invalid!");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    u_mutex_lock(gMutexStopUnicast);
+    gStopUnicast = false;
+    u_mutex_unlock(gMutexStopUnicast);
+
+    u_mutex_lock(gMutexUnicastServerSocketDescriptor);
+    // Create a UDP socket
+    if ((gUnicastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s",
+                  strerror(errno));
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    // Make the socket non-blocking
+    if (-1 == fcntl(gUnicastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
+                  strerror(errno));
+        close(gUnicastServerSocketDescriptor);
+        gUnicastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "socket creation success");
+
+    if (true == forceStart)
+    {
+        int32_t setOptionOn = 1;
+        if (-1 == setsockopt(gUnicastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
+                             (char *) &setOptionOn,
+                             sizeof(setOptionOn)))
+        {
+            OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
+                      strerror(errno));
+            close(gUnicastServerSocketDescriptor);
+            gUnicastServerSocketDescriptor = -1;
+            u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+            return CA_SOCKET_OPERATION_FAILED;
+        }
+    }
+
+    struct sockaddr_in sockAddr;
+    bool isBound = false;
+    int16_t serverPort = *port;
+
+    memset((char *) &sockAddr, 0, sizeof(sockAddr));
+    sockAddr.sin_family = AF_INET;
+    sockAddr.sin_port = htons(serverPort);
+    sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    //Trying for bind in a loop
+    int16_t i;
+    for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
+    {
+        if (-1 == bind(gUnicastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
+                       sizeof(sockAddr)))
+        {
+            if (false == forceStart)
+            {
+                OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]. Trying again... ",
+                          strerror(errno));
+
+                //Set the port to next one
+                serverPort += 1;
+                sockAddr.sin_port = htons(serverPort);
+                continue;
+            }
+            else
+            {
+                OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]!",
+                          strerror(errno));
+                break;
+            }
+        }
+
+        isBound = true;
+        break;
+    }
+
+    if (false == isBound)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind Socket! Return code[%d]",
+                  CA_SOCKET_OPERATION_FAILED);
+        close(gUnicastServerSocketDescriptor);
+        gUnicastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "socket bind success");
+
+    socklen_t len;
+    char *serverAddress = NULL;
+    if (-1 != getsockname(gUnicastServerSocketDescriptor, (struct sockaddr *)&sockAddr, &len))
+    {
+        serverPort = ntohs(sockAddr.sin_port);
+        serverAddress = inet_ntoa(sockAddr.sin_addr);
+    }
+
+    /**
+      * The task to listen for data from unicast socket is added to the thread pool.
+      * This is a blocking call is made where we try to receive some data..
+      * We will keep waiting until some data is received.
+      * This task will be terminated when thread pool is freed on stopping the adapters.
+      */
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAWiFiReceiveThreadForUnicast,
+            (void *) NULL))
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+
+        close(gUnicastServerSocketDescriptor);
+        gUnicastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_STATUS_FAILED;
+    }
+
+    //Free the server address previously stored
+    OICFree(gUnicastServerAddress);
+    gUnicastServerAddress = NULL;
+    gUnicastServerPort = serverPort;
+    gUnicastServerAddress = (serverAddress) ? strndup(serverAddress, strlen(serverAddress)) :
+                            NULL;
+    *port = serverPort;
+    *serverFD = gUnicastServerSocketDescriptor;
+    u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server Started Successfully");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiStopMulticastServer(void)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+
+    if (gMulticastServerSocketDescriptor == -1)
+    {
+        OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server is not yet Started");
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SERVER_NOT_STARTED;
+    }
+
+    u_mutex_lock(gMutexStopMulticast);
+    gStopMulticast = true;
+
+    // leave the group after you are done
+    if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+                         (char *)&gMReq,
+                         sizeof(struct ip_mreq)))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "cannot leave multicast group, Error code: %s\n",
+                  strerror(errno));
+    }
+
+    // close the socket
+    if (-1 == close(gMulticastServerSocketDescriptor))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server socket close failed, Error code: %s\n",
+                  strerror(errno));
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        u_mutex_unlock(gMutexStopMulticast);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    u_mutex_unlock(gMutexStopMulticast);
+
+    gMulticastServerSocketDescriptor = -1;
+    u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server Stopped Successfully");
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+
+}
+
+CAResult_t CAWiFiStopUnicastServer()
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+    u_mutex_lock(gMutexUnicastServerSocketDescriptor);
+
+    if (gUnicastServerSocketDescriptor == -1)
+    {
+        OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server is not yet Started");
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_SERVER_NOT_STARTED;
+    }
+    u_mutex_lock(gMutexStopUnicast);
+    gStopUnicast = true;
+
+    // close the socket
+    if (-1 == close(gUnicastServerSocketDescriptor))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server socket close failed, Error code: %s\n",
+                  strerror(errno));
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        u_mutex_unlock(gMutexStopUnicast);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    u_mutex_unlock(gMutexStopUnicast);
+    gUnicastServerSocketDescriptor = -1;
+
+    u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server Stopped Successfully");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    //Input validation
+    VERIFY_NON_NULL(ipAddress, WIFI_SERVER_TAG, "ipAddress holder is NULL");
+    VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "port holder is NULL");
+    VERIFY_NON_NULL(serverFD, WIFI_SERVER_TAG, "serverID holder is NULL");
+
+    *ipAddress = gUnicastServerAddress;
+    *port = gUnicastServerPort;
+    *serverFD = gUnicastServerSocketDescriptor;
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCallback callback)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    gPacketReceivedCallback = callback;
+}
+
+void CAWiFiSetExceptionCallback(CAWiFiExceptionCallback callback)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    gExceptionCallback = callback;
+}
+
+CAResult_t CAWiFiServerCreateMutex(void)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    gMutexUnicastServerSocketDescriptor = u_mutex_new();
+    if (!gMutexUnicastServerSocketDescriptor)
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+        return CA_STATUS_FAILED;
+    }
+
+    gMutexMulticastServerSocketDescriptor = u_mutex_new();
+    if (!gMutexMulticastServerSocketDescriptor)
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+
+        CAWiFiServerDestroyMutex();
+        return CA_STATUS_FAILED;
+    }
+
+    gMutexStopUnicast = u_mutex_new();
+    if (!gMutexStopUnicast)
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+
+        CAWiFiServerDestroyMutex();
+        return CA_STATUS_FAILED;
+    }
+
+    gMutexStopMulticast = u_mutex_new();
+    if (!gMutexStopMulticast)
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+
+        CAWiFiServerDestroyMutex();
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAWiFiServerDestroyMutex(void)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    if (gMutexUnicastServerSocketDescriptor)
+    {
+        u_mutex_free(gMutexUnicastServerSocketDescriptor);
+        gMutexUnicastServerSocketDescriptor = NULL;
+    }
+
+    if (gMutexMulticastServerSocketDescriptor)
+    {
+        u_mutex_free(gMutexMulticastServerSocketDescriptor);
+        gMutexMulticastServerSocketDescriptor = NULL;
+    }
+
+    if (gMutexStopUnicast)
+    {
+        u_mutex_free(gMutexStopUnicast);
+        gMutexStopUnicast = NULL;
+    }
+
+    if (gMutexStopMulticast)
+    {
+        u_mutex_free(gMutexStopMulticast);
+        gMutexStopMulticast = NULL;
+    }
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+}
+
+void *CAWiFiReceiveThreadForUnicast(void *data)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    fd_set reads;
+    struct timeval timeout;
+
+    //keep listening for data
+    while (!gStopUnicast)
+    {
+        //OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Waiting for data..");
+
+        timeout.tv_sec = 1;
+        timeout.tv_usec = 0;
+
+        FD_ZERO(&reads);
+        FD_SET(gUnicastServerSocketDescriptor, &reads);
+
+        int32_t ret = select(gUnicastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
+        if (gStopUnicast)
+        {
+            OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop Unicast is called");
+            break;
+        }
+        if (ret < 0)
+        {
+            OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
+            continue;
+        }
+        if (!FD_ISSET(gUnicastServerSocketDescriptor, &reads))
+        {
+            //OIC_LOG(DEBUG, WIFI_SERVER_TAG, "No data to read");
+            continue;
+        }
+
+        memset(gUnicastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
+
+        //Read data from socket
+        struct sockaddr_in srcSockAddress;
+        int32_t recvLen;
+        socklen_t srcAddressLen = sizeof(srcSockAddress);
+        if (-1 == (recvLen = recvfrom(gUnicastServerSocketDescriptor, gUnicastRecvBuffer,
+                                      COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
+                                      &srcAddressLen)))
+        {
+            OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
+            continue;
+        }
+        else if (0 == recvLen)
+        {
+            OIC_LOG(ERROR, WIFI_SERVER_TAG, "Unicast server socket is shutdown !");
+
+            //Notify upper layer this exception
+            if (gExceptionCallback)
+            {
+                gExceptionCallback(CA_UNICAST_SERVER);
+            }
+            return NULL;
+        }
+
+        const char *srcIPAddress = NULL;
+        int32_t srcPort = -1;
+
+        srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
+        srcPort = ntohs(srcSockAddress.sin_port);
+
+        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
+                  srcIPAddress, srcPort);
+        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
+                  gUnicastRecvBuffer, recvLen);
+
+        //Notify data to upper layer
+        if (gPacketReceivedCallback)
+        {
+            gPacketReceivedCallback(srcIPAddress, srcPort, gUnicastRecvBuffer, recvLen);
+        }
+    }
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+    return NULL;
+}
+
+void *CAReceiveThreadForMulticast(void *data)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    fd_set reads;
+    struct timeval timeout;
+
+    //keep listening for data
+    while (!gStopMulticast)
+    {
+        timeout.tv_sec = 1;
+        timeout.tv_usec = 0;
+
+        FD_ZERO(&reads);
+        FD_SET(gMulticastServerSocketDescriptor, &reads);
+
+        int32_t ret = select(gMulticastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
+        if (gStopMulticast)
+        {
+            OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop Multicast is called");
+            break;
+        }
+        if ( ret < 0)
+        {
+            OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
+            continue;
+        }
+        if (!FD_ISSET(gMulticastServerSocketDescriptor, &reads))
+        {
+            continue;
+        }
+
+        memset(gMulticastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
+
+        //Read data from socket
+        struct sockaddr_in srcSockAddress;
+        int32_t recvLen;
+        socklen_t srcAddressLen = sizeof(srcSockAddress);
+        if (-1 == (recvLen = recvfrom(gMulticastServerSocketDescriptor, gMulticastRecvBuffer,
+                                      COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
+                                      &srcAddressLen)))
+        {
+            OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
+            continue;
+        }
+        else if (0 == recvLen)
+        {
+            OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast socket is shutdown, returning from \
+                thread\n");
+
+            //Notify upper layer this exception
+            if (gExceptionCallback)
+            {
+                gExceptionCallback(CA_MULTICAST_SERVER);
+            }
+            return NULL;
+        }
+
+        const char *srcIPAddress = NULL;
+        int32_t srcPort = -1;
+
+        srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
+        srcPort = ntohs(srcSockAddress.sin_port);
+
+        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
+                  srcIPAddress, srcPort);
+        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
+                  gMulticastRecvBuffer, recvLen);
+
+
+        //Notify data to upper layer
+        if (gPacketReceivedCallback)
+        {
+            gPacketReceivedCallback(srcIPAddress, srcPort, gMulticastRecvBuffer, recvLen);
+        }
+    }
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+    return NULL;
+}
+
+
diff --git a/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter.c b/resource/csdk/connectivity/src/wifi_adapter/cawifiadapter.c
new file mode 100644 (file)
index 0000000..8ca8a84
--- /dev/null
@@ -0,0 +1,679 @@
+/******************************************************************
+ *
+ * Copyright 2014 Samsung Electronics All Rights Reserved.
+ *
+ *
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ *
+ ******************************************************************/
+#include "cawifiadapter.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <stdint.h>
+
+#include "cawifiinterface.h"
+#include "caqueueingthread.h"
+#include "caadapterutils.h"
+#include "umutex.h"
+#include "logger.h"
+#include "oic_malloc.h"
+
+/**
+ * @def WIFI_ETHERNET_ADAPTER_TAG
+ * @brief Logging tag for module name
+ */
+#define WIFI_ADAPTER_TAG "WIFI_ADAP"
+
+/**
+ * @def CA_PORT
+ * @brief Port to listen for incoming data
+ */
+#define CA_PORT   5283
+
+/**
+ * @def CA_MCAST_PORT
+ * @brief Multicast Port Number
+ */
+#define CA_MCAST_PORT   5298
+
+/**
+ * @def CA_MULTICAST_IP
+ * @brief Multicast IP Address
+ */
+#define CA_MULTICAST_IP "224.0.1.187"
+
+
+typedef struct
+{
+    CARemoteEndpoint_t *remoteEndpoint;
+    void *data;
+    uint32_t dataLen;
+} CAWiFiData;
+
+/**
+ * @var gNetworkPacketCallback
+ * @brief Network Packet Received Callback to CA
+ */
+static CANetworkPacketReceivedCallback gNetworkPacketCallback = NULL;
+
+/**
+ * @var gNetworkChangeCb
+ * @brief Network Changed Callback to CA
+ */
+CANetworkChangeCallback gNetworkChangeCallback = NULL;
+
+/**
+ * @var gIsMulticastServerStarted
+ * @brief Flag to check if multicast server is started
+ */
+static bool gIsMulticastServerStarted = false;
+
+/**
+ * @var gIsStartServerCalled
+ * @brief Flag to check if server start requested by CA.
+ */
+static bool gStartUnicastServerRequested = false;
+
+/**
+ * @var gUnicastServerport
+ * @brief port number on which unicast server is running.
+ */
+static int16_t gUnicastServerport = 0;
+
+/**
+ * @var gIsStartServerCalled
+ * @brief Flag to check if server start requested by CA.
+ */
+static bool gStartMulticastServerRequested = false;
+
+/**
+ * @var gSendQueueHandle
+ * @brief Queue handle for Send Data
+ */
+static CAQueueingThread_t *gSendQueueHandle = NULL;
+
+/**
+ * @var gThreadPool
+ * @brief ThreadPool for storing u_thread_pool_t handle passed from CA
+ */
+static u_thread_pool_t gThreadPool = NULL;
+
+static CAResult_t CAWiFiInitializeQueueHandles();
+static void CAWiFiDeinitializeQueueHandles();
+static void CAWiFiNotifyNetworkChange(const char *address, const int16_t port,
+                                      const CANetworkStatus_t status);
+static void CAWiFiConnectionStateCB(const char *ipAddress,
+                                    const CANetworkStatus_t status);
+static void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
+                                   const void *data, const uint32_t dataLength);
+static CAResult_t CAWiFiStopServers();
+static void CAWiFiSendDataThread(void *threadData);
+static CAWiFiData *CACreateWiFiData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+                                    uint32_t dataLength);
+void CAFreeWiFiData(CAWiFiData *wifiData);
+
+
+CAResult_t CAWiFiInitializeQueueHandles()
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+    // Check if the message queue is already initialized
+    if (gSendQueueHandle)
+    {
+        OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "Already queue is initialized!");
+        return CA_STATUS_OK;
+    }
+
+    // Create send message queue
+    gSendQueueHandle = OICMalloc(sizeof(CAQueueingThread_t));
+    if (!gSendQueueHandle)
+    {
+        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Memory allocation failed!");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    if (CA_STATUS_OK != CAQueueingThreadInitialize(gSendQueueHandle, gThreadPool,
+            CAWiFiSendDataThread))
+    {
+        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Initialize send queue thread");
+        OICFree(gSendQueueHandle);
+        gSendQueueHandle = NULL;
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAWiFiDeinitializeQueueHandles()
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+    CAQueueingThreadDestroy(gSendQueueHandle);
+    OICFree(gSendQueueHandle);
+    gSendQueueHandle = NULL;
+
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+}
+
+void CAWiFiNotifyNetworkChange(const char *address, const int16_t port,
+                               const CANetworkStatus_t status)
+{
+    CALocalConnectivity_t *localEndpoint = CAAdapterCreateLocalEndpoint(CA_WIFI, address, "WiFi");
+    if (!localEndpoint)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
+        return;
+    }
+    localEndpoint->addressInfo.IP.port = port;
+
+    if (NULL != gNetworkChangeCallback)
+    {
+        gNetworkChangeCallback(localEndpoint, status);
+    }
+
+    CAAdapterFreeLocalEndpoint(localEndpoint);
+}
+
+void CAWiFiConnectionStateCB(const char *ipAddress,
+                             const CANetworkStatus_t status)
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+    CAResult_t ret = CA_STATUS_FAILED;
+
+    /* *
+        * If Wifi is connected, then get the latest IP from the WIFI Interface
+        * and start unicast and multicast servers if requested earlier
+        */
+    if (CA_INTERFACE_UP == status)
+    {
+        int16_t port = CA_PORT;
+        int32_t serverFd = -1;
+        
+        // Start Unicast server if requested earlier
+        if (gStartUnicastServerRequested)
+        {
+            ret = CAWiFiStartUnicastServer("0.0.0.0", &port, false, &serverFd);
+            if (CA_STATUS_OK == ret)
+            {
+                OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", port);
+                CAWiFiSetUnicastSocket(serverFd);
+                gUnicastServerport = port;
+            }
+            else
+            {
+                OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to start Unicast server [%d]", ret);
+            }
+        }
+
+        // Start Multicast server if requested earlier
+        if (gStartMulticastServerRequested)
+        {
+            int16_t multicastPort = CA_MCAST_PORT;
+            int32_t multicastFd = 0;
+            ret = CAWiFiStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, 
+                &multicastFd);
+            if (CA_STATUS_OK == ret)
+            {
+                OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Multicast server started on %d port", 
+                    multicastPort);
+                gIsMulticastServerStarted = true;
+            }
+            else
+            {
+                OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to start Multicast server [%d]", ret);
+            }
+        }
+
+        char *ipAddress = NULL;
+        char *ifcName = NULL;
+        ret = CAWiFiGetInterfaceInfo(&ifcName, &ipAddress);
+        if (CA_STATUS_OK != ret)
+        {
+            OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
+            return;
+        }
+
+        // Notify network change to CA
+        CAWiFiNotifyNetworkChange(ipAddress, port, status);
+        OICFree(ipAddress);
+        OICFree(ifcName);
+    }
+    else
+    {
+        CAWiFiNotifyNetworkChange("", 0, status);
+
+        // Stop both Unicast and Multicast servers
+        ret = CAWiFiStopServers();
+        if (CA_STATUS_OK != ret)
+        {
+            OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Servers![%d]", ret);
+            return;
+        }
+    }
+
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+}
+
+void CAWiFiPacketReceivedCB(const char *ipAddress, const uint32_t port,
+                            const void *data, const uint32_t dataLength)
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+    OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Address: %s, port:%d, data:%s", ipAddress, port, data);
+
+    // CA is freeing this memory
+    CARemoteEndpoint_t *endPoint = CAAdapterCreateRemoteEndpoint(CA_WIFI, ipAddress, NULL);
+    if (NULL == endPoint)
+    {
+        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
+        return;
+    }
+    endPoint->addressInfo.IP.port = port;
+
+    void *buf = OICMalloc(dataLength + 1);
+    if (NULL == buf)
+    {
+        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Out of memory");
+        CAAdapterFreeRemoteEndpoint(endPoint);
+        return;
+    }
+    memcpy(buf, data, dataLength);
+    memset(buf + dataLength, 0, 1);
+    if (gNetworkPacketCallback)
+    {
+        gNetworkPacketCallback(endPoint, buf, dataLength);
+    }
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+}
+
+CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
+                            CANetworkPacketReceivedCallback networkPacketCallback,
+                            CANetworkChangeCallback netCallback, u_thread_pool_t handle)
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+    VERIFY_NON_NULL(registerCallback, WIFI_ADAPTER_TAG, "registerCallback");
+    VERIFY_NON_NULL(networkPacketCallback, WIFI_ADAPTER_TAG, "networkPacketCallback");
+    VERIFY_NON_NULL(netCallback, WIFI_ADAPTER_TAG, "netCallback");
+    VERIFY_NON_NULL(handle, WIFI_ADAPTER_TAG, "thread pool handle");
+
+    gThreadPool  = handle;
+    gNetworkChangeCallback = netCallback;
+    gNetworkPacketCallback = networkPacketCallback;
+
+    CAResult_t ret = CAWiFiInitializeNetworkMonitor(gThreadPool);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to initialize n/w monitor![%d]", ret);
+        return ret;
+    }
+    CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateCB);
+
+    ret = CAWiFiInitializeServer(gThreadPool);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to initialize server![%d]", ret);
+        CATerminateWIfI();
+        return ret;
+    }
+    CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCB);
+
+    CAConnectivityHandler_t wifiHandler;
+    wifiHandler.startAdapter = CAStartWIFI;
+    wifiHandler.startListenServer = CAStartWIFIListeningServer;
+    wifiHandler.startDiscoverServer = CAStartWIFIDiscoveryServer;
+    wifiHandler.sendData = CASendWIFIUnicastData;
+    wifiHandler.sendDataToAll = CASendWIFIMulticastData;
+    wifiHandler.GetnetInfo = CAGetWIFIInterfaceInformation;
+    wifiHandler.readData = CAReadWIFIData;
+    wifiHandler.stopAdapter = CAStopWIFI;
+    wifiHandler.terminate = CATerminateWIfI;
+    registerCallback(wifiHandler, CA_WIFI);
+
+    if (CA_STATUS_OK != CAWiFiInitializeQueueHandles())
+    {
+        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Initialize Queue Handle");
+        CATerminateWIfI();
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(INFO, WIFI_ADAPTER_TAG, "IntializeWifi is Success");
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAStartWIFI()
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+    // Start monitoring wifi network
+    CAResult_t ret = CAWiFiStartNetworkMonitor();
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start n/w monitor");
+    }
+
+    gStartUnicastServerRequested = true;
+    bool retVal = CAWiFiIsConnected();
+    if (false == retVal)
+    {
+        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "WIFI is not Connected");
+        return ret;
+    }
+
+    int16_t unicastPort = CA_PORT;
+    int32_t serverFd = 0;
+    // Address is hardcoded as we are using Single Interface
+    ret = CAWiFiStartUnicastServer("0.0.0.0", &unicastPort, false, &serverFd);
+    if (CA_STATUS_OK == ret)
+    {
+        OIC_LOG_V(DEBUG, WIFI_ADAPTER_TAG, "Unicast server started on %d port", unicastPort);
+        CAWiFiSetUnicastSocket(serverFd);
+        gUnicastServerport = unicastPort;
+    }
+
+    // Start send queue thread
+    if (CA_STATUS_OK != CAQueueingThreadStart(gSendQueueHandle))
+    {
+        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start Send Data Thread");
+        CAStopWIFI();
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+    return ret;
+}
+
+CAResult_t CAStartWIFIListeningServer()
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+    CAResult_t ret = CA_STATUS_OK;
+    int16_t multicastPort = CA_MCAST_PORT;
+
+    if (gIsMulticastServerStarted == true)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
+                  "Failed to Start Multicast Server, Already Started!");
+        return CA_SERVER_STARTED_ALREADY;
+    }
+
+    gStartMulticastServerRequested = true;
+    bool retVal = CAWiFiIsConnected();
+    if (false == retVal)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
+                  "Failed to Start Multicast Server, WIFI not Connected");
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    int32_t multicastFd = 0;
+    ret = CAWiFiStartMulticastServer("0.0.0.0", CA_MULTICAST_IP, multicastPort, &multicastFd);
+    if (CA_STATUS_OK == ret)
+    {
+        OIC_LOG(INFO, WIFI_ADAPTER_TAG, "Multicast Server is Started Successfully");
+        gIsMulticastServerStarted = true;
+    }
+
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+    return ret;
+}
+
+CAResult_t CAStartWIFIDiscoveryServer()
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+    return CAStartWIFIListeningServer();
+}
+
+uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+                               uint32_t dataLength)
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+    uint32_t dataSize = 0;
+    VERIFY_NON_NULL_RET(remoteEndpoint, WIFI_ADAPTER_TAG, "remoteEndpoint", dataSize);
+    VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "data", dataSize);
+    VERIFY_NON_NULL_RET(gSendQueueHandle, WIFI_ADAPTER_TAG, "sendQueueHandle", dataSize);
+
+    if (0 == dataLength)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Invalid Data Length");
+        return dataSize;
+    }
+
+    // Create WifiData to add to queue
+    CAWiFiData *wifiData = CACreateWiFiData(remoteEndpoint, data, dataLength);
+    if (!wifiData)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create wifidata!");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    // Add message to send queue
+    CAQueueingThreadAddData(gSendQueueHandle, wifiData, sizeof(CAWiFiData));
+
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+    return dataLength;
+}
+
+uint32_t CASendWIFIMulticastData(void *data, uint32_t dataLength)
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+    uint32_t dataSize = 0;
+    VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "data", dataSize);
+    VERIFY_NON_NULL_RET(gSendQueueHandle, WIFI_ADAPTER_TAG, "sendQueueHandle", dataSize);
+
+    if (0 == dataLength)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Invalid Data Length");
+        return dataSize;
+    }
+
+    // Create WifiData to add to queue
+    CAWiFiData *wifiData = CACreateWiFiData(NULL, data, dataLength);
+    if (!wifiData)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create wifidata!");
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    // Add message to send queue
+    CAQueueingThreadAddData(gSendQueueHandle, wifiData, sizeof(CAWiFiData));
+
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+    return dataLength;
+}
+
+CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+    VERIFY_NON_NULL(info, WIFI_ADAPTER_TAG, "info");
+    VERIFY_NON_NULL(size, WIFI_ADAPTER_TAG, "size");
+
+    bool retVal = CAWiFiIsConnected();
+    if (false == retVal)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
+                  "Failed to get interface address, WIFI not Connected", CA_ADAPTER_NOT_ENABLED);
+        return CA_ADAPTER_NOT_ENABLED;
+    }
+
+    char *ipAddress = NULL;
+    char *ifcName = NULL;
+    CAResult_t ret = CAWiFiGetInterfaceInfo(&ifcName, &ipAddress);
+    if (CA_STATUS_OK != ret)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to get interface info [%d]", ret);
+        return ret;
+    }
+
+    // Create local endpoint using util function
+    (*info) = CAAdapterCreateLocalEndpoint(CA_WIFI, ipAddress, ifcName);
+    if (NULL == (*info))
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create Local Endpoint!",
+                  CA_MEMORY_ALLOC_FAILED);
+        OICFree(ipAddress);
+        OICFree(ifcName);
+        return CA_MEMORY_ALLOC_FAILED;
+    }
+
+    (*info)->addressInfo.IP.port = gUnicastServerport;
+    (*size) = 1;
+
+    OICFree(ipAddress);
+    OICFree(ifcName);
+
+    OIC_LOG(INFO, WIFI_ADAPTER_TAG, "GetWIFIInterfaceInformation success");
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAReadWIFIData()
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiStopServers()
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+    CAResult_t result = CAWiFiStopUnicastServer();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Unicast Server![%d]", result);
+        return result;
+    }
+    CAWiFiSetUnicastSocket(-1);
+    gUnicastServerport = -1;
+
+    result = CAWiFiStopMulticastServer();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Multicast Server![%d]", result);
+        return result;
+    }
+    gIsMulticastServerStarted = false;
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+    return result;
+}
+
+CAResult_t CAStopWIFI()
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+    gStartUnicastServerRequested = false;
+    gStartMulticastServerRequested = false;
+
+    // Stop wifi network monitor
+    CAWiFiStopNetworkMonitor();
+
+    //Stop send queue thread
+    CAQueueingThreadStop(gSendQueueHandle);
+
+    // Stop unicast/multicast servers running
+    CAResult_t result = CAWiFiStopServers();
+    if (CA_STATUS_OK != result)
+    {
+        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Servers![%d]", result);
+    }
+
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+    return result;
+}
+
+void CATerminateWIfI()
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+    CAWiFiSetConnectionStateChangeCallback(NULL);
+    CAWiFiTerminateNetworkMonitor();
+    OIC_LOG(INFO, WIFI_ADAPTER_TAG, "nw monitor terminated");
+    CAWiFiDeinitializeQueueHandles();
+    OIC_LOG(INFO, WIFI_ADAPTER_TAG, "sendQueue terminated");
+
+    CAWiFiSetPacketReceiveCallback(NULL);
+    OIC_LOG(INFO, WIFI_ADAPTER_TAG, "TerminateWifi Success");
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+    return;
+}
+
+void CAWiFiSendDataThread(void *threadData)
+{
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
+
+    CAWiFiData *wifiData = (CAWiFiData *) threadData;
+    if (!wifiData)
+    {
+        OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "Invalid wifidata!");
+        return;
+    }
+
+    if (NULL != wifiData->remoteEndpoint)
+    {
+        OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "Send Unicast Data is called");
+        CAWiFiSendData(wifiData->remoteEndpoint->addressInfo.IP.ipAddress,
+                       wifiData->remoteEndpoint->addressInfo.IP.port, wifiData->data,
+                       wifiData->dataLen, false);
+    }
+    else
+    {
+        OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "Send Multicast Data is called");
+        CAWiFiSendData(CA_MULTICAST_IP, CA_MCAST_PORT, wifiData->data, wifiData->dataLen, true);
+    }
+
+    //Free wifi data
+    CAFreeWiFiData(wifiData);
+
+    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
+    return;
+}
+
+CAWiFiData *CACreateWiFiData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
+                             uint32_t dataLength)
+{
+    CAWiFiData *wifiData = (CAWiFiData *) OICMalloc(sizeof(CAWiFiData));
+    if (!wifiData)
+    {
+        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Memory allocation failed!");
+        return NULL;
+    }
+
+    wifiData->remoteEndpoint = CAAdapterCopyRemoteEndpoint(remoteEndpoint);
+    wifiData->data = (void *)OICMalloc(dataLength);
+    if (NULL == wifiData->data)
+    {
+        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Memory allocation failed!");
+        CAFreeWiFiData(wifiData);
+        return NULL;
+    }
+    memcpy(wifiData->data, data, dataLength);
+    wifiData->dataLen = dataLength;
+
+    return wifiData;
+}
+
+void CAFreeWiFiData(CAWiFiData *wifiData)
+{
+    if (!wifiData)
+        return;
+
+    CAAdapterFreeRemoteEndpoint(wifiData->remoteEndpoint);
+    OICFree(wifiData->data);
+    OICFree(wifiData);
+}
diff --git a/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiadapter.c b/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiadapter.c
deleted file mode 100644 (file)
index 5fda51a..0000000
+++ /dev/null
@@ -1,196 +0,0 @@
-/******************************************************************
- *
- * Copyright 2014 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include "cawifiadapter.h"
-#include "config.h"
-#include "coap.h"
-#include "cawificore.h"
-#include "logger.h"
-#include "oic_malloc.h"
-
-#define TAG PCF("CA")
-
-// received packet callback
-static CANetworkPacketReceivedCallback gWifiReceivedCallback = NULL;
-static u_thread_pool_t gThreadPoolHandle = NULL;
-
-static void CAWiFiPacketReceiveCallback(char* address, const int port, const char* data,
-        uint32_t dataLen)
-{
-    OIC_LOG_V(DEBUG, TAG, "CAWiFiPacketReceiveCallback, from: %s:%d, data: %s", address, port,
-            data);
-
-    // call the callback
-    if (gWifiReceivedCallback != NULL)
-    {
-        CARemoteEndpoint_t* endpoint = NULL;
-        endpoint = (CARemoteEndpoint_t*) OICMalloc(sizeof(CARemoteEndpoint_t));
-
-        // set address
-        memset((void*) endpoint->addressInfo.IP.ipAddress, 0, CA_IPADDR_SIZE);
-        if (CA_IPADDR_SIZE > strlen(address))
-        {
-            strcpy((char*) endpoint->addressInfo.IP.ipAddress, address);
-        }
-        OICFree(address);
-
-        // set port
-        endpoint->addressInfo.IP.port = port;
-
-        // set connectivity type
-        endpoint->connectivityType = CA_WIFI;
-
-        gWifiReceivedCallback(endpoint, (void *) data, dataLen);
-    }
-}
-
-CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
-        CANetworkPacketReceivedCallback reqRespCallback, CANetworkChangeCallback netCallback,
-        u_thread_pool_t handle)
-{
-    OIC_LOG(DEBUG, TAG, "IntializeWifi");
-
-    gWifiReceivedCallback = reqRespCallback;
-    gThreadPoolHandle = handle;
-
-    // register handlers
-    CAConnectivityHandler_t handler;
-    memset(&handler, 0, sizeof(CAConnectivityHandler_t));
-
-    handler.startAdapter = CAStartWIFI;
-    handler.startListenServer = CAStartWIFIListeningServer;
-    handler.startDiscoverServer = CAStartWIFIDiscoveryServer;
-    handler.sendData = CASendWIFIUnicastData;
-    handler.sendDataToAll = CASendWIFIMulticastData;
-    handler.GetnetInfo = CAGetWIFIInterfaceInformation;
-    handler.readData = CAReadWIFIData;
-    handler.stopAdapter = CAStopWIFI;
-    handler.terminate = CATerminateWIfI;
-
-    registerCallback(handler, CA_WIFI);
-
-    CAWiFiSetCallback(CAWiFiPacketReceiveCallback);
-
-    CAWiFiInitMutex();
-
-    CAWiFiInitialize(gThreadPoolHandle);
-
-    return CA_STATUS_OK;
-}
-
-void CATerminateWIfI()
-{
-    OIC_LOG(DEBUG, TAG, "TerminateWifi");
-
-    OIC_LOG(DEBUG, TAG, "[ToDo] call CAStopWIFI in TerminateWifi");
-    CAStopWIFI();
-
-    CAWiFiTerminate();
-}
-
-CAResult_t CAStartWIFI()
-{
-    OIC_LOG(DEBUG, TAG, "CAStartWIFI");
-
-    OIC_LOG(DEBUG, TAG, "CAWiFiStartUnicastServer");
-    int32_t res = CAWiFiStartUnicastServer("0.0.0.0", atoi("5283"));
-
-    if (res < 0)
-        return CA_STATUS_FAILED;
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStopWIFI()
-{
-    OIC_LOG(DEBUG, TAG, "CAStopWIFI");
-
-    CAWiFiStopUnicastServer(0);
-
-    CAWiFiStopMulticastServer(0);
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartWIFIListeningServer()
-{
-    OIC_LOG(DEBUG, TAG, "StartWIFIListeningServer");
-
-    int32_t res = CAWiFiStartMulticastServer("0.0.0.0", atoi("5283"));
-
-    if (res < 0)
-        return CA_STATUS_FAILED;
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartWIFIDiscoveryServer()
-{
-    OIC_LOG(DEBUG, TAG, "StartWIFIDiscoveryServer");
-
-    int32_t res = CAWiFiStartMulticastServer("0.0.0.0", atoi("5283"));
-
-    if (res < 0)
-        return CA_STATUS_FAILED;
-
-    return CA_STATUS_OK;
-}
-
-uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t* endpoint, void* data, uint32_t dataLen)
-{
-    OIC_LOG(DEBUG, TAG, "SendWIFIUnicastData");
-
-    CAWiFiSendUnicastMessage(endpoint->addressInfo.IP.ipAddress, endpoint->addressInfo.IP.port,
-            data, dataLen);
-
-    return 0;
-}
-
-uint32_t CASendWIFIMulticastData(void* data, uint32_t dataLen)
-{
-    OIC_LOG(DEBUG, TAG, "CASendWIFIMulticastData");
-
-    CAWiFiSendMulticastMessage("0.0.0.0", (char*) data, dataLen);
-
-    return 0;
-}
-
-CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t** info, uint32_t* size)
-{
-    OIC_LOG(DEBUG, TAG, "GetWIFIInterfaceInformation");
-
-    CAGetWIFIInterfaceInfo(info, size);
-
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAReadWIFIData()
-{
-    OIC_LOG(DEBUG, TAG, "Read WIFI Data");
-
-    // ToDo:
-
-    return CA_STATUS_OK;
-}
-
diff --git a/resource/csdk/connectivity/src/wifi_adapter/linux/cawificlient.c b/resource/csdk/connectivity/src/wifi_adapter/linux/cawificlient.c
new file mode 100644 (file)
index 0000000..707d377
--- /dev/null
@@ -0,0 +1,94 @@
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+#include "cawifiinterface.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <errno.h>
+
+#include "caadapterutils.h"
+
+/**
+ * @def WIFI_CLIENT_TAG
+ * @brief Logging tag for module name
+ */
+#define WIFI_CLIENT_TAG "WIFI_CLIENT"
+
+/**
+ * @var gUnicastServerSocketDescClient
+ * @brief socket descriptor for unicast server
+ */
+static int32_t gUnicastServerSocketDescClient = -1;
+
+void CAWiFiSetUnicastSocket(const int32_t socketFD)
+{
+    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
+
+    gUnicastServerSocketDescClient = socketFD;
+}
+
+uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
+                        const void *data, const uint32_t dataLength, bool isMulticast)
+{
+    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
+
+    VERIFY_NON_NULL_RET(remoteAddress, WIFI_CLIENT_TAG, "IP address is NULL", 0);
+    VERIFY_NON_NULL_RET(data, WIFI_CLIENT_TAG, "data is NULL", 0);
+
+    if (dataLength == 0)
+    {
+        OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Data length is 0 !");
+        return 0;
+    }
+
+    if (0 > gUnicastServerSocketDescClient)
+    {
+        OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Unicast Server is not running !");
+        return 0;
+    }
+
+    struct sockaddr_in destAddr;
+    memset((char *)&destAddr, 0, sizeof(destAddr));
+    destAddr.sin_family = AF_INET;
+    destAddr.sin_port = htons(port);
+
+    // Conversion from ASCII format to Network format
+    if (inet_aton(remoteAddress, &destAddr.sin_addr) == 0)
+    {
+        OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Failed to convert from ASCII to Network Address");
+        return 0;
+    }
+
+    int32_t sendDataLength = sendto(gUnicastServerSocketDescClient, data, dataLength, 0,
+                                    (struct sockaddr *)&destAddr, sizeof(destAddr));
+    if (sendDataLength == -1)
+    {
+        OIC_LOG_V(ERROR, WIFI_CLIENT_TAG, "Failed to Send Data, Error code: %s", strerror(errno));
+        return 0;
+    }
+
+    OIC_LOG_V(INFO, WIFI_CLIENT_TAG, "Sending data is successful, sent bytes[%d]", sendDataLength);
+
+    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT");
+    return sendDataLength;
+}
+
diff --git a/resource/csdk/connectivity/src/wifi_adapter/linux/cawificore.c b/resource/csdk/connectivity/src/wifi_adapter/linux/cawificore.c
deleted file mode 100644 (file)
index 57c5e6a..0000000
+++ /dev/null
@@ -1,852 +0,0 @@
-#include <stdio.h>
-#include <sys/socket.h>
-#include <arpa/inet.h>
-#include <string.h>
-#include <pthread.h>
-#include <unistd.h>
-#include <errno.h>
-#include <sys/types.h>
-#include <ifaddrs.h>
-#include <netinet/in.h>
-#include <string.h>
-#include <arpa/inet.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
-#include <net/if.h>
-
-#include "cawificore.h"
-#include "logger.h"
-#include "uthreadpool.h" /* for thread pool */
-#include "umutex.h"
-#include "caqueueingthread.h"
-#include "oic_malloc.h"
-
-#define TAG PCF("CA")
-
-#define REQ_CNT 20
-#define CA_MAX_BUFFER_SIZE 512  // Max length of buffer
-#define CA_UNICAST_PORT 5000 // The port on which to listen for incoming data
-#define CA_MULTICAST_ADDR "224.0.1.187"
-#define CA_MULTICAST_PORT 5683
-
-typedef enum
-{
-    CA_UNICAST = 1, CA_MULTICAST
-} CATransmissionType_t;
-
-typedef struct
-{
-    CATransmissionType_t transmissionType; // 0: none, 1: unicast, 2: multicast
-    char* address;
-    int port;
-    void* data;
-    uint32_t len;
-} CAThreadData_t;
-
-typedef struct
-{
-    u_mutex threadMutex;
-    u_cond threadCond;
-    int32_t isStop;
-    int32_t status; // 0: stopped, 1: running
-} CATask_t;
-
-static int gUnicastPort = 0;
-
-int32_t unicast_receive_socket; // unicast server, unicast client, multicast client
-struct sockaddr_in multicast_send_interface_addr;
-
-int32_t multicast_receive_socket; // multicast server
-struct sockaddr_in multicast_receive_interface_addr;
-
-static CAPacketReceiveCallback gPacketReceiveCallback = NULL;
-
-static u_thread_pool_t gThreadPoolHandle = NULL;
-
-// message handler main thread
-static CAQueueingThread_t gSendThread;
-static CAQueueingThread_t gReceiveThread;
-
-static CATask_t unicastListenTask;
-static CATask_t multicastListenTask;
-
-static void CASendProcess(void* threadData)
-{
-    OIC_LOG(DEBUG, TAG, "CASendThreadProcess");
-
-    CAThreadData_t* data = (CAThreadData_t*) threadData;
-    if (data == NULL)
-    {
-        OIC_LOG(DEBUG, TAG, "thread data is error!");
-        return;
-    }
-
-    if (data->transmissionType == CA_UNICAST)
-    {
-        // unicast
-        CASendUnicastMessageImpl(data->address, data->port, (char*) (data->data), data->len);
-    }
-    else if (data->transmissionType == CA_MULTICAST)
-    {
-        // multicast
-        CASendMulticastMessageImpl((char*) (data->data), data->len);
-    }
-}
-
-static void CAReceiveProcess(void* threadData)
-{
-    OIC_LOG(DEBUG, TAG, "CAReceiveProcess");
-
-    CAThreadData_t* data = (CAThreadData_t*) threadData;
-    if (data == NULL)
-    {
-        OIC_LOG(DEBUG, TAG, "thread data is error!");
-        return;
-    }
-
-    if (gPacketReceiveCallback != NULL)
-    {
-        gPacketReceiveCallback(data->address, data->port, (char*) (data->data), data->len);
-    }
-}
-
-void CAWiFiSetCallback(CAPacketReceiveCallback callback)
-{
-    gPacketReceiveCallback = callback;
-}
-
-void CAWiFiInitMutex()
-{
-    OIC_LOG(DEBUG, TAG, "CAWiFiInitMutex");
-
-    unicastListenTask.threadMutex = u_mutex_new();
-    unicastListenTask.threadCond = u_cond_new();
-    unicastListenTask.isStop = FALSE;
-    unicastListenTask.status = 0; // stopped
-
-    multicastListenTask.threadMutex = u_mutex_new();
-    multicastListenTask.threadCond = u_cond_new();
-    multicastListenTask.isStop = FALSE;
-    multicastListenTask.status = 0; // stopped
-}
-
-static void CAUnicastListenThread(void* threadData)
-{
-    OIC_LOG(DEBUG, TAG, "CAUnicastListenThread");
-
-    char buf[CA_MAX_BUFFER_SIZE];
-    uint32_t recv_len;
-
-    int32_t ret = 0;
-
-    struct sockaddr_in si_other;
-    socklen_t slen = sizeof(si_other);
-
-    fd_set reads;
-    struct timeval timeout;
-
-    while (1)
-    {
-        u_mutex_lock(unicastListenTask.threadMutex);
-        int32_t isStop = unicastListenTask.isStop;
-        u_mutex_unlock(unicastListenTask.threadMutex);
-        if (isStop)
-            break;
-
-        // OIC_LOG(DEBUG, TAG, "CAUnicastListenThread, Waiting for data...");
-
-        memset(buf, 0, sizeof(char) * CA_MAX_BUFFER_SIZE);
-
-        timeout.tv_sec = 1;
-        timeout.tv_usec = 0;
-
-        FD_ZERO(&reads);
-
-        // Use select for polling the socket fd
-        FD_SET(unicast_receive_socket, &reads);
-
-        ret = select(unicast_receive_socket + 1, &reads, NULL, NULL, &timeout);
-        if (ret < 0)
-        {
-            // OIC_LOG(DEBUG, TAG, "CAUnicastListenThread, select API failed");
-
-            continue;
-        }
-        if (!FD_ISSET(unicast_receive_socket, &reads))
-        {
-            // OIC_LOG(DEBUG, TAG, "CAUnicastListenThread, No data to read");
-            continue;
-        }
-
-        // try to receive some data
-        if ((recv_len = recvfrom(unicast_receive_socket, buf, CA_MAX_BUFFER_SIZE, 0,
-                (struct sockaddr *) &si_other, &slen)) == -1)
-        {
-            OIC_LOG_V(DEBUG, TAG, "%s\n", strerror(errno));
-            continue;
-        }
-        else if (0 == recv_len)
-        {
-            OIC_LOG(DEBUG, TAG, "Unicast socket is shutdown, returning from thread\n");
-            return;
-        }
-
-        // print details of the client/peer and the data received
-        OIC_LOG_V(DEBUG, TAG, "CAUnicastListenThread, Received packet from %s:%d",
-                inet_ntoa(si_other.sin_addr), ntohs(si_other.sin_port));
-        OIC_LOG_V(DEBUG, TAG, "CAUnicastListenThread, Data: %s", buf);
-
-        // store the data at queue.
-        CAThreadData_t* td = NULL;
-        td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t));
-        memset(td, 0, sizeof(CAThreadData_t));
-        td->transmissionType = 1; // unicast
-
-        char* _address = inet_ntoa(si_other.sin_addr);
-        int len = strlen(_address);
-        td->address = (char*) OICMalloc(sizeof(char) * (len + 1));
-        memset(td->address, 0, len + 1);
-        memcpy(td->address, _address, len);
-
-        td->port = ntohs(si_other.sin_port);
-
-        td->data = (void*) OICMalloc(sizeof(void) * CA_MAX_BUFFER_SIZE);
-        memset(td->data, 0, CA_MAX_BUFFER_SIZE);
-        memcpy(td->data, buf, sizeof(buf));
-        td->len = recv_len;
-
-        CAQueueingThreadAddData(&gReceiveThread, td, sizeof(CAThreadData_t));
-    }
-
-    u_cond_signal(unicastListenTask.threadCond);
-    OIC_LOG(DEBUG, TAG, "end of CAUnicastListenThread");
-}
-
-static void CAMulticastListenThread(void* threadData)
-{
-    OIC_LOG(DEBUG, TAG, "CAMulticastListenThread");
-
-    char msgbuf[CA_MAX_BUFFER_SIZE];
-
-    struct sockaddr_in client;
-    int32_t addrlen = sizeof(client);
-
-    fd_set reads;
-    struct timeval timeout;
-
-    while (1)
-    {
-        u_mutex_lock(multicastListenTask.threadMutex);
-        int32_t isStop = multicastListenTask.isStop;
-        u_mutex_unlock(multicastListenTask.threadMutex);
-        if (isStop)
-            break;
-
-        timeout.tv_sec = 1;
-        timeout.tv_usec = 0;
-
-        FD_ZERO(&reads);
-
-        // Use select for polling the socket fd
-        FD_SET(multicast_receive_socket, &reads);
-
-        int32_t ret = select(multicast_receive_socket + 1, &reads, NULL, NULL, &timeout);
-        if (ret < 0)
-        {
-            // OIC_LOG_V(FATAL, TAG, "CAMulticastListenThread, select API failed");
-            continue;
-        }
-        if (!FD_ISSET(multicast_receive_socket, &reads))
-        {
-            // OIC_LOG_V(DEBUG, TAG, "CAMulticastListenThread, No data to read");
-            continue;
-        }
-
-        // try to receive some data
-        int32_t recv_bytes = 0;
-        if ((recv_bytes = recvfrom(multicast_receive_socket, msgbuf, CA_MAX_BUFFER_SIZE, 0,
-                (struct sockaddr *) &client, (socklen_t *) &addrlen)) == -1)
-        {
-            OIC_LOG_V(DEBUG, TAG, "%s\n", strerror(errno));
-            continue;
-        }
-        else if (0 == recv_bytes)
-        {
-            OIC_LOG_V(ERROR, TAG, "Multicast socket is shutdown, returning from thread\n");
-            OIC_LOG(DEBUG, TAG, "return here ");
-            return;
-        }
-
-        OIC_LOG_V(DEBUG, TAG, "Received msg: %s, size: %d", msgbuf, recv_bytes);
-
-        // store the data at queue.
-        CAThreadData_t* td = NULL;
-        td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t));
-        memset(td, 0, sizeof(CAThreadData_t));
-        td->transmissionType = 2; // multicast
-
-        char* _address = inet_ntoa(client.sin_addr);
-        int len = strlen(_address);
-        td->address = (char*) OICMalloc(sizeof(char) * (len + 1));
-        memset(td->address, 0, len + 1);
-        memcpy(td->address, _address, len);
-        td->port = ntohs(client.sin_port);
-
-        td->data = (void*) OICMalloc(sizeof(void) * CA_MAX_BUFFER_SIZE);
-        memset(td->data, 0, CA_MAX_BUFFER_SIZE);
-        memcpy(td->data, msgbuf, sizeof(msgbuf));
-        td->len = recv_bytes;
-
-        CAQueueingThreadAddData(&gReceiveThread, td, sizeof(CAThreadData_t));
-
-    }
-
-    // leave the group after you are done
-    int16_t result = setsockopt(multicast_receive_socket, IPPROTO_IP, IP_DROP_MEMBERSHIP,
-            (struct sockaddr *) &multicast_receive_interface_addr,
-            sizeof(multicast_receive_interface_addr));
-    if (result < 0)
-    {
-        OIC_LOG_V(DEBUG, TAG,
-                "CAWiFiStopMulticastServer, cannot leave multicast group, Error code: %s\n",
-                strerror(errno));
-    }
-    u_cond_signal(multicastListenTask.threadCond);
-
-    OIC_LOG(DEBUG, TAG, "end of CAMulticastListenThread");
-}
-
-void CAWiFiInitialize(u_thread_pool_t handle)
-{
-    OIC_LOG(DEBUG, TAG, "CAWiFiInitialize");
-
-    gThreadPoolHandle = handle;
-
-    // unicast/multicast send queue
-    CAQueueingThreadInitialize(&gSendThread, gThreadPoolHandle, CASendProcess);
-
-    // start send thread
-    CAResult_t res = CAQueueingThreadStart(&gSendThread);
-    if (res != CA_STATUS_OK)
-    {
-        OIC_LOG(DEBUG, TAG, "thread start is error (send thread)");
-        // return res;
-        return;
-    }
-
-    // unicast/multicast receive queue
-    CAQueueingThreadInitialize(&gReceiveThread, gThreadPoolHandle, CAReceiveProcess);
-
-    // start send thread
-    res = CAQueueingThreadStart(&gReceiveThread);
-    if (res != CA_STATUS_OK)
-    {
-        OIC_LOG(DEBUG, TAG, "thread start is error (receive thread)");
-        // return res;
-        return;
-    }
-}
-
-int32_t CABindUnicastSocket()
-{
-    int32_t i;
-    for (i = 0; i < 100; i++)
-    {
-        int32_t port = CA_UNICAST_PORT + i;
-
-        struct sockaddr_in si_me;
-        memset((char *) &si_me, 0, sizeof(si_me));
-        si_me.sin_family = AF_INET;
-        si_me.sin_port = htons(port);
-        si_me.sin_addr.s_addr = htonl(INADDR_ANY);
-
-        // bind socket to port
-        if (bind(unicast_receive_socket, (struct sockaddr*) &si_me, sizeof(si_me)) == 0)
-        {
-            OIC_LOG_V(DEBUG, TAG, "CABindUnicastSocket, socket binded, port: %d", port);
-
-            gUnicastPort = port;
-
-            return 0;
-        }
-
-    }
-
-    OIC_LOG(DEBUG, TAG, "CABindUnicastSocket, binding socket failed");
-
-    return -1;
-}
-
-void CAWiFiTerminate()
-{
-    OIC_LOG(DEBUG, TAG, "CAWiFiTerminate");
-
-    close(unicast_receive_socket);
-    close(multicast_receive_socket);
-
-    // stop thread
-    CAQueueingThreadStop(&gSendThread);
-    // delete thread data
-    CAQueueingThreadDestroy(&gSendThread);
-
-    // stop thread
-    CAQueueingThreadStop(&gReceiveThread);
-    // delete thread data
-    CAQueueingThreadDestroy(&gReceiveThread);
-
-    u_mutex_free(unicastListenTask.threadMutex);
-
-    u_mutex_free(multicastListenTask.threadMutex);
-
-    OIC_LOG(DEBUG, TAG, "end of CAWiFiTerminate");
-}
-
-int32_t CAWiFiSendUnicastMessage(const char* address, const int port, char* data, uint32_t lengh)
-{
-    // store the data at queue.
-    CAThreadData_t* td = NULL;
-    td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t));
-    if (td == NULL)
-    {
-        OICFree(data);
-        return 0;
-    }
-    memset(td, 0, sizeof(CAThreadData_t));
-    td->transmissionType = CA_UNICAST; // unicast type
-    int len = strlen(address);
-    td->address = (char*) OICMalloc(sizeof(char) * (len + 1));
-    if (td->address != NULL)
-    {
-        memset(td->address, 0, len + 1);
-        memcpy(td->address, address, len);
-    }
-    else
-    {
-        OIC_LOG_V(DEBUG, TAG, "Memory Full");
-        OICFree(td);
-        OICFree(data);
-        return 0;
-    }
-
-    td->port = port;
-    td->data = data;
-    td->len = lengh;
-
-    CAQueueingThreadAddData(&gSendThread, td, sizeof(CAThreadData_t));
-
-    return 0;
-}
-
-int32_t CAWiFiSendMulticastMessage(const char* m_address, char* data, uint32_t dataLen)
-{
-    // store the data at queue.
-    CAThreadData_t* td = NULL;
-    td = (CAThreadData_t*) OICMalloc(sizeof(CAThreadData_t));
-    if (td == NULL)
-    {
-        OICFree(data);
-        return 0;
-    }
-    memset(td, 0, sizeof(CAThreadData_t));
-    td->transmissionType = CA_MULTICAST; // multicast type
-    td->address = NULL;
-    td->port = 0;
-    td->data = data;
-    td->len = dataLen;
-
-    CAQueueingThreadAddData(&gSendThread, td, sizeof(CAThreadData_t));
-
-    return 0;
-}
-
-int32_t CAWiFiStartUnicastServer()
-{
-    OIC_LOG_V(DEBUG, TAG, "CAWiFiStartUnicastServer");
-
-    // check the server status
-    if (unicastListenTask.status == 1)
-    {
-        OIC_LOG(DEBUG, TAG, "CAWiFiStartUnicastServer, already running");
-
-        return 0;
-    }
-
-    // 1. create a UDP socket
-    if ((unicast_receive_socket = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
-    {
-        OIC_LOG_V(DEBUG, TAG, "CAWiFiInitialize, creating socket failed");
-
-        return -1;
-    }
-
-    OIC_LOG(DEBUG, TAG, "CAWiFiInitialize, socket created");
-
-    // 2. Make the socket non-blocking
-    int16_t status = 0;
-    if ((status = fcntl(unicast_receive_socket, F_SETFL, O_NONBLOCK)) < 0)
-    {
-        OIC_LOG_V(ERROR, TAG,
-                "CAWiFiInitialize, fcntl to make the socket non-blocking failed, Error code: %s",
-                strerror(errno));
-
-        close(unicast_receive_socket);
-
-        return -1;
-    }
-
-    OIC_LOG(DEBUG, TAG, "CAWiFiInitialize, socket creation success");
-
-    // 3. set socket option // This is will allow server , client bining on same socket
-    /* uint32_t multiTTL = 1;
-     int32_t ret_val = setsockopt(unicast_receive_socket, SOL_SOCKET, SO_REUSEADDR, &multiTTL,
-     sizeof(multiTTL));
-     if (ret_val < 0)
-     {
-     OIC_LOG(DEBUG, TAG, "CAWiFiInit, Failed to set REUSEADDR");
-     close(unicast_receive_socket);
-
-     return -1;
-     }*/
-
-    // 4. bind socket
-    if (CABindUnicastSocket() == -1)
-    {
-        close(unicast_receive_socket);
-
-        return -1;
-    }
-
-    // unicast listen thread
-    CAResult_t res = u_thread_pool_add_task(gThreadPoolHandle, CAUnicastListenThread, NULL);
-    if (res != CA_STATUS_OK)
-    {
-        OIC_LOG(DEBUG, TAG, "adding task to thread pool is error (unicast listen thread)");
-        return res;
-    }
-
-    unicastListenTask.status = 1; // running
-    OIC_LOG_V(DEBUG, TAG, "CAWiFiStartUnicastServer(%s, %d)", "Local Address", gUnicastPort);
-
-    return 0;
-}
-
-int32_t CAWiFiStartMulticastServer()
-{
-    OIC_LOG_V(DEBUG, TAG, "CAWiFiStartMulticastServer(%s, %d)", "0.0.0.0", CA_MULTICAST_PORT);
-
-    // check the server status
-    if (multicastListenTask.status == 1)
-    {
-        OIC_LOG(DEBUG, TAG, "CAWiFiStartMulticastServer, already running");
-
-        return 0;
-    }
-
-    memset(&multicast_send_interface_addr, 0, sizeof(multicast_send_interface_addr));
-    multicast_send_interface_addr.sin_family = AF_INET;
-    multicast_send_interface_addr.sin_addr.s_addr = inet_addr(CA_MULTICAST_ADDR);
-    multicast_send_interface_addr.sin_port = htons(CA_MULTICAST_PORT);
-
-    // 1. Create a typical UDP socket and set Non-blocking for reading
-    multicast_receive_socket = socket(AF_INET, SOCK_DGRAM, 0);
-    if (multicast_receive_socket == -1)
-    {
-        OIC_LOG(DEBUG, TAG, "CAWiFiInit, Socket error");
-
-        return -1;
-    }
-
-    // 2. Make the socket non-blocking
-    int16_t status = 0;
-    if ((status = fcntl(multicast_receive_socket, F_SETFL, O_NONBLOCK)) < 0)
-    {
-        OIC_LOG_V(ERROR, TAG, "fcntl to make the socket non-blocking failed, Error code: %s",
-                strerror(errno));
-        close(multicast_receive_socket);
-
-        return -1;
-    }
-
-    // 2. Allow multiple sockets to use the same port number
-    uint32_t multiTTL = 1;
-    int32_t ret_val = setsockopt(multicast_receive_socket, SOL_SOCKET, SO_REUSEADDR, &multiTTL,
-            sizeof(multiTTL));
-    if (ret_val < 0)
-    {
-        OIC_LOG(DEBUG, TAG, "CAWiFiInit, Failed to set REUSEADDR");
-        close(multicast_receive_socket);
-
-        return -1;
-    }
-
-    // 3. Set up the interface
-    memset(&multicast_receive_interface_addr, 0, sizeof(multicast_receive_interface_addr));
-    multicast_receive_interface_addr.sin_family = AF_INET;
-    multicast_receive_interface_addr.sin_addr.s_addr = htonl(INADDR_ANY);
-    multicast_receive_interface_addr.sin_port = htons(CA_MULTICAST_PORT);
-
-    // 4. Bind to the interface
-    ret_val = bind(multicast_receive_socket, (struct sockaddr *) &multicast_receive_interface_addr,
-            sizeof(multicast_receive_interface_addr));
-    if (ret_val < 0)
-    {
-        OIC_LOG(DEBUG, TAG, "CAWiFiInit, Failed to bind socket");
-        close(multicast_receive_socket);
-
-        return -1;
-    }
-
-    // 5. Join the multicast group
-    struct ip_mreq mreq;
-    memset(&mreq, 0, sizeof(mreq));
-    mreq.imr_multiaddr.s_addr = inet_addr(CA_MULTICAST_ADDR);
-    mreq.imr_interface.s_addr = htonl(INADDR_ANY);
-    ret_val = setsockopt(multicast_receive_socket, IPPROTO_IP, IP_ADD_MEMBERSHIP, &mreq,
-            sizeof(mreq));
-    if (ret_val < 0)
-    {
-        OIC_LOG(DEBUG, TAG, "CAWiFiInit, Failed to join multicast group");
-        close(multicast_receive_socket);
-
-        return -1;
-    }
-
-    // multicast listen thread
-    CAResult_t res = u_thread_pool_add_task(gThreadPoolHandle, CAMulticastListenThread, NULL);
-    if (res != CA_STATUS_OK)
-    {
-        OIC_LOG(DEBUG, TAG, "adding task to thread pool is error (multicast listen thread)");
-        return res;
-    }
-
-    multicastListenTask.status = 1;
-
-    return 0;
-}
-
-int32_t CAWiFiStopUnicastServer()
-{
-    OIC_LOG(DEBUG, TAG, "CAWiFiStopUnicastServer");
-
-    // check the server status
-    if (unicastListenTask.status == 0)
-    {
-        OIC_LOG(DEBUG, TAG, "CAWiFiStopUnicastServer, already stopped");
-
-        return 0;
-    }
-
-    // mutex lock
-    u_mutex_lock(unicastListenTask.threadMutex);
-
-    // set stop flag
-    unicastListenTask.isStop = TRUE;
-
-    u_cond_wait(unicastListenTask.threadCond, unicastListenTask.threadMutex);
-
-    // notity the thread
-    // u_cond_signal(unicastListenTask.threadCond);
-
-    // mutex unlock
-    u_mutex_unlock(unicastListenTask.threadMutex);
-
-    unicastListenTask.status = 0; // stopped
-
-    // close(unicast_receive_socket);
-
-    return 0;
-}
-
-int32_t CAWiFiStopMulticastServer()
-{
-    OIC_LOG(DEBUG, TAG, "CAWiFiStopMulticastServer");
-
-    // check the server status
-    if (multicastListenTask.status == 0)
-    {
-        OIC_LOG(DEBUG, TAG, "CAWiFiStopMulticastServer, already stopped");
-
-        return 0;
-    }
-
-    // mutex lock
-    u_mutex_lock(multicastListenTask.threadMutex);
-
-    // set stop flag
-    multicastListenTask.isStop = TRUE;
-
-    u_cond_wait(multicastListenTask.threadCond, multicastListenTask.threadMutex);
-
-    // mutex unlock
-    u_mutex_unlock(multicastListenTask.threadMutex);
-
-    multicastListenTask.status = 0; // stopped
-
-    return 0;
-}
-
-void CAGetLocalAddress(char* addressBuffer)
-{
-    //char addressBuffer[INET_ADDRSTRLEN];
-    memset(addressBuffer, 0, INET_ADDRSTRLEN);
-
-    struct ifaddrs* ifAddrStruct = NULL;
-    struct ifaddrs* ifa = NULL;
-    void* tmpAddrPtr = NULL;
-
-    getifaddrs(&ifAddrStruct);
-
-    for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next)
-    {
-        if (!ifa->ifa_addr)
-        {
-            continue;
-        }
-
-        if (ifa->ifa_addr->sa_family == AF_INET)
-        { // check it is IP4
-          // is a valid IP4 Address
-            tmpAddrPtr = &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr;
-
-            memset(addressBuffer, 0, INET_ADDRSTRLEN);
-            inet_ntop(AF_INET, tmpAddrPtr, addressBuffer, INET_ADDRSTRLEN);
-
-            if (strcmp(addressBuffer, "127.0.0.1") == 0)
-                continue;
-        }
-    }
-
-    if (ifAddrStruct != NULL)
-        freeifaddrs(ifAddrStruct);
-}
-
-int32_t CASendUnicastMessageImpl(const char* address, const int port, const char* data,
-        uint32_t len)
-{
-    OIC_LOG_V(DEBUG, TAG, "CASendUnicastMessageImpl, address: %s:%d, data: %s", address, port,
-            data);
-
-    // [UDP Client]
-
-    struct sockaddr_in si_other;
-    int32_t slen = sizeof(si_other);
-
-    memset((char *) &si_other, 0, sizeof(si_other));
-
-    si_other.sin_family = AF_INET;
-    si_other.sin_port = htons(port);
-    if (inet_aton(address, &si_other.sin_addr) == 0)
-    {
-        OIC_LOG(DEBUG, TAG, "CASendUnicastMessageImpl, inet_aton, error...");
-        return 0;
-    }
-
-    OIC_LOG_V(DEBUG, TAG, "CASendUnicastMessageImpl, sendto, to: %s, data: %s", address, data);
-    if (sendto(unicast_receive_socket, data, len, 0, (struct sockaddr *) &si_other, slen) == -1)
-    {
-        OIC_LOG(DEBUG, TAG, "CASendUnicastMessageImpl, sendto, error...");
-
-        return 0;
-    }
-
-    return 0;
-}
-
-int32_t CASendMulticastMessageImpl(const char* msg, uint32_t len)
-{
-    OIC_LOG_V(DEBUG, TAG, "CASendMulticastMessageImpl, sendto, data: %s", msg);
-
-    int32_t result = sendto(unicast_receive_socket, msg, len, 0,
-            (struct sockaddr *) &multicast_send_interface_addr,
-            sizeof(multicast_send_interface_addr));
-    if (result < 0)
-    {
-        OIC_LOG(DEBUG, TAG, "CASendMulticastMessageImpl, sending message error...");
-
-        return -1;
-    }
-
-    return 0;
-}
-
-CAResult_t CAGetWIFIInterfaceInfo(CALocalConnectivity_t **info, uint32_t* size)
-{
-    uint32_t cnt, req_cnt = REQ_CNT;
-    int32_t fd;
-    uint32_t cmd = SIOCGIFCONF;
-    uint32_t resSize = 0;
-    char* localIPAddress;
-    struct sockaddr_in *sock;
-    struct ifconf ifc;
-    struct ifreq *ifr;
-
-    memset((void *) &ifc, 0, sizeof(struct ifconf));
-    ifc.ifc_len = sizeof(struct ifconf) * req_cnt;
-    ifc.ifc_buf = NULL;
-    ifc.ifc_buf = malloc(ifc.ifc_len);
-
-    if ((fd = socket(AF_INET, SOCK_STREAM, 0)) < 0)
-    {
-        OIC_LOG(DEBUG, TAG, "create socket error!");
-        return CA_STATUS_FAILED;
-    }
-
-    if (ioctl(fd, cmd, &ifc) < 0)
-    {
-        OIC_LOG(DEBUG, TAG, "SIOCGIFCONF fail");
-        close(fd);
-        return CA_STATUS_FAILED;
-    }
-    close(fd);
-
-    if (ifc.ifc_len > (sizeof(struct ifreq) * req_cnt))
-    {
-        req_cnt = ifc.ifc_len;
-        ifc.ifc_buf = realloc(ifc.ifc_buf, req_cnt);
-    }
-
-    ifr = ifc.ifc_req;
-    for (cnt = 0; cnt < ifc.ifc_len; cnt += sizeof(struct ifreq), ifr++)
-    {
-        sock = (struct sockaddr_in *) &ifr->ifr_addr;
-
-        // except loopback address
-        if (ntohl(sock->sin_addr.s_addr) == INADDR_LOOPBACK)
-            continue;
-
-        // get local address
-        localIPAddress = inet_ntoa(sock->sin_addr);
-
-        CALocalConnectivity_t* localInfo;
-
-        // memory allocation
-        localInfo = (CALocalConnectivity_t*) OICMalloc(sizeof(CALocalConnectivity_t));
-        if (localInfo == NULL)
-        {
-            OIC_LOG_V(DEBUG, TAG, "memory alloc error!!");
-            free(localInfo);
-            return CA_STATUS_FAILED;
-        }
-        memset(localInfo, 0, sizeof(CALocalConnectivity_t));
-
-        if (strlen(localIPAddress) > CA_IPADDR_SIZE)
-        {
-            OIC_LOG_V(DEBUG, TAG, "address size is wrong!!");
-            free(localInfo);
-            return CA_STATUS_FAILED;
-        }
-        // set local ip address
-        strncpy(localInfo->addressInfo.IP.ipAddress, localIPAddress, strlen(localIPAddress));
-
-        // set network type
-        localInfo->type = CA_WIFI;
-
-        *info = localInfo;
-
-        resSize++;
-    }
-
-    *size = resSize;
-
-    return CA_STATUS_OK;
-}
diff --git a/resource/csdk/connectivity/src/wifi_adapter/linux/cawifinwmonitor.c b/resource/csdk/connectivity/src/wifi_adapter/linux/cawifinwmonitor.c
new file mode 100644 (file)
index 0000000..a0fe577
--- /dev/null
@@ -0,0 +1,307 @@
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+
+#include "cawifiinterface.h"
+
+#include <string.h>
+#include <ifaddrs.h>
+#include <netdb.h>
+
+#include "caadapterutils.h"
+#include "umutex.h"
+#include "logger.h"
+#include "oic_malloc.h"
+
+#define WIFI_MONITOR_TAG "WIFI_MONITOR"
+
+/**
+ * @var nwConnectivityStatus
+ * @brief  Maintains network status.
+ */
+static CANetworkStatus_t nwConnectivityStatus;
+
+/**
+ * @var gWifiNetInfoMutex
+ * @brief  Mutex for synchronizing access to cached interface and IP address information.
+ */
+static u_mutex gWifiNetInfoMutex = NULL;
+
+/**
+ * @var gWifiInterfaceName
+ * @brief  Maintains interface name.
+ */
+static char *gWifiInterfaceName = NULL;
+
+/**
+ * @var gWifiIPAddress
+ * @brief  Maintains interface IP address.
+ */
+static char *gWifiIPAddress = NULL;
+
+/**
+ * @var gThreadPool
+ * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
+ */
+static u_thread_pool_t gThreadPool = NULL;
+
+/**
+ * @var gStopNetworkMonitor
+ * @brief Flag to control the Network Monitor Thread
+ */
+static bool gStopNetworkMonitor = false;
+
+/**
+ * @var gNetworkChangeCb
+ * @brief  Maintains network connection state change callback.
+ */
+static CAWiFiConnectionStateChangeCallback gNetworkChangeCb = NULL;
+
+/**
+ * @fn CAWiFiGetInterfaceInformation
+ * @brief This methods gets local interface name and IP address information.
+ */
+static void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress);
+
+static void CANetworkMonitorThread(void* threadData);
+
+CAResult_t CAWiFiInitializeNetworkMonitor(const u_thread_pool_t threadPool)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    gThreadPool = threadPool;
+
+    if (!gWifiNetInfoMutex)
+    {
+        gWifiNetInfoMutex = u_mutex_new();
+    }
+
+    u_mutex_lock(gWifiNetInfoMutex);
+    CAWiFiGetInterfaceInformation(&gWifiInterfaceName, &gWifiIPAddress);
+    u_mutex_unlock(gWifiNetInfoMutex);
+
+    nwConnectivityStatus = (gWifiIPAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAWiFiTerminateNetworkMonitor(void)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    gThreadPool = NULL;
+
+    if (gWifiInterfaceName)
+    {
+        OICFree(gWifiInterfaceName);
+        gWifiInterfaceName = NULL;
+    }
+
+    if (gWifiIPAddress)
+    {
+        OICFree(gWifiIPAddress);
+        gWifiIPAddress = NULL;
+    }
+
+    if (gWifiNetInfoMutex)
+    {
+        u_mutex_free(gWifiNetInfoMutex);
+        gWifiNetInfoMutex = NULL;
+    }
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+}
+
+CAResult_t CAWiFiStartNetworkMonitor(void)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    u_mutex_lock(gWifiNetInfoMutex);
+    gStopNetworkMonitor = false;
+    u_mutex_unlock(gWifiNetInfoMutex);
+
+    if (gStopNetworkMonitor)
+    {
+        OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Network Monitor Thread is already running!");
+        return CA_SERVER_STARTED_ALREADY;
+    }
+
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CANetworkMonitorThread,
+            (void *)NULL))
+    {
+        OIC_LOG(ERROR, WIFI_MONITOR_TAG, "[ThreadPool] thread_pool_add_task failed!");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiStopNetworkMonitor(void)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    if (gStopNetworkMonitor)
+    {
+        OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "CAWiFiStopNetworkMonitor, already stopped");
+
+        return CA_STATUS_OK;
+    }
+
+    u_mutex_lock(gWifiNetInfoMutex);
+    gStopNetworkMonitor = true;
+    u_mutex_unlock(gWifiNetInfoMutex);
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    VERIFY_NON_NULL(interfaceName, WIFI_MONITOR_TAG, "interface name holder is NULL");
+    VERIFY_NON_NULL(ipAddress, WIFI_MONITOR_TAG, "IP address holder is NULL");
+
+    u_mutex_lock(gWifiNetInfoMutex);
+
+    if (gWifiInterfaceName && strlen(gWifiInterfaceName))
+    {
+        *interfaceName = (gWifiInterfaceName) ? strndup(gWifiInterfaceName, strlen(gWifiInterfaceName)) :
+                                NULL;
+    }
+
+    if (gWifiIPAddress && strlen(gWifiIPAddress))
+    {
+        *ipAddress = (gWifiIPAddress) ? strndup(gWifiIPAddress, strlen(gWifiIPAddress)) :
+                                NULL;
+    }
+
+    u_mutex_unlock(gWifiNetInfoMutex);
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+bool CAWiFiIsConnected(void)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    if (nwConnectivityStatus == CA_INTERFACE_DOWN)
+        return false;
+
+    return true;
+}
+
+void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback callback)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    gNetworkChangeCb = callback;
+}
+
+void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress)
+{
+    struct ifaddrs *ifa = NULL;
+    struct ifaddrs *ifp = NULL;
+
+    if (getifaddrs(&ifp) < 0)
+    {
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Get network interface list error");
+    }
+
+    for (ifa = ifp; ifa; ifa = ifa->ifa_next)
+    {
+        char localIPAddress[CA_IPADDR_SIZE];
+        socklen_t len;
+
+        if (ifa->ifa_addr == NULL)
+            continue;
+
+        if (ifa->ifa_addr->sa_family == AF_INET)
+            len = sizeof(struct sockaddr_in);
+        else if (ifa->ifa_addr->sa_family == AF_INET6)
+            continue;
+        else
+            continue;
+
+        if (getnameinfo(ifa->ifa_addr, len, localIPAddress,
+                        sizeof(localIPAddress), NULL, 0, NI_NUMERICHOST) < 0)
+        {
+            OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Get IPAddress fail");
+        }
+
+        // except loopback address
+        if (strcmp(localIPAddress, "127.0.0.1") == 0)
+            continue;
+
+        // set interface name
+        *interfaceName = strndup(ifa->ifa_name, strlen(ifa->ifa_name));
+
+        // set local ip address
+        *ipAddress = strndup(localIPAddress, strlen(localIPAddress));
+    }
+
+    freeifaddrs(ifp);
+}
+
+void CANetworkMonitorThread(void* threadData)
+{
+    while (!gStopNetworkMonitor)
+    {
+        if (gStopNetworkMonitor)
+        {
+            OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Stop Network Monitor Thread is called");
+            break;
+        }
+
+        // Get network information
+        CANetworkStatus_t currNetworkStatus;
+        char *interfaceName = NULL;
+        char *ipAddress = NULL;
+        CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress);
+
+        // check current network status
+        currNetworkStatus = (ipAddress) ? CA_INTERFACE_UP : CA_INTERFACE_DOWN;
+
+        // if network status is changed
+        if (currNetworkStatus != nwConnectivityStatus)
+        {
+            // set current network information
+            u_mutex_lock(gWifiNetInfoMutex);
+
+            nwConnectivityStatus = currNetworkStatus;
+
+            OICFree(gWifiInterfaceName);
+            OICFree(gWifiIPAddress);
+            gWifiInterfaceName = (interfaceName) ? strndup(interfaceName, strlen(interfaceName)) : NULL;
+            gWifiIPAddress = (ipAddress) ? strndup(ipAddress, strlen(ipAddress)) : NULL;
+
+            u_mutex_unlock(gWifiNetInfoMutex);
+
+            if (gNetworkChangeCb)
+            {
+                gNetworkChangeCb(gWifiIPAddress, nwConnectivityStatus);
+            }
+        }
+        OICFree(interfaceName);
+        OICFree(ipAddress);
+    }
+}
diff --git a/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiserver.c b/resource/csdk/connectivity/src/wifi_adapter/linux/cawifiserver.c
new file mode 100644 (file)
index 0000000..e715759
--- /dev/null
@@ -0,0 +1,822 @@
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+#include "cawifiinterface.h"
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/select.h>
+#include <arpa/inet.h>
+#include <netinet/in.h>
+#include <errno.h>
+
+#include "pdu.h"
+#include "caadapterutils.h"
+#include "umutex.h"
+
+/**
+ * @def WIFI_SERVER_TAG
+ * @brief Logging tag for module name
+ */
+#define WIFI_SERVER_TAG "WIFI_SERVER"
+
+/**
+ * @def CA_UDP_BIND_RETRY_COUNT
+ * @brief Retry count in case of socket bind failure.
+ */
+#define CA_UDP_BIND_RETRY_COUNT 10
+
+/**
+ * @var gUnicastServerSocketDescriptor
+ * @brief socket descriptor for unicast server
+ */
+static int32_t gUnicastServerSocketDescriptor = -1;
+
+/**
+ * @var gUnicastServerSocketDescriptor
+ * @brief socket descriptor for unicast server
+ */
+static char *gUnicastServerAddress = NULL;
+
+/**
+ * @var gUnicastServerSocketDescriptor
+ * @brief socket descriptor for unicast server
+ */
+static int16_t gUnicastServerPort = -1;
+
+/**
+ * @var gMutexUnicastServerSocketDescriptor
+ * @brief Mutex for socket descriptor for unicast server
+ */
+static u_mutex gMutexUnicastServerSocketDescriptor = NULL;
+/**
+ * @var gMulticastServerSocketDescriptor
+ * @brief socket descriptor for multicast server
+ */
+static int32_t gMulticastServerSocketDescriptor = -1;
+
+/**
+ * @var gMutexMulticastServerSocketDescriptor
+ * @brief Mutex for socket descriptor for Multicast server
+ */
+static u_mutex gMutexMulticastServerSocketDescriptor = NULL;
+
+/**
+ * @var gThreadPool
+ * @brief ThreadPool for storing u_thread_pool_t handle passed from adapter
+ */
+static u_thread_pool_t gThreadPool = NULL;
+
+/**
+ * @var gMReq
+ * @brief ip_mreq structure passed to join a multicast group
+ */
+static struct ip_mreq gMReq;
+
+/**
+ * @var gStopUnicast
+ * @brief Flag to control the Receive Unicast Data Thread
+ */
+static bool gStopUnicast = false;
+
+/**
+ * @var gMutexStopUnicast
+ * @brief Mutex for gStopUnicast
+ */
+static u_mutex gMutexStopUnicast = NULL;
+
+/**
+ * @var gStopMulticast
+ * @brief Flag to control the Receive Multicast Data Thread
+ */
+static bool gStopMulticast = false;
+
+/**
+ * @var gMutexStopMulticast
+ * @brief Mutex for gStopMulticast
+ */
+static u_mutex gMutexStopMulticast = NULL;
+
+/**
+ * @var gPacketReceivedCallback
+ * @brief Callback for notifying the upper layer on receival data from remote OIC device
+ */
+static CAWiFiPacketReceivedCallback gPacketReceivedCallback = NULL;
+
+/**
+ * @var gExceptionCallback
+ * @brief Callback for notifying the upper layer when unicast/multicast server encounters exception
+ */
+static CAWiFiExceptionCallback gExceptionCallback = NULL;
+
+/**
+ * @var gUnicastRecvBuffer
+ * @brief Character buffer used for receiving unicast data from network
+ */
+static char gUnicastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
+
+/**
+ * @var gMulticastRecvBuffer
+ * @brief Character buffer used for receiving multicast data from network
+ */
+static char gMulticastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
+
+/**
+ * @fn CAWiFiServerCreateMutex
+ * @brief Creates and initializes mutex
+ */
+static CAResult_t CAWiFiServerCreateMutex(void);
+
+/**
+ * @fn CAWiFiServerDestroyMutex
+ * @brief Releases all created mutex
+ */
+static void CAWiFiServerDestroyMutex(void);
+
+/**
+ * @fn CAReceiveThreadForMulticast
+ * @brief Handler thread for receiving data on multicast server
+ */
+static void *CAReceiveThreadForMulticast(void *data);
+
+/**
+ * @fn CAWiFiReceiveThreadForUnicast
+ * @brief Handler thread for receiving data on unicast server
+ */
+static void *CAWiFiReceiveThreadForUnicast(void *data);
+
+CAResult_t CAWiFiInitializeServer(const u_thread_pool_t threadPool)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiInitializeServer, IN");
+
+    // Input validation
+    VERIFY_NON_NULL(threadPool, WIFI_SERVER_TAG, "Thread pool handle is NULL");
+
+    // Initialize mutex
+    if (CA_STATUS_OK != CAWiFiServerCreateMutex())
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create mutex!");
+        return CA_STATUS_FAILED;
+    }
+
+    gThreadPool = threadPool;
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiInitializeServer, OUT");
+    return CA_STATUS_OK;
+}
+
+void CAWiFiTerminateServer(void)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiTerminateServer, IN");
+
+    gThreadPool = NULL;
+
+    // Destroy mutex
+    CAWiFiServerDestroyMutex();
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiTerminateServer, OUT");
+}
+
+CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *multicastAddress,
+                                      const int16_t multicastPort, int32_t *serverFD)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiStartMulticastServer, IN");
+
+    if (gMulticastServerSocketDescriptor != -1)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server is already running!");
+        return CA_SERVER_STARTED_ALREADY;
+    }
+
+    VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Local address is NULL");
+    VERIFY_NON_NULL(multicastAddress, WIFI_SERVER_TAG, "Multicast address is NULL");
+
+    if (0 >= multicastPort)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: Multicast port is invalid!");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    // Create a datagram socket on which to recv/send.
+    u_mutex_lock(gMutexStopMulticast);
+    gStopMulticast = false;
+    u_mutex_unlock(gMutexStopMulticast);
+
+    u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+
+    // create a UDP socket
+    if ((gMulticastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s",
+                  strerror(errno));
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    // Make the socket non-blocking
+    if (-1 == fcntl(gMulticastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
+                  strerror(errno));
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "socket creation success");
+
+    int32_t setOptionOn = 1;
+    if (-1 == setsockopt(gMulticastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
+                         (char *) &setOptionOn,
+                         sizeof(setOptionOn)))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to setsockopt for SO_REUSEADDR, Error code: %s",
+                  strerror(errno));
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    struct sockaddr_in sockAddr;
+    memset((char *) &sockAddr, 0, sizeof(sockAddr));
+
+    sockAddr.sin_family = AF_INET;
+    sockAddr.sin_port = htons(multicastPort);
+    sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    // bind socket to multicast port
+    if (-1 == bind(gMulticastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
+                   sizeof(sockAddr)))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Bind Socket! Return Code[%d]",
+                  CA_SOCKET_OPERATION_FAILED);
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "socket bind success");
+
+    // Add membership to receiving socket (join group)
+    memset(&gMReq, 0, sizeof(struct ip_mreq));
+    gMReq.imr_interface.s_addr = htonl(INADDR_ANY);
+    inet_aton(multicastAddress, &gMReq.imr_multiaddr);
+
+    if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+                         (char *) &gMReq,
+                         sizeof(struct ip_mreq)))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n",
+                  strerror(errno));
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    /**
+      * The task to listen to data from multicastcast socket is added to the thread pool.
+      * This is a blocking call is made where we try to receive some data.. We will keep waiting until some data is received.
+      * This task will be terminated when thread pool is freed on stopping the adapters.
+      */
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAReceiveThreadForMulticast,
+            (void *)NULL))
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_STATUS_FAILED;
+    }
+
+    *serverFD = gMulticastServerSocketDescriptor;
+    u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "thread_pool_add_task done");
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server Started Successfully");
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiStartMulticastServer, OUT");
+    return CA_STATUS_OK;
+
+}
+
+CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
+                                    const bool forceStart, int32_t *serverFD)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "CAWiFiStartUnicastServer, IN");
+
+    if (gUnicastServerSocketDescriptor != -1)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server is Started Already! Return Code[%d]",
+                  CA_SERVER_STARTED_ALREADY);
+        return CA_SERVER_STARTED_ALREADY;
+    }
+
+    VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Invalid argument : localAddress is NULL");
+    VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "Invalid argument : port is NULL");
+
+    if (*port < 0)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: port is invalid!");
+        return CA_STATUS_INVALID_PARAM;
+    }
+
+    u_mutex_lock(gMutexStopUnicast);
+    gStopUnicast = false;
+    u_mutex_unlock(gMutexStopUnicast);
+
+    u_mutex_lock(gMutexUnicastServerSocketDescriptor);
+    // Create a UDP socket
+    if ((gUnicastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s",
+                  strerror(errno));
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    // Make the socket non-blocking
+    if (-1 == fcntl(gUnicastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
+                  strerror(errno));
+        close(gUnicastServerSocketDescriptor);
+        gUnicastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "socket creation success");
+
+    if (true == forceStart)
+    {
+        int32_t setOptionOn = 1;
+        if (-1 == setsockopt(gUnicastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
+                             (char *) &setOptionOn,
+                             sizeof(setOptionOn)))
+        {
+            OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
+                      strerror(errno));
+            close(gUnicastServerSocketDescriptor);
+            gUnicastServerSocketDescriptor = -1;
+            u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+            return CA_SOCKET_OPERATION_FAILED;
+        }
+    }
+
+    struct sockaddr_in sockAddr;
+    bool isBound = false;
+    int16_t serverPort = *port;
+
+    memset((char *) &sockAddr, 0, sizeof(sockAddr));
+    sockAddr.sin_family = AF_INET;
+    sockAddr.sin_port = htons(serverPort);
+    sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
+
+    // Trying for bind in a loop
+    int16_t i;
+    for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
+    {
+        if (-1 == bind(gUnicastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
+                       sizeof(sockAddr)))
+        {
+            if (false == forceStart)
+            {
+                OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]. Trying again... ",
+                          strerror(errno));
+
+                // Set the port to next one
+                serverPort += 1;
+                sockAddr.sin_port = htons(serverPort);
+                continue;
+            }
+            else
+            {
+                OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]!",
+                          strerror(errno));
+                break;
+            }
+        }
+
+        isBound = true;
+        break;
+    }
+
+    if (false == isBound)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind Socket! Return code[%d]",
+                  CA_SOCKET_OPERATION_FAILED);
+        close(gUnicastServerSocketDescriptor);
+        gUnicastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "socket bind success");
+
+    socklen_t len = 0;
+    char *serverAddress = NULL;
+    if (-1 != getsockname(gUnicastServerSocketDescriptor, (struct sockaddr *)&sockAddr, &len))
+    {
+        serverPort = ntohs(sockAddr.sin_port);
+        serverAddress = inet_ntoa(sockAddr.sin_addr);
+    }
+
+    /**
+      * The task to listen for data from unicast socket is added to the thread pool.
+      * This is a blocking call is made where we try to receive some data..
+      * We will keep waiting until some data is received.
+      * This task will be terminated when thread pool is freed on stopping the adapters.
+      */
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAWiFiReceiveThreadForUnicast,
+            (void *) NULL))
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+
+        close(gUnicastServerSocketDescriptor);
+        gUnicastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_STATUS_FAILED;
+    }
+
+    // Free the server address previously stored
+    OICFree(gUnicastServerAddress);
+    gUnicastServerAddress = NULL;
+    gUnicastServerPort = serverPort;
+    gUnicastServerAddress = (serverAddress) ? strndup(serverAddress, strlen(serverAddress)) :
+                            NULL;
+    *port = serverPort;
+    *serverFD = gUnicastServerSocketDescriptor;
+    u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "CAWiFiStartUnicastServer, OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiStopMulticastServer(void)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+
+    if (gMulticastServerSocketDescriptor == -1)
+    {
+        OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server is not yet Started");
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SERVER_NOT_STARTED;
+    }
+
+    u_mutex_lock(gMutexStopMulticast);
+    gStopMulticast = true;
+
+    // leave the group after you are done
+    if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+                         (char *)&gMReq,
+                         sizeof(struct ip_mreq)))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "cannot leave multicast group, Error code: %s\n",
+                  strerror(errno));
+    }
+
+    // close the socket
+    if (-1 == close(gMulticastServerSocketDescriptor))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server socket close failed, Error code: %s\n",
+                  strerror(errno));
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        u_mutex_unlock(gMutexStopMulticast);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    u_mutex_unlock(gMutexStopMulticast);
+
+    gMulticastServerSocketDescriptor = -1;
+    u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server Stopped Successfully");
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+
+}
+
+CAResult_t CAWiFiStopUnicastServer()
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+    u_mutex_lock(gMutexUnicastServerSocketDescriptor);
+
+    if (gUnicastServerSocketDescriptor == -1)
+    {
+        OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server is not yet Started");
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_SERVER_NOT_STARTED;
+    }
+    u_mutex_lock(gMutexStopUnicast);
+    gStopUnicast = true;
+
+    // close the socket
+    if (-1 == close(gUnicastServerSocketDescriptor))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server socket close failed, Error code: %s\n",
+                  strerror(errno));
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        u_mutex_unlock(gMutexStopUnicast);
+        return CA_SOCKET_OPERATION_FAILED;
+    }
+
+    u_mutex_unlock(gMutexStopUnicast);
+    gUnicastServerSocketDescriptor = -1;
+
+    u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server Stopped Successfully");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    // Input validation
+    VERIFY_NON_NULL(ipAddress, WIFI_SERVER_TAG, "ipAddress holder is NULL");
+    VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "port holder is NULL");
+    VERIFY_NON_NULL(serverFD, WIFI_SERVER_TAG, "serverID holder is NULL");
+
+    *ipAddress = gUnicastServerAddress;
+    *port = gUnicastServerPort;
+    *serverFD = gUnicastServerSocketDescriptor;
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCallback callback)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    gPacketReceivedCallback = callback;
+}
+
+void CAWiFiSetExceptionCallback(CAWiFiExceptionCallback callback)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    gExceptionCallback = callback;
+}
+
+CAResult_t CAWiFiServerCreateMutex(void)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    gMutexUnicastServerSocketDescriptor = u_mutex_new();
+    if (!gMutexUnicastServerSocketDescriptor)
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+        return CA_STATUS_FAILED;
+    }
+
+    gMutexMulticastServerSocketDescriptor = u_mutex_new();
+    if (!gMutexMulticastServerSocketDescriptor)
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+
+        CAWiFiServerDestroyMutex();
+        return CA_STATUS_FAILED;
+    }
+
+    gMutexStopUnicast = u_mutex_new();
+    if (!gMutexStopUnicast)
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+
+        CAWiFiServerDestroyMutex();
+        return CA_STATUS_FAILED;
+    }
+
+    gMutexStopMulticast = u_mutex_new();
+    if (!gMutexStopMulticast)
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+
+        CAWiFiServerDestroyMutex();
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAWiFiServerDestroyMutex(void)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    if (gMutexUnicastServerSocketDescriptor)
+    {
+        u_mutex_free(gMutexUnicastServerSocketDescriptor);
+        gMutexUnicastServerSocketDescriptor = NULL;
+    }
+
+    if (gMutexMulticastServerSocketDescriptor)
+    {
+        u_mutex_free(gMutexMulticastServerSocketDescriptor);
+        gMutexMulticastServerSocketDescriptor = NULL;
+    }
+
+    if (gMutexStopUnicast)
+    {
+        u_mutex_free(gMutexStopUnicast);
+        gMutexStopUnicast = NULL;
+    }
+
+    if (gMutexStopMulticast)
+    {
+        u_mutex_free(gMutexStopMulticast);
+        gMutexStopMulticast = NULL;
+    }
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+}
+
+void *CAWiFiReceiveThreadForUnicast(void *data)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    fd_set reads;
+    struct timeval timeout;
+
+    // keep listening for data
+    while (!gStopUnicast)
+    {
+        timeout.tv_sec = 1;
+        timeout.tv_usec = 0;
+
+        FD_ZERO(&reads);
+        FD_SET(gUnicastServerSocketDescriptor, &reads);
+
+        int32_t ret = select(gUnicastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
+        if (gStopUnicast)
+        {
+            OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop Unicast is called");
+            break;
+        }
+        if (ret < 0)
+        {
+            OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
+            continue;
+        }
+        if (!FD_ISSET(gUnicastServerSocketDescriptor, &reads))
+        {
+            continue;
+        }
+
+        memset(gUnicastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
+
+        // Read data from socket
+        struct sockaddr_in srcSockAddress;
+        int32_t recvLen;
+        socklen_t srcAddressLen = sizeof(srcSockAddress);
+        if (-1 == (recvLen = recvfrom(gUnicastServerSocketDescriptor, gUnicastRecvBuffer,
+                                      COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
+                                      &srcAddressLen)))
+        {
+            OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
+            continue;
+        }
+        else if (0 == recvLen)
+        {
+            OIC_LOG(ERROR, WIFI_SERVER_TAG, "Unicast server socket is shutdown !");
+
+            // Notify upper layer this exception
+            if (gExceptionCallback)
+            {
+                gExceptionCallback(CA_UNICAST_SERVER);
+            }
+            return NULL;
+        }
+
+        const char *srcIPAddress = NULL;
+        int32_t srcPort = -1;
+
+        srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
+        srcPort = ntohs(srcSockAddress.sin_port);
+
+        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
+                  srcIPAddress, srcPort);
+        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
+                  gUnicastRecvBuffer, recvLen);
+
+        // Notify data to upper layer
+        if (gPacketReceivedCallback)
+        {
+            gPacketReceivedCallback(srcIPAddress, srcPort, gUnicastRecvBuffer, recvLen);
+        }
+    }
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+    return NULL;
+}
+
+void *CAReceiveThreadForMulticast(void *data)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    fd_set reads;
+    struct timeval timeout;
+
+    // keep listening for data
+    while (!gStopMulticast)
+    {
+        timeout.tv_sec = 1;
+        timeout.tv_usec = 0;
+
+        FD_ZERO(&reads);
+        FD_SET(gMulticastServerSocketDescriptor, &reads);
+
+        int32_t ret = select(gMulticastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
+        if (gStopMulticast)
+        {
+            OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop Multicast is called");
+            break;
+        }
+        if ( ret < 0)
+        {
+            OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
+            continue;
+        }
+        if (!FD_ISSET(gMulticastServerSocketDescriptor, &reads))
+        {
+            continue;
+        }
+
+        memset(gMulticastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
+
+        // Read data from socket
+        struct sockaddr_in srcSockAddress;
+        int32_t recvLen;
+        socklen_t srcAddressLen = sizeof(srcSockAddress);
+        if (-1 == (recvLen = recvfrom(gMulticastServerSocketDescriptor, gMulticastRecvBuffer,
+                                      COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
+                                      &srcAddressLen)))
+        {
+            OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
+            continue;
+        }
+        else if (0 == recvLen)
+        {
+            OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast socket is shutdown, returning from \
+                thread\n");
+
+            // Notify upper layer this exception
+            if (gExceptionCallback)
+            {
+                gExceptionCallback(CA_MULTICAST_SERVER);
+            }
+            return NULL;
+        }
+
+        const char *srcIPAddress = NULL;
+        int32_t srcPort = -1;
+
+        srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
+        srcPort = ntohs(srcSockAddress.sin_port);
+
+        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
+                  srcIPAddress, srcPort);
+        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
+                  gMulticastRecvBuffer, recvLen);
+
+
+        // Notify data to upper layer
+        if (gPacketReceivedCallback)
+        {
+            gPacketReceivedCallback(srcIPAddress, srcPort, gMulticastRecvBuffer, recvLen);
+        }
+    }
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+    return NULL;
+}
+
+
diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/caethernetadapter.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/caethernetadapter.c
deleted file mode 100644 (file)
index ce9a390..0000000
+++ /dev/null
@@ -1,120 +0,0 @@
-/******************************************************************
- *
- * Copyright 2014 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
-#include "caethernetadapter.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include "logger.h"
-
-/**
- * @def WIFI_ETHERNET_ADAPTER_TAG
- * @brief Logging tag for module name
- */
-#define ETHERNET_ADAPTER_TAG "ETHERNET_ADAPTER"
-
-CAResult_t CAInitializeEthernet(CARegisterConnectivityCallback registerCallback,
-                                CANetworkPacketReceivedCallback networkPacketCallback,
-                                CANetworkChangeCallback netCallback, u_thread_pool_t handle)
-{
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return CA_NOT_SUPPORTED;
-}
-
-CAResult_t CAStartEthernet()
-{
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return CA_NOT_SUPPORTED;
-}
-
-CAResult_t CAStartEthernetListeningServer()
-{
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return CA_NOT_SUPPORTED;
-
-}
-
-CAResult_t CAStartEthernetDiscoveryServer()
-{
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return CA_NOT_SUPPORTED;
-}
-
-uint32_t CASendEthernetUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
-                                   uint32_t dataLen)
-{
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return 0;
-}
-
-uint32_t CASendEthernetMulticastData(void *data, uint32_t dataLength)
-{
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return 0;
-}
-
-CAResult_t CAStartEthernetNotifyServer()
-{
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return CA_NOT_SUPPORTED;
-}
-
-uint32_t CASendEthernetNotification(const CARemoteEndpoint_t *endpoint, void *data,
-                                    uint32_t dataLen)
-{
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return CA_NOT_SUPPORTED;
-}
-
-CAResult_t CAGetEthernetInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
-{
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return CA_NOT_SUPPORTED;
-}
-
-CAResult_t CAReadEthernetData()
-{
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return CA_NOT_SUPPORTED;
-}
-
-CAResult_t CAStopEthernet()
-{
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-    return CA_NOT_SUPPORTED;
-}
-
-void CATerminateEthernet()
-{
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "IN");
-    OIC_LOG(DEBUG, ETHERNET_ADAPTER_TAG, "OUT");
-}
diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiadapter.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiadapter.c
deleted file mode 100644 (file)
index 9eb0937..0000000
+++ /dev/null
@@ -1,478 +0,0 @@
-/******************************************************************
- *
- * Copyright 2014 Samsung Electronics All Rights Reserved.
- *
- *
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *      http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- ******************************************************************/
-#include "cawifiadapter.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include "caadapterutils.h"
-#include "umutex.h"
-#include "logger.h"
-#include "cawifiserver.h"
-#include "cawificlient.h"
-#include "cawifimonitor.h"
-#include "camessagequeue.h"
-
-/**
- * @def WIFI_ETHERNET_ADAPTER_TAG
- * @brief Logging tag for module name
- */
-#define WIFI_ADAPTER_TAG "WIFI_ADAPTER"
-
-/**
- * @def CA_PORT
- * @brief Port to listen for incoming data
- */
-#define CA_PORT   5283
-
-/**
- * @def CA_MCAST_PORT
- * @brief Multicast Port Number
- */
-#define CA_MCAST_PORT   5298
-
-/**
- * @def CA_MULTICAST_IP
- * @brief Multicast IP Address
- */
-#define CA_MULTICAST_IP "224.0.1.187"
-
-/* Skip Queue */
-/**
- * @var gNetworkPacketCallback
- * @brief Network Packet Received Callback
- */
-static CANetworkPacketReceivedCallback gNetworkPacketCallback = NULL;
-
-/**
- * @var gIsMulticastServerStarted
- * @brief Flag to check if multicast server is started
- */
-static int gIsMulticastServerStarted = 0;
-
-/**
- * @var gMutexIsMulticastServerStarted
- * @brief Mutex for gIsMulticastServerStarted
- */
-static u_mutex gMutexIsMulticastServerStarted = NULL;
-
-/**
- * @var gSendQueueHandle
- * @brief Queue handle for Send Data
- */
-static CAAdapterMessageQueue_t *gSendQueueHandle = NULL;
-
-/**
- * @var gRecvQueueHandle
- * @brief Queue handle for Receive Data
- */
-static CAAdapterMessageQueue_t *gRecvQueueHandle = NULL;
-
-/**
- * @var gSendDataCond
- * @brief Condition for Send Data
- */
-static u_cond gSendDataCond = NULL;
-
-void CAInitializeMutex()
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-    u_mutex_init();
-    if(NULL == gMutexIsMulticastServerStarted)
-    {
-        gMutexIsMulticastServerStarted = u_mutex_new();
-    }
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-}
-
-CAResult_t CAInitializeQueueHandles()
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-    if (CA_STATUS_OK != CAAdapterInitializeMessageQueue(&gSendQueueHandle))
-    {
-        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Initialize Send queue Handle");
-        return CA_STATUS_FAILED;
-    }
-    gSendDataCond = u_cond_new();
-    CASetSendQueueHandle(gSendQueueHandle, CA_TRUE, gSendDataCond);
-
-    if (CA_STATUS_OK != CAAdapterInitializeMessageQueue(&gRecvQueueHandle))
-    {
-        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Initialize Receive queue Handle");
-        return CA_STATUS_FAILED;
-    }
-    CASetRecvQueueHandle(gRecvQueueHandle);
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-void CADeinitializeSendQueueHandle()
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-    CASetSendQueueHandle(NULL, CA_FALSE, NULL);
-    CAAdapterTerminateMessageQueue(gSendQueueHandle);
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-}
-
-void CADeinitializeRecvQueueHandle()
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-    CAAdapterTerminateMessageQueue(gRecvQueueHandle);
-    CASetRecvQueueHandle(NULL);
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-}
-
-int CAWIFIRegisterNetworkNotifications(CANetworkChangeCallback netCallback)
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
-    if (NULL != netCallback)
-    {
-        CAInitializeWIFIAdapter();
-        CASetWIFINetworkChangeCallback(netCallback);
-    }
-    else
-    {
-        CADeinitializeWIFIAdapter();
-    }
-
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-#if 0 /* Skip Queue */
-void CASetWIFINetworkPacketCallback(CANetworkPacketReceivedCallback callback)
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-    gNetworkPacketCallback = callback;
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-}
-#endif //#if 0
-
-CAResult_t CAInitializeWifi(CARegisterConnectivityCallback registerCallback,
-                            CANetworkPacketReceivedCallback networkPacketCallback,
-                            CANetworkChangeCallback netCallback, u_thread_pool_t handle)
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-    VERIFY_NON_NULL(registerCallback, WIFI_ADAPTER_TAG,
-            "Invalid argument : registerCallback is NULL");
-    VERIFY_NON_NULL(networkPacketCallback, WIFI_ADAPTER_TAG,
-                    "Invalid argument : networkPacketCallback is NULL");
-    VERIFY_NON_NULL(netCallback, WIFI_ADAPTER_TAG, "Invalid argument : netCallback is NULL");
-
-    CASetWIFINetworkPacketCallback(networkPacketCallback);
-    CAWIFIRegisterNetworkNotifications(netCallback);
-
-    CAConnectivityHandler_t wifiHandler;
-    wifiHandler.startAdapter = CAStartWIFI;
-    wifiHandler.startListenServer = CAStartWIFIListeningServer;
-    wifiHandler.startDiscoverServer = CAStartWIFIDiscoveryServer;
-    wifiHandler.sendData = CASendWIFIUnicastData;
-    wifiHandler.sendDataToAll = CASendWIFIMulticastData;
-    wifiHandler.GetnetInfo = CAGetWIFIInterfaceInformation;
-    wifiHandler.readData = CAReadWIFIData;
-    wifiHandler.stopAdapter = CAStopWIFI;
-    wifiHandler.terminate = CATerminateWIfI;
-    registerCallback(wifiHandler, CA_WIFI);
-
-    CAInitializeMutex();
-    CAInitializeServerMutex();
-    CASetThreadHandle(handle);
-    CASetMulticastData(CA_MULTICAST_IP, CA_MCAST_PORT);
-
-    if (CA_STATUS_OK != CAInitializeQueueHandles())
-    {
-        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Initialize Queue Handle");
-        return CA_STATUS_FAILED;
-    }
-    if (CA_STATUS_OK != CAStartSendDataThread(handle))
-    {
-        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Failed to Start Send Data Thread");
-        return CA_STATUS_FAILED;
-    }
-
-    OIC_LOG(INFO, WIFI_ADAPTER_TAG, "IntializeWifi is Success");
-
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStartWIFI()
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-    int16_t unicastPort = CA_PORT;
-    CAResult_t ret = CA_STATUS_OK;
-
-    CASetIsStartServerInvoked();
-    CABool_t retVal = CAIsWIFIConnected();
-    if (CA_FALSE == retVal)
-    {
-        OIC_LOG(INFO, WIFI_ADAPTER_TAG, "WIFI is not Connected");
-        return ret;
-    }
-
-    // Address is hardcoded as we are using Single Interface
-    ret = CAStartUnicastServer("0.0.0.0", &unicastPort);
-
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-    return ret;
-}
-
-CAResult_t CAStartWIFIListeningServer()
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
-    CAResult_t ret = CA_STATUS_OK;
-    int16_t multicastPort = CA_MCAST_PORT;
-
-    if (gIsMulticastServerStarted == 1)
-    {
-        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
-                "Failed to Start Listening Server, Already Started! Return code[%d]",
-                CA_SERVER_STARTED_ALREADY);
-        return CA_SERVER_STARTED_ALREADY;
-    }
-
-    CABool_t retVal = CAIsWIFIConnected();
-    if (CA_FALSE == retVal)
-    {
-        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
-                "Failed to Start Listening Server, WIFI is not Connected! Return code[%d]",
-                CA_ADAPTER_NOT_ENABLED);
-        return CA_ADAPTER_NOT_ENABLED;
-    }
-
-    ret = CAStartMulticastServer(CA_MULTICAST_IP, "0.0.0.0", &multicastPort);
-    if (CA_STATUS_OK == ret)
-    {
-        OIC_LOG(INFO, WIFI_ADAPTER_TAG, "Multicast Server is Started Successfully");
-        u_mutex_lock(gMutexIsMulticastServerStarted);
-        gIsMulticastServerStarted = 1;
-        u_mutex_unlock(gMutexIsMulticastServerStarted);
-    }
-
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-    return ret;
-}
-
-CAResult_t CAStartWIFIDiscoveryServer()
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
-    CAResult_t ret = CA_STATUS_OK;
-    int16_t multicastPort = CA_MCAST_PORT;
-
-    if (gIsMulticastServerStarted == 1)
-    {
-        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
-                "Failed to Start Discovery Server, Already Started! Return code[%d]",
-                CA_SERVER_STARTED_ALREADY);
-        return CA_SERVER_STARTED_ALREADY;
-    }
-
-    CABool_t retVal = CAIsWIFIConnected();
-    if (CA_FALSE == retVal)
-    {
-        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
-                "Failed to Start Discovery Server, WIFI is not Connected! Return code[%d]",
-                CA_ADAPTER_NOT_ENABLED);
-        return CA_ADAPTER_NOT_ENABLED;
-    }
-
-    ret = CAStartMulticastServer(CA_MULTICAST_IP, "0.0.0.0", &multicastPort);
-    if (CA_STATUS_OK == ret)
-    {
-        OIC_LOG(INFO, WIFI_ADAPTER_TAG, "Multicast Server is Started Successfully");
-        u_mutex_lock(gMutexIsMulticastServerStarted);
-        gIsMulticastServerStarted = 1;
-        u_mutex_unlock(gMutexIsMulticastServerStarted);
-    }
-
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-    return ret;
-}
-
-uint32_t CASendWIFIUnicastData(const CARemoteEndpoint_t *remoteEndpoint, void *data,
-                               uint32_t dataLen)
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
-    uint32_t dataSize = 0;
-
-    VERIFY_NON_NULL_RET(remoteEndpoint, WIFI_ADAPTER_TAG, "Invalid argument : remoteEndpoint is NULL",
-                        dataSize);
-    VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "Invalid argument : data is NULL", dataSize);
-
-    if (dataLen <= 0)
-    {
-        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Invalid argument : Data Length is 0");
-        return dataSize;
-
-    }
-
-    if (NULL == gSendQueueHandle)
-    {
-        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Queue Handle is not Initialized");
-        return dataSize;
-    }
-    CAAdapterEnqueueMessage(gSendQueueHandle, remoteEndpoint, data, dataLen);
-    u_cond_signal(gSendDataCond);
-
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-    return dataLen;
-}
-
-uint32_t CASendWIFIMulticastData(void *data, uint32_t dataLength)
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
-    uint32_t dataSize = 0;
-
-    VERIFY_NON_NULL_RET(data, WIFI_ADAPTER_TAG, "Invalid argument : data is NULL", dataSize);
-
-    if (dataLength <= 0)
-    {
-        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Invalid argument : Data Length is 0");
-        return 0;
-
-    }
-
-    if (NULL == gSendQueueHandle)
-    {
-        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Queue Handle is not Initialized");
-        return dataSize;
-    }
-    CAAdapterEnqueueMessage(gSendQueueHandle, NULL, data, dataLength);
-    u_cond_signal(gSendDataCond);
-
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-    return dataLength;
-}
-
-CAResult_t CAGetWIFIInterfaceInformation(CALocalConnectivity_t **info, uint32_t *size)
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-
-    CABool_t retVal = CAIsWIFIConnected();
-    if (CA_FALSE == retVal)
-    {
-        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG,
-                "Failed to get interface address, WIFI is not Connected! Return code[%d]",
-                CA_ADAPTER_NOT_ENABLED);
-        return CA_ADAPTER_NOT_ENABLED;
-    }
-
-    VERIFY_NON_NULL(info, WIFI_ADAPTER_TAG, "Invalid argument : info is NULL");
-    char localIpAddress[CA_IPADDR_SIZE];
-    int32_t localIpAddressLen = sizeof(localIpAddress);
-
-    CAGetInterfaceAddress(localIpAddress, localIpAddressLen);
-
-
-    // Create local endpoint using util function
-    (*info) = CAAdapterCreateLocalEndpoint(CA_WIFI, localIpAddress, "WiFi");
-    if (NULL == (*info))
-    {
-        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to create Local Endpoint! Return code[%d]",
-                  CA_MEMORY_ALLOC_FAILED);
-        return CA_MEMORY_ALLOC_FAILED;
-    }
-
-    (*size) = 1;
-
-    OIC_LOG(INFO, WIFI_ADAPTER_TAG, "GetWIFIInterfaceInformation success");
-
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAReadWIFIData()
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-    if (NULL == gRecvQueueHandle)
-    {
-        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "QueueHandle is NULL");
-        return CA_STATUS_FAILED;
-    }
-    CAAdapterMessage_t *messageReceived;
-    if (CA_STATUS_OK != CAAdapterDequeueMessage(gRecvQueueHandle, &messageReceived))
-    {
-        OIC_LOG(ERROR, WIFI_ADAPTER_TAG, "Dequeue Message failed");
-        return CA_STATUS_FAILED;
-    }
-
-    if (gNetworkPacketCallback && (NULL != messageReceived))
-    {
-        gNetworkPacketCallback(messageReceived->remoteEndpoint, messageReceived->data,
-                               messageReceived->dataLen);
-    }
-
-    CAAdapterFreeMessage(messageReceived);
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAStopWIFI()
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-    CAResult_t result = CA_STATUS_FAILED;
-    result = CAStopUnicastServer();
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Unicast Server! Return code[%d]", result);
-        return result;
-    }
-    CAUnsetIsStartServerInvoked();
-    result = CAStopMulticastServer();
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG_V(ERROR, WIFI_ADAPTER_TAG, "Failed to Stop Multicast Server! Return code[%d]", result);
-        return result;
-    }
-    else
-    {
-        u_mutex_lock(gMutexIsMulticastServerStarted);
-        gIsMulticastServerStarted = 0;
-        u_mutex_unlock(gMutexIsMulticastServerStarted);
-    }
-    CADeinitializeRecvQueueHandle();
-    CADeinitializeSendQueueHandle();
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-void CATerminateWIfI()
-{
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "IN");
-    CAResult_t result = CA_STATUS_FAILED;
-
-    CASetWIFINetworkPacketCallback(NULL);
-    result = CAWIFIRegisterNetworkNotifications(NULL);
-    if (CA_STATUS_OK != result)
-    {
-        OIC_LOG(ERROR, WIFI_ADAPTER_TAG,
-                "Failed to Unregister Network Notifications");
-    }
-    OIC_LOG(INFO, WIFI_ADAPTER_TAG, "TerminateWifi Success");
-
-    OIC_LOG(DEBUG, WIFI_ADAPTER_TAG, "OUT");
-    return;
-}
index cd000ce..e2cc90b 100644 (file)
 * limitations under the License.
 *
 ******************************************************************/
-#include "cawificlient.h"
+#include "cawifiinterface.h"
 
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <errno.h>
-#include <arpa/inet.h>
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <arpa/inet.h>
 #include <netinet/in.h>
-#include <unistd.h>
+#include <errno.h>
+
 #include "caadapterutils.h"
 
 /**
 #define WIFI_CLIENT_TAG "WIFI_CLIENT"
 
 /**
- * @var gClientSendQueueHandle
- * @brief Queue Handle for send Data
- */
-static CAAdapterMessageQueue_t *gClientSendQueueHandle = NULL;
-
-/**
- * @var gSendDataFlag
- * @brief Flag to check if Termination is Called
- */
-static CABool_t gSendDataFlag = CA_FALSE;
-
-/**
- * @var gClientSendDataCond
- * @brief Condition for Send Data
- */
-static u_cond gClientSendDataCond = NULL;
-
-/**
- * @var gMulticastIP
- * @brief Multicast IP address
- */
-static char gMulticastIP[CA_IPADDR_SIZE];
-
-/**
- * @var gMulticastPort
- * @brief Multicast Port
- */
-static uint32_t gMulticastPort;
-
-/**
  * @var gUnicastServerSocketDescClient
  * @brief socket descriptor for unicast server
  */
 static int gUnicastServerSocketDescClient = -1;
 
-void CASetUnicastSocketDescriptor(int unicastSocketDesc)
+void CAWiFiSetUnicastSocket(const int32_t socketFD)
 {
     OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
-    gUnicastServerSocketDescClient = unicastSocketDesc;
-    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT");
-}
 
-void CASetSendQueueHandle(CAAdapterMessageQueue_t *gSendQueueHandle, CABool_t flag, u_cond cond)
-{
-    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
-    gClientSendQueueHandle = gSendQueueHandle;
-    gSendDataFlag = flag;
-    if (NULL == cond)
-    {
-        u_cond_signal(gClientSendDataCond);
-    }
-    gClientSendDataCond = cond;
-    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT");
+    gUnicastServerSocketDescClient = socketFD;
 }
 
-void CASetMulticastData(char *mAddr, uint32_t mPort)
-{
-    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
-    strncpy(gMulticastIP, mAddr, CA_IPADDR_SIZE - 1);
-    gMulticastPort = mPort;
-    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT");
-}
-
-CAResult_t CAStartSendDataThread(u_thread_pool_t threadHandle)
-{
-    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
-    VERIFY_NON_NULL(threadHandle, WIFI_CLIENT_TAG, "Invalid argument : threadHandle is NULL");
-    if (CA_STATUS_OK != u_thread_pool_add_task(threadHandle, (void *) CAStartThreadForSendData,
-            (void *) NULL))
-    {
-        OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Failed to add task in thread pool");
-        return CA_STATUS_FAILED;
-    }
-    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-uint32_t CAWIFISendData(const char *remoteIpAddress, const uint32_t port, const char *data,
-                        uint32_t dataLen, int16_t isMulticast)
+uint32_t CAWiFiSendData(const char *remoteAddress, const uint32_t port,
+                        const void *data, const uint32_t dataLength, bool isMulticast)
 {
     OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
 
-    VERIFY_NON_NULL_RET(remoteIpAddress, WIFI_CLIENT_TAG, "Invalid argument : remoteIpAddress is NULL",
-                        0);
-    VERIFY_NON_NULL_RET(data, WIFI_CLIENT_TAG, "Invalid argument : data is NULL", 0);
+    VERIFY_NON_NULL_RET(remoteAddress, WIFI_CLIENT_TAG, "IP address is NULL", 0);
+    VERIFY_NON_NULL_RET(data, WIFI_CLIENT_TAG, "data is NULL", 0);
 
-    OIC_LOG_V(DEBUG, WIFI_CLIENT_TAG, "remoteIPAddress is %s", remoteIpAddress);
-    OIC_LOG_V(DEBUG, WIFI_CLIENT_TAG, "PortNumber is %d", port);
-    OIC_LOG_V(DEBUG, WIFI_CLIENT_TAG, "Data[%d] to send is %s", dataLen, data);
-
-    uint32_t sendDataLength = 0;
-
-    if (dataLen <= 0)
+    if (dataLength == 0)
     {
-        OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Invalid Arguemnet : Datalength is <= 0");
-        return sendDataLength;
+        OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Data length is 0 !");
+        return 0;
     }
 
-    if (-1 == gUnicastServerSocketDescClient)
+    if (0 > gUnicastServerSocketDescClient)
     {
-        OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Unicast Server is not running");
-        return sendDataLength;
+        OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Unicast Server is not running !");
+        return 0;
     }
 
     struct sockaddr_in destAddr;
@@ -147,14 +72,14 @@ uint32_t CAWIFISendData(const char *remoteIpAddress, const uint32_t port, const
     destAddr.sin_port = htons(port);
 
     // Conversion from ASCII format to Network format
-    if (inet_aton(remoteIpAddress, &destAddr.sin_addr) == 0)
+    if (inet_aton(remoteAddress, &destAddr.sin_addr) == 0)
     {
         OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Failed to convert from ASCII to Network Address");
-        return sendDataLength;
+        return 0;
     }
 
-    sendDataLength = sendto(gUnicastServerSocketDescClient, data, dataLen, 0,
-                            (struct sockaddr *)&destAddr, sizeof(destAddr));
+    int32_t sendDataLength = sendto(gUnicastServerSocketDescClient, data, dataLength, 0,
+                                    (struct sockaddr *)&destAddr, sizeof(destAddr));
     if (sendDataLength == -1)
     {
         OIC_LOG_V(ERROR, WIFI_CLIENT_TAG, "Failed to Send Data, Error code: %s", strerror(errno));
@@ -167,41 +92,3 @@ uint32_t CAWIFISendData(const char *remoteIpAddress, const uint32_t port, const
     return sendDataLength;
 }
 
-void *CAStartThreadForSendData()
-{
-    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "IN");
-    if (NULL == gClientSendQueueHandle)
-    {
-        OIC_LOG(ERROR, WIFI_CLIENT_TAG, "Queue Handle is NULL");
-        return NULL;
-    }
-
-    u_mutex sendDataMutex = u_mutex_new();
-    CAAdapterMessage_t *message;
-
-    while (gSendDataFlag)
-    {
-        OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "Inside The while loop");
-        u_mutex_lock(sendDataMutex);
-        u_cond_wait(gClientSendDataCond, sendDataMutex);
-        while (CA_STATUS_OK == CAAdapterDequeueMessage(gClientSendQueueHandle, &message))
-        {
-            if (NULL != message->remoteEndpoint)
-            {
-                OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "Send Unicast Data is called");
-                CAWIFISendData(message->remoteEndpoint->addressInfo.IP.ipAddress,
-                               message->remoteEndpoint->addressInfo.IP.port, message->data, message->dataLen, 0);
-            }
-            else
-            {
-                OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "Send Multicast Data is called");
-                CAWIFISendData(gMulticastIP, gMulticastPort, message->data, message->dataLen, 1);
-            }
-            CAAdapterFreeMessage(message);
-        }
-        u_mutex_unlock(sendDataMutex);
-    }
-
-    OIC_LOG(DEBUG, WIFI_CLIENT_TAG, "OUT");
-    return NULL;
-}
diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.h b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawificlient.h
deleted file mode 100644 (file)
index 9e6f561..0000000
+++ /dev/null
@@ -1,82 +0,0 @@
-/******************************************************************
-*
-* Copyright 2014 Samsung Electronics All Rights Reserved.
-*
-*
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-******************************************************************/
-
-/**
- * @file cawificlient.h
- * @brief This file contains the APIs for WiFi Client module
- */
-
-#ifndef _CA_WIFI_CLIENT_
-#define _CA_WIFI_CLIENT_
-
-#include <stdint.h>
-#include "cacommon.h"
-#include "logger.h"
-#include "camessagequeue.h"
-#include "uthreadpool.h"
-
-/**
- * @brief API to Set the Unicast Socket descriptor
- * @param  unicastSocketDesc         [IN] Unicast Socket Descriptor
- * @return - None
- */
-void CASetUnicastSocketDescriptor(int unicastSocketDesc);
-/**
- * @brief API to Set the send queue handle
- * @param  gSendQueueHandle         [IN] Queue Handle to Send Data
- * @return - None
- */
-void CASetSendQueueHandle(CAAdapterMessageQueue_t *gSendQueueHandle,
-                          CABool_t flag, u_cond cond);
-
-/**
- * @brief API to Set the Multicast IP and Port Address
- * @param  mAddr            [IN] Multicast IP
- * @param  mPort            [IN] Multicast Port
- * @return - None
- */
-void CASetMulticastData(char *mAddr, uint32_t mPort);
-
-/**
- * @brief API to Start the Thread for Send Unicast and Multicast Data
- * @param  threadHandle         [IN] ThreadHandle to Add the task in Thread pool
- * @return - None
- */
-CAResult_t CAStartSendDataThread(u_thread_pool_t threadHandle);
-
-/**
- * @brief  To send Unicast or Multicast Data
- * @param  remoteIpAddress      [IN] RemoteEndpoint IP Address
- * @param  port                 [IN] RemoteEndpoint Port Number
- * @param  data                 [IN] Data to be sent to the RemoteEndpoint
- * @param  dataLen              [IN] Length of the data to be sent
- * @param  isMulticast          [IN] Unicast/Multicast flag, 0 for Unicast and 1 for Multicast
- * @return Return               0 on failure and length of data on success
- */
-uint32_t CAWIFISendData(const char *remoteIpAddress, const uint32_t port, const char *data,
-                        uint32_t dataLen, int16_t isMulticast);
-
-/**
- * @brief API to Invoke SendData.
- * @return - NULL
- */
-void *CAStartThreadForSendData();
-
-#endif  // #ifndef _CA_WIFI_CLIENT_
\ No newline at end of file
diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.c
deleted file mode 100644 (file)
index 04b5522..0000000
+++ /dev/null
@@ -1,282 +0,0 @@
-/******************************************************************
-*
-* Copyright 2014 Samsung Electronics All Rights Reserved.
-*
-*
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-******************************************************************/
-
-#include "cawifimonitor.h"
-#include <arpa/inet.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <ifaddrs.h>
-#include <unistd.h>
-#include <wifi.h>
-#include "logger.h"
-#include "caadapterutils.h"
-#include "cawifiadapter.h"
-#include "cawifiserver.h"
-#include "umutex.h"
-
-#define WIFI_MONITOR_TAG "WIFI_MONITOR"
-
-/**
- * @var gIsStartServerCalled
- * @brief Flag for start server started or not.
- */
-static int gIsStartServerCalled = 0;
-
-/**
- * @var gMutexIsStartServerCalled
- * @brief Mutex for global variable gIsStartServerCalled.
- */
-static u_mutex gMutexIsStartServerCalled = NULL;
-
-CANetworkChangeCallback gNetworkChangeCb = NULL;
-
-CAResult_t CAGetInterfaceAddress(char *address, int32_t addrLen)
-{
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
-    VERIFY_NON_NULL(address, WIFI_MONITOR_TAG, "Invalid argument : address is NULL");
-    if (addrLen < CA_IPADDR_SIZE)
-    {
-        OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "addrLen MUST be atleast %d", CA_IPADDR_SIZE);
-        return CA_STATUS_INVALID_PARAM;
-    }
-
-    struct ifaddrs *interfaceAddr, *ifAddr;
-    int interfaceFamily, name;
-
-    /* Getting All Interfaces*/
-    if (getifaddrs(&interfaceAddr) == -1)
-    {
-        OIC_LOG(ERROR, WIFI_MONITOR_TAG, "Failed to get interface list");
-        return CA_STATUS_FAILED;
-    }
-
-    for (ifAddr = interfaceAddr; ifAddr != NULL; ifAddr = ifAddr->ifa_next)
-    {
-        if (ifAddr->ifa_addr == NULL)
-            continue;
-
-        /* Currently, check for wifi interface and get the IP Address */
-        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "interface name = %s", ifAddr->ifa_name);
-        if (0 == strncmp(ifAddr->ifa_name, "wlan0", strlen("wlan0")))
-        {
-            interfaceFamily = ifAddr->ifa_addr->sa_family;
-            OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "interfaceFamily = %d", interfaceFamily);
-
-            if (interfaceFamily == AF_INET || interfaceFamily == AF_INET6)
-            {
-                name = getnameinfo(ifAddr->ifa_addr,
-                                   (interfaceFamily == AF_INET) ? sizeof(struct sockaddr_in) :
-                                   sizeof(struct sockaddr_in6),
-                                   address, CA_IPADDR_SIZE,
-                                   NULL, 0, NI_NUMERICHOST);
-                if (0 != name)
-                {
-                    OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get IPAddress, Error code: %s",
-                              strerror(errno));
-                    return CA_STATUS_FAILED;
-                }
-                OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "interface name = %s", address);
-                break;
-            }
-        }
-    }
-    freeifaddrs(interfaceAddr);
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CAInitializeWIFIAdapter()
-{
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
-    gMutexIsStartServerCalled = u_mutex_new();
-    wifi_error_e ret = WIFI_ERROR_INVALID_PARAMETER;
-    ret = wifi_initialize();
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, WIFI_MONITOR_TAG, "wifi_initialize failed");
-        return CA_STATUS_FAILED;
-    }
-    else
-    {
-        OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_initialize success");
-    }
-
-    ret = wifi_set_device_state_changed_cb(CAWIFIDeviceStateChangedCb, NULL);
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, WIFI_MONITOR_TAG, "wifi_set_device_state_changed_cb failed");
-        return CA_STATUS_FAILED;
-    }
-    else
-    {
-        OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_set_device_state_changed_cb success");
-    }
-
-    ret = wifi_set_connection_state_changed_cb(CAWIFIConnectionStateChangedCb, NULL);
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(ERROR, WIFI_MONITOR_TAG, "wifi_set_connection_state_changed_cb failed");
-        return CA_STATUS_FAILED;
-    }
-    else
-    {
-        OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_set_connection_state_changed_cb success");
-    }
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CAResult_t CADeinitializeWIFIAdapter()
-{
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
-    wifi_error_e ret = WIFI_ERROR_INVALID_PARAMETER;
-
-    ret = wifi_unset_device_state_changed_cb();
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_unset_device_state_changed_cb failed");
-    }
-    else
-    {
-        OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_unset_device_state_changed_cb success");
-    }
-
-    ret = wifi_unset_connection_state_changed_cb();
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_unset_connection_state_changed_cb failed");
-    }
-    else
-    {
-        OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_unset_connection_state_changed_cb success");
-    }
-
-    ret = wifi_deinitialize();
-    if (WIFI_ERROR_NONE != ret)
-    {
-        OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_deinitialize failed");
-    }
-    else
-    {
-        OIC_LOG(INFO, WIFI_MONITOR_TAG, "wifi_deinitialize success");
-    }
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
-    return CA_STATUS_OK;
-}
-
-CABool_t CAIsWIFIConnected()
-{
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
-    wifi_connection_state_e connection_state;
-    int retVal = wifi_get_connection_state(&connection_state);
-    if (WIFI_ERROR_NONE != retVal)
-    {
-        OIC_LOG(ERROR, WIFI_MONITOR_TAG, "Failed to get the Connection State");
-        return CA_FALSE;
-    }
-    if (WIFI_CONNECTION_STATE_DISCONNECTED == connection_state)
-    {
-        OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "WIFI is not Connected");
-        return CA_FALSE;
-    }
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "WIFI is Connected");
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
-    return CA_TRUE;
-}
-
-void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap, void *userData)
-{
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
-    if (WIFI_CONNECTION_STATE_ASSOCIATION == state
-        || WIFI_CONNECTION_STATE_CONFIGURATION == state)
-    {
-        OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Connection is in Association State");
-        return;
-    }
-    CANetworkStatus_t nwConnectivityStatus = CA_INTERFACE_DOWN;
-    CALocalConnectivity_t *localEndpoint = NULL;
-    uint32_t size = 0;
-    /* If Wifi is connected, then get the latest IP from the WIFI Interface */
-    if (WIFI_CONNECTION_STATE_CONNECTED == state)
-    {
-        if (gIsStartServerCalled)
-        {
-            CAStartWIFI();
-        }
-        nwConnectivityStatus = CA_INTERFACE_UP;
-        CAGetWIFIInterfaceInformation(&localEndpoint, &size);
-    }
-    else
-    {
-        localEndpoint = CAAdapterCreateLocalEndpoint(CA_WIFI, "", NULL);
-        CAStopUnicastServer();
-    }
-    if (NULL != gNetworkChangeCb)
-    {
-        gNetworkChangeCb(localEndpoint, nwConnectivityStatus);
-    }
-
-    CAAdapterFreeLocalEndpoint(localEndpoint);
-
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
-    return;
-}
-
-void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData)
-{
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
-
-    if (WIFI_DEVICE_STATE_ACTIVATED == state)
-    {
-        OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Wifi is in Activated State");
-    }
-    else
-    {
-        CAWIFIConnectionStateChangedCb(WIFI_CONNECTION_STATE_DISCONNECTED, NULL, NULL);
-        OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "Wifi is in Deactivated State");
-    }
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
-    return;
-}
-
-void CASetIsStartServerInvoked()
-{
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
-    u_mutex_lock(gMutexIsStartServerCalled);
-    gIsStartServerCalled = 1;
-    u_mutex_unlock(gMutexIsStartServerCalled);
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
-}
-
-void CAUnsetIsStartServerInvoked()
-{
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
-    u_mutex_lock(gMutexIsStartServerCalled);
-    gIsStartServerCalled = 0;
-    u_mutex_unlock(gMutexIsStartServerCalled);
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
-}
-
-void CASetWIFINetworkChangeCallback(CANetworkChangeCallback netCallback)
-{
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "IN");
-    gNetworkChangeCb = netCallback;
-    OIC_LOG(DEBUG, WIFI_MONITOR_TAG, "OUT");
-}
\ No newline at end of file
diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.h b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifimonitor.h
deleted file mode 100644 (file)
index d5fc6bf..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-/******************************************************************
-*
-* Copyright 2014 Samsung Electronics All Rights Reserved.
-*
-*
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-******************************************************************/
-
-/**
- * @file cawifiutils.h
- * @brief This file contains the APIs for WiFi Specific Calls
- */
-
-#ifndef _CA_WIFI_MONITOR_
-#define _CA_WIFI_MONITOR_
-
-#include <stdint.h>
-#include <wifi.h>
-#include "caadapterinterface.h"
-#include "cacommon.h"
-
-/**
- * @brief  To send Unicast or Multicast Data
- * @param  remoteIpAddress      [OUT] IP Address of the device
- * @param  port                 [IN]  Length of the IP address
- * @return Return  Error Code
- */
-CAResult_t CAGetInterfaceAddress(char *address, int32_t addrLen);
-
-/**
- * @brief  To Initialize the WIFI Adapter
- * @return Return  Error Code
- */
-CAResult_t CAInitializeWIFIAdapter();
-
-/**
- * @brief  To Deinitialize WIFI Adapter
- * @return Return  Error Code
- */
-CAResult_t CADeinitializeWIFIAdapter();
-
-/**
- * @brief  To Check if WIFI is connected
- * @return Return  True or False
- */
-CABool_t CAIsWIFIConnected();
-
-/**
- * @brief  WIFI connection state Changed Callback
- * @param  state              [IN] Connection state of the Device
- * @param  ap                 [IN] Access Point handler
- * @param  userData           [IN] User Data Passed on Setting the Callback
- * @return Return  None
- */
-void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap, void *userData);
-
-/**
- * @brief  WIFI Device state Changed Callback
- * @param  state              [IN] Device state
- * @param  userData           [IN] User Data Passed on Setting the Callback
- * @return Return  None
- */
-void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData);
-
-/**
- * @brief  To set the IsStartServerCalled global variable
- * @return Return  None
- */
-void CASetIsStartServerInvoked();
-
-/**
- * @brief  To unset the IsStartServerCalled global variable
- * @return Return  None
- */
-void CAUnsetIsStartServerInvoked();
-
-/**
- * @brief API to set Network Changed callback to upper layer.
- * @param netCallback - upper layer callback function to notify the change in WIFI connection state.
- * @return - Error Code
- */
-void CASetWIFINetworkChangeCallback(CANetworkChangeCallback netCallback);
-#endif
\ No newline at end of file
diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifinwmonitor.c b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifinwmonitor.c
new file mode 100644 (file)
index 0000000..b87d727
--- /dev/null
@@ -0,0 +1,340 @@
+/******************************************************************
+*
+* Copyright 2014 Samsung Electronics All Rights Reserved.
+*
+*
+*
+* Licensed under the Apache License, Version 2.0 (the "License");
+* you may not use this file except in compliance with the License.
+* You may obtain a copy of the License at
+*
+*      http://www.apache.org/licenses/LICENSE-2.0
+*
+* Unless required by applicable law or agreed to in writing, software
+* distributed under the License is distributed on an "AS IS" BASIS,
+* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+* See the License for the specific language governing permissions and
+* limitations under the License.
+*
+******************************************************************/
+
+#include "cawifiinterface.h"
+
+#include <wifi.h>
+#include "logger.h"
+#include "caadapterutils.h"
+#include "umutex.h"
+#include "oic_malloc.h"
+
+#define WIFI_MONITOR_TAG "WIFI_MONITOR"
+
+
+/**
+ * @var gWifiNetInfoMutex
+ * @brief  Mutex for synchronizing access to cached interface and IP address information.
+ */
+static u_mutex gWifiNetInfoMutex = NULL;
+
+/**
+ * @var gWifiInterfaceName
+ * @brief  Maintains interface name.
+ */
+static char *gWifiInterfaceName = NULL;
+
+/**
+ * @var gWifiIPAddress
+ * @brief  Maintains interface IP address.
+ */
+static char *gWifiIPAddress = NULL;
+
+/**
+ * @var gNetworkChangeCb
+ * @brief  Maintains network connection state change callback.
+ */
+static CAWiFiConnectionStateChangeCallback gNetworkChangeCb = NULL;
+
+/**
+ * @fn CAWIFIConnectionStateChangedCb
+ * @brief  This callback is registered to receive wifi network connection state changes.
+ */
+static void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap,
+        void *userData);
+
+/**
+ * @fn CAWIFIDeviceStateChangedCb
+ * @brief This callback is registered to receive wifi device state changes.
+ */
+static void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData);
+
+/**
+ * @fn CAWiFiGetInterfaceInformation
+ * @brief This methods gets local interface name and IP address information.
+ */
+static void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress);
+
+CAResult_t CAWiFiInitializeNetworkMonitor(const u_thread_pool_t threadPool)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    // Initialize Wifi service
+    wifi_error_e ret = wifi_initialize();
+    if (WIFI_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "wifi_initialize failed");
+        return CA_STATUS_FAILED;
+    }
+
+    if (!gWifiNetInfoMutex)
+    {
+        gWifiNetInfoMutex = u_mutex_new();
+    }
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+void CAWiFiTerminateNetworkMonitor(void)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    // Deinitialize Wifi service
+    wifi_error_e ret = wifi_deinitialize();
+    if (WIFI_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(INFO, WIFI_MONITOR_TAG, "wifi_deinitialize failed");
+    }
+
+    if (gWifiInterfaceName)
+    {
+        OICFree(gWifiInterfaceName);
+        gWifiInterfaceName = NULL;
+    }
+
+    if (gWifiIPAddress)
+    {
+        OICFree(gWifiIPAddress);
+        gWifiIPAddress = NULL;
+    }
+
+    if (gWifiNetInfoMutex)
+    {
+        u_mutex_free(gWifiNetInfoMutex);
+        gWifiNetInfoMutex = NULL;
+    }
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+}
+
+CAResult_t CAWiFiStartNetworkMonitor(void)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    // Set callback for receiving state changes
+    wifi_error_e ret = wifi_set_device_state_changed_cb(CAWIFIDeviceStateChangedCb, NULL);
+    if (WIFI_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "wifi_set_device_state_changed_cb failed");
+        return CA_STATUS_FAILED;
+    }
+
+    // Set callback for receiving connection state changes
+    ret = wifi_set_connection_state_changed_cb(CAWIFIConnectionStateChangedCb, NULL);
+    if (WIFI_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "wifi_set_connection_state_changed_cb failed");
+        return CA_STATUS_FAILED;
+    }
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiStopNetworkMonitor(void)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    // Reset callback for receiving state changes
+    wifi_error_e ret = wifi_unset_device_state_changed_cb();
+    if (WIFI_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(INFO, WIFI_MONITOR_TAG, "wifi_unset_device_state_changed_cb failed");
+    }
+
+    // Reset callback for receiving connection state changes
+    ret = wifi_unset_connection_state_changed_cb();
+    if (WIFI_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(INFO, WIFI_MONITOR_TAG, "wifi_unset_connection_state_changed_cb failed");
+    }
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiGetInterfaceInfo(char **interfaceName, char **ipAddress)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    VERIFY_NON_NULL(interfaceName, WIFI_MONITOR_TAG, "interface name holder is NULL");
+    VERIFY_NON_NULL(ipAddress, WIFI_MONITOR_TAG, "IP address holder is NULL");
+
+    u_mutex_lock(gWifiNetInfoMutex);
+
+    if (gWifiInterfaceName && strlen(gWifiInterfaceName))
+    {
+        *interfaceName = strndup(gWifiInterfaceName, strlen(gWifiInterfaceName));
+    }
+
+    if (gWifiIPAddress && strlen(gWifiIPAddress))
+    {
+        *ipAddress = strndup(gWifiIPAddress, strlen(gWifiIPAddress));
+    }
+
+    u_mutex_unlock(gWifiNetInfoMutex);
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return CA_STATUS_OK;
+}
+
+bool CAWiFiIsConnected(void)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    wifi_connection_state_e connection_state;
+    wifi_error_e ret = wifi_get_connection_state(&connection_state);
+    if (WIFI_ERROR_NONE != ret)
+    {
+        OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get the Connection State");
+        return false;
+    }
+
+    if (WIFI_CONNECTION_STATE_DISCONNECTED == connection_state)
+    {
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "WIFI is not Connected");
+        return false;
+    }
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return true;
+}
+
+void CAWiFiSetConnectionStateChangeCallback(CAWiFiConnectionStateChangeCallback callback)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    gNetworkChangeCb = callback;
+}
+
+void CAWIFIConnectionStateChangedCb(wifi_connection_state_e state, wifi_ap_h ap, void *userData)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    if (WIFI_CONNECTION_STATE_ASSOCIATION == state
+        || WIFI_CONNECTION_STATE_CONFIGURATION == state)
+    {
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Connection is in Association State");
+        return;
+    }
+
+    CANetworkStatus_t nwStatus = CA_INTERFACE_DOWN;
+
+    // If Wifi is connected, then get the latest IP from the WIFI Interface
+    if (WIFI_CONNECTION_STATE_CONNECTED == state)
+    {
+        nwStatus = CA_INTERFACE_UP;
+
+        // Get network information
+        char *interfaceName = NULL;
+        char *ipAddress = NULL;
+        CAWiFiGetInterfaceInformation(&interfaceName, &ipAddress);
+
+        // Update the cached network information
+        u_mutex_lock(gWifiNetInfoMutex);
+
+        OICFree(gWifiInterfaceName);
+        OICFree(gWifiIPAddress);
+        gWifiInterfaceName = interfaceName;
+        gWifiIPAddress = ipAddress;
+
+        u_mutex_unlock(gWifiNetInfoMutex);
+    }
+    else
+    {
+        nwStatus = CA_INTERFACE_DOWN;
+    }
+
+    if (gNetworkChangeCb)
+    {
+        gNetworkChangeCb(gWifiIPAddress, nwStatus);
+    }
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return;
+}
+
+void CAWIFIDeviceStateChangedCb(wifi_device_state_e state, void *userData)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    if (WIFI_DEVICE_STATE_ACTIVATED == state)
+    {
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Wifi is in Activated State");
+    }
+    else
+    {
+        CAWIFIConnectionStateChangedCb(WIFI_CONNECTION_STATE_DISCONNECTED, NULL, NULL);
+        OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "Wifi is in Deactivated State");
+    }
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+    return;
+}
+
+void CAWiFiGetInterfaceInformation(char **interfaceName, char **ipAddress)
+{
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "IN");
+
+    int ret = WIFI_ERROR_NONE;
+
+    u_mutex_lock(gWifiNetInfoMutex);
+    if (interfaceName)
+    {
+        // Get wifi interface name
+        if (WIFI_ERROR_NONE != (ret = wifi_get_network_interface_name(interfaceName)))
+        {
+            OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get interface name! error num [%d]", ret);
+
+            u_mutex_unlock(gWifiNetInfoMutex);
+            return;
+        }
+    }
+
+    if (ipAddress)
+    {
+        // Get wifi connected IP address
+        wifi_ap_h accessPoint = NULL;
+        if (WIFI_ERROR_NONE != (ret = wifi_get_connected_ap(&accessPoint)))
+        {
+            OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get connected access point! error num [%d]",
+                      ret);
+
+            OICFree(interfaceName);
+            u_mutex_unlock(gWifiNetInfoMutex);
+            return;
+        }
+
+        if (WIFI_ERROR_NONE != (ret = wifi_ap_get_ip_address(accessPoint, WIFI_ADDRESS_FAMILY_IPV4,
+                                      ipAddress)))
+        {
+            OIC_LOG_V(ERROR, WIFI_MONITOR_TAG, "Failed to get interface address! error num [%d]", ret);
+
+            OICFree(interfaceName);
+            u_mutex_unlock(gWifiNetInfoMutex);
+            return;
+        }
+    }
+
+    u_mutex_unlock(gWifiNetInfoMutex);
+
+    OIC_LOG_V(DEBUG, WIFI_MONITOR_TAG, "OUT");
+}
\ No newline at end of file
index 0347624..8d2ebe0 100644 (file)
 * limitations under the License.
 *
 ******************************************************************/
-#include "cawifiserver.h"
+#include "cawifiinterface.h"
 
 #include <sys/types.h>
 #include <sys/socket.h>
+#include <unistd.h>
+#include <fcntl.h>
 #include <sys/select.h>
 #include <arpa/inet.h>
 #include <netinet/in.h>
-#include <netinet/ip.h>
-#include <stdio.h>
-#include <stdbool.h>
-#include <stdlib.h>
-#include <fcntl.h>
-#include <net/if.h>
 #include <errno.h>
-#include <ifaddrs.h>
-#include <unistd.h>
+
+#include "pdu.h"
 #include "caadapterutils.h"
 #include "umutex.h"
-#include "cawificlient.h"
 
 /**
  * @def WIFI_SERVER_TAG
 #define WIFI_SERVER_TAG "WIFI_SERVER"
 
 /**
- * @def CA_BUFFER_LEN
- * @brief Length of buffer for receiving data
- */
-#define CA_BUFFER_LEN 512  // Max length of buffer
-
-/**
  * @def CA_UDP_BIND_RETRY_COUNT
  * @brief Retry count in case of socket bind failure.
  */
 #define CA_UDP_BIND_RETRY_COUNT 10
 
+/**
+ * @var gUnicastServerSocketDescriptor
+ * @brief socket descriptor for unicast server
+ */
+static int32_t gUnicastServerSocketDescriptor = -1;
+
+/**
+ * @var gUnicastServerSocketDescriptor
+ * @brief socket descriptor for unicast server
+ */
+static char *gUnicastServerAddress = NULL;
 
 /**
  * @var gUnicastServerSocketDescriptor
  * @brief socket descriptor for unicast server
  */
-static int gUnicastServerSocketDescriptor = -1;
+static int16_t gUnicastServerPort = -1;
 
 /**
  * @var gMutexUnicastServerSocketDescriptor
@@ -71,7 +71,7 @@ static u_mutex gMutexUnicastServerSocketDescriptor = NULL;
  * @var gMulticastServerSocketDescriptor
  * @brief socket descriptor for multicast server
  */
-static int gMulticastServerSocketDescriptor = -1;
+static int32_t gMulticastServerSocketDescriptor = -1;
 
 /**
  * @var gMutexMulticastServerSocketDescriptor
@@ -116,321 +116,413 @@ static bool gStopMulticast = false;
 static u_mutex gMutexStopMulticast = NULL;
 
 /**
- * @var gServerRecvQueueHandle
- * @brief Queue Handle for Receive Data
+ * @var gPacketReceivedCallback
+ * @brief Callback for notifying the upper layer on receival data from remote OIC device
  */
-static CAAdapterMessageQueue_t *gServerRecvQueueHandle = NULL;
+static CAWiFiPacketReceivedCallback gPacketReceivedCallback = NULL;
 
-/* Skip Queue */
 /**
- * @var gNetworkPacketCallback
- * @brief receiving request response callback
+ * @var gExceptionCallback
+ * @brief Callback for notifying the upper layer when unicast/multicast server encounters exception
  */
-static CANetworkPacketReceivedCallback gNetworkPacketCallback = NULL;
+static CAWiFiExceptionCallback gExceptionCallback = NULL;
 
-void CAInitializeServerMutex()
-{
-    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
-    gMutexUnicastServerSocketDescriptor = u_mutex_new();
-    gMutexMulticastServerSocketDescriptor = u_mutex_new();
-    gMutexStopUnicast = u_mutex_new();
-    gMutexStopMulticast = u_mutex_new();
-    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
-}
+/**
+ * @var gUnicastRecvBuffer
+ * @brief Character buffer used for receiving unicast data from network
+ */
+static char gUnicastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
+
+/**
+ * @var gMulticastRecvBuffer
+ * @brief Character buffer used for receiving multicast data from network
+ */
+static char gMulticastRecvBuffer[COAP_MAX_PDU_SIZE] = {0};
+
+/**
+ * @fn CAWiFiServerCreateMutex
+ * @brief Creates and initializes mutex
+ */
+static CAResult_t CAWiFiServerCreateMutex(void);
+
+/**
+ * @fn CAWiFiServerDestroyMutex
+ * @brief Releases all created mutex
+ */
+static void CAWiFiServerDestroyMutex(void);
 
-void CASetRecvQueueHandle(CAAdapterMessageQueue_t *recvQueueHandle)
+/**
+ * @fn CAReceiveThreadForMulticast
+ * @brief Handler thread for receiving data on multicast server
+ */
+static void *CAReceiveThreadForMulticast(void *data);
+
+/**
+ * @fn CAWiFiReceiveThreadForUnicast
+ * @brief Handler thread for receiving data on unicast server
+ */
+static void *CAWiFiReceiveThreadForUnicast(void *data);
+
+CAResult_t CAWiFiInitializeServer(const u_thread_pool_t threadPool)
 {
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
-    gServerRecvQueueHandle = recvQueueHandle;
+
+    // Input validation
+    VERIFY_NON_NULL(threadPool, WIFI_SERVER_TAG, "Thread pool handle is NULL");
+
+    // Initialize mutex
+    if (CA_STATUS_OK != CAWiFiServerCreateMutex())
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to create mutex!");
+        return CA_STATUS_FAILED;
+    }
+
+    gThreadPool = threadPool;
+
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+    return CA_STATUS_OK;
 }
 
-void CASetThreadHandle(u_thread_pool_t handle)
+void CAWiFiTerminateServer(void)
 {
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
-    gThreadPool = handle;
+
+    gThreadPool = NULL;
+
+    // Destroy mutex
+    CAWiFiServerDestroyMutex();
+
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
 }
 
-CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port)
+CAResult_t CAWiFiStartMulticastServer(const char *localAddress, const char *multicastAddress,
+                                      const int16_t multicastPort, int32_t *serverFD)
 {
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
 
-    if (gUnicastServerSocketDescriptor != -1)
+    if (gMulticastServerSocketDescriptor != -1)
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server is Started Already! Return Code[%d]",
-                  CA_SERVER_STARTED_ALREADY);
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server is already running!");
         return CA_SERVER_STARTED_ALREADY;
     }
 
-    VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Invalid argument : localAddress is NULL");
-    VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "Invalid argument : port is NULL");
+    VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Local address is NULL");
+    VERIFY_NON_NULL(multicastAddress, WIFI_SERVER_TAG, "Multicast address is NULL");
 
-    struct sockaddr_in sockAddr;
-    int16_t isBound = 0;
-    int16_t i = 0;
-    int16_t result = 0;
-    int16_t status = 0;
-    int setOptionOn = 1;
-    u_mutex_lock(gMutexStopUnicast);
-    gStopUnicast = false;
-    u_mutex_unlock(gMutexStopUnicast);
+    if (0 >= multicastPort)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: Multicast port is invalid!");
+        return CA_STATUS_INVALID_PARAM;
+    }
 
-    u_mutex_lock(gMutexUnicastServerSocketDescriptor);
-    // Create a UDP socket
-    if ((gUnicastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+    // Create a datagram socket on which to recv/send.
+    u_mutex_lock(gMutexStopMulticast);
+    gStopMulticast = false;
+    u_mutex_unlock(gMutexStopMulticast);
+
+    u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+
+    // create a UDP socket
+    if ((gMulticastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s", strerror(errno));
-        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s",
+                  strerror(errno));
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
         return CA_SOCKET_OPERATION_FAILED;
     }
 
     // Make the socket non-blocking
-    if ((status = fcntl(gUnicastServerSocketDescriptor, F_SETFL, O_NONBLOCK)) < 0)
+    if (-1 == fcntl(gMulticastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "fcntl to make the socket non-blocking failed, Error code: %s",
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
                   strerror(errno));
-        close(gUnicastServerSocketDescriptor);
-        gUnicastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
         return CA_STATUS_FAILED;
     }
 
     OIC_LOG(INFO, WIFI_SERVER_TAG, "socket creation success");
 
-    if ((result = setsockopt(gUnicastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
-                             (char *) &setOptionOn,
-                             sizeof(setOptionOn))) < 0)
+    int32_t setOptionOn = 1;
+    if (-1 == setsockopt(gMulticastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
+                         (char *) &setOptionOn,
+                         sizeof(setOptionOn)))
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to setsockopt for SO_REUSEADDR! Error code: %s",
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to setsockopt for SO_REUSEADDR, Error code: %s",
                   strerror(errno));
-        close(gUnicastServerSocketDescriptor);
-        gUnicastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
         return CA_SOCKET_OPERATION_FAILED;
     }
 
-    // zero out the structure
+    struct sockaddr_in sockAddr;
     memset((char *) &sockAddr, 0, sizeof(sockAddr));
-    sockAddr.sin_family = AF_INET;
-    sockAddr.sin_port = htons(*port);
 
-    // TODO: Assign the Particular Address on Multiple Interfaces
+    sockAddr.sin_family = AF_INET;
+    sockAddr.sin_port = htons(multicastPort);
     sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
 
-    // Trying for bind in a loop
-    for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
+    // bind socket to multicast port
+    if (-1 == bind(gMulticastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
+                   sizeof(sockAddr)))
     {
-        // bind socket to port
-        if (bind(gUnicastServerSocketDescriptor, (struct sockaddr *) &sockAddr, sizeof(sockAddr)) == -1)
-        {
-            OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]. Trying again... ", strerror(errno));
-            continue;
-        }
-        isBound = 1;
-        break;
-    }
-
-    if (!isBound)
-    {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind Socket! Return code[%d]",
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Bind Socket! Return Code[%d]",
                   CA_SOCKET_OPERATION_FAILED);
-        close(gUnicastServerSocketDescriptor);
-        gUnicastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
         return CA_SOCKET_OPERATION_FAILED;
     }
 
     OIC_LOG(INFO, WIFI_SERVER_TAG, "socket bind success");
 
-    socklen_t len = sizeof(sockAddr);
+    // Add membership to receiving socket (join group)
+    memset(&gMReq, 0, sizeof(struct ip_mreq));
+    gMReq.imr_interface.s_addr = htonl(INADDR_ANY);
+    inet_aton(multicastAddress, &gMReq.imr_multiaddr);
 
-    if (getsockname(gUnicastServerSocketDescriptor, (struct sockaddr *)&sockAddr, &len) == -1)
+    if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP,
+                         (char *) &gMReq,
+                         sizeof(struct ip_mreq)))
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to getsockname, Error code: %s", strerror(errno));
-    }
-    else
-    {
-        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "port number %d", ntohs(sockAddr.sin_port));
-        *port = ntohs(sockAddr.sin_port);
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to add to multicast group, Error code: %s\n",
+                  strerror(errno));
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        return CA_SOCKET_OPERATION_FAILED;
     }
 
     /**
-      * The task to listen for data from unicast socket is added to the thread pool.
+      * The task to listen to data from multicastcast socket is added to the thread pool.
       * This is a blocking call is made where we try to receive some data.. We will keep waiting until some data is received.
       * This task will be terminated when thread pool is freed on stopping the adapters.
       */
-    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAReceiveThreadForUnicast,
-            (void *) NULL))
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAReceiveThreadForMulticast,
+            (void *)NULL))
     {
         OIC_LOG(ERROR, WIFI_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
 
-        close(gUnicastServerSocketDescriptor);
-        gUnicastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        close(gMulticastServerSocketDescriptor);
+        gMulticastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
         return CA_STATUS_FAILED;
     }
-    u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
 
-    // Set Unicast Socket Descriptor in cawificlient
-    CASetUnicastSocketDescriptor(gUnicastServerSocketDescriptor);
+    *serverFD = gMulticastServerSocketDescriptor;
+    u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
 
     OIC_LOG(INFO, WIFI_SERVER_TAG, "thread_pool_add_task done");
-    OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server Started Successfully");
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server Started Successfully");
 
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
     return CA_STATUS_OK;
+
 }
 
-CAResult_t CAStartMulticastServer(const char *mcastAddress, const char *localAddress,
-                                  int16_t *port)
+CAResult_t CAWiFiStartUnicastServer(const char *localAddress, int16_t *port,
+                                    const bool forceStart, int32_t *serverFD)
 {
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
 
-    if (gMulticastServerSocketDescriptor != -1)
+    if (gUnicastServerSocketDescriptor != -1)
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server is Started Already! Return Code[%d]",
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server is Started Already! Return Code[%d]",
                   CA_SERVER_STARTED_ALREADY);
         return CA_SERVER_STARTED_ALREADY;
     }
 
-    VERIFY_NON_NULL(mcastAddress, WIFI_SERVER_TAG, "Invalid argument : mcastAddress is NULL");
     VERIFY_NON_NULL(localAddress, WIFI_SERVER_TAG, "Invalid argument : localAddress is NULL");
     VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "Invalid argument : port is NULL");
 
-    // Create a datagram socket on which to recv/send.
-    struct sockaddr_in sockAddr;
-    int16_t result = 0;
-    int16_t i = 0;
-    int16_t status = 0;
-
-    int setOptionOn = 1;
-    u_mutex_lock(gMutexStopMulticast);
-    gStopMulticast = false;
-    u_mutex_unlock(gMutexStopMulticast);
+    if (0 >= port)
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Invalid input: port is invalid!");
+        return CA_STATUS_INVALID_PARAM;
+    }
 
-    u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+    u_mutex_lock(gMutexStopUnicast);
+    gStopUnicast = false;
+    u_mutex_unlock(gMutexStopUnicast);
 
-    // create a UDP socket
-    if ((gMulticastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
+    u_mutex_lock(gMutexUnicastServerSocketDescriptor);
+    // Create a UDP socket
+    if ((gUnicastServerSocketDescriptor = socket(AF_INET, SOCK_DGRAM, IPPROTO_UDP)) == -1)
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s", strerror(errno));
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Create Socket, Error code: %s",
+                  strerror(errno));
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
         return CA_SOCKET_OPERATION_FAILED;
     }
 
     // Make the socket non-blocking
-    if ((status = fcntl(gMulticastServerSocketDescriptor, F_SETFL, O_NONBLOCK)) < 0)
+    if (-1 == fcntl(gUnicastServerSocketDescriptor, F_SETFL, O_NONBLOCK))
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "fcntl to make the socket non-blocking failed, Error code: %s",
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set non-block mode, Error code: %s",
                   strerror(errno));
-        close(gMulticastServerSocketDescriptor);
-        gMulticastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        close(gUnicastServerSocketDescriptor);
+        gUnicastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
         return CA_STATUS_FAILED;
     }
 
     OIC_LOG(INFO, WIFI_SERVER_TAG, "socket creation success");
 
-    if ((result = setsockopt(gMulticastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
-                             (char *) &setOptionOn,
-                             sizeof(setOptionOn))) < 0)
+    if (true == forceStart)
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to setsockopt for SO_REUSEADDR, Error code: %s",
-                  strerror(errno));
-        close(gMulticastServerSocketDescriptor);
-        gMulticastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-        return CA_SOCKET_OPERATION_FAILED;
+        int32_t setOptionOn = 1;
+        if (-1 == setsockopt(gUnicastServerSocketDescriptor, SOL_SOCKET, SO_REUSEADDR,
+                             (char *) &setOptionOn,
+                             sizeof(setOptionOn)))
+        {
+            OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to set SO_REUSEADDR! Error code: %s",
+                      strerror(errno));
+            close(gUnicastServerSocketDescriptor);
+            gUnicastServerSocketDescriptor = -1;
+            u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+            return CA_SOCKET_OPERATION_FAILED;
+        }
     }
 
-    // zero out the structure
-    memset((char *) &sockAddr, 0, sizeof(sockAddr));
+    struct sockaddr_in sockAddr;
+    bool isBound = false;
+    int16_t serverPort = *port;
 
+    memset((char *) &sockAddr, 0, sizeof(sockAddr));
     sockAddr.sin_family = AF_INET;
-    sockAddr.sin_port = htons(*port);
-    // TODO: Assign the Particular Address on Multiple Interfaces
+    sockAddr.sin_port = htons(serverPort);
     sockAddr.sin_addr.s_addr = htonl(INADDR_ANY);
 
     // Trying for bind in a loop
+    int16_t i;
     for (i = 0; i < CA_UDP_BIND_RETRY_COUNT; i++)
     {
-        // bind socket to multicast port
-        if (bind(gMulticastServerSocketDescriptor, (struct sockaddr *) &sockAddr, sizeof(sockAddr)) == -1)
+        if (-1 == bind(gUnicastServerSocketDescriptor, (struct sockaddr *) &sockAddr,
+                       sizeof(sockAddr)))
         {
-            OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]. Trying again...", strerror(errno));
-            continue;
+            if (false == forceStart)
+            {
+                OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]. Trying again... ",
+                          strerror(errno));
+
+                // Set the port to next one
+                serverPort += 1;
+                sockAddr.sin_port = htons(serverPort);
+                continue;
+            }
+            else
+            {
+                OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind socket[%s]!",
+                          strerror(errno));
+                break;
+            }
         }
-        result = 1;
+
+        isBound = true;
         break;
     }
-    if (!result)
+
+    if (false == isBound)
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to Bind Socket! Return Code[%d]",
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Failed to bind Socket! Return code[%d]",
                   CA_SOCKET_OPERATION_FAILED);
-        close(gMulticastServerSocketDescriptor);
-        gMulticastServerSocketDescriptor = -1;
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        close(gUnicastServerSocketDescriptor);
+        gUnicastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
         return CA_SOCKET_OPERATION_FAILED;
     }
 
     OIC_LOG(INFO, WIFI_SERVER_TAG, "socket bind success");
 
-    socklen_t len = sizeof(sockAddr);
-
-    if (getsockname(gMulticastServerSocketDescriptor, (struct sockaddr *)&sockAddr, &len) == -1)
+    socklen_t len;
+    char *serverAddress = NULL;
+    if (-1 != getsockname(gUnicastServerSocketDescriptor, (struct sockaddr *)&sockAddr, &len))
     {
-        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "getsockname failed, Error code: %s", strerror(errno));
+        serverPort = ntohs(sockAddr.sin_port);
+        serverAddress = inet_ntoa(sockAddr.sin_addr);
     }
-    else
+
+    /**
+      * The task to listen for data from unicast socket is added to the thread pool.
+      * This is a blocking call is made where we try to receive some data..
+      * We will keep waiting until some data is received.
+      * This task will be terminated when thread pool is freed on stopping the adapters.
+      */
+    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAWiFiReceiveThreadForUnicast,
+            (void *) NULL))
     {
-        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "port number %d\n", ntohs(sockAddr.sin_port));
-        *port = ntohs(sockAddr.sin_port);
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+
+        close(gUnicastServerSocketDescriptor);
+        gUnicastServerSocketDescriptor = -1;
+        u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
+        return CA_STATUS_FAILED;
     }
 
-    // add membership to receiving socket (join group)
-    memset(&gMReq, 0, sizeof(struct ip_mreq));
-    gMReq.imr_interface.s_addr = htonl(INADDR_ANY);
-    inet_aton(mcastAddress, &gMReq.imr_multiaddr);
+    // Free the server address previously stored
+    OICFree(gUnicastServerAddress);
+    gUnicastServerAddress = NULL;
+    gUnicastServerPort = serverPort;
+    gUnicastServerAddress = (serverAddress) ? strndup(serverAddress, strlen(serverAddress)) :
+                            NULL;
+    *port = serverPort;
+    *serverFD = gUnicastServerSocketDescriptor;
+    u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
 
-    if ((result = setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_ADD_MEMBERSHIP,
-                             (char *) &gMReq,
-                             sizeof(struct ip_mreq))) < 0)
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server Started Successfully");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiStopMulticastServer(void)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+
+    if (gMulticastServerSocketDescriptor == -1)
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "setsockopt API for IP_ADD_MEMBERSHIP failed, Error code: %s\n",
-                  strerror(errno));
-        close(gMulticastServerSocketDescriptor);
-        gMulticastServerSocketDescriptor = -1;
+        OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server is not yet Started");
         u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-        return CA_SOCKET_OPERATION_FAILED;
+        return CA_SERVER_NOT_STARTED;
     }
 
-    /**
-      * The task to listen to data from multicastcast socket is added to the thread pool.
-      * This is a blocking call is made where we try to receive some data.. We will keep waiting until some data is received.
-      * This task will be terminated when thread pool is freed on stopping the adapters.
-      */
-    if (CA_STATUS_OK != u_thread_pool_add_task(gThreadPool, (void *) CAReceiveThreadForMulticast,
-            (void *)NULL))
+    u_mutex_lock(gMutexStopMulticast);
+    gStopMulticast = true;
+
+    // leave the group after you are done
+    if (-1 == setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP,
+                         (char *)&gMReq,
+                         sizeof(struct ip_mreq)))
     {
-        OIC_LOG(ERROR, WIFI_SERVER_TAG, "[testThreadPool] thread_pool_add_task failed!");
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "cannot leave multicast group, Error code: %s\n",
+                  strerror(errno));
+    }
 
-        close(gMulticastServerSocketDescriptor);
-        gMulticastServerSocketDescriptor = -1;
+    // close the socket
+    if (-1 == close(gMulticastServerSocketDescriptor))
+    {
+        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server socket close failed, Error code: %s\n",
+                  strerror(errno));
         u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-        return CA_STATUS_FAILED;
+        u_mutex_unlock(gMutexStopMulticast);
+        return CA_SOCKET_OPERATION_FAILED;
     }
 
+    u_mutex_unlock(gMutexStopMulticast);
+
+    gMulticastServerSocketDescriptor = -1;
     u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
 
-    OIC_LOG(INFO, WIFI_SERVER_TAG, "thread_pool_add_task done");
-    OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server Started Successfully");
+    OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server Stopped Successfully");
 
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
     return CA_STATUS_OK;
+
 }
 
-CAResult_t CAStopUnicastServer()
+CAResult_t CAWiFiStopUnicastServer()
 {
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
     u_mutex_lock(gMutexUnicastServerSocketDescriptor);
@@ -445,9 +537,7 @@ CAResult_t CAStopUnicastServer()
     gStopUnicast = true;
 
     // close the socket
-    int16_t ret = close(gUnicastServerSocketDescriptor);
-
-    if (-1 == ret)
+    if (-1 == close(gUnicastServerSocketDescriptor))
     {
         OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Unicast Server socket close failed, Error code: %s\n",
                   strerror(errno));
@@ -458,290 +548,275 @@ CAResult_t CAStopUnicastServer()
 
     u_mutex_unlock(gMutexStopUnicast);
     gUnicastServerSocketDescriptor = -1;
-    // UnSet Unicast Socket Descriptor in cawificlient
-    CASetUnicastSocketDescriptor(gUnicastServerSocketDescriptor);
+
     u_mutex_unlock(gMutexUnicastServerSocketDescriptor);
 
     OIC_LOG(INFO, WIFI_SERVER_TAG, "Unicast Server Stopped Successfully");
+    return CA_STATUS_OK;
+}
+
+CAResult_t CAWiFiGetUnicastServerInfo(char **ipAddress, int16_t *port, int32_t *serverFD)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    // Input validation
+    VERIFY_NON_NULL(ipAddress, WIFI_SERVER_TAG, "ipAddress holder is NULL");
+    VERIFY_NON_NULL(port, WIFI_SERVER_TAG, "port holder is NULL");
+    VERIFY_NON_NULL(serverFD, WIFI_SERVER_TAG, "serverID holder is NULL");
+
+    *ipAddress = gUnicastServerAddress;
+    *port = gUnicastServerPort;
+    *serverFD = gUnicastServerSocketDescriptor;
 
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-CAResult_t CAStopMulticastServer()
+void CAWiFiSetPacketReceiveCallback(CAWiFiPacketReceivedCallback callback)
 {
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
 
-    u_mutex_lock(gMutexMulticastServerSocketDescriptor);
+    gPacketReceivedCallback = callback;
+}
 
-    if (gMulticastServerSocketDescriptor == -1)
-    {
-        OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server is not yet Started");
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-        return CA_SERVER_NOT_STARTED;
-    }
+void CAWiFiSetExceptionCallback(CAWiFiExceptionCallback callback)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
 
-    u_mutex_lock(gMutexStopMulticast);
-    gStopMulticast = true;
+    gExceptionCallback = callback;
+}
 
-    // leave the group after you are done
-    int16_t result = setsockopt(gMulticastServerSocketDescriptor, IPPROTO_IP, IP_DROP_MEMBERSHIP,
-                                (char *)&gMReq,
-                                sizeof(struct ip_mreq));
-    if (result < 0)
+CAResult_t CAWiFiServerCreateMutex(void)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    gMutexUnicastServerSocketDescriptor = u_mutex_new();
+    if (!gMutexUnicastServerSocketDescriptor)
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "cannot leave multicast group, Error code: %s\n",
-                  strerror(errno));
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+        return CA_STATUS_FAILED;
     }
 
-    // close the socket
-    result = close(gMulticastServerSocketDescriptor);
-    if (-1 == result)
+    gMutexMulticastServerSocketDescriptor = u_mutex_new();
+    if (!gMutexMulticastServerSocketDescriptor)
     {
-        OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast Server socket close failed, Error code: %s\n",
-                  strerror(errno));
-        u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
-        u_mutex_unlock(gMutexStopMulticast);
-        return CA_SOCKET_OPERATION_FAILED;
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+
+        CAWiFiServerDestroyMutex();
+        return CA_STATUS_FAILED;
     }
 
-    u_mutex_unlock(gMutexStopMulticast);
+    gMutexStopUnicast = u_mutex_new();
+    if (!gMutexStopUnicast)
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
 
-    gMulticastServerSocketDescriptor = -1;
-    u_mutex_unlock(gMutexMulticastServerSocketDescriptor);
+        CAWiFiServerDestroyMutex();
+        return CA_STATUS_FAILED;
+    }
 
-    OIC_LOG(INFO, WIFI_SERVER_TAG, "Multicast Server Stopped Successfully");
+    gMutexStopMulticast = u_mutex_new();
+    if (!gMutexStopMulticast)
+    {
+        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Failed to created mutex!");
+
+        CAWiFiServerDestroyMutex();
+        return CA_STATUS_FAILED;
+    }
 
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
     return CA_STATUS_OK;
 }
 
-void *CAReceiveThreadForUnicast(void *data)
+void CAWiFiServerDestroyMutex(void)
 {
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
-    if (NULL == gServerRecvQueueHandle)
+
+    if (gMutexUnicastServerSocketDescriptor)
     {
-        OIC_LOG(ERROR, WIFI_SERVER_TAG, "QueueHandle is not Initialized");
-        return NULL;
+        u_mutex_free(gMutexUnicastServerSocketDescriptor);
+        gMutexUnicastServerSocketDescriptor = NULL;
     }
 
-    uint32_t recvLen;
-    int32_t ret = 0;
-    struct sockaddr_in siOther;
-    socklen_t sLen = sizeof(siOther);
-    fd_set reads;
-    struct timeval timeout;
-    CARemoteEndpoint_t *endPointUnicast = (CARemoteEndpoint_t *) OICMalloc (sizeof(CARemoteEndpoint_t));
-    if (NULL == endPointUnicast)
+    if (gMutexMulticastServerSocketDescriptor)
     {
-        OIC_LOG(ERROR, WIFI_SERVER_TAG, "Memory Allocation failed");
-        return NULL;
+        u_mutex_free(gMutexMulticastServerSocketDescriptor);
+        gMutexMulticastServerSocketDescriptor = NULL;
     }
-    memset (endPointUnicast, 0, sizeof(CARemoteEndpoint_t));
 
+    if (gMutexStopUnicast)
+    {
+        u_mutex_free(gMutexStopUnicast);
+        gMutexStopUnicast = NULL;
+    }
 
+    if (gMutexStopMulticast)
+    {
+        u_mutex_free(gMutexStopMulticast);
+        gMutexStopMulticast = NULL;
+    }
+
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
+}
+
+void *CAWiFiReceiveThreadForUnicast(void *data)
+{
+    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
+
+    fd_set reads;
+    struct timeval timeout;
 
     // keep listening for data
     while (!gStopUnicast)
     {
-        OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Waiting for data..");
-
         timeout.tv_sec = 1;
         timeout.tv_usec = 0;
 
         FD_ZERO(&reads);
-        // Use select for polling the socket fd
         FD_SET(gUnicastServerSocketDescriptor, &reads);
 
-        ret = select(gUnicastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
-        if ( ret < 0)
+        int32_t ret = select(gUnicastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
+        if (gStopUnicast)
         {
-            OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select API failed");
-            continue;
+            OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop Unicast is called");
+            break;
         }
-        if (!FD_ISSET(gUnicastServerSocketDescriptor, &reads))
+        if (ret < 0)
         {
-            OIC_LOG(DEBUG, WIFI_SERVER_TAG, "No data to read");
+            OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
             continue;
         }
-
-        // Allocate Memory for COAP Buffer
-        char *buf = (char *) OICMalloc (CA_BUFFER_LEN);
-        if (NULL == buf)
-        {
-            OIC_LOG(ERROR, WIFI_SERVER_TAG, "Memory Allocation failed");
-            return (void *) NULL;
-        }
-
-        memset(buf, 0, sizeof(char) * CA_BUFFER_LEN);
-
-        CARemoteEndpoint_t *endPointUnicast = (CARemoteEndpoint_t *) OICMalloc (sizeof(CARemoteEndpoint_t));
-        if (NULL == endPointUnicast)
+        if (!FD_ISSET(gUnicastServerSocketDescriptor, &reads))
         {
-            OIC_LOG(ERROR, WIFI_SERVER_TAG, "Memory Allocation failed");
-            OICFree(buf);
-            return NULL;
+            continue;
         }
-        memset (endPointUnicast, 0, sizeof(CARemoteEndpoint_t));
 
+        memset(gUnicastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
 
-        // try to receive some data
-        if ((recvLen = recvfrom(gUnicastServerSocketDescriptor, buf, CA_BUFFER_LEN, 0,
-                                (struct sockaddr *) &siOther, &sLen)) == -1)
+        // Read data from socket
+        struct sockaddr_in srcSockAddress;
+        int32_t recvLen;
+        socklen_t srcAddressLen = sizeof(srcSockAddress);
+        if (-1 == (recvLen = recvfrom(gUnicastServerSocketDescriptor, gUnicastRecvBuffer,
+                                      COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
+                                      &srcAddressLen)))
         {
-            OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s\n", strerror(errno));
-            OICFree(buf);
-            OICFree(endPointUnicast);
+            OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
             continue;
         }
         else if (0 == recvLen)
         {
-            OIC_LOG(ERROR, WIFI_SERVER_TAG, "Unicast socket is shutdown, returning from thread\n");
-            OICFree(buf);
-            OICFree(endPointUnicast);
-            return (void *) NULL;
-        }
+            OIC_LOG(ERROR, WIFI_SERVER_TAG, "Unicast server socket is shutdown !");
 
-        // print details of the client/peer and the data received
-        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n", inet_ntoa(siOther.sin_addr),
-                  ntohs(siOther.sin_port));
-        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s, DataLength: %d\n", buf, sizeof(buf));
-
-        endPointUnicast->resourceUri = NULL; // will be filled by upper layer
-        strncpy((char *)endPointUnicast->addressInfo.IP.ipAddress, inet_ntoa(siOther.sin_addr),
-                CA_IPADDR_SIZE);
-        endPointUnicast->addressInfo.IP.port = ntohs(siOther.sin_port);
-        endPointUnicast->connectivityType = CA_WIFI;
-
-        // Enqueue the Received Message in the Queue
-#if 0 /* Skip Queue */
-        CAAdapterEnqueueMessage(gServerRecvQueueHandle, &endPointUnicast, buf, recvLen);
-#else
-        if (gNetworkPacketCallback)
-        {
-            gNetworkPacketCallback(endPointUnicast, buf, recvLen);
+            // Notify upper layer this exception
+            if (gExceptionCallback)
+            {
+                gExceptionCallback(CA_UNICAST_SERVER);
+            }
+            return NULL;
         }
-        else
+
+        const char *srcIPAddress = NULL;
+        int32_t srcPort = -1;
+
+        srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
+        srcPort = ntohs(srcSockAddress.sin_port);
+
+        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
+                  srcIPAddress, srcPort);
+        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
+                  gUnicastRecvBuffer, recvLen);
+
+        // Notify data to upper layer
+        if (gPacketReceivedCallback)
         {
-            OICFree(buf);
-            OICFree(endPointUnicast);
+            gPacketReceivedCallback(srcIPAddress, srcPort, gUnicastRecvBuffer, recvLen);
         }
-        // Currently, endPointUnicast and buf is freed in gNetworkPacketCallback
-#endif //#if 0
     }
-    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "stopUnicastServer is called, Breaking from while loop\n");
+
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
-    return (void *) NULL;
+    return NULL;
 }
 
 void *CAReceiveThreadForMulticast(void *data)
 {
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
 
-    if (NULL == gServerRecvQueueHandle)
-    {
-        OIC_LOG(ERROR, WIFI_SERVER_TAG, "QueueHandle is not Initialized");
-        return NULL;
-    }
-
-    int recvLen;
-    struct sockaddr_in siOther;
-    int32_t ret = 0;
-    socklen_t sLen = sizeof(siOther);
     fd_set reads;
     struct timeval timeout;
 
     // keep listening for data
     while (!gStopMulticast)
     {
-        OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Waiting for data...\n");
-
         timeout.tv_sec = 1;
         timeout.tv_usec = 0;
+
         FD_ZERO(&reads);
-        // Use select for polling the socket fd
         FD_SET(gMulticastServerSocketDescriptor, &reads);
 
-        ret = select(gMulticastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
+        int32_t ret = select(gMulticastServerSocketDescriptor + 1, &reads, NULL, NULL, &timeout);
+        if (gStopMulticast)
+        {
+            OIC_LOG(DEBUG, WIFI_SERVER_TAG, "Stop Multicast is called");
+            break;
+        }
         if ( ret < 0)
         {
-            OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select API failed");
+            OIC_LOG_V(FATAL, WIFI_SERVER_TAG, "select returned error %s", strerror(errno));
             continue;
         }
         if (!FD_ISSET(gMulticastServerSocketDescriptor, &reads))
         {
-            OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "No data to read");
             continue;
         }
 
-        // Allocate Memory for COAP Buffer
-        char *buf = (char *) OICMalloc (CA_BUFFER_LEN);
-        if (NULL == buf)
-        {
-            OIC_LOG(ERROR, WIFI_SERVER_TAG, "Memory Allocation failed");
-            return (void *) NULL;
-        }
-
-        memset(buf, 0, sizeof(char) * CA_BUFFER_LEN);
-
-        CARemoteEndpoint_t *endPointMulticast = (CARemoteEndpoint_t *) OICMalloc (sizeof(
-                CARemoteEndpoint_t));
-        if (NULL == endPointMulticast)
-        {
-            OIC_LOG(ERROR, WIFI_SERVER_TAG, "Memory Allocation failed");
-            OICFree(buf);
-            return NULL;
-        }
-        memset (endPointMulticast, 0, sizeof(CARemoteEndpoint_t));
+        memset(gMulticastRecvBuffer, 0, sizeof(char)*COAP_MAX_PDU_SIZE);
 
-        // try to receive some data
-        if ((recvLen = recvfrom(gMulticastServerSocketDescriptor, buf, CA_BUFFER_LEN, 0,
-                                (struct sockaddr *) &siOther, &sLen)) == -1)
+        // Read data from socket
+        struct sockaddr_in srcSockAddress;
+        int32_t recvLen;
+        socklen_t srcAddressLen = sizeof(srcSockAddress);
+        if (-1 == (recvLen = recvfrom(gMulticastServerSocketDescriptor, gMulticastRecvBuffer,
+                                      COAP_MAX_PDU_SIZE, 0, (struct sockaddr *) &srcSockAddress,
+                                      &srcAddressLen)))
         {
-            OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s\n", strerror(errno));
-            OICFree(buf);
-            OICFree(endPointMulticast);
+            OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "%s", strerror(errno));
             continue;
         }
         else if (0 == recvLen)
         {
-            OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast socket is shutdown, returning from thread\n");
-            OICFree(buf);
-            OICFree(endPointMulticast);
-            return (void *) NULL;
+            OIC_LOG_V(ERROR, WIFI_SERVER_TAG, "Multicast socket is shutdown, returning from \
+                thread\n");
+
+            // Notify upper layer this exception
+            if (gExceptionCallback)
+            {
+                gExceptionCallback(CA_MULTICAST_SERVER);
+            }
+            return NULL;
         }
 
-        // print details of the client/peer and the data received
+        const char *srcIPAddress = NULL;
+        int32_t srcPort = -1;
+
+        srcIPAddress = inet_ntoa(srcSockAddress.sin_addr);
+        srcPort = ntohs(srcSockAddress.sin_port);
+
         OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Received packet from %s:%d\n",
-                  inet_ntoa(siOther.sin_addr), ntohs(siOther.sin_port));
-        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n", buf, recvLen);
-
-        endPointMulticast->resourceUri = NULL; // will be filled by upper layer
-        strncpy((char *)endPointMulticast->addressInfo.IP.ipAddress, inet_ntoa(siOther.sin_addr),
-                (CA_IPADDR_SIZE-1));
-        endPointMulticast->addressInfo.IP.port = ntohs(siOther.sin_port);
-        endPointMulticast->connectivityType = CA_WIFI;
-        if (gNetworkPacketCallback)
-        {
-            gNetworkPacketCallback(endPointMulticast, buf, recvLen);
-        }
-        else
+                  srcIPAddress, srcPort);
+        OIC_LOG_V(DEBUG, WIFI_SERVER_TAG, "Data: %s\t, DataLength: %d\n",
+                  gMulticastRecvBuffer, recvLen);
+
+
+        // Notify data to upper layer
+        if (gPacketReceivedCallback)
         {
-            OICFree(buf);
-            OICFree(endPointMulticast);
+            gPacketReceivedCallback(srcIPAddress, srcPort, gMulticastRecvBuffer, recvLen);
         }
-        // Currently, endpointMulticast and buf is freed in gNetworkPacketCallback
     }
-    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "stopMulticastServer is called, Breaking from while loop\n");
 
     OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
-    return (void *) NULL;
+    return NULL;
 }
 
-/* Skip Queue */
-void CASetWIFINetworkPacketCallback(CANetworkPacketReceivedCallback callback)
-{
-    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "IN");
-    gNetworkPacketCallback = callback;
-    OIC_LOG(DEBUG, WIFI_SERVER_TAG, "OUT");
-}
+
diff --git a/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.h b/resource/csdk/connectivity/src/wifi_adapter/tizen/cawifiserver.h
deleted file mode 100644 (file)
index 1a619e6..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-/******************************************************************
-*
-* Copyright 2014 Samsung Electronics All Rights Reserved.
-*
-*
-*
-* Licensed under the Apache License, Version 2.0 (the "License");
-* you may not use this file except in compliance with the License.
-* You may obtain a copy of the License at
-*
-*      http://www.apache.org/licenses/LICENSE-2.0
-*
-* Unless required by applicable law or agreed to in writing, software
-* distributed under the License is distributed on an "AS IS" BASIS,
-* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-* See the License for the specific language governing permissions and
-* limitations under the License.
-*
-******************************************************************/
-
-/**
- * @file cawifiserver.h
- * @brief This file contains the APIs for WiFi Server module
- */
-
-#ifndef _CA_WIFI_SERVER_H_
-#define _CA_WIFI_SERVER_H_
-
-#include "caadapterinterface.h"
-#include "logger.h"
-#include "uthreadpool.h"
-#include "camessagequeue.h"
-
-/**
- * @brief API to Initialize Server Mutex
- * @return - None
- */
-void CAInitializeServerMutex();
-
-/**
- * @brief API to Set the Receive queue handle
- * @param  recvQueueHandle          [IN] Queue Handle to Receive Data
- * @return - None
- */
-void CASetRecvQueueHandle(CAAdapterMessageQueue_t *recvQueueHandle);
-
-/**
- * @brief API to Get thread pool handle initialized in interface sample.
- * @return - None
- */
-void CASetThreadHandle(u_thread_pool_t gThreadPool);
-
-/**
- * @brief API to start unicast server.
- * @param localAddress - Local Unicast IP address to bind the socket.
- * @param port - Local port number where socket will listen for incoming request.
- * @return - Error Code
- */
-CAResult_t CAStartUnicastServer(const char *localAddress, int16_t *port);
-
-/**
- * @brief API to start multicast server.
- * @param mcastAddress - IP address to join multicast group.
- * @param localAddress - Local Unicast IP address to bind the socket.
- * @param port - multicast port number where socket will listen for incoming request.
- * @return - Error Code
- */
-CAResult_t CAStartMulticastServer(const char *mcastAddress, const char *localAddress,
-                                  int16_t *port);
-
-/**
- * @brief API to stop unicast server.
- * @return - Error Code
- */
-CAResult_t CAStopUnicastServer();
-
-/**
- * @brief API to stop multicast server.
- * @return - Error Code
- */
-CAResult_t CAStopMulticastServer();
-
-/**
- * @brief API to receive the data in unicast server socket thread.
- * @param data - data received in server from lower layer.
- * @return - NULL
- */
-void *CAReceiveThreadForUnicast(void *data);
-
-/**
- * @brief API to receive the data in multicast server socket thread.
- * @param data - data received in server from lower layer.
- * @return - NULL
- */
-void *CAReceiveThreadForMulticast(void *data);
-/* Skip Queue */
-/**
- * @brief API to set request response callback to upper layer.
- * @param RequestResponseCallback - upper layer callback function to pass the data received in the server.
- * @return - Error Code
- */
-void CASetWIFINetworkPacketCallback(CANetworkPacketReceivedCallback callback);
-
-#endif  // #ifndef _CA_WIFI_SERVER_H_
index c58492d..8f33a20 100644 (file)
@@ -265,7 +265,7 @@ TEST(SendNotificationTest, TC_19_Positive_01)
     responseData.payload = (char *) "Temp Notification Data";
 
     memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
-    responseInfo.result = CA_CONTENT;
+    responseInfo.result = CA_SUCCESS;
     responseInfo.info = responseData;
 
     EXPECT_EQ(CA_STATUS_OK, CASendNotification(tempRep, &responseInfo));
@@ -284,7 +284,7 @@ TEST(SendNotificationTest, TC_20_Nagative_01)
     responseData.payload = (char *) "Temp Notification Data";
 
     memset(&responseInfo, 0, sizeof(CAResponseInfo_t));
-    responseInfo.result = CA_CONTENT;
+    responseInfo.result = CA_SUCCESS;
     responseInfo.info = responseData;
 
     EXPECT_EQ(CA_STATUS_FAILED, CASendNotification(tempRep, &responseInfo));